All of lore.kernel.org
 help / color / mirror / Atom feed
* [git patches] net driver updates
@ 2007-02-08  0:29 Jeff Garzik
  2007-02-08  6:30 ` Junio C Hamano
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2007-02-08  0:29 UTC (permalink / raw)
  To: netdev; +Cc: LKML


Just sent this upstream...

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 Documentation/feature-removal-schedule.txt    |    7 +
 MAINTAINERS                                   |   18 +-
 drivers/net/3c59x.c                           |    3 +-
 drivers/net/Kconfig                           |   65 +-
 drivers/net/Makefile                          |    6 +-
 drivers/net/Space.c                           |    4 -
 drivers/net/amd8111e.c                        |    3 +-
 drivers/net/b44.c                             |    8 +-
 drivers/net/b44.h                             |   10 +-
 drivers/net/bmac.c                            |   20 +-
 drivers/net/bnx2.c                            |   13 +-
 drivers/net/bonding/bond_main.c               |   23 +-
 drivers/net/bonding/bond_sysfs.c              |   15 +
 drivers/net/bonding/bonding.h                 |    9 +-
 drivers/net/chelsio/common.h                  |    2 +-
 drivers/net/chelsio/cpl5_cmd.h                |   18 +-
 drivers/net/chelsio/cxgb2.c                   |  149 +-
 drivers/net/chelsio/elmer0.h                  |   40 +-
 drivers/net/chelsio/espi.c                    |   44 +-
 drivers/net/chelsio/fpga_defs.h               |    6 +-
 drivers/net/chelsio/gmac.h                    |   11 +-
 drivers/net/chelsio/ixf1010.c                 |  100 +-
 drivers/net/chelsio/mv88e1xxx.c               |   27 +-
 drivers/net/chelsio/my3126.c                  |   16 +-
 drivers/net/chelsio/pm3393.c                  |   91 +-
 drivers/net/chelsio/sge.c                     |  328 ++--
 drivers/net/chelsio/subr.c                    |   89 +-
 drivers/net/chelsio/tp.c                      |   62 +-
 drivers/net/chelsio/vsc7326.c                 |  139 +-
 drivers/net/chelsio/vsc7326_reg.h             |  139 +-
 drivers/net/chelsio/vsc8244.c                 |   41 +-
 drivers/net/cxgb3/Makefile                    |    8 +
 drivers/net/cxgb3/adapter.h                   |  279 ++
 drivers/net/cxgb3/ael1002.c                   |  251 ++
 drivers/net/cxgb3/common.h                    |  729 ++++++
 drivers/net/cxgb3/cxgb3_ctl_defs.h            |  164 ++
 drivers/net/cxgb3/cxgb3_defs.h                |   99 +
 drivers/net/cxgb3/cxgb3_ioctl.h               |  185 ++
 drivers/net/cxgb3/cxgb3_main.c                | 2515 ++++++++++++++++++
 drivers/net/cxgb3/cxgb3_offload.c             | 1222 +++++++++
 drivers/net/cxgb3/cxgb3_offload.h             |  193 ++
 drivers/net/cxgb3/firmware_exports.h          |  177 ++
 drivers/net/cxgb3/l2t.c                       |  450 ++++
 drivers/net/cxgb3/l2t.h                       |  143 ++
 drivers/net/cxgb3/mc5.c                       |  473 ++++
 drivers/net/cxgb3/regs.h                      | 2195 ++++++++++++++++
 drivers/net/cxgb3/sge.c                       | 2681 ++++++++++++++++++++
 drivers/net/cxgb3/sge_defs.h                  |  251 ++
 drivers/net/cxgb3/t3_cpl.h                    | 1444 +++++++++++
 drivers/net/cxgb3/t3_hw.c                     | 3375 +++++++++++++++++++++++++
 drivers/net/cxgb3/t3cdev.h                    |   73 +
 drivers/net/cxgb3/version.h                   |   39 +
 drivers/net/cxgb3/vsc8211.c                   |  228 ++
 drivers/net/cxgb3/xgmac.c                     |  409 +++
 drivers/net/declance.c                        |  164 +-
 drivers/net/e1000/e1000.h                     |    7 -
 drivers/net/e1000/e1000_ethtool.c             |    6 -
 drivers/net/e1000/e1000_main.c                |  128 +-
 drivers/net/e1000/e1000_osdep.h               |    4 +-
 drivers/net/e1000/e1000_param.c               |   15 +-
 drivers/net/forcedeth.c                       | 1342 +++++++----
 drivers/net/hp100.c                           |    2 +-
 drivers/net/ixgb/ixgb.h                       |    2 -
 drivers/net/ixgb/ixgb_ethtool.c               |    6 -
 drivers/net/ixgb/ixgb_main.c                  |    4 -
 drivers/net/macb.c                            |   25 +-
 drivers/net/macb.h                            |    8 +-
 drivers/net/mace.c                            |   16 +-
 drivers/net/macmace.c                         |   18 +-
 drivers/net/macsonic.c                        |    6 +-
 drivers/net/myri10ge/myri10ge.c               |   10 -
 drivers/net/netxen/netxen_nic.h               |   17 +-
 drivers/net/netxen/netxen_nic_ethtool.c       |   96 +-
 drivers/net/netxen/netxen_nic_init.c          |  279 ++-
 drivers/net/oaknet.c                          |  666 -----
 drivers/net/pasemi_mac.c                      | 1019 ++++++++
 drivers/net/pasemi_mac.h                      |  460 ++++
 drivers/net/qla3xxx.c                         |  363 +++-
 drivers/net/qla3xxx.h                         |   88 +-
 drivers/net/s2io-regs.h                       |    7 +-
 drivers/net/s2io.c                            | 1178 +++++-----
 drivers/net/s2io.h                            |  223 +-
 drivers/net/sc92031.c                         | 1620 ++++++++++++
 drivers/net/sk_mca.c                          | 1216 ---------
 drivers/net/sk_mca.h                          |  170 --
 drivers/net/skfp/can.c                        |   83 -
 drivers/net/skfp/drvfbi.c                     |   24 +-
 drivers/net/skfp/fplustm.c                    |    4 +-
 drivers/net/skfp/smt.c                        |   10 +-
 drivers/net/skge.c                            |  235 ++-
 drivers/net/skge.h                            |    2 +
 drivers/net/sky2.c                            |  543 +++--
 drivers/net/sky2.h                            |   85 +-
 drivers/net/spider_net.c                      |  313 ++--
 drivers/net/spider_net.h                      |   20 +-
 drivers/net/spider_net_ethtool.c              |    4 +-
 drivers/net/tg3.c                             |   32 -
 drivers/net/ucc_geth.c                        |   23 +-
 drivers/net/wan/Kconfig                       |   24 +-
 drivers/net/wan/Makefile                      |    1 +
 drivers/net/wan/hdlc.c                        |    3 +-
 drivers/net/wan/pc300too.c                    |  565 +++++
 drivers/net/wan/z85230.c                      |   14 +-
 drivers/net/wireless/bcm43xx/bcm43xx.h        |    7 +-
 drivers/net/wireless/bcm43xx/bcm43xx_leds.c   |   11 +-
 drivers/net/wireless/bcm43xx/bcm43xx_main.c   |   36 +-
 drivers/net/wireless/bcm43xx/bcm43xx_radio.c  |    2 +
 drivers/net/wireless/bcm43xx/bcm43xx_radio.h  |   16 +
 drivers/net/wireless/ipw2200.c                |    4 +-
 drivers/net/wireless/orinoco.c                |    2 +-
 drivers/net/wireless/prism54/islpci_dev.c     |   13 +
 drivers/net/wireless/prism54/islpci_dev.h     |    4 +
 drivers/net/wireless/prism54/islpci_hotplug.c |    3 -
 drivers/net/wireless/zd1211rw/zd_chip.c       |  126 +-
 drivers/net/wireless/zd1211rw/zd_chip.h       |  158 +-
 drivers/net/wireless/zd1211rw/zd_def.h        |    2 +
 drivers/net/wireless/zd1211rw/zd_ieee80211.h  |    1 -
 drivers/net/wireless/zd1211rw/zd_rf.h         |    2 -
 drivers/net/wireless/zd1211rw/zd_types.h      |   71 -
 drivers/net/wireless/zd1211rw/zd_usb.c        |  128 +-
 drivers/net/wireless/zd1211rw/zd_usb.h        |    6 +-
 drivers/usb/net/asix.c                        |    4 +
 drivers/usb/net/pegasus.h                     |    4 +-
 include/linux/pci_ids.h                       |    2 +
 net/ieee80211/softmac/ieee80211softmac_wx.c   |    6 +
 125 files changed, 25584 insertions(+), 5263 deletions(-)
 create mode 100644 drivers/net/cxgb3/Makefile
 create mode 100644 drivers/net/cxgb3/adapter.h
 create mode 100644 drivers/net/cxgb3/ael1002.c
 create mode 100644 drivers/net/cxgb3/common.h
 create mode 100644 drivers/net/cxgb3/cxgb3_ctl_defs.h
 create mode 100644 drivers/net/cxgb3/cxgb3_defs.h
 create mode 100644 drivers/net/cxgb3/cxgb3_ioctl.h
 create mode 100644 drivers/net/cxgb3/cxgb3_main.c
 create mode 100644 drivers/net/cxgb3/cxgb3_offload.c
 create mode 100644 drivers/net/cxgb3/cxgb3_offload.h
 create mode 100644 drivers/net/cxgb3/firmware_exports.h
 create mode 100644 drivers/net/cxgb3/l2t.c
 create mode 100644 drivers/net/cxgb3/l2t.h
 create mode 100644 drivers/net/cxgb3/mc5.c
 create mode 100644 drivers/net/cxgb3/regs.h
 create mode 100644 drivers/net/cxgb3/sge.c
 create mode 100644 drivers/net/cxgb3/sge_defs.h
 create mode 100644 drivers/net/cxgb3/t3_cpl.h
 create mode 100644 drivers/net/cxgb3/t3_hw.c
 create mode 100644 drivers/net/cxgb3/t3cdev.h
 create mode 100644 drivers/net/cxgb3/version.h
 create mode 100644 drivers/net/cxgb3/vsc8211.c
 create mode 100644 drivers/net/cxgb3/xgmac.c
 delete mode 100644 drivers/net/oaknet.c
 create mode 100644 drivers/net/pasemi_mac.c
 create mode 100644 drivers/net/pasemi_mac.h
 mode change 100644 => 100755 drivers/net/qla3xxx.c
 mode change 100644 => 100755 drivers/net/qla3xxx.h
 create mode 100644 drivers/net/sc92031.c
 delete mode 100644 drivers/net/sk_mca.c
 delete mode 100644 drivers/net/sk_mca.h
 delete mode 100644 drivers/net/skfp/can.c
 create mode 100644 drivers/net/wan/pc300too.c
 delete mode 100644 drivers/net/wireless/zd1211rw/zd_types.h

Adrian Bunk (5):
      remove the broken SKMC driver
      make hdlc_setup() static again
      remove the broken OAKNET driver
      bonding.h: "extern inline" -> "static inline"
      remove one remaining "#define BCM_TSO 1"

Ahmed S. Darwish (1):
      UCC Ether driver: kmalloc casting cleanups

Akinobu Mita (1):
      net: use bitrev8

Al Viro (1):
      b44 endian annotations

Alan Cox (1):
      z85230: spinlock logic

Amit S. Kale (2):
      NetXen: Firmware crb init changes.
      NetXen: Added ethtool support for user level tools.

Andrew Morton (1):
      git-netdev-all: chelsio fix

Andrew Victor (1):
      AT91: MACB support

Arjan van de Ven (1):
      remove NETIF_F_TSO ifdefery

Auke Kok (3):
      e1000: clean up debug output defines
      e1000: display flow control of link status at link up
      e1000: update version to 7.3.20-k2

Ayaz Abdulla (12):
      forcedeth: dma access
      forcedeth: ring access
      forcedeth: tx locking
      forcedeth: rx skb recycle
      forcedeth: optimized routines
      forcedeth: tx limiting
      forcedeth: tx data path optimization
      forcedeth: rx data path optimization
      forcedeth: irq data path optimization
      forcedeth: tx max work
      forcedeth: statistics supported
      forcedeth: statistics optimization

Bruce Allan (1):
      e1000: clear ip csum info from context descriptor

Cesar Eduardo Barros (1):
      driver for Silan SC92031 netdev

Daniel Drake (6):
      zd1211rw: Generic HMAC initialization
      zd1211rw: 2 new ZD1211B device ID's
      zd1211rw: Consistency for address space constants
      zd1211rw: Remove addressing abstraction
      zd1211rw: Add ID for Linksys WUSBF54G
      zd1211rw: Add ID for ZyXEL ZyAIR G-220 v2

Divy Le Ray (10):
      Add support for the latest 1G/10G Chelsio adapter, T3.
      cxgb3 - FW versioning
      cxgb3 - bind qsets on multiport adapter
      cxgb3 - remove SW Tx credits coalescing
      cxgb3 - bogus status error string
      cxgb3 - Clean up HW init routine
      cxgb3 - white space to tabs
      cxgb3 - Remove BUG_ON from t3b_intr_napi
      cxgb3 - Add <linux/mutex.h>
      cxgb3 - Add dual licensing

Francois Romieu (7):
      chelsio: move return, break and continue statements on their own line
      chelsio: the return statement is not a function
      chelsio: spaces, tabs and friends
      chelsio: useless curly braces
      chelsio: useless test in cxgb2::remove_one
      chelsio: misc cleanups in sge
      chelsio: tabulate the update of the statistic counters

Hennerich, Michael (1):
      fix unaligned exception in /drivers/net/wireless/orinoco.c

Jay Cliburn (1):
      maintainers: add atl1 maintainers

Jay Vosburgh (4):
      bonding: fix device name allocation error
      bonding: fix error check in sysfs creation
      bonding: modify sysfs support to permit multiple loads
      bonding: update version

Jesse Brandeburg (4):
      e1000: simplify case handling gigabit at half duplex
      e1000: Fix MSI only interrupt handler routine
      e1000: fix NAPI performance on 4-port adapters
      e1000: tune our dynamic itr transmit packet accounting

Jiri Kosina (2):
      NET-3c59x: turn local_save_flags() + local_irq_disable() into local_irq_save()
      NET: turn local_save_flags() + local_irq_disable() into local_irq_save()

John W. Linville (1):
      softmac: avoid assert in ieee80211softmac_wx_get_rate

Kai Engert (1):
      prism54: add ethtool -i interface

Krzysztof Halasa (1):
      PC300too alternative WAN driver

Larry Finger (1):
      bcm43xx: Interrogate hardware-enable switch and update LEDs

Linas Vepstas (14):
      Spidernet DMA coalescing
      Spidernet add net_ratelimit to suppress long output
      Spidernet remove rxramfull tasklet
      Spidernet cleanup un-needed API
      Spidernet RX skb mem leak
      Spidernet another skb mem leak
      Spidernet Cleanup return codes
      Spidernet RX Refill
      Spidernet Remove unused variable
      Spidernet RX Chain tail
      Spidernet Memory barrier
      Spidernet Avoid possible RX chain corruption
      Spidernet RX Debugging printout
      Spidernet: Rework RX linked list

Maciej W. Rozycki (1):
      mips: declance: Driver model for the PMAD-A

Michael Buesch (1):
      Update Prism54 MAINTAINERS entry

Olof Johansson (1):
      PA Semi PWRficient Ethernet driver

Ralf Baechle (1):
      s2io: De-typedef driver.

Richard Knutsson (1):
      hp100: convert pci_module_init() to pci_register_driver()

Robert P. J. Day (1):
      Remove unused kernel config option DLCI_COUNT

Ron Mercer (1):
      qla3xxx: Add support for Qlogic 4032 chip.

shemminger@linux-foundation.org (3):
      sky2: version 1.11.1
      sky2: software rx/tx stats
      sky2: handle network device allocation failure

Sivakumar Subramani (4):
      s2io: Making LRO and UFO as module loadable parameter.
      S2IO: Fixes for reset and link handling.
      s2io: Fixes in updating skb->truesize and code cleanup.
      s2io: Removed enabling of some of the unused interrupts.

Stephen Hemminger (15):
      sky2: better power state management
      chelsio: NAPI speed improvement
      chelsio: more rx speedup
      skge: handle zero address at open
      skge: use dev_printk
      skge: WOL support
      skge: version 1.10
      sky2: add Wake On Lan support
      sky2: use dev_err for error reports
      sky2: TSO support for EC_U
      sky2: safer transmit timeout
      sky2: Yukon Extreme support
      sky2: add new chip ids
      sky2: version 1.12
      sk98lin: planned removal

YOSHIFUJI Hideaki / 吉藤英明 (2):
      ASIX: Add IO-DATA ETG-US2 Support.
      PEGASUS: Fix typo in Corega products.

Zhu Yi (1):
      ipw2200: add iwconfig rts/frag auto support



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-02-08  0:29 [git patches] net driver updates Jeff Garzik
@ 2007-02-08  6:30 ` Junio C Hamano
  2007-02-08 14:30   ` Jeff Garzik
  0 siblings, 1 reply; 101+ messages in thread
From: Junio C Hamano @ 2007-02-08  6:30 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel

Jeff Garzik <jeff@garzik.org> writes:

>  mode change 100644 => 100755 drivers/net/qla3xxx.c
>  mode change 100644 => 100755 drivers/net/qla3xxx.h

Did you mean to have these?  Commit bd36b0ac appears to have
brought the mode bits change in.

Not trying to nitpick --- I am trying to find out if this was
caused by a git bug.



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-02-08  6:30 ` Junio C Hamano
@ 2007-02-08 14:30   ` Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2007-02-08 14:30 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: linux-kernel

Junio C Hamano wrote:
> Jeff Garzik <jeff@garzik.org> writes:
> 
>>  mode change 100644 => 100755 drivers/net/qla3xxx.c
>>  mode change 100644 => 100755 drivers/net/qla3xxx.h
> 
> Did you mean to have these?  Commit bd36b0ac appears to have
> brought the mode bits change in.
> 
> Not trying to nitpick --- I am trying to find out if this was
> caused by a git bug.

No idea, presumably not.

FWIW I never chmod anything source in the kernel tree, so I'm guessing 
that maybe the patch associated with the commit contained mode bits?

	Jeff




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-10-27 23:18 Jeff Garzik
@ 2008-10-28 18:10 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2008-10-28 18:10 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Mon, 27 Oct 2008 19:18:41 -0400

> 
> Note 1: The dm9601 change is, strictly speaking, an addition, but it
> fixes the inability to perform several basic functions related to MAC
> address.
> 
> Please pull from 'davem-fixes' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git davem-fixes
> 
> to receive the following updates:

Pulled, thanks a lot Jeff.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2008-10-27 23:18 Jeff Garzik
  2008-10-28 18:10 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2008-10-27 23:18 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


Note 1: The dm9601 change is, strictly speaking, an addition, but it
fixes the inability to perform several basic functions related to MAC
address.

Please pull from 'davem-fixes' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git davem-fixes

to receive the following updates:

 drivers/net/ehea/ehea.h           |    2 +-
 drivers/net/ehea/ehea_qmr.c       |   57 +++++++++++++++++++++++++++++++++---
 drivers/net/ehea/ehea_qmr.h       |    3 ++
 drivers/net/ibm_newemac/core.c    |    2 +-
 drivers/net/mlx4/en_main.c        |    1 -
 drivers/net/mlx4/fw.c             |    2 +-
 drivers/net/tulip/dmfe.c          |   12 +++++++-
 drivers/net/usb/dm9601.c          |   15 ++++++++++
 drivers/net/via-velocity.c        |   11 ++++--
 drivers/net/wan/syncppp.c         |    5 ++-
 drivers/s390/net/qeth_core_main.c |    3 +-
 drivers/s390/net/qeth_l2_main.c   |   27 ++++++-----------
 drivers/s390/net/qeth_l3_main.c   |   13 +--------
 drivers/s390/net/qeth_l3_sys.c    |    7 ----
 14 files changed, 106 insertions(+), 54 deletions(-)

FUJITA Tomonori (1):
      dmfe: check pci_alloc_consistent errors

Frank Blaschka (2):
      qeth: fix offset error in non prealloc header path
      qeth: remove unnecessary support ckeck in sysfs route6

Huang Weiyi (1):
      mlx4_en: remove duplicated #include

Jeff Garzik (1):
      drivers/net/wan/syncppp: Fix unused-var warnings

Josh Boyer (1):
      ibm_newemac: Fix typo in flow control config option

Peter Korsgaard (1):
      dm9601: runtime mac address change support

Sven Hartge (1):
      via-velocity: use driver string instead of dev->name before register_netdev()

Thomas Klein (1):
      ehea: Detect 16GB hugepages for firmware restriction

Ursula Braun (2):
      qeth: remove non-recover-thread checkings
      qeth: avoid skb_under_panic for malformatted inbound data

Yevgeny Petrilin (1):
      mlx4: Setting the correct offset for default mac address

diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 82dd1a8..002d918 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0094"
+#define DRV_VERSION	"EHEA_0095"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 9b61dc9..9d00687 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -632,10 +632,13 @@ static void ehea_rebuild_busmap(void)
 	}
 }
 
-static int ehea_update_busmap(unsigned long pfn, unsigned long pgnum, int add)
+static int ehea_update_busmap(unsigned long pfn, unsigned long nr_pages, int add)
 {
 	unsigned long i, start_section, end_section;
 
+	if (!nr_pages)
+		return 0;
+
 	if (!ehea_bmap) {
 		ehea_bmap = kzalloc(sizeof(struct ehea_bmap), GFP_KERNEL);
 		if (!ehea_bmap)
@@ -643,7 +646,7 @@ static int ehea_update_busmap(unsigned long pfn, unsigned long pgnum, int add)
 	}
 
 	start_section = (pfn * PAGE_SIZE) / EHEA_SECTSIZE;
-	end_section = start_section + ((pgnum * PAGE_SIZE) / EHEA_SECTSIZE);
+	end_section = start_section + ((nr_pages * PAGE_SIZE) / EHEA_SECTSIZE);
 	/* Mark entries as valid or invalid only; address is assigned later */
 	for (i = start_section; i < end_section; i++) {
 		u64 flag;
@@ -692,10 +695,54 @@ int ehea_rem_sect_bmap(unsigned long pfn, unsigned long nr_pages)
 	return ret;
 }
 
-static int ehea_create_busmap_callback(unsigned long pfn,
-				       unsigned long nr_pages, void *arg)
+static int ehea_is_hugepage(unsigned long pfn)
+{
+	int page_order;
+
+	if (pfn & EHEA_HUGEPAGE_PFN_MASK)
+		return 0;
+
+	page_order = compound_order(pfn_to_page(pfn));
+	if (page_order + PAGE_SHIFT != EHEA_HUGEPAGESHIFT)
+		return 0;
+
+	return 1;
+}
+
+static int ehea_create_busmap_callback(unsigned long initial_pfn,
+				       unsigned long total_nr_pages, void *arg)
 {
-	return ehea_update_busmap(pfn, nr_pages, EHEA_BUSMAP_ADD_SECT);
+	int ret;
+	unsigned long pfn, start_pfn, end_pfn, nr_pages;
+
+	if ((total_nr_pages * PAGE_SIZE) < EHEA_HUGEPAGE_SIZE)
+		return ehea_update_busmap(initial_pfn, total_nr_pages,
+					  EHEA_BUSMAP_ADD_SECT);
+
+	/* Given chunk is >= 16GB -> check for hugepages */
+	start_pfn = initial_pfn;
+	end_pfn = initial_pfn + total_nr_pages;
+	pfn = start_pfn;
+
+	while (pfn < end_pfn) {
+		if (ehea_is_hugepage(pfn)) {
+			/* Add mem found in front of the hugepage */
+			nr_pages = pfn - start_pfn;
+			ret = ehea_update_busmap(start_pfn, nr_pages,
+						 EHEA_BUSMAP_ADD_SECT);
+			if (ret)
+				return ret;
+
+			/* Skip the hugepage */
+			pfn += (EHEA_HUGEPAGE_SIZE / PAGE_SIZE);
+			start_pfn = pfn;
+		} else
+			pfn += (EHEA_SECTSIZE / PAGE_SIZE);
+	}
+
+	/* Add mem found behind the hugepage(s)  */
+	nr_pages = pfn - start_pfn;
+	return ehea_update_busmap(start_pfn, nr_pages, EHEA_BUSMAP_ADD_SECT);
 }
 
 int ehea_create_busmap(void)
diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h
index 1e58dc0..0817c1e 100644
--- a/drivers/net/ehea/ehea_qmr.h
+++ b/drivers/net/ehea/ehea_qmr.h
@@ -40,6 +40,9 @@
 #define EHEA_PAGESIZE          (1UL << EHEA_PAGESHIFT)
 #define EHEA_SECTSIZE          (1UL << 24)
 #define EHEA_PAGES_PER_SECTION (EHEA_SECTSIZE >> EHEA_PAGESHIFT)
+#define EHEA_HUGEPAGESHIFT     34
+#define EHEA_HUGEPAGE_SIZE     (1UL << EHEA_HUGEPAGESHIFT)
+#define EHEA_HUGEPAGE_PFN_MASK ((EHEA_HUGEPAGE_SIZE - 1) >> PAGE_SHIFT)
 
 #if ((1UL << SECTION_SIZE_BITS) < EHEA_SECTSIZE)
 #error eHEA module cannot work if kernel sectionsize < ehea sectionsize
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 2ee2622..901212a 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2605,7 +2605,7 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 		    of_device_is_compatible(np, "ibm,emac-440gr"))
 			dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX;
 		if (of_device_is_compatible(np, "ibm,emac-405ez")) {
-#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CONTROL
+#ifdef CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL
 			dev->features |= EMAC_FTR_NO_FLOW_CONTROL_40x;
 #else
 			printk(KERN_ERR "%s: Flow control not disabled!\n",
diff --git a/drivers/net/mlx4/en_main.c b/drivers/net/mlx4/en_main.c
index 1b0eebf..4b9794e 100644
--- a/drivers/net/mlx4/en_main.c
+++ b/drivers/net/mlx4/en_main.c
@@ -35,7 +35,6 @@
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
-#include <linux/cpumask.h>
 
 #include <linux/mlx4/driver.h>
 #include <linux/mlx4/device.h>
diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index be09fdb..cee199c 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -360,9 +360,9 @@ int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 #define QUERY_PORT_ETH_MTU_OFFSET		0x02
 #define QUERY_PORT_WIDTH_OFFSET			0x06
 #define QUERY_PORT_MAX_GID_PKEY_OFFSET		0x07
-#define QUERY_PORT_MAC_OFFSET			0x08
 #define QUERY_PORT_MAX_MACVLAN_OFFSET		0x0a
 #define QUERY_PORT_MAX_VL_OFFSET		0x0b
+#define QUERY_PORT_MAC_OFFSET			0x10
 
 		for (i = 1; i <= dev_cap->num_ports; ++i) {
 			err = mlx4_cmd_box(dev, 0, mailbox->dma, i, 0, MLX4_CMD_QUERY_PORT,
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c
index 8e46a51..c91852f 100644
--- a/drivers/net/tulip/dmfe.c
+++ b/drivers/net/tulip/dmfe.c
@@ -420,9 +420,13 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
 	/* Allocate Tx/Rx descriptor memory */
 	db->desc_pool_ptr = pci_alloc_consistent(pdev, sizeof(struct tx_desc) *
 			DESC_ALL_CNT + 0x20, &db->desc_pool_dma_ptr);
+	if (!db->desc_pool_ptr)
+		goto err_out_res;
 
 	db->buf_pool_ptr = pci_alloc_consistent(pdev, TX_BUF_ALLOC *
 			TX_DESC_CNT + 4, &db->buf_pool_dma_ptr);
+	if (!db->buf_pool_ptr)
+		goto err_out_free_desc;
 
 	db->first_tx_desc = (struct tx_desc *) db->desc_pool_ptr;
 	db->first_tx_desc_dma = db->desc_pool_dma_ptr;
@@ -469,7 +473,7 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
 
 	err = register_netdev (dev);
 	if (err)
-		goto err_out_res;
+		goto err_out_free_buf;
 
 	printk(KERN_INFO "%s: Davicom DM%04lx at pci%s, "
 	       "%s, irq %d.\n",
@@ -483,6 +487,12 @@ static int __devinit dmfe_init_one (struct pci_dev *pdev,
 
 	return 0;
 
+err_out_free_buf:
+	pci_free_consistent(pdev, TX_BUF_ALLOC * TX_DESC_CNT + 4,
+			    db->buf_pool_ptr, db->buf_pool_dma_ptr);
+err_out_free_desc:
+	pci_free_consistent(pdev, sizeof(struct tx_desc) * DESC_ALL_CNT + 0x20,
+			    db->desc_pool_ptr, db->desc_pool_dma_ptr);
 err_out_res:
 	pci_release_regions(pdev);
 err_out_disable:
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 78df2be..db3377d 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -396,6 +396,20 @@ static void dm9601_set_multicast(struct net_device *net)
 	dm_write_reg_async(dev, DM_RX_CTRL, rx_ctl);
 }
 
+static int dm9601_set_mac_address(struct net_device *net, void *p)
+{
+	struct sockaddr *addr = p;
+	struct usbnet *dev = netdev_priv(net);
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EINVAL;
+
+	memcpy(net->dev_addr, addr->sa_data, net->addr_len);
+	dm_write_async(dev, DM_PHY_ADDR, net->addr_len, net->dev_addr);
+
+	return 0;
+}
+
 static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
 {
 	int ret;
@@ -406,6 +420,7 @@ static int dm9601_bind(struct usbnet *dev, struct usb_interface *intf)
 
 	dev->net->do_ioctl = dm9601_ioctl;
 	dev->net->set_multicast_list = dm9601_set_multicast;
+	dev->net->set_mac_address = dm9601_set_mac_address;
 	dev->net->ethtool_ops = &dm9601_ethtool_ops;
 	dev->net->hard_header_len += DM_TX_OVERHEAD;
 	dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 2dced38..3590ea5 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -521,7 +521,7 @@ static void __devexit velocity_remove1(struct pci_dev *pdev)
  *	we don't duplicate code for each option.
  */
 
-static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max, int def, char *name, char *devname)
+static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max, int def, char *name, const char *devname)
 {
 	if (val == -1)
 		*opt = def;
@@ -550,7 +550,7 @@ static void __devinit velocity_set_int_opt(int *opt, int val, int min, int max,
  *	we don't duplicate code for each option.
  */
 
-static void __devinit velocity_set_bool_opt(u32 * opt, int val, int def, u32 flag, char *name, char *devname)
+static void __devinit velocity_set_bool_opt(u32 * opt, int val, int def, u32 flag, char *name, const char *devname)
 {
 	(*opt) &= (~flag);
 	if (val == -1)
@@ -576,7 +576,7 @@ static void __devinit velocity_set_bool_opt(u32 * opt, int val, int def, u32 fla
  *	for the current device
  */
 
-static void __devinit velocity_get_options(struct velocity_opt *opts, int index, char *devname)
+static void __devinit velocity_get_options(struct velocity_opt *opts, int index, const char *devname)
 {
 
 	velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname);
@@ -863,6 +863,7 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
 	static int first = 1;
 	struct net_device *dev;
 	int i;
+	const char *drv_string;
 	const struct velocity_info_tbl *info = &chip_info_table[ent->driver_data];
 	struct velocity_info *vptr;
 	struct mac_regs __iomem * regs;
@@ -935,7 +936,9 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
 		dev->dev_addr[i] = readb(&regs->PAR[i]);
 
 
-	velocity_get_options(&vptr->options, velocity_nics, dev->name);
+	drv_string = dev_driver_string(&pdev->dev);
+
+	velocity_get_options(&vptr->options, velocity_nics, drv_string);
 
 	/*
 	 *	Mask out the options cannot be set to the chip
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index 327d585..6e92f7b 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -756,10 +756,11 @@ static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
 	case CISCO_ADDR_REQ:
 		/* Stolen from net/ipv4/devinet.c -- SIOCGIFADDR ioctl */
 		{
-		struct in_device *in_dev;
-		struct in_ifaddr *ifa;
 		__be32 addr = 0, mask = htonl(~0U); /* FIXME: is the mask correct? */
 #ifdef CONFIG_INET
+		struct in_device *in_dev;
+		struct in_ifaddr *ifa;
+
 		rcu_read_lock();
 		if ((in_dev = __in_dev_get_rcu(dev)) != NULL)
 		{
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 7de410d..52d2659 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3025,7 +3025,7 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb,
 	struct qdio_buffer *buffer, int is_tso, int *next_element_to_fill,
 	int offset)
 {
-	int length = skb->len - offset;
+	int length = skb->len;
 	int length_here;
 	int element;
 	char *data;
@@ -3037,6 +3037,7 @@ static inline void __qeth_fill_buffer(struct sk_buff *skb,
 
 	if (offset >= 0) {
 		data = skb->data + offset;
+		length -= offset;
 		first_lap = 0;
 	}
 
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 955ba7a..1b1e803 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -373,8 +373,6 @@ static int qeth_l2_stop_card(struct qeth_card *card, int recovery_mode)
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
 
 	qeth_set_allowed_threads(card, 0, 1);
-	if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD))
-		return -ERESTARTSYS;
 	if (card->read.state == CH_STATE_UP &&
 	    card->write.state == CH_STATE_UP &&
 	    (card->state == CARD_STATE_UP)) {
@@ -451,12 +449,15 @@ static void qeth_l2_process_inbound_buffer(struct qeth_card *card,
 			netif_rx(skb);
 			break;
 		case QETH_HEADER_TYPE_OSN:
-			skb_push(skb, sizeof(struct qeth_hdr));
-			skb_copy_to_linear_data(skb, hdr,
+			if (card->info.type == QETH_CARD_TYPE_OSN) {
+				skb_push(skb, sizeof(struct qeth_hdr));
+				skb_copy_to_linear_data(skb, hdr,
 						sizeof(struct qeth_hdr));
-			len = skb->len;
-			card->osn_info.data_cb(skb);
-			break;
+				len = skb->len;
+				card->osn_info.data_cb(skb);
+				break;
+			}
+			/* else unknown */
 		default:
 			dev_kfree_skb_any(skb);
 			QETH_DBF_TEXT(TRACE, 3, "inbunkno");
@@ -975,12 +976,6 @@ static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode)
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
 
 	qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
-	if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD)) {
-		PRINT_WARN("set_online of card %s interrupted by user!\n",
-			   CARD_BUS_ID(card));
-		return -ERESTARTSYS;
-	}
-
 	recover_flag = card->state;
 	rc = ccw_device_set_online(CARD_RDEV(card));
 	if (rc) {
@@ -1091,11 +1086,7 @@ static int __qeth_l2_set_offline(struct ccwgroup_device *cgdev,
 	if (card->dev && netif_carrier_ok(card->dev))
 		netif_carrier_off(card->dev);
 	recover_flag = card->state;
-	if (qeth_l2_stop_card(card, recovery_mode) == -ERESTARTSYS) {
-		PRINT_WARN("Stopping card %s interrupted by user!\n",
-			   CARD_BUS_ID(card));
-		return -ERESTARTSYS;
-	}
+	qeth_l2_stop_card(card, recovery_mode);
 	rc  = ccw_device_set_offline(CARD_DDEV(card));
 	rc2 = ccw_device_set_offline(CARD_WDEV(card));
 	rc3 = ccw_device_set_offline(CARD_RDEV(card));
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 99547de..ed59fed 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2064,8 +2064,6 @@ static int qeth_l3_stop_card(struct qeth_card *card, int recovery_mode)
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
 
 	qeth_set_allowed_threads(card, 0, 1);
-	if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD))
-		return -ERESTARTSYS;
 	if (card->read.state == CH_STATE_UP &&
 	    card->write.state == CH_STATE_UP &&
 	    (card->state == CARD_STATE_UP)) {
@@ -3049,11 +3047,6 @@ static int __qeth_l3_set_online(struct ccwgroup_device *gdev, int recovery_mode)
 	QETH_DBF_HEX(SETUP, 2, &card, sizeof(void *));
 
 	qeth_set_allowed_threads(card, QETH_RECOVER_THREAD, 1);
-	if (qeth_wait_for_threads(card, ~QETH_RECOVER_THREAD)) {
-		PRINT_WARN("set_online of card %s interrupted by user!\n",
-			   CARD_BUS_ID(card));
-		return -ERESTARTSYS;
-	}
 
 	recover_flag = card->state;
 	rc = ccw_device_set_online(CARD_RDEV(card));
@@ -3170,11 +3163,7 @@ static int __qeth_l3_set_offline(struct ccwgroup_device *cgdev,
 	if (card->dev && netif_carrier_ok(card->dev))
 		netif_carrier_off(card->dev);
 	recover_flag = card->state;
-	if (qeth_l3_stop_card(card, recovery_mode) == -ERESTARTSYS) {
-		PRINT_WARN("Stopping card %s interrupted by user!\n",
-			   CARD_BUS_ID(card));
-		return -ERESTARTSYS;
-	}
+	qeth_l3_stop_card(card, recovery_mode);
 	rc  = ccw_device_set_offline(CARD_DDEV(card));
 	rc2 = ccw_device_set_offline(CARD_WDEV(card));
 	rc3 = ccw_device_set_offline(CARD_RDEV(card));
diff --git a/drivers/s390/net/qeth_l3_sys.c b/drivers/s390/net/qeth_l3_sys.c
index 210ddb6..c144b99 100644
--- a/drivers/s390/net/qeth_l3_sys.c
+++ b/drivers/s390/net/qeth_l3_sys.c
@@ -121,9 +121,6 @@ static ssize_t qeth_l3_dev_route6_show(struct device *dev,
 	if (!card)
 		return -EINVAL;
 
-	if (!qeth_is_supported(card, IPA_IPV6))
-		return sprintf(buf, "%s\n", "n/a");
-
 	return qeth_l3_dev_route_show(card, &card->options.route6, buf);
 }
 
@@ -135,10 +132,6 @@ static ssize_t qeth_l3_dev_route6_store(struct device *dev,
 	if (!card)
 		return -EINVAL;
 
-	if (!qeth_is_supported(card, IPA_IPV6)) {
-		return -EOPNOTSUPP;
-	}
-
 	return qeth_l3_dev_route_store(card, &card->options.route6,
 				QETH_PROT_IPV6, buf, count);
 }

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-08-14  9:32 Jeff Garzik
@ 2008-08-14 21:54 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2008-08-14 21:54 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Thu, 14 Aug 2008 05:32:54 -0400

> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem
> 
> to receive the following updates:

Pulled and pushed back out to kernel.org, thanks Jeff.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2008-08-14  9:32 Jeff Garzik
  2008-08-14 21:54 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2008-08-14  9:32 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


Please pull from 'upstream-davem' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

to receive the following updates:

 drivers/net/Kconfig                      |    2 +-
 drivers/net/acenic.c                     |    1 -
 drivers/net/arm/ixp4xx_eth.c             |    6 +-
 drivers/net/atl1e/atl1e_ethtool.c        |    2 +-
 drivers/net/atl1e/atl1e_main.c           |    4 +-
 drivers/net/au1000_eth.c                 |    2 +-
 drivers/net/ax88796.c                    |    4 +-
 drivers/net/bnx2x_link.c                 |    1 -
 drivers/net/bnx2x_main.c                 |    1 -
 drivers/net/cpmac.c                      |    1 -
 drivers/net/e1000e/defines.h             |    2 +-
 drivers/net/e1000e/e1000.h               |    1 +
 drivers/net/e1000e/ethtool.c             |    2 +-
 drivers/net/e1000e/netdev.c              |  185 ++++++++++++++++++++++++--
 drivers/net/e1000e/param.c               |   25 +++-
 drivers/net/gianfar.c                    |    6 +-
 drivers/net/gianfar_sysfs.c              |    1 -
 drivers/net/ipg.h                        |    2 -
 drivers/net/ixgbe/ixgbe_82598.c          |    1 +
 drivers/net/ixgbe/ixgbe_main.c           |    4 +-
 drivers/net/ixgbe/ixgbe_type.h           |    1 +
 drivers/net/myri10ge/myri10ge.c          |    6 +-
 drivers/net/ne.c                         |    4 +-
 drivers/net/netxen/netxen_nic.h          |    7 +-
 drivers/net/netxen/netxen_nic_hw.c       |   59 ++++++---
 drivers/net/netxen/netxen_nic_init.c     |   28 ++--
 drivers/net/netxen/netxen_nic_main.c     |  210 ++++++++++++++----------------
 drivers/net/netxen/netxen_nic_phan_reg.h |    2 +
 drivers/net/ppp_mppe.c                   |    1 -
 drivers/net/pppol2tp.c                   |    1 -
 drivers/net/r6040.c                      |    1 -
 drivers/net/sh_eth.c                     |    1 -
 drivers/net/sky2.c                       |    8 +-
 drivers/net/tehuti.h                     |    1 -
 drivers/net/tlan.c                       |    8 +-
 drivers/net/typhoon.c                    |    1 -
 drivers/net/usb/Kconfig                  |   21 ++--
 drivers/net/usb/hso.c                    |   53 +++++----
 38 files changed, 425 insertions(+), 241 deletions(-)

Adrian Bunk (1):
      [netdrvr] uninline atl1e_setup_mac_ctrl()

Atsushi Nemoto (1):
      [netdrvr] ne: Use CONFIG_MACH_TX49XX

Ben Dooks (1):
      AX88796: Fix locking in ethtool support

Brice Goglin (1):
      myri10ge: myri10ge_fw_name also overrides the rss firmware

Bruce Allan (7):
      e1000e: Return 1 instead of a non-zero value for link up indication
      e1000e: Set InterruptThrottleRate to default when invalid value used
      e1000e: Use skb_copy_to_linear_data_offset introduced in 2.6.22
      e1000e: Increase Tx timeout factor for 10Mbps
      e1000e: increase minimum frame size allowed
      e1000e: test for unusable MSI support
      e1000e: remove unnecessary snippet missed in prior check_options update

David Brownell (1):
      Kconfig: HSO driver bugfixes and updates

Dhananjay Phadke (6):
      netxen: fix mac addr setup
      netxen: fix rxbuf leak across driver reload
      netxen: force link update across ifdown/ifup
      netxen: fix dma watchdog
      netxen: cleanup interrupt code
      netxen: update driver version

Greg Kroah-Hartman (2):
      USB: HSO: make tty_operations const
      USB: HSO: minor fixes due to code review

Huang Weiyi (1):
      [netdrvr] remove unnecessary #include

Jesse Brandeburg (1):
      ixgbe: add cx4 device ID

Mikael Pettersson (1):
      ixp4xx_eth: fix dma_mapping_error() compile errors

Olivier Blin (2):
      hso: fix oops in read/write callbacks
      hso: fix refcounting on the ttyHSx devices

Rafael J. Wysocki (1):
      sky2: Fix suspend/hibernation/shutdown regression with WOL enabled (rev. 2)

Robert Fitzsimons (1):
      tlan: Fix two regressions introduced by 64bit conversion.

Scott Wood (1):
      gianfar: Call gfar_halt_nodisable() from gfar_halt().

Vegard Nossum (1):
      au1000_eth: use 'unsigned long' for irqflags

roel kluin (1):
      atl1e: WAKE_MCAST 2x. 1st WAKE_UCAST?

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4b4cb2b..a5c141c 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1172,7 +1172,7 @@ config ETH16I
 
 config NE2000
 	tristate "NE2000/NE1000 support"
-	depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938
+	depends on NET_ISA || (Q40 && m) || M32R || MACH_TX49XX
 	select CRC32
 	---help---
 	  If you have a network (Ethernet) card of this type, say Y and read
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index e4483de..66de80b 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -52,7 +52,6 @@
 
 #include <linux/module.h>
 #include <linux/moduleparam.h>
-#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
diff --git a/drivers/net/arm/ixp4xx_eth.c b/drivers/net/arm/ixp4xx_eth.c
index 9b777d9..7d5db2e 100644
--- a/drivers/net/arm/ixp4xx_eth.c
+++ b/drivers/net/arm/ixp4xx_eth.c
@@ -551,7 +551,7 @@ static int eth_poll(struct napi_struct *napi, int budget)
 		if ((skb = netdev_alloc_skb(dev, RX_BUFF_SIZE))) {
 			phys = dma_map_single(&dev->dev, skb->data,
 					      RX_BUFF_SIZE, DMA_FROM_DEVICE);
-			if (dma_mapping_error(phys)) {
+			if (dma_mapping_error(&dev->dev, phys)) {
 				dev_kfree_skb(skb);
 				skb = NULL;
 			}
@@ -698,7 +698,7 @@ static int eth_xmit(struct sk_buff *skb, struct net_device *dev)
 #endif
 
 	phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE);
-	if (dma_mapping_error(phys)) {
+	if (dma_mapping_error(&dev->dev, phys)) {
 #ifdef __ARMEB__
 		dev_kfree_skb(skb);
 #else
@@ -883,7 +883,7 @@ static int init_queues(struct port *port)
 		desc->buf_len = MAX_MRU;
 		desc->data = dma_map_single(&port->netdev->dev, data,
 					    RX_BUFF_SIZE, DMA_FROM_DEVICE);
-		if (dma_mapping_error(desc->data)) {
+		if (dma_mapping_error(&port->netdev->dev, desc->data)) {
 			free_buffer(buff);
 			return -EIO;
 		}
diff --git a/drivers/net/atl1e/atl1e_ethtool.c b/drivers/net/atl1e/atl1e_ethtool.c
index cdc3b85..619c658 100644
--- a/drivers/net/atl1e/atl1e_ethtool.c
+++ b/drivers/net/atl1e/atl1e_ethtool.c
@@ -355,7 +355,7 @@ static int atl1e_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
 	struct atl1e_adapter *adapter = netdev_priv(netdev);
 
 	if (wol->wolopts & (WAKE_ARP | WAKE_MAGICSECURE |
-			    WAKE_MCAST | WAKE_BCAST | WAKE_MCAST))
+			    WAKE_UCAST | WAKE_MCAST | WAKE_BCAST))
 		return -EOPNOTSUPP;
 	/* these settings will always override what we currently have */
 	adapter->wol = 0;
diff --git a/drivers/net/atl1e/atl1e_main.c b/drivers/net/atl1e/atl1e_main.c
index 35264c2..82d7be1 100644
--- a/drivers/net/atl1e/atl1e_main.c
+++ b/drivers/net/atl1e/atl1e_main.c
@@ -47,7 +47,7 @@ MODULE_DESCRIPTION("Atheros 1000M Ethernet Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 
-static inline void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter);
+static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter);
 
 static const u16
 atl1e_rx_page_vld_regs[AT_MAX_RECEIVE_QUEUE][AT_PAGE_NUM_PER_QUEUE] =
@@ -1037,7 +1037,7 @@ static inline void atl1e_configure_dma(struct atl1e_adapter *adapter)
 	return;
 }
 
-static inline void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
+static void atl1e_setup_mac_ctrl(struct atl1e_adapter *adapter)
 {
 	u32 value;
 	struct atl1e_hw *hw = &adapter->hw;
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index cb8be49..5ee1b05 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -807,7 +807,7 @@ err_out:
 static int au1000_init(struct net_device *dev)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
-	u32 flags;
+	unsigned long flags;
 	int i;
 	u32 control;
 
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 0b4adf4..a886a4b 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -554,7 +554,7 @@ static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	spin_lock_irqsave(&ax->mii_lock, flags);
 	mii_ethtool_gset(&ax->mii, cmd);
-	spin_lock_irqsave(&ax->mii_lock, flags);
+	spin_unlock_irqrestore(&ax->mii_lock, flags);
 
 	return 0;
 }
@@ -567,7 +567,7 @@ static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 
 	spin_lock_irqsave(&ax->mii_lock, flags);
 	rc = mii_ethtool_sset(&ax->mii, cmd);
-	spin_lock_irqsave(&ax->mii_lock, flags);
+	spin_unlock_irqrestore(&ax->mii_lock, flags);
 
 	return rc;
 }
diff --git a/drivers/net/bnx2x_link.c b/drivers/net/bnx2x_link.c
index 8b92c6a..4ce7fe9 100644
--- a/drivers/net/bnx2x_link.c
+++ b/drivers/net/bnx2x_link.c
@@ -21,7 +21,6 @@
 #include <linux/delay.h>
 #include <linux/ethtool.h>
 #include <linux/mutex.h>
-#include <linux/version.h>
 
 #include "bnx2x_reg.h"
 #include "bnx2x_fw_defs.h"
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index 3e7dc17..971576b 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -44,7 +44,6 @@
 #include <net/ip.h>
 #include <net/tcp.h>
 #include <net/checksum.h>
-#include <linux/version.h>
 #include <net/ip6_checksum.h>
 #include <linux/workqueue.h>
 #include <linux/crc32.h>
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index a7800e5..ec6b0af 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -26,7 +26,6 @@
 #include <linux/errno.h>
 #include <linux/types.h>
 #include <linux/delay.h>
-#include <linux/version.h>
 
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index f823b8b..14b0e6c 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -389,7 +389,7 @@
 
 /* Interrupt Cause Set */
 #define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
-#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_ICS_RXSEQ     E1000_ICR_RXSEQ     /* Rx sequence error */
 #define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */
 
 /* Transmit Descriptor Control */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index cf57050..ac4e506 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -326,6 +326,7 @@ struct e1000_info {
 #define FLAG_RX_CSUM_ENABLED              (1 << 28)
 #define FLAG_TSO_FORCE                    (1 << 29)
 #define FLAG_RX_RESTART_NOW               (1 << 30)
+#define FLAG_MSI_TEST_FAILED              (1 << 31)
 
 #define E1000_RX_DESC_PS(R, i)	    \
 	(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index cf9679f..e21c9e0 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -177,7 +177,7 @@ static u32 e1000_get_link(struct net_device *netdev)
 	u32 status;
 	
 	status = er32(STATUS);
-	return (status & E1000_STATUS_LU);
+	return (status & E1000_STATUS_LU) ? 1 : 0;
 }
 
 static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 05b0b2f..d266510 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -510,9 +510,12 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
 			if (new_skb) {
 				skb_reserve(new_skb, NET_IP_ALIGN);
-				memcpy(new_skb->data - NET_IP_ALIGN,
-				       skb->data - NET_IP_ALIGN,
-				       length + NET_IP_ALIGN);
+				skb_copy_to_linear_data_offset(new_skb,
+							       -NET_IP_ALIGN,
+							       (skb->data -
+								NET_IP_ALIGN),
+							       (length +
+								NET_IP_ALIGN));
 				/* save the skb in buffer_info as good */
 				buffer_info->skb = skb;
 				skb = new_skb;
@@ -1233,26 +1236,36 @@ static irqreturn_t e1000_intr(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
+/**
+ * e1000_request_irq - initialize interrupts
+ *
+ * Attempts to configure interrupts using the best available
+ * capabilities of the hardware and kernel.
+ **/
 static int e1000_request_irq(struct e1000_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	irq_handler_t handler = e1000_intr;
 	int irq_flags = IRQF_SHARED;
 	int err;
 
-	if (!pci_enable_msi(adapter->pdev)) {
-		adapter->flags |= FLAG_MSI_ENABLED;
-		handler = e1000_intr_msi;
-		irq_flags = 0;
+	if (!(adapter->flags & FLAG_MSI_TEST_FAILED)) {
+		err = pci_enable_msi(adapter->pdev);
+		if (!err) {
+			adapter->flags |= FLAG_MSI_ENABLED;
+			irq_flags = 0;
+		}
 	}
 
-	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
-			  netdev);
+	err = request_irq(adapter->pdev->irq,
+			  ((adapter->flags & FLAG_MSI_ENABLED) ?
+				&e1000_intr_msi : &e1000_intr),
+			  irq_flags, netdev->name, netdev);
 	if (err) {
-		e_err("Unable to allocate %s interrupt (return: %d)\n",
-		      adapter->flags & FLAG_MSI_ENABLED ? "MSI":"INTx",	err);
-		if (adapter->flags & FLAG_MSI_ENABLED)
+		if (adapter->flags & FLAG_MSI_ENABLED) {
 			pci_disable_msi(adapter->pdev);
+			adapter->flags &= ~FLAG_MSI_ENABLED;
+		}
+		e_err("Unable to allocate interrupt, Error: %d\n", err);
 	}
 
 	return err;
@@ -2592,6 +2605,135 @@ err:
 }
 
 /**
+ * e1000_intr_msi_test - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ **/
+static irqreturn_t e1000_intr_msi_test(int irq, void *data)
+{
+	struct net_device *netdev = data;
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+	u32 icr = er32(ICR);
+
+	e_dbg("%s: icr is %08X\n", netdev->name, icr);
+	if (icr & E1000_ICR_RXSEQ) {
+		adapter->flags &= ~FLAG_MSI_TEST_FAILED;
+		wmb();
+	}
+
+	return IRQ_HANDLED;
+}
+
+/**
+ * e1000_test_msi_interrupt - Returns 0 for successful test
+ * @adapter: board private struct
+ *
+ * code flow taken from tg3.c
+ **/
+static int e1000_test_msi_interrupt(struct e1000_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct e1000_hw *hw = &adapter->hw;
+	int err;
+
+	/* poll_enable hasn't been called yet, so don't need disable */
+	/* clear any pending events */
+	er32(ICR);
+
+	/* free the real vector and request a test handler */
+	e1000_free_irq(adapter);
+
+	/* Assume that the test fails, if it succeeds then the test
+	 * MSI irq handler will unset this flag */
+	adapter->flags |= FLAG_MSI_TEST_FAILED;
+
+	err = pci_enable_msi(adapter->pdev);
+	if (err)
+		goto msi_test_failed;
+
+	err = request_irq(adapter->pdev->irq, &e1000_intr_msi_test, 0,
+			  netdev->name, netdev);
+	if (err) {
+		pci_disable_msi(adapter->pdev);
+		goto msi_test_failed;
+	}
+
+	wmb();
+
+	e1000_irq_enable(adapter);
+
+	/* fire an unusual interrupt on the test handler */
+	ew32(ICS, E1000_ICS_RXSEQ);
+	e1e_flush();
+	msleep(50);
+
+	e1000_irq_disable(adapter);
+
+	rmb();
+
+	if (adapter->flags & FLAG_MSI_TEST_FAILED) {
+		err = -EIO;
+		e_info("MSI interrupt test failed!\n");
+	}
+
+	free_irq(adapter->pdev->irq, netdev);
+	pci_disable_msi(adapter->pdev);
+
+	if (err == -EIO)
+		goto msi_test_failed;
+
+	/* okay so the test worked, restore settings */
+	e_dbg("%s: MSI interrupt test succeeded!\n", netdev->name);
+msi_test_failed:
+	/* restore the original vector, even if it failed */
+	e1000_request_irq(adapter);
+	return err;
+}
+
+/**
+ * e1000_test_msi - Returns 0 if MSI test succeeds or INTx mode is restored
+ * @adapter: board private struct
+ *
+ * code flow taken from tg3.c, called with e1000 interrupts disabled.
+ **/
+static int e1000_test_msi(struct e1000_adapter *adapter)
+{
+	int err;
+	u16 pci_cmd;
+
+	if (!(adapter->flags & FLAG_MSI_ENABLED))
+		return 0;
+
+	/* disable SERR in case the MSI write causes a master abort */
+	pci_read_config_word(adapter->pdev, PCI_COMMAND, &pci_cmd);
+	pci_write_config_word(adapter->pdev, PCI_COMMAND,
+			      pci_cmd & ~PCI_COMMAND_SERR);
+
+	err = e1000_test_msi_interrupt(adapter);
+
+	/* restore previous setting of command word */
+	pci_write_config_word(adapter->pdev, PCI_COMMAND, pci_cmd);
+
+	/* success ! */
+	if (!err)
+		return 0;
+
+	/* EIO means MSI test failed */
+	if (err != -EIO)
+		return err;
+
+	/* back to INTx mode */
+	e_warn("MSI interrupt test failed, using legacy interrupt.\n");
+
+	e1000_free_irq(adapter);
+
+	err = e1000_request_irq(adapter);
+
+	return err;
+}
+
+/**
  * e1000_open - Called when a network interface is made active
  * @netdev: network interface device structure
  *
@@ -2649,6 +2791,19 @@ static int e1000_open(struct net_device *netdev)
 	if (err)
 		goto err_req_irq;
 
+	/*
+	 * Work around PCIe errata with MSI interrupts causing some chipsets to
+	 * ignore e1000e MSI messages, which means we need to test our MSI
+	 * interrupt now
+	 */
+	{
+		err = e1000_test_msi(adapter);
+		if (err) {
+			e_err("Interrupt allocation failed\n");
+			goto err_req_irq;
+		}
+	}
+
 	/* From here on the code is the same as e1000e_up() */
 	clear_bit(__E1000_DOWN, &adapter->state);
 
@@ -3055,7 +3210,7 @@ static void e1000_watchdog_task(struct work_struct *work)
 			case SPEED_10:
 				txb2b = 0;
 				netdev->tx_queue_len = 10;
-				adapter->tx_timeout_factor = 14;
+				adapter->tx_timeout_factor = 16;
 				break;
 			case SPEED_100:
 				txb2b = 0;
@@ -3721,7 +3876,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
-	if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
+	if ((new_mtu < ETH_ZLEN + ETH_FCS_LEN + VLAN_HLEN) ||
 	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
 		e_err("Invalid MTU setting\n");
 		return -EINVAL;
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index 8effc31..ed912e0 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -324,14 +324,27 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 				adapter->itr = 20000;
 				break;
 			default:
-				e1000_validate_option(&adapter->itr, &opt,
-					adapter);
 				/*
-				 * save the setting, because the dynamic bits
-				 * change itr. clear the lower two bits
-				 * because they are used as control
+				 * Save the setting, because the dynamic bits
+				 * change itr.
 				 */
-				adapter->itr_setting = adapter->itr & ~3;
+				if (e1000_validate_option(&adapter->itr, &opt,
+							  adapter) &&
+				    (adapter->itr == 3)) {
+					/*
+					 * In case of invalid user value,
+					 * default to conservative mode.
+					 */
+					adapter->itr_setting = adapter->itr;
+					adapter->itr = 20000;
+				} else {
+					/*
+					 * Clear the lower two bits because
+					 * they are used as control.
+					 */
+					adapter->itr_setting =
+						adapter->itr & ~3;
+				}
 				break;
 			}
 		} else {
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index ca6cf6e..999d691 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -134,9 +134,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int l
 static void gfar_vlan_rx_register(struct net_device *netdev,
 		                struct vlan_group *grp);
 void gfar_halt(struct net_device *dev);
-#ifdef CONFIG_PM
 static void gfar_halt_nodisable(struct net_device *dev);
-#endif
 void gfar_start(struct net_device *dev);
 static void gfar_clear_exact_match(struct net_device *dev);
 static void gfar_set_mac_for_addr(struct net_device *dev, int num, u8 *addr);
@@ -631,7 +629,6 @@ static void init_registers(struct net_device *dev)
 }
 
 
-#ifdef CONFIG_PM
 /* Halt the receive and transmit queues */
 static void gfar_halt_nodisable(struct net_device *dev)
 {
@@ -657,7 +654,6 @@ static void gfar_halt_nodisable(struct net_device *dev)
 			cpu_relax();
 	}
 }
-#endif
 
 /* Halt the receive and transmit queues */
 void gfar_halt(struct net_device *dev)
@@ -666,6 +662,8 @@ void gfar_halt(struct net_device *dev)
 	struct gfar __iomem *regs = priv->regs;
 	u32 tempval;
 
+	gfar_halt_nodisable(dev);
+
 	/* Disable Rx and Tx */
 	tempval = gfar_read(&regs->maccfg1);
 	tempval &= ~(MACCFG1_RX_EN | MACCFG1_TX_EN);
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index 5116f68..782c201 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -33,7 +33,6 @@
 
 #include <asm/uaccess.h>
 #include <linux/module.h>
-#include <linux/version.h>
 
 #include "gianfar.h"
 
diff --git a/drivers/net/ipg.h b/drivers/net/ipg.h
index e0e718a..dd9318f 100644
--- a/drivers/net/ipg.h
+++ b/drivers/net/ipg.h
@@ -7,7 +7,6 @@
 #ifndef __LINUX_IPG_H
 #define __LINUX_IPG_H
 
-#include <linux/version.h>
 #include <linux/module.h>
 
 #include <linux/kernel.h>
@@ -21,7 +20,6 @@
 #include <linux/etherdevice.h>
 #include <linux/init.h>
 #include <linux/skbuff.h>
-#include <linux/version.h>
 #include <asm/bitops.h>
 
 /*
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index 2f38e84..f96358b 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -190,6 +190,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
 	case IXGBE_DEV_ID_82598AF_SINGLE_PORT:
 	case IXGBE_DEV_ID_82598EB_CX4:
+	case IXGBE_DEV_ID_82598_CX4_DUAL_PORT:
 		media_type = ixgbe_media_type_fiber;
 		break;
 	case IXGBE_DEV_ID_82598AT_DUAL_PORT:
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index e5f3da8..34bca16 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -48,7 +48,7 @@ char ixgbe_driver_name[] = "ixgbe";
 static const char ixgbe_driver_string[] =
 	"Intel(R) 10 Gigabit PCI Express Network Driver";
 
-#define DRV_VERSION "1.3.18-k2"
+#define DRV_VERSION "1.3.18-k4"
 const char ixgbe_driver_version[] = DRV_VERSION;
 static const char ixgbe_copyright[] =
 	 "Copyright (c) 1999-2007 Intel Corporation.";
@@ -72,6 +72,8 @@ static struct pci_device_id ixgbe_pci_tbl[] = {
 	 board_82598 },
 	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598EB_CX4),
 	 board_82598 },
+	{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_82598_CX4_DUAL_PORT),
+	 board_82598 },
 
 	/* required last entry */
 	{0, }
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 1ad7cb9..c0282a2 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -39,6 +39,7 @@
 #define IXGBE_DEV_ID_82598AF_SINGLE_PORT 0x10C7
 #define IXGBE_DEV_ID_82598AT_DUAL_PORT   0x10C8
 #define IXGBE_DEV_ID_82598EB_CX4         0x10DD
+#define IXGBE_DEV_ID_82598_CX4_DUAL_PORT 0x10EC
 
 /* General Registers */
 #define IXGBE_CTRL      0x00000
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index f1de38f..5d76cd0 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -3548,7 +3548,11 @@ static void myri10ge_probe_slices(struct myri10ge_priv *mgp)
 
 	/* try to load the slice aware rss firmware */
 	old_fw = mgp->fw_name;
-	if (old_fw == myri10ge_fw_aligned)
+	if (myri10ge_fw_name != NULL) {
+		dev_info(&mgp->pdev->dev, "overriding rss firmware to %s\n",
+			 myri10ge_fw_name);
+		mgp->fw_name = myri10ge_fw_name;
+	} else if (old_fw == myri10ge_fw_aligned)
 		mgp->fw_name = myri10ge_fw_rss_aligned;
 	else
 		mgp->fw_name = myri10ge_fw_rss_unaligned;
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index 42443d6..fa3ceca 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -118,7 +118,7 @@ bad_clone_list[] __initdata = {
     {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
     {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
     {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
-#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+#ifdef CONFIG_MACH_TX49XX
     {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
 #endif
     {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
@@ -142,7 +142,7 @@ bad_clone_list[] __initdata = {
 #if defined(CONFIG_PLAT_MAPPI)
 #  define DCR_VAL 0x4b
 #elif defined(CONFIG_PLAT_OAKS32R)  || \
-   defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+   defined(CONFIG_MACH_TX49XX)
 #  define DCR_VAL 0x48		/* 8-bit mode */
 #else
 #  define DCR_VAL 0x49
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 93a7b9b..ab871df 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -66,8 +66,8 @@
 
 #define _NETXEN_NIC_LINUX_MAJOR 4
 #define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 0
-#define NETXEN_NIC_LINUX_VERSIONID  "4.0.0"
+#define _NETXEN_NIC_LINUX_SUBVERSION 11
+#define NETXEN_NIC_LINUX_VERSIONID  "4.0.11"
 
 #define NETXEN_VERSION_CODE(a, b, c)	(((a) << 16) + ((b) << 8) + (c))
 
@@ -1615,7 +1615,8 @@ dma_watchdog_wakeup(struct netxen_adapter *adapter)
 
 
 int netxen_is_flash_supported(struct netxen_adapter *adapter);
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[]);
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
+int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac);
 extern void netxen_change_ringparam(struct netxen_adapter *adapter);
 extern int netxen_rom_fast_read(struct netxen_adapter *adapter, int addr,
 				int *valp);
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 9aa20f9..84978f8 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -733,31 +733,56 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
 	return 0;
 }
 
-int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 mac[])
+int netxen_get_flash_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
 {
-	__le32 *pmac = (__le32 *) & mac[0];
+	__le32 *pmac = (__le32 *) mac;
+	u32 offset;
 
-	if (netxen_get_flash_block(adapter,
-				   NETXEN_USER_START +
-				   offsetof(struct netxen_new_user_info,
-					    mac_addr),
-				   FLASH_NUM_PORTS * sizeof(u64), pmac) == -1) {
+	offset = NETXEN_USER_START +
+		offsetof(struct netxen_new_user_info, mac_addr) +
+		adapter->portnum * sizeof(u64);
+
+	if (netxen_get_flash_block(adapter, offset, sizeof(u64), pmac) == -1)
 		return -1;
-	}
+
 	if (*mac == cpu_to_le64(~0ULL)) {
+
+		offset = NETXEN_USER_START_OLD +
+			offsetof(struct netxen_user_old_info, mac_addr) +
+			adapter->portnum * sizeof(u64);
+
 		if (netxen_get_flash_block(adapter,
-					   NETXEN_USER_START_OLD +
-					   offsetof(struct netxen_user_old_info,
-						    mac_addr),
-					   FLASH_NUM_PORTS * sizeof(u64),
-					   pmac) == -1)
+					offset, sizeof(u64), pmac) == -1)
 			return -1;
+
 		if (*mac == cpu_to_le64(~0ULL))
 			return -1;
 	}
 	return 0;
 }
 
+int netxen_p3_get_mac_addr(struct netxen_adapter *adapter, __le64 *mac)
+{
+	uint32_t crbaddr, mac_hi, mac_lo;
+	int pci_func = adapter->ahw.pci_func;
+
+	crbaddr = CRB_MAC_BLOCK_START +
+		(4 * ((pci_func/2) * 3)) + (4 * (pci_func & 1));
+
+	adapter->hw_read_wx(adapter, crbaddr, &mac_lo, 4);
+	adapter->hw_read_wx(adapter, crbaddr+4, &mac_hi, 4);
+
+	mac_hi = cpu_to_le32(mac_hi);
+	mac_lo = cpu_to_le32(mac_lo);
+
+	if (pci_func & 1)
+		*mac = ((mac_lo >> 16) | ((u64)mac_hi << 16));
+	else
+		*mac = ((mac_lo) | ((u64)mac_hi << 32));
+
+	return 0;
+}
+
 #define CRB_WIN_LOCK_TIMEOUT 100000000
 
 static int crb_win_lock(struct netxen_adapter *adapter)
@@ -2183,10 +2208,10 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
 	if (adapter->portnum == 0) {
 		get_brd_name_by_type(board_info->board_type, brd_name);
 
-		printk("NetXen %s Board S/N %s  Chip id 0x%x\n",
-				brd_name, serial_num, board_info->chip_id);
-		printk("NetXen Firmware version %d.%d.%d\n", fw_major,
-				fw_minor, fw_build);
+		printk(KERN_INFO "NetXen %s Board S/N %s  Chip rev 0x%x\n",
+				brd_name, serial_num, adapter->ahw.revision_id);
+		printk(KERN_INFO "NetXen Firmware version %d.%d.%d\n",
+				fw_major, fw_minor, fw_build);
 	}
 
 	if (NETXEN_VERSION_CODE(fw_major, fw_minor, fw_build) <
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 519fc86..5bba675 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1079,10 +1079,12 @@ int netxen_initialize_adapter_offload(struct netxen_adapter *adapter)
 
 void netxen_free_adapter_offload(struct netxen_adapter *adapter)
 {
-	int i;
+	int i = 100;
+
+	if (!adapter->dummy_dma.addr)
+		return;
 
-	if (adapter->dummy_dma.addr) {
-		i = 100;
+	if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
 		do {
 			if (dma_watchdog_shutdown_request(adapter) == 1)
 				break;
@@ -1090,17 +1092,17 @@ void netxen_free_adapter_offload(struct netxen_adapter *adapter)
 			if (dma_watchdog_shutdown_poll_result(adapter) == 1)
 				break;
 		} while (--i);
+	}
 
-		if (i) {
-			pci_free_consistent(adapter->pdev,
-				    NETXEN_HOST_DUMMY_DMA_SIZE,
-				    adapter->dummy_dma.addr,
-				    adapter->dummy_dma.phys_addr);
-			adapter->dummy_dma.addr = NULL;
-		} else {
-			printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
-					adapter->netdev->name);
-		}
+	if (i) {
+		pci_free_consistent(adapter->pdev,
+			    NETXEN_HOST_DUMMY_DMA_SIZE,
+			    adapter->dummy_dma.addr,
+			    adapter->dummy_dma.phys_addr);
+		adapter->dummy_dma.addr = NULL;
+	} else {
+		printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
+				adapter->netdev->name);
 	}
 }
 
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 7615c71..32bb47a 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -149,76 +149,18 @@ static uint32_t msi_tgt_status[8] = {
 
 static struct netxen_legacy_intr_set legacy_intr[] = NX_LEGACY_INTR_CONFIG;
 
-static void netxen_nic_disable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
 {
-	u32 mask = 0x7ff;
-	int retries = 32;
-	int pci_fn = adapter->ahw.pci_func;
-
-	if (adapter->msi_mode != MSI_MODE_MULTIFUNC)
-		adapter->pci_write_normalize(adapter,
-				adapter->crb_intr_mask, 0);
-
-	if (adapter->intr_scheme != -1 &&
-	    adapter->intr_scheme != INTR_SCHEME_PERPORT)
-		adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
-
-	if (!NETXEN_IS_MSI_FAMILY(adapter)) {
-		do {
-			adapter->pci_write_immediate(adapter,
-					adapter->legacy_intr.tgt_status_reg,
-					0xffffffff);
-			mask = adapter->pci_read_immediate(adapter,
-					ISR_INT_VECTOR);
-			if (!(mask & 0x80))
-				break;
-			udelay(10);
-		} while (--retries);
-
-		if (!retries) {
-			printk(KERN_NOTICE "%s: Failed to disable interrupt\n",
-					netxen_nic_driver_name);
-		}
-	} else {
-		if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
-			adapter->pci_write_immediate(adapter,
-					msi_tgt_status[pci_fn], 0xffffffff);
-		}
-	}
+	adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0);
 }
 
-static void netxen_nic_enable_int(struct netxen_adapter *adapter)
+static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
 {
-	u32 mask;
-
-	if (adapter->intr_scheme != -1 &&
-		adapter->intr_scheme != INTR_SCHEME_PERPORT) {
-		switch (adapter->ahw.board_type) {
-		case NETXEN_NIC_GBE:
-			mask  =  0x77b;
-			break;
-		case NETXEN_NIC_XGBE:
-			mask  =  0x77f;
-			break;
-		default:
-			mask  =  0x7ff;
-			break;
-		}
-
-		adapter->pci_write_immediate(adapter, ISR_INT_MASK, mask);
-	}
-
 	adapter->pci_write_normalize(adapter, adapter->crb_intr_mask, 0x1);
 
-	if (!NETXEN_IS_MSI_FAMILY(adapter)) {
-		mask = 0xbff;
-		if (adapter->intr_scheme == INTR_SCHEME_PERPORT)
-			adapter->pci_write_immediate(adapter,
-				adapter->legacy_intr.tgt_mask_reg, mask);
-		else
-			adapter->pci_write_normalize(adapter,
-					CRB_INT_VECTOR, 0);
-	}
+	if (!NETXEN_IS_MSI_FAMILY(adapter))
+		adapter->pci_write_immediate(adapter,
+				adapter->legacy_intr.tgt_mask_reg, 0xfbff);
 }
 
 static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
@@ -501,6 +443,44 @@ static void netxen_init_msix_entries(struct netxen_adapter *adapter)
 		adapter->msix_entries[i].entry = i;
 }
 
+static int
+netxen_read_mac_addr(struct netxen_adapter *adapter)
+{
+	int i;
+	unsigned char *p;
+	__le64 mac_addr;
+	DECLARE_MAC_BUF(mac);
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+
+	if (netxen_is_flash_supported(adapter) != 0)
+		return -EIO;
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		if (netxen_p3_get_mac_addr(adapter, &mac_addr) != 0)
+			return -EIO;
+	} else {
+		if (netxen_get_flash_mac_addr(adapter, &mac_addr) != 0)
+			return -EIO;
+	}
+
+	p = (unsigned char *)&mac_addr;
+	for (i = 0; i < 6; i++)
+		netdev->dev_addr[i] = *(p + 5 - i);
+
+	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
+
+	/* set station address */
+
+	if (!is_valid_ether_addr(netdev->perm_addr)) {
+		dev_warn(&pdev->dev, "Bad MAC address %s.\n",
+				print_mac(mac, netdev->dev_addr));
+	} else
+		adapter->macaddr_set(adapter, netdev->dev_addr);
+
+	return 0;
+}
+
 /*
  * netxen_nic_probe()
  *
@@ -529,10 +509,8 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	unsigned long mem_base, mem_len, db_base, db_len, pci_len0 = 0;
 	int i = 0, err;
 	int first_driver, first_boot;
-	__le64 mac_addr[FLASH_NUM_PORTS + 1];
 	u32 val;
 	int pci_func_id = PCI_FUNC(pdev->devfn);
-	DECLARE_MAC_BUF(mac);
 	struct netxen_legacy_intr_set *legacy_intrp;
 	uint8_t revision_id;
 
@@ -545,6 +523,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		return -ENODEV;
 	}
 
+	if (pdev->revision >= NX_P3_A0 && pdev->revision < NX_P3_B1) {
+		printk(KERN_WARNING "NetXen chip revisions between 0x%x-0x%x"
+				"will not be enabled.\n",
+				NX_P3_A0, NX_P3_B1);
+		return -ENODEV;
+	}
+
 	if ((err = pci_enable_device(pdev)))
 		return err;
 
@@ -898,34 +883,14 @@ request_msi:
 		goto err_out_disable_msi;
 
 	init_timer(&adapter->watchdog_timer);
-	adapter->ahw.linkup = 0;
 	adapter->watchdog_timer.function = &netxen_watchdog;
 	adapter->watchdog_timer.data = (unsigned long)adapter;
 	INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
 	INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
 
-	if (netxen_is_flash_supported(adapter) == 0 &&
-			netxen_get_flash_mac_addr(adapter, mac_addr) == 0) {
-		unsigned char *p;
-
-		p = (unsigned char *)&mac_addr[adapter->portnum];
-		netdev->dev_addr[0] = *(p + 5);
-		netdev->dev_addr[1] = *(p + 4);
-		netdev->dev_addr[2] = *(p + 3);
-		netdev->dev_addr[3] = *(p + 2);
-		netdev->dev_addr[4] = *(p + 1);
-		netdev->dev_addr[5] = *(p + 0);
-
-		memcpy(netdev->perm_addr, netdev->dev_addr,
-			netdev->addr_len);
-		if (!is_valid_ether_addr(netdev->perm_addr)) {
-			printk(KERN_ERR "%s: Bad MAC address %s.\n",
-					netxen_nic_driver_name,
-					print_mac(mac, netdev->dev_addr));
-		} else {
-			adapter->macaddr_set(adapter, netdev->dev_addr);
-		}
-	}
+	err = netxen_read_mac_addr(adapter);
+	if (err)
+		dev_warn(&pdev->dev, "failed to read mac addr\n");
 
 	netif_carrier_off(netdev);
 	netif_stop_queue(netdev);
@@ -1000,6 +965,7 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
 	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
 		netxen_free_hw_resources(adapter);
+		netxen_release_rx_buffers(adapter);
 		netxen_free_sw_resources(adapter);
 	}
 
@@ -1069,6 +1035,15 @@ static int netxen_nic_open(struct net_device *netdev)
 			goto err_out_free_sw;
 		}
 
+		if ((adapter->msi_mode != MSI_MODE_MULTIFUNC) ||
+			(adapter->intr_scheme != INTR_SCHEME_PERPORT)) {
+			printk(KERN_ERR "%s: Firmware interrupt scheme is "
+					"incompatible with driver\n",
+					netdev->name);
+			adapter->driver_mismatch = 1;
+			goto err_out_free_hw;
+		}
+
 		if (adapter->fw_major < 4) {
 			adapter->crb_addr_cmd_producer =
 				crb_cmd_producer[adapter->portnum];
@@ -1094,7 +1069,7 @@ static int netxen_nic_open(struct net_device *netdev)
 				  flags, netdev->name, adapter);
 		if (err) {
 			printk(KERN_ERR "request_irq failed with: %d\n", err);
-			goto err_out_free_hw;
+			goto err_out_free_rxbuf;
 		}
 
 		adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
@@ -1116,6 +1091,7 @@ static int netxen_nic_open(struct net_device *netdev)
 	if (adapter->set_mtu)
 		adapter->set_mtu(adapter, netdev->mtu);
 
+	adapter->ahw.linkup = 0;
 	mod_timer(&adapter->watchdog_timer, jiffies);
 
 	napi_enable(&adapter->napi);
@@ -1127,6 +1103,8 @@ static int netxen_nic_open(struct net_device *netdev)
 
 err_out_free_irq:
 	free_irq(adapter->irq, adapter);
+err_out_free_rxbuf:
+	netxen_release_rx_buffers(adapter);
 err_out_free_hw:
 	netxen_free_hw_resources(adapter);
 err_out_free_sw:
@@ -1152,10 +1130,8 @@ static int netxen_nic_close(struct net_device *netdev)
 
 	netxen_release_tx_buffers(adapter);
 
-	if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
-		FLUSH_SCHEDULED_WORK();
-		del_timer_sync(&adapter->watchdog_timer);
-	}
+	FLUSH_SCHEDULED_WORK();
+	del_timer_sync(&adapter->watchdog_timer);
 
 	return 0;
 }
@@ -1458,7 +1434,8 @@ void netxen_watchdog_task(struct work_struct *work)
 
 	netxen_nic_handle_phy_intr(adapter);
 
-	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+	if (netif_running(adapter->netdev))
+		mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
 }
 
 static void netxen_tx_timeout(struct net_device *netdev)
@@ -1518,18 +1495,9 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
 	return stats;
 }
 
-static inline void
-netxen_handle_int(struct netxen_adapter *adapter)
-{
-	netxen_nic_disable_int(adapter);
-	napi_schedule(&adapter->napi);
-}
-
 static irqreturn_t netxen_intr(int irq, void *data)
 {
 	struct netxen_adapter *adapter = data;
-	u32 our_int = 0;
-
 	u32 status = 0;
 
 	status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
@@ -1544,22 +1512,32 @@ static irqreturn_t netxen_intr(int irq, void *data)
 		if (!ISR_LEGACY_INT_TRIGGERED(status))
 			return IRQ_NONE;
 
-	} else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+	} else {
+		unsigned long our_int = 0;
 
 		our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
+
 		/* not our interrupt */
-		if ((our_int & (0x80 << adapter->portnum)) == 0)
+		if (!test_and_clear_bit((7 + adapter->portnum), &our_int))
 			return IRQ_NONE;
 
-		if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
-			/* claim interrupt */
-			adapter->pci_write_normalize(adapter,
-				CRB_INT_VECTOR,
-				our_int & ~((u32)(0x80 << adapter->portnum)));
-		}
+		/* claim interrupt */
+		adapter->pci_write_normalize(adapter,
+				CRB_INT_VECTOR, (our_int & 0xffffffff));
 	}
 
-	netxen_handle_int(adapter);
+	/* clear interrupt */
+	if (adapter->fw_major < 4)
+		netxen_nic_disable_int(adapter);
+
+	adapter->pci_write_immediate(adapter,
+			adapter->legacy_intr.tgt_status_reg,
+			0xffffffff);
+	/* read twice to ensure write is flushed */
+	adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+	adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+
+	napi_schedule(&adapter->napi);
 
 	return IRQ_HANDLED;
 }
@@ -1568,7 +1546,11 @@ static irqreturn_t netxen_msi_intr(int irq, void *data)
 {
 	struct netxen_adapter *adapter = data;
 
-	netxen_handle_int(adapter);
+	/* clear interrupt */
+	adapter->pci_write_immediate(adapter,
+			msi_tgt_status[adapter->ahw.pci_func], 0xffffffff);
+
+	napi_schedule(&adapter->napi);
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
index 83e5ee5..b293adc 100644
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ b/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -125,6 +125,8 @@
 #define CRB_SW_INT_MASK_2	   NETXEN_NIC_REG(0x1e4)
 #define CRB_SW_INT_MASK_3	   NETXEN_NIC_REG(0x1e8)
 
+#define CRB_MAC_BLOCK_START        NETXEN_CAM_RAM(0x1c0)
+
 /*
  * capabilities register, can be used to selectively enable/disable features
  * for backward compability
diff --git a/drivers/net/ppp_mppe.c b/drivers/net/ppp_mppe.c
index b35d794..88f03c9 100644
--- a/drivers/net/ppp_mppe.c
+++ b/drivers/net/ppp_mppe.c
@@ -46,7 +46,6 @@
 #include <linux/err.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/slab.h>
diff --git a/drivers/net/pppol2tp.c b/drivers/net/pppol2tp.c
index f929882..ff175e8 100644
--- a/drivers/net/pppol2tp.c
+++ b/drivers/net/pppol2tp.c
@@ -61,7 +61,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/string.h>
 #include <linux/list.h>
 #include <asm/uaccess.h>
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 6531ff5..5d86281 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -24,7 +24,6 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/version.h>
 #include <linux/moduleparam.h>
 #include <linux/string.h>
 #include <linux/timer.h>
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 25e62cf..1c370e6 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -20,7 +20,6 @@
  *  the file called "COPYING".
  */
 
-#include <linux/version.h>
 #include <linux/init.h>
 #include <linux/dma-mapping.h>
 #include <linux/etherdevice.h>
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 7d29edc..e24b25c 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -24,7 +24,6 @@
 
 #include <linux/crc32.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/dma-mapping.h>
@@ -666,11 +665,16 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
 
 	if (hw->chip_id != CHIP_ID_YUKON_EC) {
 		if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
-			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+			/* select page 2 to access MAC control register */
+			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 2);
 
+			ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
 			/* enable Power Down */
 			ctrl |= PHY_M_PC_POW_D_ENA;
 			gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+			/* set page register back to 0 */
+			gm_phy_write(hw, port, PHY_MARV_EXT_ADR, 0);
 		}
 
 		/* set IEEE compatible Power Down Mode (dev. #4.99) */
diff --git a/drivers/net/tehuti.h b/drivers/net/tehuti.h
index c66dfc9..7db48f1 100644
--- a/drivers/net/tehuti.h
+++ b/drivers/net/tehuti.h
@@ -27,7 +27,6 @@
 #include <linux/sched.h>
 #include <linux/tty.h>
 #include <linux/if_vlan.h>
-#include <linux/version.h>
 #include <linux/interrupt.h>
 #include <linux/vmalloc.h>
 #include <asm/byteorder.h>
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 85246ed..ec871f6 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -360,8 +360,8 @@ TLan_GetSKB( const struct tlan_list_tag *tag)
 {
 	unsigned long addr;
 
-	addr = tag->buffer[8].address;
-	addr |= (tag->buffer[9].address << 16) << 16;
+	addr = tag->buffer[9].address;
+	addr |= (tag->buffer[8].address << 16) << 16;
 	return (struct sk_buff *) addr;
 }
 
@@ -1984,7 +1984,6 @@ static void TLan_ResetLists( struct net_device *dev )
 	TLanList	*list;
 	dma_addr_t	list_phys;
 	struct sk_buff	*skb;
-	void		*t = NULL;
 
 	priv->txHead = 0;
 	priv->txTail = 0;
@@ -2022,7 +2021,8 @@ static void TLan_ResetLists( struct net_device *dev )
 			}
 
 			skb_reserve( skb, NET_IP_ALIGN );
-			list->buffer[0].address = pci_map_single(priv->pciDev, t,
+			list->buffer[0].address = pci_map_single(priv->pciDev,
+								 skb->data,
 								 TLAN_MAX_FRAME_SIZE,
 								 PCI_DMA_FROMDEVICE);
 			TLan_StoreSKB(list, skb);
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 8549f11..734ce09 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -128,7 +128,6 @@ static const int multicast_filter_limit = 32;
 #include <asm/io.h>
 #include <asm/uaccess.h>
 #include <linux/in6.h>
-#include <linux/version.h>
 #include <linux/dma-mapping.h>
 
 #include "typhoon.h"
diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 68e198b..0973b6e 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -154,17 +154,6 @@ config USB_NET_AX8817X
 	  This driver creates an interface named "ethX", where X depends on
 	  what other networking devices you have in use.
 
-config USB_HSO
-	tristate "Option USB High Speed Mobile Devices"
-	depends on USB && RFKILL
-	default n
-	help
-	  Choose this option if you have an Option HSDPA/HSUPA card.
-	  These cards support downlink speeds of 7.2Mbps or greater.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called hso.
-
 config USB_NET_CDCETHER
 	tristate "CDC Ethernet support (smart devices such as cable modems)"
 	depends on USB_USBNET
@@ -337,5 +326,15 @@ config USB_NET_ZAURUS
 	  really need this non-conformant variant of CDC Ethernet (or in
 	  some cases CDC MDLM) protocol, not "g_ether".
 
+config USB_HSO
+	tristate "Option USB High Speed Mobile Devices"
+	depends on USB && RFKILL
+	default n
+	help
+	  Choose this option if you have an Option HSDPA/HSUPA card.
+	  These cards support downlink speeds of 7.2Mbps or greater.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called hso.
 
 endmenu
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
index 031d07b..1b7cac7 100644
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -102,8 +102,12 @@
 
 #define MAX_RX_URBS			2
 
-#define get_serial_by_tty(x)	\
-	(x ? (struct hso_serial *)x->driver_data : NULL)
+static inline struct hso_serial *get_serial_by_tty(struct tty_struct *tty)
+{
+	if (tty)
+		return tty->driver_data;
+	return NULL;
+}
 
 /*****************************************************************************/
 /* Debugging functions                                                       */
@@ -294,24 +298,25 @@ static int hso_get_activity(struct hso_device *hso_dev);
 
 /* #define DEBUG */
 
-#define dev2net(x) (x->port_data.dev_net)
-#define dev2ser(x) (x->port_data.dev_serial)
+static inline struct hso_net *dev2net(struct hso_device *hso_dev)
+{
+	return hso_dev->port_data.dev_net;
+}
+
+static inline struct hso_serial *dev2ser(struct hso_device *hso_dev)
+{
+	return hso_dev->port_data.dev_serial;
+}
 
 /* Debugging functions */
 #ifdef DEBUG
 static void dbg_dump(int line_count, const char *func_name, unsigned char *buf,
 		     unsigned int len)
 {
-	u8 i = 0;
+	static char name[255];
 
-	printk(KERN_DEBUG "[%d:%s]: len %d", line_count, func_name, len);
-
-	for (i = 0; i < len; i++) {
-		if (!(i % 16))
-			printk("\n    0x%03x:  ", i);
-		printk("%02x ", (unsigned char)buf[i]);
-	}
-	printk("\n");
+	sprintf(name, "hso[%d:%s]", line_count, func_name);
+	print_hex_dump_bytes(name, DUMP_PREFIX_NONE, buf, len);
 }
 
 #define DUMP(buf_, len_)	\
@@ -528,13 +533,12 @@ static struct hso_serial *get_serial_by_shared_int_and_type(
 
 static struct hso_serial *get_serial_by_index(unsigned index)
 {
-	struct hso_serial *serial;
+	struct hso_serial *serial = NULL;
 	unsigned long flags;
 
-	if (!serial_table[index])
-		return NULL;
 	spin_lock_irqsave(&serial_table_lock, flags);
-	serial = dev2ser(serial_table[index]);
+	if (serial_table[index])
+		serial = dev2ser(serial_table[index]);
 	spin_unlock_irqrestore(&serial_table_lock, flags);
 
 	return serial;
@@ -561,6 +565,7 @@ static int get_free_serial_index(void)
 static void set_serial_by_index(unsigned index, struct hso_serial *serial)
 {
 	unsigned long flags;
+
 	spin_lock_irqsave(&serial_table_lock, flags);
 	if (serial)
 		serial_table[index] = serial->parent;
@@ -569,7 +574,7 @@ static void set_serial_by_index(unsigned index, struct hso_serial *serial)
 	spin_unlock_irqrestore(&serial_table_lock, flags);
 }
 
-/* log a meaningfull explanation of an USB status */
+/* log a meaningful explanation of an USB status */
 static void log_usb_status(int status, const char *function)
 {
 	char *explanation;
@@ -1103,8 +1108,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp)
 	/* reset the rts and dtr */
 	/* do the actual close */
 	serial->open_count--;
+	kref_put(&serial->parent->ref, hso_serial_ref_free);
 	if (serial->open_count <= 0) {
-		kref_put(&serial->parent->ref, hso_serial_ref_free);
 		serial->open_count = 0;
 		if (serial->tty) {
 			serial->tty->driver_data = NULL;
@@ -1467,7 +1472,8 @@ static void hso_std_serial_write_bulk_callback(struct urb *urb)
 		return;
 	}
 	hso_put_activity(serial->parent);
-	tty_wakeup(serial->tty);
+	if (serial->tty)
+		tty_wakeup(serial->tty);
 	hso_kick_transmit(serial);
 
 	D1(" ");
@@ -1538,7 +1544,8 @@ static void ctrl_callback(struct urb *urb)
 			clear_bit(HSO_SERIAL_FLAG_RX_SENT, &serial->flags);
 	} else {
 		hso_put_activity(serial->parent);
-		tty_wakeup(serial->tty);
+		if (serial->tty)
+			tty_wakeup(serial->tty);
 		/* response to a write command */
 		hso_kick_transmit(serial);
 	}
@@ -2652,7 +2659,7 @@ static void hso_free_interface(struct usb_interface *interface)
 			hso_stop_net_device(network_table[i]);
 			cancel_work_sync(&network_table[i]->async_put_intf);
 			cancel_work_sync(&network_table[i]->async_get_intf);
-			if(rfk)
+			if (rfk)
 				rfkill_unregister(rfk);
 			hso_free_net_device(network_table[i]);
 		}
@@ -2723,7 +2730,7 @@ static int hso_mux_submit_intr_urb(struct hso_shared_int *shared_int,
 }
 
 /* operations setup of the serial interface */
-static struct tty_operations hso_serial_ops = {
+static const struct tty_operations hso_serial_ops = {
 	.open = hso_serial_open,
 	.close = hso_serial_close,
 	.write = hso_serial_write,

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-08-07  8:50 Jeff Garzik
  2008-08-07  9:19 ` David Miller
@ 2008-08-07 10:09 ` Martin Michlmayr
  1 sibling, 0 replies; 101+ messages in thread
From: Martin Michlmayr @ 2008-08-07 10:09 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David Miller, netdev, LKML

Jeff, it seems you missed this patch:

From: Mikael Pettersson <mikpe@it.uu.se>

The arm ixp4xx_eth driver doesn't compile in 2.6.27-rc1:

  CC [M]  drivers/net/arm/ixp4xx_eth.o
drivers/net/arm/ixp4xx_eth.c: In function 'eth_poll':
drivers/net/arm/ixp4xx_eth.c:554: warning: passing argument 1 of 'dma_mapping_error' makes pointer from integer without a cast
drivers/net/arm/ixp4xx_eth.c:554: error: too few arguments to function 'dma_mapping_error'
drivers/net/arm/ixp4xx_eth.c: In function 'eth_xmit':
drivers/net/arm/ixp4xx_eth.c:701: warning: passing argument 1 of 'dma_mapping_error' makes pointer from integer without a cast
drivers/net/arm/ixp4xx_eth.c:701: error: too few arguments to function 'dma_mapping_error'
drivers/net/arm/ixp4xx_eth.c: In function 'init_queues':
drivers/net/arm/ixp4xx_eth.c:886: warning: passing argument 1 of 'dma_mapping_error' makes pointer from integer without a cast
drivers/net/arm/ixp4xx_eth.c:886: error: too few arguments to function 'dma_mapping_error'
make[3]: *** [drivers/net/arm/ixp4xx_eth.o] Error 1
make[2]: *** [drivers/net/arm] Error 2
make[1]: *** [drivers/net] Error 2
make: *** [drivers] Error 2

dma_mapping_error() changed in 2.6.27-rc1 to also take a device parameter,
but nobody bothered updating ixp4xx_eth.c. Fixed by passing the appropriate
device value in the dma_mapping_error() calls.

Tested on an ixp425 box.

Signed-off-by: Mikael Pettersson <mikpe@it.uu.se>
Acked-by: Krzysztof Halasa <khc@pm.waw.pl>
Signed-off-by: Martin Michlmayr <tbm@cyrius.com>

diff -rupN linux-2.6.27-rc1/drivers/net/arm/ixp4xx_eth.c linux-2.6.27-rc1.arm-ixp4xx_eth-dma_mapping_error-fix/drivers/net/arm/ixp4xx_eth.c
--- linux-2.6.27-rc1/drivers/net/arm/ixp4xx_eth.c	2008-07-29 10:40:10.000000000 +0200
+++ linux-2.6.27-rc1.arm-ixp4xx_eth-dma_mapping_error-fix/drivers/net/arm/ixp4xx_eth.c	2008-08-01 19:38:35.000000000 +0200
@@ -551,7 +551,7 @@ static int eth_poll(struct napi_struct *
 		if ((skb = netdev_alloc_skb(dev, RX_BUFF_SIZE))) {
 			phys = dma_map_single(&dev->dev, skb->data,
 					      RX_BUFF_SIZE, DMA_FROM_DEVICE);
-			if (dma_mapping_error(phys)) {
+			if (dma_mapping_error(&dev->dev, phys)) {
 				dev_kfree_skb(skb);
 				skb = NULL;
 			}
@@ -698,7 +698,7 @@ static int eth_xmit(struct sk_buff *skb,
 #endif
 
 	phys = dma_map_single(&dev->dev, mem, bytes, DMA_TO_DEVICE);
-	if (dma_mapping_error(phys)) {
+	if (dma_mapping_error(&dev->dev, phys)) {
 #ifdef __ARMEB__
 		dev_kfree_skb(skb);
 #else
@@ -883,7 +883,7 @@ static int init_queues(struct port *port
 		desc->buf_len = MAX_MRU;
 		desc->data = dma_map_single(&port->netdev->dev, data,
 					    RX_BUFF_SIZE, DMA_FROM_DEVICE);
-		if (dma_mapping_error(desc->data)) {
+		if (dma_mapping_error(&port->netdev->dev, desc->data)) {
 			free_buffer(buff);
 			return -EIO;
 		}

-- 
Martin Michlmayr
http://www.cyrius.com/

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-08-07  8:50 Jeff Garzik
@ 2008-08-07  9:19 ` David Miller
  2008-08-07 10:09 ` Martin Michlmayr
  1 sibling, 0 replies; 101+ messages in thread
From: David Miller @ 2008-08-07  9:19 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Thu, 7 Aug 2008 04:50:09 -0400

> Rough summary:
> 
> * fixes
> 
> * additions of the variety where only a few lines are added, to support
>   new hardware (forcedeth, netxen)
> 
> * a WAN update that got missed, and IMO should go in for 2.6.27.  This
>   is addressing the complaint about too much stuff still using syncppp,
>   so things get switched more to generic HDLC.  MUCH more typesafe, and
>   links directly with struct net_device, rather than through opaque void
>   pointers and syncppp-specific structs.
> 
> * bonding update with core bits previously ack'd by you
> 
> * that ethtool.h change increasing speed to 32 bits
> 
> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

I've pulled, but the WAN bits were borderline.  If you couldn't pull
that WAN stuff in on time, that's just the way it goes sometimes.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2008-08-07  8:50 Jeff Garzik
  2008-08-07  9:19 ` David Miller
  2008-08-07 10:09 ` Martin Michlmayr
  0 siblings, 2 replies; 101+ messages in thread
From: Jeff Garzik @ 2008-08-07  8:50 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML

Rough summary:

* fixes

* additions of the variety where only a few lines are added, to support
  new hardware (forcedeth, netxen)

* a WAN update that got missed, and IMO should go in for 2.6.27.  This
  is addressing the complaint about too much stuff still using syncppp,
  so things get switched more to generic HDLC.  MUCH more typesafe, and
  links directly with struct net_device, rather than through opaque void
  pointers and syncppp-specific structs.

* bonding update with core bits previously ack'd by you

* that ethtool.h change increasing speed to 32 bits

Please pull from 'upstream-davem' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

to receive the following updates:

 Documentation/DocBook/z8530book.tmpl           |   38 +-
 arch/sh/include/asm/sh_eth.h                   |   11 +
 drivers/char/pcmcia/synclink_cs.c              |    4 -
 drivers/char/synclink.c                        |    4 -
 drivers/char/synclink_gt.c                     |    5 -
 drivers/char/synclinkmp.c                      |    4 -
 drivers/net/3c523.c                            |    4 +-
 drivers/net/3c527.c                            |    9 +-
 drivers/net/3c59x.c                            |   14 +-
 drivers/net/8390.c                             |   13 +-
 drivers/net/8390p.c                            |   19 +-
 drivers/net/Kconfig                            |    5 +-
 drivers/net/atlx/atl1.c                        |   19 +-
 drivers/net/atp.c                              |    9 +-
 drivers/net/bonding/bond_3ad.c                 |    1 +
 drivers/net/bonding/bond_main.c                |  398 ++++++--------
 drivers/net/bonding/bond_sysfs.c               |    3 -
 drivers/net/de620.c                            |    7 -
 drivers/net/dm9000.c                           |    5 +
 drivers/net/e1000e/e1000.h                     |   31 +-
 drivers/net/e1000e/ethtool.c                   |   44 +-
 drivers/net/e1000e/netdev.c                    |  246 ++++-----
 drivers/net/e1000e/param.c                     |   31 +-
 drivers/net/eepro.c                            |    8 -
 drivers/net/eth16i.c                           |    1 -
 drivers/net/forcedeth.c                        |  110 +++--
 drivers/net/fs_enet/mac-fcc.c                  |    2 +-
 drivers/net/gianfar.c                          |    4 -
 drivers/net/hamradio/mkiss.c                   |    2 +-
 drivers/net/igb/e1000_82575.c                  |   72 +---
 drivers/net/igb/e1000_82575.h                  |    1 -
 drivers/net/igb/e1000_defines.h                |    1 +
 drivers/net/igb/e1000_hw.h                     |    1 -
 drivers/net/igb/e1000_mac.c                    |   84 +---
 drivers/net/igb/e1000_mac.h                    |    5 +-
 drivers/net/igb/e1000_regs.h                   |    3 -
 drivers/net/igb/igb_main.c                     |   30 +-
 drivers/net/lp486e.c                           |    2 -
 drivers/net/meth.c                             |    2 +-
 drivers/net/myri10ge/myri10ge.c                |    1 +
 drivers/net/myri10ge/myri10ge_mcp.h            |   52 ++-
 drivers/net/myri10ge/myri10ge_mcp_gen_header.h |    2 +-
 drivers/net/netxen/netxen_nic.h                |   41 ++-
 drivers/net/netxen/netxen_nic_ctx.c            |    9 +-
 drivers/net/netxen/netxen_nic_ethtool.c        |   35 +-
 drivers/net/netxen/netxen_nic_hdr.h            |   10 +
 drivers/net/netxen/netxen_nic_hw.c             |  103 +++--
 drivers/net/netxen/netxen_nic_hw.h             |   13 +-
 drivers/net/netxen/netxen_nic_init.c           |    5 +
 drivers/net/netxen/netxen_nic_main.c           |   99 ++--
 drivers/net/netxen/netxen_nic_niu.c            |   16 +-
 drivers/net/netxen/netxen_nic_phan_reg.h       |    4 +-
 drivers/net/ni5010.c                           |    1 -
 drivers/net/ni52.c                             |    2 +-
 drivers/net/qla3xxx.c                          |   23 +-
 drivers/net/qla3xxx.h                          |  105 ----
 drivers/net/sh_eth.c                           |   69 ++-
 drivers/net/sh_eth.h                           |   22 +-
 drivers/net/sky2.c                             |  103 +----
 drivers/net/sky2.h                             |    2 -
 drivers/net/sun3_82586.c                       |    7 +-
 drivers/net/usb/pegasus.c                      |   21 +
 drivers/net/via-velocity.c                     |  301 ++++++-----
 drivers/net/via-velocity.h                     |   50 +-
 drivers/net/wan/Kconfig                        |   15 +-
 drivers/net/wan/Makefile                       |   11 +-
 drivers/net/wan/cosa.c                         |  293 +++++------
 drivers/net/wan/dscc4.c                        |    1 -
 drivers/net/wan/farsync.c                      |    5 +-
 drivers/net/wan/farsync.h                      |    6 -
 drivers/net/wan/hdlc.c                         |   25 +-
 drivers/net/wan/hdlc_cisco.c                   |   29 +-
 drivers/net/wan/hdlc_fr.c                      |   19 +-
 drivers/net/wan/hdlc_ppp.c                     |   15 +-
 drivers/net/wan/hdlc_raw.c                     |   15 +-
 drivers/net/wan/hdlc_raw_eth.c                 |   17 +-
 drivers/net/wan/hdlc_x25.c                     |   17 +-
 drivers/net/wan/hostess_sv11.c                 |  382 ++++++--------
 drivers/net/wan/lmc/lmc.h                      |   11 +-
 drivers/net/wan/lmc/lmc_debug.c                |    7 +-
 drivers/net/wan/lmc/lmc_debug.h                |    6 +-
 drivers/net/wan/lmc/lmc_ioctl.h                |    2 +-
 drivers/net/wan/lmc/lmc_main.c                 |  672 +++++++++++-------------
 drivers/net/wan/lmc/lmc_media.c                |   66 +--
 drivers/net/wan/lmc/lmc_proto.c                |  146 +-----
 drivers/net/wan/lmc/lmc_proto.h                |   14 +-
 drivers/net/wan/lmc/lmc_var.h                  |  360 +++++--------
 drivers/net/wan/pc300.h                        |  228 ++++-----
 drivers/net/wan/pc300_drv.c                    |  146 +++---
 drivers/net/wan/sealevel.c                     |  361 +++++--------
 drivers/net/wan/syncppp.c                      |    9 -
 drivers/net/wan/z85230.c                       |  193 +++----
 drivers/net/wan/z85230.h                       |   10 +-
 drivers/net/wireless/orinoco.c                 |    7 -
 drivers/net/wireless/wavelan.c                 |    3 -
 drivers/net/wireless/wavelan_cs.c              |    6 -
 drivers/net/xen-netfront.c                     |    2 +-
 include/linux/dm9000.h                         |    1 +
 include/linux/ethtool.h                        |   17 +-
 include/net/syncppp.h                          |    2 -
 net/core/dev.c                                 |   35 +-
 net/wanrouter/wanmain.c                        |   27 -
 102 files changed, 2327 insertions(+), 3202 deletions(-)
 create mode 100644 arch/sh/include/asm/sh_eth.h

Adrian Bunk (1):
      remove bogus CONFIG_GFAR_NAPI's

Alexander Duyck (6):
      igb: fix comments
      igb: fix null pointer dereference seen with fiber NICs
      igb: fixes 82576 serdes init to correctly support manual flow control changes
      igb: correct issue of set_mta member of mac.ops not being populated
      igb: remove three redundant functions left in the code
      igb: remove igb_init_managability as it is deprecated

Andrew Morton (1):
      drivers/net/netxen/netxen_nic_hw.c: fix printk warnings

Auke Kok (1):
      e1000e: perform basic 82573 EEPROM checks for known issues

Ayaz Abdulla (4):
      forcedeth: fix rx error policy
      forcedeth: add new tx stat counters
      forcedeth: add jumbo frame support for mcp79
      forcedeth: add tx pause limit

Ben Collins (1):
      pegasus: add blacklist support to fix Belkin bluetooth dongle.

Brandon Philips (1):
      ethtool: Expand ethtool_cmd.speed to 32 bits

Brice Goglin (2):
      myri10ge: update firmware headers
      myri10ge: set 64bits consistent DMA mask

Bruce Allan (1):
      e1000e: remove inapplicable test for ioport

Dhananjay Phadke (5):
      netxen: fix link status, link speed
      netxen: add new board types
      netxen: fix legacy interrupts
      netxen: fix cmd ring init
      netxen: fix promisc mode, mtu setting

Eduardo Habkost (1):
      xen-netfront: use netif_start_queue() on xennet_open()

Eugene Teo (1):
      hamradio: add missing sanity check to tty operation

Francois Romieu (2):
      via-velocity: separated struct allow wholesale copy during MTU changes.
      via-velocity: velocity_init_{rd/tx}_ring use kcalloc(..., GFP_KERNEL).

Gustavo F. Padovan (3):
      drivers/net: Remove 'return' of void function NS8390p_init()
      drivers/net: coding styles fixes to drivers/net/8390p.c
      drivers/net: coding styles fixes to drivers/net/8390.c

Jay Cliburn (1):
      atl1: deal with hardware rx checksum bug

Jay Vosburgh (1):
      bonding: refactor mii monitor

Jeff Kirsher (1):
      e1000e: convert ndev_ printks to something smaller

Jesse Brandeburg (1):
      e1000e: fix drv load issues

Joe Eykholt (3):
      net/core: Uninline skb_bond().
      net/core: Allow certain receives on inactive slave.
      net/core: Allow receive on active slaves.

Krzysztof Halasa (1):
      WAN: remove extra help text from HDLC_PPP config option

Krzysztof Hałasa (15):
      WAN: cosmetic changes to generic HDLC
      Remove bogus dosyncppp variable from synclink drivers.
      Remove bogus variables from syncppp.[ch]
      Remove dead code from wanmain.c, CONFIG_WANPIPE_MULTPPP doesn't exist
      wanmain.c doesn't need syncppp.h
      WAN: Remove unneeded "#include <net/syncppp.h>"
      WAN: Remove dead code from PC300 driver, part #1
      WAN: Remove dead code from PC300 driver, part #2
      WAN: Convert PC300 driver to use normal u8/u16/u32 types
      WAN: farsync driver no longer uses syncppp.c directly
      WAN: Port COSA driver to generic HDLC.
      WAN: Convert Zilog-based drivers to generic HDLC
      WAN: Port LMC driver to generic HDLC
      WAN: don't mention syncppp in z8530 DocBook.
      WAN: Use u32 type instead of u_int32_t in LMC driver.

Laurent Pinchart (1):
      dm9000: Support MAC address setting through platform data.

Li Yang (1):
      net/fs_enet: remove redundant messages for performance

Moni Shoua (1):
      bonding: Don't destroy bonding master when removing slave via sysfs

Ron Mercer (4):
      qla3xxx: fix: Remove unused set_multicast function.
      qla3xxx: fix: Fix IFF_MULTICAST setting.
      qla3xxx: cleanup: Remove some unused defined constants in the header file.
      qla3xxx: cleanup: Remove some unused structure definitions and structure elements.

Stephen Hemminger (2):
      sky2: fix PM related regressions
      3c59x: use netdev_alloc_skb

Thomas Bogendoerfer (1):
      METH: fix MAC address setup

Wang Chen (1):
      [netdrvr] Drivers should not set IFF_* flag themselves

Yoshinori Sato (1):
      [netdrvr] sh_eth: Add SH7619 support

root (1):
      qla3xxx: driver version change.

diff --git a/Documentation/DocBook/z8530book.tmpl b/Documentation/DocBook/z8530book.tmpl
index 42c75ba..a42a8a4 100644
--- a/Documentation/DocBook/z8530book.tmpl
+++ b/Documentation/DocBook/z8530book.tmpl
@@ -69,12 +69,6 @@
 	device to be used as both a tty interface and as a synchronous 
 	controller is a project for Linux post the 2.4 release
   </para>
-  <para>
-	The support code handles most common card configurations and
-	supports running both Cisco HDLC and Synchronous PPP. With extra
-	glue the frame relay and X.25 protocols can also be used with this
-	driver.
-  </para>
   </chapter>
   
   <chapter id="Driver_Modes">
@@ -179,35 +173,27 @@
   <para>
 	If you wish to use the network interface facilities of the driver,
 	then you need to attach a network device to each channel that is
-	present and in use. In addition to use the SyncPPP and Cisco HDLC
+	present and in use. In addition to use the generic HDLC
 	you need to follow some additional plumbing rules. They may seem 
 	complex but a look at the example hostess_sv11 driver should
 	reassure you.
   </para>
   <para>
 	The network device used for each channel should be pointed to by
-	the netdevice field of each channel. The dev-&gt; priv field of the
+	the netdevice field of each channel. The hdlc-&gt; priv field of the
 	network device points to your private data - you will need to be
-	able to find your ppp device from this. In addition to use the
-	sync ppp layer the private data must start with a void * pointer
-	to the syncppp structures.
+	able to find your private data from this.
   </para>
   <para>
 	The way most drivers approach this particular problem is to
 	create a structure holding the Z8530 device definition and
-	put that and the syncppp pointer into the private field of
-	the network device. The network device fields of the channels
-	then point back to the network devices. The ppp_device can also
-	be put in the private structure conveniently.
+	put that into the private field of the network device. The
+	network device fields of the channels then point back to the
+	network devices.
   </para>
   <para>
-	If you wish to use the synchronous ppp then you need to attach
-	the syncppp layer to the network device. You should do this before
-	you register the network device. The
-	<function>sppp_attach</function> requires that the first void *
-	pointer in your private data is pointing to an empty struct
-	ppp_device. The function fills in the initial data for the
-	ppp/hdlc layer.
+	If you wish to use the generic HDLC then you need to register
+	the HDLC device.
   </para>
   <para>
 	Before you register your network device you will also need to
@@ -314,10 +300,10 @@
 	buffer in sk_buff format and queues it for transmission. The
 	caller must provide the entire packet with the exception of the
 	bitstuffing and CRC. This is normally done by the caller via
-	the syncppp interface layer. It returns 0 if the buffer has been 
-        queued and non zero values  for queue full. If the function accepts 
-	the buffer it becomes property of the Z8530 layer and the caller 
-	should not free it. 
+	the generic HDLC interface layer. It returns 0 if the buffer has been
+	queued and non zero values for queue full. If the function accepts
+	the buffer it becomes property of the Z8530 layer and the caller
+	should not free it.
   </para>
   <para>
 	The function <function>z8530_get_stats</function> returns a pointer
diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h
new file mode 100644
index 0000000..bb83258
--- /dev/null
+++ b/arch/sh/include/asm/sh_eth.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_SH_ETH_H__
+#define __ASM_SH_ETH_H__
+
+enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN};
+
+struct sh_eth_plat_data {
+	int phy;
+	int edmac_endian;
+};
+
+#endif
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index d1fceab..c240562 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -232,7 +232,6 @@ typedef struct _mgslpc_info {
 
 	/* SPPP/Cisco HDLC device parts */
 	int netcount;
-	int dosyncppp;
 	spinlock_t netlock;
 
 #if SYNCLINK_GENERIC_HDLC
@@ -459,13 +458,11 @@ static int ttymajor=0;
 
 static int debug_level = 0;
 static int maxframe[MAX_DEVICE_COUNT] = {0,};
-static int dosyncppp[MAX_DEVICE_COUNT] = {1,1,1,1};
 
 module_param(break_on_load, bool, 0);
 module_param(ttymajor, int, 0);
 module_param(debug_level, int, 0);
 module_param_array(maxframe, int, NULL, 0);
-module_param_array(dosyncppp, int, NULL, 0);
 
 MODULE_LICENSE("GPL");
 
@@ -2915,7 +2912,6 @@ static void mgslpc_add_device(MGSLPC_INFO *info)
 	if (info->line < MAX_DEVICE_COUNT) {
 		if (maxframe[info->line])
 			info->max_frame_size = maxframe[info->line];
-		info->dosyncppp = dosyncppp[info->line];
 	}
 
 	mgslpc_device_count++;
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ef6706f..500f517 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -304,7 +304,6 @@ struct mgsl_struct {
 
 	/* generic HDLC device parts */
 	int netcount;
-	int dosyncppp;
 	spinlock_t netlock;
 
 #if SYNCLINK_GENERIC_HDLC
@@ -868,7 +867,6 @@ static int irq[MAX_ISA_DEVICES];
 static int dma[MAX_ISA_DEVICES];
 static int debug_level;
 static int maxframe[MAX_TOTAL_DEVICES];
-static int dosyncppp[MAX_TOTAL_DEVICES];
 static int txdmabufs[MAX_TOTAL_DEVICES];
 static int txholdbufs[MAX_TOTAL_DEVICES];
 	
@@ -879,7 +877,6 @@ module_param_array(irq, int, NULL, 0);
 module_param_array(dma, int, NULL, 0);
 module_param(debug_level, int, 0);
 module_param_array(maxframe, int, NULL, 0);
-module_param_array(dosyncppp, int, NULL, 0);
 module_param_array(txdmabufs, int, NULL, 0);
 module_param_array(txholdbufs, int, NULL, 0);
 
@@ -4258,7 +4255,6 @@ static void mgsl_add_device( struct mgsl_struct *info )
 	if (info->line < MAX_TOTAL_DEVICES) {
 		if (maxframe[info->line])
 			info->max_frame_size = maxframe[info->line];
-		info->dosyncppp = dosyncppp[info->line];
 
 		if (txdmabufs[info->line]) {
 			info->num_tx_dma_buffers = txdmabufs[info->line];
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 3e90589..509c89a 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -128,17 +128,14 @@ static int slgt_device_count;
 static int ttymajor;
 static int debug_level;
 static int maxframe[MAX_DEVICES];
-static int dosyncppp[MAX_DEVICES];
 
 module_param(ttymajor, int, 0);
 module_param(debug_level, int, 0);
 module_param_array(maxframe, int, NULL, 0);
-module_param_array(dosyncppp, int, NULL, 0);
 
 MODULE_PARM_DESC(ttymajor, "TTY major device number override: 0=auto assigned");
 MODULE_PARM_DESC(debug_level, "Debug syslog output: 0=disabled, 1 to 5=increasing detail");
 MODULE_PARM_DESC(maxframe, "Maximum frame size used by device (4096 to 65535)");
-MODULE_PARM_DESC(dosyncppp, "Enable synchronous net device, 0=disable 1=enable");
 
 /*
  * tty support and callbacks
@@ -349,7 +346,6 @@ struct slgt_info {
 	/* SPPP/Cisco HDLC device parts */
 
 	int netcount;
-	int dosyncppp;
 	spinlock_t netlock;
 #if SYNCLINK_GENERIC_HDLC
 	struct net_device *netdev;
@@ -3405,7 +3401,6 @@ static void add_device(struct slgt_info *info)
 	if (info->line < MAX_DEVICES) {
 		if (maxframe[info->line])
 			info->max_frame_size = maxframe[info->line];
-		info->dosyncppp = dosyncppp[info->line];
 	}
 
 	slgt_device_count++;
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index c0490cb..6bdb44f 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -270,7 +270,6 @@ typedef struct _synclinkmp_info {
 
 	/* SPPP/Cisco HDLC device parts */
 	int netcount;
-	int dosyncppp;
 	spinlock_t netlock;
 
 #if SYNCLINK_GENERIC_HDLC
@@ -469,13 +468,11 @@ static int ttymajor = 0;
  */
 static int debug_level = 0;
 static int maxframe[MAX_DEVICES] = {0,};
-static int dosyncppp[MAX_DEVICES] = {0,};
 
 module_param(break_on_load, bool, 0);
 module_param(ttymajor, int, 0);
 module_param(debug_level, int, 0);
 module_param_array(maxframe, int, NULL, 0);
-module_param_array(dosyncppp, int, NULL, 0);
 
 static char *driver_name = "SyncLink MultiPort driver";
 static char *driver_version = "$Revision: 4.38 $";
@@ -3752,7 +3749,6 @@ static void add_device(SLMP_INFO *info)
 	if (info->line < MAX_DEVICES) {
 		if (maxframe[info->line])
 			info->max_frame_size = maxframe[info->line];
-		info->dosyncppp = dosyncppp[info->line];
 	}
 
 	synclinkmp_device_count++;
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index dc6e474..e2ce41d 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -640,10 +640,8 @@ static int init586(struct net_device *dev)
 	cfg_cmd->time_low = 0x00;
 	cfg_cmd->time_high = 0xf2;
 	cfg_cmd->promisc = 0;
-	if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
+	if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC))
 		cfg_cmd->promisc = 1;
-		dev->flags |= IFF_PROMISC;
-	}
 	cfg_cmd->carr_coll = 0x00;
 
 	p->scb->cbl_offset = make16(cfg_cmd);
diff --git a/drivers/net/3c527.c b/drivers/net/3c527.c
index 6aca0c6..abc84f7 100644
--- a/drivers/net/3c527.c
+++ b/drivers/net/3c527.c
@@ -1521,14 +1521,11 @@ static void do_mc32_set_multicast_list(struct net_device *dev, int retry)
 	struct mc32_local *lp = netdev_priv(dev);
 	u16 filt = (1<<2); /* Save Bad Packets, for stats purposes */
 
-	if (dev->flags&IFF_PROMISC)
+	if ((dev->flags&IFF_PROMISC) ||
+	    (dev->flags&IFF_ALLMULTI) ||
+	    dev->mc_count > 10)
 		/* Enable promiscuous mode */
 		filt |= 1;
-	else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > 10)
-	{
-		dev->flags|=IFF_PROMISC;
-		filt |= 1;
-	}
 	else if(dev->mc_count)
 	{
 		unsigned char block[62];
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 8db4e6b..491ee16 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1692,12 +1692,14 @@ vortex_open(struct net_device *dev)
 			vp->rx_ring[i].next = cpu_to_le32(vp->rx_ring_dma + sizeof(struct boom_rx_desc) * (i+1));
 			vp->rx_ring[i].status = 0;	/* Clear complete bit. */
 			vp->rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LAST_FRAG);
-			skb = dev_alloc_skb(PKT_BUF_SZ);
+
+			skb = __netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN,
+						 GFP_KERNEL);
 			vp->rx_skbuff[i] = skb;
 			if (skb == NULL)
 				break;			/* Bad news!  */
-			skb->dev = dev;			/* Mark as being used by this device. */
-			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
+
+			skb_reserve(skb, NET_IP_ALIGN);	/* Align IP on 16 byte boundaries */
 			vp->rx_ring[i].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 		}
 		if (i != RX_RING_SIZE) {
@@ -2538,7 +2540,7 @@ boomerang_rx(struct net_device *dev)
 		struct sk_buff *skb;
 		entry = vp->dirty_rx % RX_RING_SIZE;
 		if (vp->rx_skbuff[entry] == NULL) {
-			skb = dev_alloc_skb(PKT_BUF_SZ);
+			skb = netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN);
 			if (skb == NULL) {
 				static unsigned long last_jif;
 				if (time_after(jiffies, last_jif + 10 * HZ)) {
@@ -2549,8 +2551,8 @@ boomerang_rx(struct net_device *dev)
 					mod_timer(&vp->rx_oom_timer, RUN_AT(HZ * 1));
 				break;			/* Bad news!  */
 			}
-			skb->dev = dev;			/* Mark as being used by this device. */
-			skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
+
+			skb_reserve(skb, NET_IP_ALIGN);
 			vp->rx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, PKT_BUF_SZ, PCI_DMA_FROMDEVICE));
 			vp->rx_skbuff[entry] = skb;
 		}
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index dc5d258..f72a2e8 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -9,42 +9,39 @@ int ei_open(struct net_device *dev)
 {
 	return __ei_open(dev);
 }
+EXPORT_SYMBOL(ei_open);
 
 int ei_close(struct net_device *dev)
 {
 	return __ei_close(dev);
 }
+EXPORT_SYMBOL(ei_close);
 
 irqreturn_t ei_interrupt(int irq, void *dev_id)
 {
 	return __ei_interrupt(irq, dev_id);
 }
+EXPORT_SYMBOL(ei_interrupt);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 void ei_poll(struct net_device *dev)
 {
 	__ei_poll(dev);
 }
+EXPORT_SYMBOL(ei_poll);
 #endif
 
 struct net_device *__alloc_ei_netdev(int size)
 {
 	return ____alloc_ei_netdev(size);
 }
+EXPORT_SYMBOL(__alloc_ei_netdev);
 
 void NS8390_init(struct net_device *dev, int startp)
 {
 	__NS8390_init(dev, startp);
 }
-
-EXPORT_SYMBOL(ei_open);
-EXPORT_SYMBOL(ei_close);
-EXPORT_SYMBOL(ei_interrupt);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-EXPORT_SYMBOL(ei_poll);
-#endif
 EXPORT_SYMBOL(NS8390_init);
-EXPORT_SYMBOL(__alloc_ei_netdev);
 
 #if defined(MODULE)
 
diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c
index 71f1988..4c6eea4 100644
--- a/drivers/net/8390p.c
+++ b/drivers/net/8390p.c
@@ -4,9 +4,9 @@ static const char version[] =
     "8390p.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
 
 #define ei_inb(_p)	inb(_p)
-#define ei_outb(_v,_p)	outb(_v,_p)
+#define ei_outb(_v, _p)	outb(_v, _p)
 #define ei_inb_p(_p)	inb_p(_p)
-#define ei_outb_p(_v,_p) outb_p(_v,_p)
+#define ei_outb_p(_v, _p) outb_p(_v, _p)
 
 #include "lib8390.c"
 
@@ -14,42 +14,39 @@ int eip_open(struct net_device *dev)
 {
 	return __ei_open(dev);
 }
+EXPORT_SYMBOL(eip_open);
 
 int eip_close(struct net_device *dev)
 {
 	return __ei_close(dev);
 }
+EXPORT_SYMBOL(eip_close);
 
 irqreturn_t eip_interrupt(int irq, void *dev_id)
 {
 	return __ei_interrupt(irq, dev_id);
 }
+EXPORT_SYMBOL(eip_interrupt);
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 void eip_poll(struct net_device *dev)
 {
 	__ei_poll(dev);
 }
+EXPORT_SYMBOL(eip_poll);
 #endif
 
 struct net_device *__alloc_eip_netdev(int size)
 {
 	return ____alloc_ei_netdev(size);
 }
+EXPORT_SYMBOL(__alloc_eip_netdev);
 
 void NS8390p_init(struct net_device *dev, int startp)
 {
-	return __NS8390_init(dev, startp);
+	__NS8390_init(dev, startp);
 }
-
-EXPORT_SYMBOL(eip_open);
-EXPORT_SYMBOL(eip_close);
-EXPORT_SYMBOL(eip_interrupt);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-EXPORT_SYMBOL(eip_poll);
-#endif
 EXPORT_SYMBOL(NS8390p_init);
-EXPORT_SYMBOL(__alloc_eip_netdev);
 
 #if defined(MODULE)
 
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 8a03875..4b4cb2b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -510,14 +510,15 @@ config STNIC
 config SH_ETH
 	tristate "Renesas SuperH Ethernet support"
 	depends on SUPERH && \
-		(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7763)
+		(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7763 || \
+		 CPU_SUBTYPE_SH7619)
 	select CRC32
 	select MII
 	select MDIO_BITBANG
 	select PHYLIB
 	help
 	  Renesas SuperH Ethernet device driver.
-	  This driver support SH7710, SH7712 and SH7763.
+	  This driver support SH7710, SH7712, SH7763 and SH7619.
 
 config SUNLANCE
 	tristate "Sun LANCE support"
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index f12e3d1..e6a7bb7 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -1790,6 +1790,17 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
 {
 	struct pci_dev *pdev = adapter->pdev;
 
+	/*
+	 * The L1 hardware contains a bug that erroneously sets the
+	 * PACKET_FLAG_ERR and ERR_FLAG_L4_CHKSUM bits whenever a
+	 * fragmented IP packet is received, even though the packet
+	 * is perfectly valid and its checksum is correct. There's
+	 * no way to distinguish between one of these good packets
+	 * and a packet that actually contains a TCP/UDP checksum
+	 * error, so all we can do is allow it to be handed up to
+	 * the higher layers and let it be sorted out there.
+	 */
+
 	skb->ip_summed = CHECKSUM_NONE;
 
 	if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
@@ -1816,14 +1827,6 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
 		return;
 	}
 
-	/* IPv4, but hardware thinks its checksum is wrong */
-	if (netif_msg_rx_err(adapter))
-		dev_printk(KERN_DEBUG, &pdev->dev,
-			"hw csum wrong, pkt_flag:%x, err_flag:%x\n",
-			rrd->pkt_flg, rrd->err_flg);
-	skb->ip_summed = CHECKSUM_COMPLETE;
-	skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum);
-	adapter->hw_csum_err++;
 	return;
 }
 
diff --git a/drivers/net/atp.c b/drivers/net/atp.c
index 3d44333..c10cd80 100644
--- a/drivers/net/atp.c
+++ b/drivers/net/atp.c
@@ -854,14 +854,9 @@ static void set_rx_mode_8002(struct net_device *dev)
 	struct net_local *lp = netdev_priv(dev);
 	long ioaddr = dev->base_addr;
 
-	if ( dev->mc_count > 0 || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC))) {
-		/* We must make the kernel realise we had to move
-		 *	into promisc mode or we start all out war on
-		 *	the cable. - AC
-		 */
-		dev->flags|=IFF_PROMISC;
+	if (dev->mc_count > 0 || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC)))
 		lp->addr_mode = CMR2h_PROMISC;
-	} else
+	else
 		lp->addr_mode = CMR2h_Normal;
 	write_reg_high(ioaddr, CMR2, lp->addr_mode);
 }
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index ebb539e..6106660 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2107,6 +2107,7 @@ void bond_3ad_state_machine_handler(struct work_struct *work)
 			aggregator = __get_first_agg(port);
 			ad_agg_selection_logic(aggregator);
 		}
+		bond_3ad_set_carrier(bond);
 	}
 
 	// for each port run the state machines
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index a641eea..c792138 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2223,272 +2223,217 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
 
 /*-------------------------------- Monitoring -------------------------------*/
 
-/*
- * if !have_locks, return nonzero if a failover is necessary.  if
- * have_locks, do whatever failover activities are needed.
- *
- * This is to separate the inspection and failover steps for locking
- * purposes; failover requires rtnl, but acquiring it for every
- * inspection is undesirable, so a wrapper first does inspection, and
- * the acquires the necessary locks and calls again to perform
- * failover if needed.  Since all locks are dropped, a complete
- * restart is needed between calls.
- */
-static int __bond_mii_monitor(struct bonding *bond, int have_locks)
-{
-	struct slave *slave, *oldcurrent;
-	int do_failover = 0;
-	int i;
-
-	if (bond->slave_cnt == 0)
-		goto out;
 
-	/* we will try to read the link status of each of our slaves, and
-	 * set their IFF_RUNNING flag appropriately. For each slave not
-	 * supporting MII status, we won't do anything so that a user-space
-	 * program could monitor the link itself if needed.
-	 */
-
-	read_lock(&bond->curr_slave_lock);
-	oldcurrent = bond->curr_active_slave;
-	read_unlock(&bond->curr_slave_lock);
+static int bond_miimon_inspect(struct bonding *bond)
+{
+	struct slave *slave;
+	int i, link_state, commit = 0;
 
 	bond_for_each_slave(bond, slave, i) {
-		struct net_device *slave_dev = slave->dev;
-		int link_state;
-		u16 old_speed = slave->speed;
-		u8 old_duplex = slave->duplex;
+		slave->new_link = BOND_LINK_NOCHANGE;
 
-		link_state = bond_check_dev_link(bond, slave_dev, 0);
+		link_state = bond_check_dev_link(bond, slave->dev, 0);
 
 		switch (slave->link) {
-		case BOND_LINK_UP:	/* the link was up */
-			if (link_state == BMSR_LSTATUS) {
-				if (!oldcurrent) {
-					if (!have_locks)
-						return 1;
-					do_failover = 1;
-				}
-				break;
-			} else { /* link going down */
-				slave->link  = BOND_LINK_FAIL;
-				slave->delay = bond->params.downdelay;
-
-				if (slave->link_failure_count < UINT_MAX) {
-					slave->link_failure_count++;
-				}
+		case BOND_LINK_UP:
+			if (link_state)
+				continue;
 
-				if (bond->params.downdelay) {
-					printk(KERN_INFO DRV_NAME
-					       ": %s: link status down for %s "
-					       "interface %s, disabling it in "
-					       "%d ms.\n",
-					       bond->dev->name,
-					       IS_UP(slave_dev)
-					       ? ((bond->params.mode == BOND_MODE_ACTIVEBACKUP)
-						  ? ((slave == oldcurrent)
-						     ? "active " : "backup ")
-						  : "")
-					       : "idle ",
-					       slave_dev->name,
-					       bond->params.downdelay * bond->params.miimon);
-				}
+			slave->link = BOND_LINK_FAIL;
+			slave->delay = bond->params.downdelay;
+			if (slave->delay) {
+				printk(KERN_INFO DRV_NAME
+				       ": %s: link status down for %s"
+				       "interface %s, disabling it in %d ms.\n",
+				       bond->dev->name,
+				       (bond->params.mode ==
+					BOND_MODE_ACTIVEBACKUP) ?
+				       ((slave->state == BOND_STATE_ACTIVE) ?
+					"active " : "backup ") : "",
+				       slave->dev->name,
+				       bond->params.downdelay * bond->params.miimon);
 			}
-			/* no break ! fall through the BOND_LINK_FAIL test to
-			   ensure proper action to be taken
-			*/
-		case BOND_LINK_FAIL:	/* the link has just gone down */
-			if (link_state != BMSR_LSTATUS) {
-				/* link stays down */
-				if (slave->delay <= 0) {
-					if (!have_locks)
-						return 1;
-
-					/* link down for too long time */
-					slave->link = BOND_LINK_DOWN;
-
-					/* in active/backup mode, we must
-					 * completely disable this interface
-					 */
-					if ((bond->params.mode == BOND_MODE_ACTIVEBACKUP) ||
-					    (bond->params.mode == BOND_MODE_8023AD)) {
-						bond_set_slave_inactive_flags(slave);
-					}
-
-					printk(KERN_INFO DRV_NAME
-					       ": %s: link status definitely "
-					       "down for interface %s, "
-					       "disabling it\n",
-					       bond->dev->name,
-					       slave_dev->name);
-
-					/* notify ad that the link status has changed */
-					if (bond->params.mode == BOND_MODE_8023AD) {
-						bond_3ad_handle_link_change(slave, BOND_LINK_DOWN);
-					}
-
-					if ((bond->params.mode == BOND_MODE_TLB) ||
-					    (bond->params.mode == BOND_MODE_ALB)) {
-						bond_alb_handle_link_change(bond, slave, BOND_LINK_DOWN);
-					}
-
-					if (slave == oldcurrent) {
-						do_failover = 1;
-					}
-				} else {
-					slave->delay--;
-				}
-			} else {
-				/* link up again */
-				slave->link  = BOND_LINK_UP;
+			/*FALLTHRU*/
+		case BOND_LINK_FAIL:
+			if (link_state) {
+				/*
+				 * recovered before downdelay expired
+				 */
+				slave->link = BOND_LINK_UP;
 				slave->jiffies = jiffies;
 				printk(KERN_INFO DRV_NAME
 				       ": %s: link status up again after %d "
 				       "ms for interface %s.\n",
 				       bond->dev->name,
-				       (bond->params.downdelay - slave->delay) * bond->params.miimon,
-				       slave_dev->name);
+				       (bond->params.downdelay - slave->delay) *
+				       bond->params.miimon,
+				       slave->dev->name);
+				continue;
 			}
-			break;
-		case BOND_LINK_DOWN:	/* the link was down */
-			if (link_state != BMSR_LSTATUS) {
-				/* the link stays down, nothing more to do */
-				break;
-			} else {	/* link going up */
-				slave->link  = BOND_LINK_BACK;
-				slave->delay = bond->params.updelay;
 
-				if (bond->params.updelay) {
-					/* if updelay == 0, no need to
-					   advertise about a 0 ms delay */
-					printk(KERN_INFO DRV_NAME
-					       ": %s: link status up for "
-					       "interface %s, enabling it "
-					       "in %d ms.\n",
-					       bond->dev->name,
-					       slave_dev->name,
-					       bond->params.updelay * bond->params.miimon);
-				}
+			if (slave->delay <= 0) {
+				slave->new_link = BOND_LINK_DOWN;
+				commit++;
+				continue;
 			}
-			/* no break ! fall through the BOND_LINK_BACK state in
-			   case there's something to do.
-			*/
-		case BOND_LINK_BACK:	/* the link has just come back */
-			if (link_state != BMSR_LSTATUS) {
-				/* link down again */
-				slave->link  = BOND_LINK_DOWN;
 
+			slave->delay--;
+			break;
+
+		case BOND_LINK_DOWN:
+			if (!link_state)
+				continue;
+
+			slave->link = BOND_LINK_BACK;
+			slave->delay = bond->params.updelay;
+
+			if (slave->delay) {
+				printk(KERN_INFO DRV_NAME
+				       ": %s: link status up for "
+				       "interface %s, enabling it in %d ms.\n",
+				       bond->dev->name, slave->dev->name,
+				       bond->params.updelay *
+				       bond->params.miimon);
+			}
+			/*FALLTHRU*/
+		case BOND_LINK_BACK:
+			if (!link_state) {
+				slave->link = BOND_LINK_DOWN;
 				printk(KERN_INFO DRV_NAME
 				       ": %s: link status down again after %d "
 				       "ms for interface %s.\n",
 				       bond->dev->name,
-				       (bond->params.updelay - slave->delay) * bond->params.miimon,
-				       slave_dev->name);
-			} else {
-				/* link stays up */
-				if (slave->delay == 0) {
-					if (!have_locks)
-						return 1;
-
-					/* now the link has been up for long time enough */
-					slave->link = BOND_LINK_UP;
-					slave->jiffies = jiffies;
-
-					if (bond->params.mode == BOND_MODE_8023AD) {
-						/* prevent it from being the active one */
-						slave->state = BOND_STATE_BACKUP;
-					} else if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
-						/* make it immediately active */
-						slave->state = BOND_STATE_ACTIVE;
-					} else if (slave != bond->primary_slave) {
-						/* prevent it from being the active one */
-						slave->state = BOND_STATE_BACKUP;
-					}
+				       (bond->params.updelay - slave->delay) *
+				       bond->params.miimon,
+				       slave->dev->name);
 
-					printk(KERN_INFO DRV_NAME
-					       ": %s: link status definitely "
-					       "up for interface %s.\n",
-					       bond->dev->name,
-					       slave_dev->name);
-
-					/* notify ad that the link status has changed */
-					if (bond->params.mode == BOND_MODE_8023AD) {
-						bond_3ad_handle_link_change(slave, BOND_LINK_UP);
-					}
-
-					if ((bond->params.mode == BOND_MODE_TLB) ||
-					    (bond->params.mode == BOND_MODE_ALB)) {
-						bond_alb_handle_link_change(bond, slave, BOND_LINK_UP);
-					}
-
-					if ((!oldcurrent) ||
-					    (slave == bond->primary_slave)) {
-						do_failover = 1;
-					}
-				} else {
-					slave->delay--;
-				}
+				continue;
 			}
+
+			if (slave->delay <= 0) {
+				slave->new_link = BOND_LINK_UP;
+				commit++;
+				continue;
+			}
+
+			slave->delay--;
 			break;
-		default:
-			/* Should not happen */
-			printk(KERN_ERR DRV_NAME
-			       ": %s: Error: %s Illegal value (link=%d)\n",
-			       bond->dev->name,
-			       slave->dev->name,
-			       slave->link);
-			goto out;
-		} /* end of switch (slave->link) */
+		}
+	}
 
-		bond_update_speed_duplex(slave);
+	return commit;
+}
 
-		if (bond->params.mode == BOND_MODE_8023AD) {
-			if (old_speed != slave->speed) {
-				bond_3ad_adapter_speed_changed(slave);
-			}
+static void bond_miimon_commit(struct bonding *bond)
+{
+	struct slave *slave;
+	int i;
+
+	bond_for_each_slave(bond, slave, i) {
+		switch (slave->new_link) {
+		case BOND_LINK_NOCHANGE:
+			continue;
+
+		case BOND_LINK_UP:
+			slave->link = BOND_LINK_UP;
+			slave->jiffies = jiffies;
 
-			if (old_duplex != slave->duplex) {
-				bond_3ad_adapter_duplex_changed(slave);
+			if (bond->params.mode == BOND_MODE_8023AD) {
+				/* prevent it from being the active one */
+				slave->state = BOND_STATE_BACKUP;
+			} else if (bond->params.mode != BOND_MODE_ACTIVEBACKUP) {
+				/* make it immediately active */
+				slave->state = BOND_STATE_ACTIVE;
+			} else if (slave != bond->primary_slave) {
+				/* prevent it from being the active one */
+				slave->state = BOND_STATE_BACKUP;
 			}
-		}
 
-	} /* end of for */
+			printk(KERN_INFO DRV_NAME
+			       ": %s: link status definitely "
+			       "up for interface %s.\n",
+			       bond->dev->name, slave->dev->name);
 
-	if (do_failover) {
-		ASSERT_RTNL();
+			/* notify ad that the link status has changed */
+			if (bond->params.mode == BOND_MODE_8023AD)
+				bond_3ad_handle_link_change(slave, BOND_LINK_UP);
 
-		write_lock_bh(&bond->curr_slave_lock);
+			if ((bond->params.mode == BOND_MODE_TLB) ||
+			    (bond->params.mode == BOND_MODE_ALB))
+				bond_alb_handle_link_change(bond, slave,
+							    BOND_LINK_UP);
 
-		bond_select_active_slave(bond);
+			if (!bond->curr_active_slave ||
+			    (slave == bond->primary_slave))
+				goto do_failover;
 
-		write_unlock_bh(&bond->curr_slave_lock);
+			continue;
 
-	} else
-		bond_set_carrier(bond);
+		case BOND_LINK_DOWN:
+			slave->link = BOND_LINK_DOWN;
 
-out:
-	return 0;
+			if (bond->params.mode == BOND_MODE_ACTIVEBACKUP ||
+			    bond->params.mode == BOND_MODE_8023AD)
+				bond_set_slave_inactive_flags(slave);
+
+			printk(KERN_INFO DRV_NAME
+			       ": %s: link status definitely down for "
+			       "interface %s, disabling it\n",
+			       bond->dev->name, slave->dev->name);
+
+			if (bond->params.mode == BOND_MODE_8023AD)
+				bond_3ad_handle_link_change(slave,
+							    BOND_LINK_DOWN);
+
+			if (bond->params.mode == BOND_MODE_TLB ||
+			    bond->params.mode == BOND_MODE_ALB)
+				bond_alb_handle_link_change(bond, slave,
+							    BOND_LINK_DOWN);
+
+			if (slave == bond->curr_active_slave)
+				goto do_failover;
+
+			continue;
+
+		default:
+			printk(KERN_ERR DRV_NAME
+			       ": %s: invalid new link %d on slave %s\n",
+			       bond->dev->name, slave->new_link,
+			       slave->dev->name);
+			slave->new_link = BOND_LINK_NOCHANGE;
+
+			continue;
+		}
+
+do_failover:
+		ASSERT_RTNL();
+		write_lock_bh(&bond->curr_slave_lock);
+		bond_select_active_slave(bond);
+		write_unlock_bh(&bond->curr_slave_lock);
+	}
+
+	bond_set_carrier(bond);
 }
 
 /*
  * bond_mii_monitor
  *
  * Really a wrapper that splits the mii monitor into two phases: an
- * inspection, then (if inspection indicates something needs to be
- * done) an acquisition of appropriate locks followed by another pass
- * to implement whatever link state changes are indicated.
+ * inspection, then (if inspection indicates something needs to be done)
+ * an acquisition of appropriate locks followed by a commit phase to
+ * implement whatever link state changes are indicated.
  */
 void bond_mii_monitor(struct work_struct *work)
 {
 	struct bonding *bond = container_of(work, struct bonding,
 					    mii_work.work);
-	unsigned long delay;
 
 	read_lock(&bond->lock);
-	if (bond->kill_timers) {
-		read_unlock(&bond->lock);
-		return;
-	}
+	if (bond->kill_timers)
+		goto out;
+
+	if (bond->slave_cnt == 0)
+		goto re_arm;
 
 	if (bond->send_grat_arp) {
 		read_lock(&bond->curr_slave_lock);
@@ -2496,19 +2441,24 @@ void bond_mii_monitor(struct work_struct *work)
 		read_unlock(&bond->curr_slave_lock);
 	}
 
-	if (__bond_mii_monitor(bond, 0)) {
+	if (bond_miimon_inspect(bond)) {
 		read_unlock(&bond->lock);
 		rtnl_lock();
 		read_lock(&bond->lock);
-		__bond_mii_monitor(bond, 1);
+
+		bond_miimon_commit(bond);
+
 		read_unlock(&bond->lock);
 		rtnl_unlock();	/* might sleep, hold no other locks */
 		read_lock(&bond->lock);
 	}
 
-	delay = msecs_to_jiffies(bond->params.miimon);
+re_arm:
+	if (bond->params.miimon)
+		queue_delayed_work(bond->wq, &bond->mii_work,
+				   msecs_to_jiffies(bond->params.miimon));
+out:
 	read_unlock(&bond->lock);
-	queue_delayed_work(bond->wq, &bond->mii_work, delay);
 }
 
 static __be32 bond_glean_dev_ip(struct net_device *dev)
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 6caac0f..3bdb473 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -350,9 +350,6 @@ static ssize_t bonding_store_slaves(struct device *d,
 		if (dev) {
 			printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
 				bond->dev->name, dev->name);
-			if (bond->setup_by_slave)
-				res = bond_release_and_destroy(bond->dev, dev);
-			else
 				res = bond_release(bond->dev, dev);
 			if (res) {
 				ret = res;
diff --git a/drivers/net/de620.c b/drivers/net/de620.c
index 3f5190c..d454e14 100644
--- a/drivers/net/de620.c
+++ b/drivers/net/de620.c
@@ -488,13 +488,6 @@ static void de620_set_multicast_list(struct net_device *dev)
 {
 	if (dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
 	{ /* Enable promiscuous mode */
-		/*
-		 *	We must make the kernel realise we had to move
-		 *	into promisc mode or we start all out war on
-		 *	the cable. - AC
-		 */
-		dev->flags|=IFF_PROMISC;
-
 		de620_set_register(dev, W_TCR, (TCR_DEF & ~RXPBM) | RXALL);
 	}
 	else
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 0b0f1c4..f42c23f 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1374,6 +1374,11 @@ dm9000_probe(struct platform_device *pdev)
 	for (i = 0; i < 6; i += 2)
 		dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
 
+	if (!is_valid_ether_addr(ndev->dev_addr) && pdata != NULL) {
+		mac_src = "platform data";
+		memcpy(ndev->dev_addr, pdata->dev_addr, 6);
+	}
+
 	if (!is_valid_ether_addr(ndev->dev_addr)) {
 		/* try reading from mac */
 		
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 4a4f62e..cf57050 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -41,24 +41,25 @@
 
 struct e1000_info;
 
-#define ndev_printk(level, netdev, format, arg...) \
-	printk(level "%s: " format, (netdev)->name, ## arg)
+#define e_printk(level, adapter, format, arg...) \
+	printk(level "%s: %s: " format, pci_name(adapter->pdev), \
+	       adapter->netdev->name, ## arg)
 
 #ifdef DEBUG
-#define ndev_dbg(netdev, format, arg...) \
-	ndev_printk(KERN_DEBUG , netdev, format, ## arg)
+#define e_dbg(format, arg...) \
+	e_printk(KERN_DEBUG , adapter, format, ## arg)
 #else
-#define ndev_dbg(netdev, format, arg...) do { (void)(netdev); } while (0)
+#define e_dbg(format, arg...) do { (void)(adapter); } while (0)
 #endif
 
-#define ndev_err(netdev, format, arg...) \
-	ndev_printk(KERN_ERR , netdev, format, ## arg)
-#define ndev_info(netdev, format, arg...) \
-	ndev_printk(KERN_INFO , netdev, format, ## arg)
-#define ndev_warn(netdev, format, arg...) \
-	ndev_printk(KERN_WARNING , netdev, format, ## arg)
-#define ndev_notice(netdev, format, arg...) \
-	ndev_printk(KERN_NOTICE , netdev, format, ## arg)
+#define e_err(format, arg...) \
+	e_printk(KERN_ERR, adapter, format, ## arg)
+#define e_info(format, arg...) \
+	e_printk(KERN_INFO, adapter, format, ## arg)
+#define e_warn(format, arg...) \
+	e_printk(KERN_WARNING, adapter, format, ## arg)
+#define e_notice(format, arg...) \
+	e_printk(KERN_NOTICE, adapter, format, ## arg)
 
 
 /* Tx/Rx descriptor defines */
@@ -283,10 +284,6 @@ struct e1000_adapter {
 	unsigned long led_status;
 
 	unsigned int flags;
-
-	/* for ioport free */
-	int bars;
-	int need_ioport;
 };
 
 struct e1000_info {
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 9350564..cf9679f 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -189,8 +189,7 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
 	/* Fiber NICs only allow 1000 gbps Full duplex */
 	if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
 		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
-		ndev_err(adapter->netdev, "Unsupported Speed/Duplex "
-			 "configuration\n");
+		e_err("Unsupported Speed/Duplex configuration\n");
 		return -EINVAL;
 	}
 
@@ -213,8 +212,7 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
 		break;
 	case SPEED_1000 + DUPLEX_HALF: /* not supported */
 	default:
-		ndev_err(adapter->netdev, "Unsupported Speed/Duplex "
-			 "configuration\n");
+		e_err("Unsupported Speed/Duplex configuration\n");
 		return -EINVAL;
 	}
 	return 0;
@@ -231,8 +229,8 @@ static int e1000_set_settings(struct net_device *netdev,
 	 * cannot be changed
 	 */
 	if (e1000_check_reset_block(hw)) {
-		ndev_err(netdev, "Cannot change link "
-			 "characteristics when SoL/IDER is active.\n");
+		e_err("Cannot change link characteristics when SoL/IDER is "
+		      "active.\n");
 		return -EINVAL;
 	}
 
@@ -380,8 +378,7 @@ static int e1000_set_tso(struct net_device *netdev, u32 data)
 		netdev->features &= ~NETIF_F_TSO6;
 	}
 
-	ndev_info(netdev, "TSO is %s\n",
-		  data ? "Enabled" : "Disabled");
+	e_info("TSO is %s\n", data ? "Enabled" : "Disabled");
 	adapter->flags |= FLAG_TSO_FORCE;
 	return 0;
 }
@@ -722,10 +719,9 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data,
 				      (test[pat] & write));
 		val = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset);
 		if (val != (test[pat] & write & mask)) {
-			ndev_err(adapter->netdev, "pattern test reg %04X "
-				 "failed: got 0x%08X expected 0x%08X\n",
-				 reg + offset,
-				 val, (test[pat] & write & mask));
+			e_err("pattern test reg %04X failed: got 0x%08X "
+			      "expected 0x%08X\n", reg + offset, val,
+			      (test[pat] & write & mask));
 			*data = reg;
 			return 1;
 		}
@@ -740,9 +736,8 @@ static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
 	__ew32(&adapter->hw, reg, write & mask);
 	val = __er32(&adapter->hw, reg);
 	if ((write & mask) != (val & mask)) {
-		ndev_err(adapter->netdev, "set/check reg %04X test failed: "
-			 "got 0x%08X expected 0x%08X\n", reg, (val & mask),
-			 (write & mask));
+		e_err("set/check reg %04X test failed: got 0x%08X "
+		      "expected 0x%08X\n", reg, (val & mask), (write & mask));
 		*data = reg;
 		return 1;
 	}
@@ -766,7 +761,6 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 {
 	struct e1000_hw *hw = &adapter->hw;
 	struct e1000_mac_info *mac = &adapter->hw.mac;
-	struct net_device *netdev = adapter->netdev;
 	u32 value;
 	u32 before;
 	u32 after;
@@ -799,8 +793,8 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 	ew32(STATUS, toggle);
 	after = er32(STATUS) & toggle;
 	if (value != after) {
-		ndev_err(netdev, "failed STATUS register test got: "
-			 "0x%08X expected: 0x%08X\n", after, value);
+		e_err("failed STATUS register test got: 0x%08X expected: "
+		      "0x%08X\n", after, value);
 		*data = 1;
 		return 1;
 	}
@@ -903,8 +897,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
 		*data = 1;
 		return -1;
 	}
-	ndev_info(netdev, "testing %s interrupt\n",
-		  (shared_int ? "shared" : "unshared"));
+	e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared"));
 
 	/* Disable all the interrupts */
 	ew32(IMC, 0xFFFFFFFF);
@@ -1526,8 +1519,7 @@ static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data)
 	 * sessions are active
 	 */
 	if (e1000_check_reset_block(&adapter->hw)) {
-		ndev_err(adapter->netdev, "Cannot do PHY loopback test "
-			 "when SoL/IDER is active.\n");
+		e_err("Cannot do PHY loopback test when SoL/IDER is active.\n");
 		*data = 0;
 		goto out;
 	}
@@ -1612,7 +1604,7 @@ static void e1000_diag_test(struct net_device *netdev,
 		forced_speed_duplex = adapter->hw.mac.forced_speed_duplex;
 		autoneg = adapter->hw.mac.autoneg;
 
-		ndev_info(netdev, "offline testing starting\n");
+		e_info("offline testing starting\n");
 
 		/*
 		 * Link test performed before hardware reset so autoneg doesn't
@@ -1658,7 +1650,7 @@ static void e1000_diag_test(struct net_device *netdev,
 		if (if_running)
 			dev_open(netdev);
 	} else {
-		ndev_info(netdev, "online testing starting\n");
+		e_info("online testing starting\n");
 		/* Online tests */
 		if (e1000_link_test(adapter, &data[4]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
@@ -1694,8 +1686,8 @@ static void e1000_get_wol(struct net_device *netdev,
 		wol->supported &= ~WAKE_UCAST;
 
 		if (adapter->wol & E1000_WUFC_EX)
-			ndev_err(netdev, "Interface does not support "
-				 "directed (unicast) frame wake-up packets\n");
+			e_err("Interface does not support directed (unicast) "
+			      "frame wake-up packets\n");
 	}
 
 	if (adapter->wol & E1000_WUFC_EX)
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index d136778..05b0b2f 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -484,8 +484,8 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 		 * packet, also make sure the frame isn't just CRC only */
 		if (!(status & E1000_RXD_STAT_EOP) || (length <= 4)) {
 			/* All receives must fit into a single buffer */
-			ndev_dbg(netdev, "%s: Receive packet consumed "
-				 "multiple buffers\n", netdev->name);
+			e_dbg("%s: Receive packet consumed multiple buffers\n",
+			      netdev->name);
 			/* recycle */
 			buffer_info->skb = skb;
 			goto next_desc;
@@ -576,28 +576,26 @@ static void e1000_print_tx_hang(struct e1000_adapter *adapter)
 	unsigned int i = tx_ring->next_to_clean;
 	unsigned int eop = tx_ring->buffer_info[i].next_to_watch;
 	struct e1000_tx_desc *eop_desc = E1000_TX_DESC(*tx_ring, eop);
-	struct net_device *netdev = adapter->netdev;
 
 	/* detected Tx unit hang */
-	ndev_err(netdev,
-		 "Detected Tx Unit Hang:\n"
-		 "  TDH                  <%x>\n"
-		 "  TDT                  <%x>\n"
-		 "  next_to_use          <%x>\n"
-		 "  next_to_clean        <%x>\n"
-		 "buffer_info[next_to_clean]:\n"
-		 "  time_stamp           <%lx>\n"
-		 "  next_to_watch        <%x>\n"
-		 "  jiffies              <%lx>\n"
-		 "  next_to_watch.status <%x>\n",
-		 readl(adapter->hw.hw_addr + tx_ring->head),
-		 readl(adapter->hw.hw_addr + tx_ring->tail),
-		 tx_ring->next_to_use,
-		 tx_ring->next_to_clean,
-		 tx_ring->buffer_info[eop].time_stamp,
-		 eop,
-		 jiffies,
-		 eop_desc->upper.fields.status);
+	e_err("Detected Tx Unit Hang:\n"
+	      "  TDH                  <%x>\n"
+	      "  TDT                  <%x>\n"
+	      "  next_to_use          <%x>\n"
+	      "  next_to_clean        <%x>\n"
+	      "buffer_info[next_to_clean]:\n"
+	      "  time_stamp           <%lx>\n"
+	      "  next_to_watch        <%x>\n"
+	      "  jiffies              <%lx>\n"
+	      "  next_to_watch.status <%x>\n",
+	      readl(adapter->hw.hw_addr + tx_ring->head),
+	      readl(adapter->hw.hw_addr + tx_ring->tail),
+	      tx_ring->next_to_use,
+	      tx_ring->next_to_clean,
+	      tx_ring->buffer_info[eop].time_stamp,
+	      eop,
+	      jiffies,
+	      eop_desc->upper.fields.status);
 }
 
 /**
@@ -747,8 +745,8 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
 		buffer_info->dma = 0;
 
 		if (!(staterr & E1000_RXD_STAT_EOP)) {
-			ndev_dbg(netdev, "%s: Packet Split buffers didn't pick "
-				 "up the full packet\n", netdev->name);
+			e_dbg("%s: Packet Split buffers didn't pick up the "
+			      "full packet\n", netdev->name);
 			dev_kfree_skb_irq(skb);
 			goto next_desc;
 		}
@@ -761,8 +759,8 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
 		length = le16_to_cpu(rx_desc->wb.middle.length0);
 
 		if (!length) {
-			ndev_dbg(netdev, "%s: Last part of the packet spanning"
-				 " multiple descriptors\n", netdev->name);
+			e_dbg("%s: Last part of the packet spanning multiple "
+			      "descriptors\n", netdev->name);
 			dev_kfree_skb_irq(skb);
 			goto next_desc;
 		}
@@ -1011,7 +1009,7 @@ static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
 
 		/* eth type trans needs skb->data to point to something */
 		if (!pskb_may_pull(skb, ETH_HLEN)) {
-			ndev_err(netdev, "pskb_may_pull failed.\n");
+			e_err("pskb_may_pull failed.\n");
 			dev_kfree_skb(skb);
 			goto next_desc;
 		}
@@ -1251,10 +1249,8 @@ static int e1000_request_irq(struct e1000_adapter *adapter)
 	err = request_irq(adapter->pdev->irq, handler, irq_flags, netdev->name,
 			  netdev);
 	if (err) {
-		ndev_err(netdev,
-		       "Unable to allocate %s interrupt (return: %d)\n",
-			adapter->flags & FLAG_MSI_ENABLED ? "MSI":"INTx",
-			err);
+		e_err("Unable to allocate %s interrupt (return: %d)\n",
+		      adapter->flags & FLAG_MSI_ENABLED ? "MSI":"INTx",	err);
 		if (adapter->flags & FLAG_MSI_ENABLED)
 			pci_disable_msi(adapter->pdev);
 	}
@@ -1395,8 +1391,7 @@ int e1000e_setup_tx_resources(struct e1000_adapter *adapter)
 	return 0;
 err:
 	vfree(tx_ring->buffer_info);
-	ndev_err(adapter->netdev,
-	"Unable to allocate memory for the transmit descriptor ring\n");
+	e_err("Unable to allocate memory for the transmit descriptor ring\n");
 	return err;
 }
 
@@ -1450,8 +1445,7 @@ err_pages:
 	}
 err:
 	vfree(rx_ring->buffer_info);
-	ndev_err(adapter->netdev,
-	"Unable to allocate memory for the transmit descriptor ring\n");
+	e_err("Unable to allocate memory for the transmit descriptor ring\n");
 	return err;
 }
 
@@ -2450,13 +2444,13 @@ void e1000e_reset(struct e1000_adapter *adapter)
 	 * For parts with AMT enabled, let the firmware know
 	 * that the network interface is in control
 	 */
-	if ((adapter->flags & FLAG_HAS_AMT) && e1000e_check_mng_mode(hw))
+	if (adapter->flags & FLAG_HAS_AMT)
 		e1000_get_hw_control(adapter);
 
 	ew32(WUC, 0);
 
 	if (mac->ops.init_hw(hw))
-		ndev_err(adapter->netdev, "Hardware Error\n");
+		e_err("Hardware Error\n");
 
 	e1000_update_mng_vlan(adapter);
 
@@ -2591,7 +2585,7 @@ static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
 	return 0;
 
 err:
-	ndev_err(netdev, "Unable to allocate memory for queues\n");
+	e_err("Unable to allocate memory for queues\n");
 	kfree(adapter->rx_ring);
 	kfree(adapter->tx_ring);
 	return -ENOMEM;
@@ -2640,8 +2634,7 @@ static int e1000_open(struct net_device *netdev)
 	 * If AMT is enabled, let the firmware know that the network
 	 * interface is now open
 	 */
-	if ((adapter->flags & FLAG_HAS_AMT) &&
-	    e1000e_check_mng_mode(&adapter->hw))
+	if (adapter->flags & FLAG_HAS_AMT)
 		e1000_get_hw_control(adapter);
 
 	/*
@@ -2719,8 +2712,7 @@ static int e1000_close(struct net_device *netdev)
 	 * If AMT is enabled, let the firmware know that the network
 	 * interface is now closed
 	 */
-	if ((adapter->flags & FLAG_HAS_AMT) &&
-	    e1000e_check_mng_mode(&adapter->hw))
+	if (adapter->flags & FLAG_HAS_AMT)
 		e1000_release_hw_control(adapter);
 
 	return 0;
@@ -2917,8 +2909,7 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
 		ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000);
 		ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);
 		if (ret_val)
-			ndev_warn(adapter->netdev,
-				  "Error reading PHY register\n");
+			e_warn("Error reading PHY register\n");
 	} else {
 		/*
 		 * Do not read PHY registers if link is not up
@@ -2943,18 +2934,16 @@ static void e1000_phy_read_status(struct e1000_adapter *adapter)
 static void e1000_print_link_info(struct e1000_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	struct net_device *netdev = adapter->netdev;
 	u32 ctrl = er32(CTRL);
 
-	ndev_info(netdev,
-		"Link is Up %d Mbps %s, Flow Control: %s\n",
-		adapter->link_speed,
-		(adapter->link_duplex == FULL_DUPLEX) ?
-				"Full Duplex" : "Half Duplex",
-		((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ?
-				"RX/TX" :
-		((ctrl & E1000_CTRL_RFCE) ? "RX" :
-		((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
+	e_info("Link is Up %d Mbps %s, Flow Control: %s\n",
+	       adapter->link_speed,
+	       (adapter->link_duplex == FULL_DUPLEX) ?
+	                        "Full Duplex" : "Half Duplex",
+	       ((ctrl & E1000_CTRL_TFCE) && (ctrl & E1000_CTRL_RFCE)) ?
+	                        "RX/TX" :
+	       ((ctrl & E1000_CTRL_RFCE) ? "RX" :
+	       ((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
 }
 
 static bool e1000_has_link(struct e1000_adapter *adapter)
@@ -2994,8 +2983,7 @@ static bool e1000_has_link(struct e1000_adapter *adapter)
 	if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
 	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
 		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
-		ndev_info(adapter->netdev,
-			  "Gigabit has been disabled, downgrading speed\n");
+		e_info("Gigabit has been disabled, downgrading speed\n");
 	}
 
 	return link_active;
@@ -3096,8 +3084,7 @@ static void e1000_watchdog_task(struct work_struct *work)
 				switch (adapter->link_speed) {
 				case SPEED_10:
 				case SPEED_100:
-					ndev_info(netdev,
-					"10/100 speed: disabling TSO\n");
+					e_info("10/100 speed: disabling TSO\n");
 					netdev->features &= ~NETIF_F_TSO;
 					netdev->features &= ~NETIF_F_TSO6;
 					break;
@@ -3130,7 +3117,7 @@ static void e1000_watchdog_task(struct work_struct *work)
 		if (netif_carrier_ok(netdev)) {
 			adapter->link_speed = 0;
 			adapter->link_duplex = 0;
-			ndev_info(netdev, "Link is Down\n");
+			e_info("Link is Down\n");
 			netif_carrier_off(netdev);
 			netif_tx_stop_all_queues(netdev);
 			if (!test_bit(__E1000_DOWN, &adapter->state))
@@ -3604,8 +3591,7 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
 			pull_size = min((unsigned int)4, skb->data_len);
 			if (!__pskb_pull_tail(skb, pull_size)) {
-				ndev_err(netdev,
-					 "__pskb_pull_tail failed.\n");
+				e_err("__pskb_pull_tail failed.\n");
 				dev_kfree_skb_any(skb);
 				return NETDEV_TX_OK;
 			}
@@ -3737,25 +3723,25 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 
 	if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
 	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-		ndev_err(netdev, "Invalid MTU setting\n");
+		e_err("Invalid MTU setting\n");
 		return -EINVAL;
 	}
 
 	/* Jumbo frame size limits */
 	if (max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) {
 		if (!(adapter->flags & FLAG_HAS_JUMBO_FRAMES)) {
-			ndev_err(netdev, "Jumbo Frames not supported.\n");
+			e_err("Jumbo Frames not supported.\n");
 			return -EINVAL;
 		}
 		if (adapter->hw.phy.type == e1000_phy_ife) {
-			ndev_err(netdev, "Jumbo Frames not supported.\n");
+			e_err("Jumbo Frames not supported.\n");
 			return -EINVAL;
 		}
 	}
 
 #define MAX_STD_JUMBO_FRAME_SIZE 9234
 	if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
-		ndev_err(netdev, "MTU > 9216 not supported.\n");
+		e_err("MTU > 9216 not supported.\n");
 		return -EINVAL;
 	}
 
@@ -3792,8 +3778,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
 					 + ETH_FCS_LEN;
 
-	ndev_info(netdev, "changing MTU from %d to %d\n",
-		netdev->mtu, new_mtu);
+	e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu);
 	netdev->mtu = new_mtu;
 
 	if (netif_running(netdev))
@@ -4006,10 +3991,7 @@ static int e1000_resume(struct pci_dev *pdev)
 	pci_restore_state(pdev);
 	e1000e_disable_l1aspm(pdev);
 
-	if (adapter->need_ioport)
-		err = pci_enable_device(pdev);
-	else
-		err = pci_enable_device_mem(pdev);
+	err = pci_enable_device_mem(pdev);
 	if (err) {
 		dev_err(&pdev->dev,
 			"Cannot enable PCI device from suspend\n");
@@ -4043,7 +4025,7 @@ static int e1000_resume(struct pci_dev *pdev)
 	 * is up.  For all other cases, let the f/w know that the h/w is now
 	 * under the control of the driver.
 	 */
-	if (!(adapter->flags & FLAG_HAS_AMT) || !e1000e_check_mng_mode(&adapter->hw))
+	if (!(adapter->flags & FLAG_HAS_AMT))
 		e1000_get_hw_control(adapter);
 
 	return 0;
@@ -4111,10 +4093,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
 	int err;
 
 	e1000e_disable_l1aspm(pdev);
-	if (adapter->need_ioport)
-		err = pci_enable_device(pdev);
-	else
-		err = pci_enable_device_mem(pdev);
+	err = pci_enable_device_mem(pdev);
 	if (err) {
 		dev_err(&pdev->dev,
 			"Cannot re-enable PCI device after reset.\n");
@@ -4162,8 +4141,7 @@ static void e1000_io_resume(struct pci_dev *pdev)
 	 * is up.  For all other cases, let the f/w know that the h/w is now
 	 * under the control of the driver.
 	 */
-	if (!(adapter->flags & FLAG_HAS_AMT) ||
-	    !e1000e_check_mng_mode(&adapter->hw))
+	if (!(adapter->flags & FLAG_HAS_AMT))
 		e1000_get_hw_control(adapter);
 
 }
@@ -4175,36 +4153,40 @@ static void e1000_print_device_info(struct e1000_adapter *adapter)
 	u32 pba_num;
 
 	/* print bus type/speed/width info */
-	ndev_info(netdev, "(PCI Express:2.5GB/s:%s) "
-		  "%02x:%02x:%02x:%02x:%02x:%02x\n",
-		  /* bus width */
-		 ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
-		  "Width x1"),
-		  /* MAC address */
-		  netdev->dev_addr[0], netdev->dev_addr[1],
-		  netdev->dev_addr[2], netdev->dev_addr[3],
-		  netdev->dev_addr[4], netdev->dev_addr[5]);
-	ndev_info(netdev, "Intel(R) PRO/%s Network Connection\n",
-		  (hw->phy.type == e1000_phy_ife)
-		   ? "10/100" : "1000");
+	e_info("(PCI Express:2.5GB/s:%s) %02x:%02x:%02x:%02x:%02x:%02x\n",
+	       /* bus width */
+	       ((hw->bus.width == e1000_bus_width_pcie_x4) ? "Width x4" :
+	        "Width x1"),
+	       /* MAC address */
+	       netdev->dev_addr[0], netdev->dev_addr[1],
+	       netdev->dev_addr[2], netdev->dev_addr[3],
+	       netdev->dev_addr[4], netdev->dev_addr[5]);
+	e_info("Intel(R) PRO/%s Network Connection\n",
+	       (hw->phy.type == e1000_phy_ife) ? "10/100" : "1000");
 	e1000e_read_pba_num(hw, &pba_num);
-	ndev_info(netdev, "MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
-		  hw->mac.type, hw->phy.type,
-		  (pba_num >> 8), (pba_num & 0xff));
+	e_info("MAC: %d, PHY: %d, PBA No: %06x-%03x\n",
+	       hw->mac.type, hw->phy.type, (pba_num >> 8), (pba_num & 0xff));
 }
 
-/**
- * e1000e_is_need_ioport - determine if an adapter needs ioport resources or not
- * @pdev: PCI device information struct
- *
- * Returns true if an adapters needs ioport resources
- **/
-static int e1000e_is_need_ioport(struct pci_dev *pdev)
+static void e1000_eeprom_checks(struct e1000_adapter *adapter)
 {
-	switch (pdev->device) {
-	/* Currently there are no adapters that need ioport resources */
-	default:
-		return false;
+	struct e1000_hw *hw = &adapter->hw;
+	int ret_val;
+	u16 buf = 0;
+
+	if (hw->mac.type != e1000_82573)
+		return;
+
+	ret_val = e1000_read_nvm(hw, NVM_INIT_CONTROL2_REG, 1, &buf);
+	if (!(le16_to_cpu(buf) & (1 << 0))) {
+		/* Deep Smart Power Down (DSPD) */
+		e_warn("Warning: detected DSPD enabled in EEPROM\n");
+	}
+
+	ret_val = e1000_read_nvm(hw, NVM_INIT_3GIO_3, 1, &buf);
+	if (le16_to_cpu(buf) & (3 << 2)) {
+		/* ASPM enable */
+		e_warn("Warning: detected ASPM enabled in EEPROM\n");
 	}
 }
 
@@ -4233,19 +4215,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	int i, err, pci_using_dac;
 	u16 eeprom_data = 0;
 	u16 eeprom_apme_mask = E1000_EEPROM_APME;
-	int bars, need_ioport;
 
 	e1000e_disable_l1aspm(pdev);
 
-	/* do not allocate ioport bars when not needed */
-	need_ioport = e1000e_is_need_ioport(pdev);
-	if (need_ioport) {
-		bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO);
-		err = pci_enable_device(pdev);
-	} else {
-		bars = pci_select_bars(pdev, IORESOURCE_MEM);
-		err = pci_enable_device_mem(pdev);
-	}
+	err = pci_enable_device_mem(pdev);
 	if (err)
 		return err;
 
@@ -4268,7 +4241,9 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 		}
 	}
 
-	err = pci_request_selected_regions(pdev, bars, e1000e_driver_name);
+	err = pci_request_selected_regions(pdev,
+	                                  pci_select_bars(pdev, IORESOURCE_MEM),
+	                                  e1000e_driver_name);
 	if (err)
 		goto err_pci_reg;
 
@@ -4293,8 +4268,6 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	adapter->hw.adapter = adapter;
 	adapter->hw.mac.type = ei->mac;
 	adapter->msg_enable = (1 << NETIF_MSG_DRV | NETIF_MSG_PROBE) - 1;
-	adapter->bars = bars;
-	adapter->need_ioport = need_ioport;
 
 	mmio_start = pci_resource_start(pdev, 0);
 	mmio_len = pci_resource_len(pdev, 0);
@@ -4366,8 +4339,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	}
 
 	if (e1000_check_reset_block(&adapter->hw))
-		ndev_info(netdev,
-			  "PHY reset is blocked due to SOL/IDER session.\n");
+		e_info("PHY reset is blocked due to SOL/IDER session.\n");
 
 	netdev->features = NETIF_F_SG |
 			   NETIF_F_HW_CSUM |
@@ -4411,25 +4383,26 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 		if (e1000_validate_nvm_checksum(&adapter->hw) >= 0)
 			break;
 		if (i == 2) {
-			ndev_err(netdev, "The NVM Checksum Is Not Valid\n");
+			e_err("The NVM Checksum Is Not Valid\n");
 			err = -EIO;
 			goto err_eeprom;
 		}
 	}
 
+	e1000_eeprom_checks(adapter);
+
 	/* copy the MAC address out of the NVM */
 	if (e1000e_read_mac_addr(&adapter->hw))
-		ndev_err(netdev, "NVM Read Error while reading MAC address\n");
+		e_err("NVM Read Error while reading MAC address\n");
 
 	memcpy(netdev->dev_addr, adapter->hw.mac.addr, netdev->addr_len);
 	memcpy(netdev->perm_addr, adapter->hw.mac.addr, netdev->addr_len);
 
 	if (!is_valid_ether_addr(netdev->perm_addr)) {
-		ndev_err(netdev, "Invalid MAC Address: "
-			 "%02x:%02x:%02x:%02x:%02x:%02x\n",
-			 netdev->perm_addr[0], netdev->perm_addr[1],
-			 netdev->perm_addr[2], netdev->perm_addr[3],
-			 netdev->perm_addr[4], netdev->perm_addr[5]);
+		e_err("Invalid MAC Address: %02x:%02x:%02x:%02x:%02x:%02x\n",
+		      netdev->perm_addr[0], netdev->perm_addr[1],
+		      netdev->perm_addr[2], netdev->perm_addr[3],
+		      netdev->perm_addr[4], netdev->perm_addr[5]);
 		err = -EIO;
 		goto err_eeprom;
 	}
@@ -4499,8 +4472,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	 * is up.  For all other cases, let the f/w know that the h/w is now
 	 * under the control of the driver.
 	 */
-	if (!(adapter->flags & FLAG_HAS_AMT) ||
-	    !e1000e_check_mng_mode(&adapter->hw))
+	if (!(adapter->flags & FLAG_HAS_AMT))
 		e1000_get_hw_control(adapter);
 
 	/* tell the stack to leave us alone until e1000_open() is called */
@@ -4517,24 +4489,25 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	return 0;
 
 err_register:
-err_hw_init:
-	e1000_release_hw_control(adapter);
+	if (!(adapter->flags & FLAG_HAS_AMT))
+		e1000_release_hw_control(adapter);
 err_eeprom:
 	if (!e1000_check_reset_block(&adapter->hw))
 		e1000_phy_hw_reset(&adapter->hw);
+err_hw_init:
 
-	if (adapter->hw.flash_address)
-		iounmap(adapter->hw.flash_address);
-
-err_flashmap:
 	kfree(adapter->tx_ring);
 	kfree(adapter->rx_ring);
 err_sw_init:
+	if (adapter->hw.flash_address)
+		iounmap(adapter->hw.flash_address);
+err_flashmap:
 	iounmap(adapter->hw.hw_addr);
 err_ioremap:
 	free_netdev(netdev);
 err_alloc_etherdev:
-	pci_release_selected_regions(pdev, bars);
+	pci_release_selected_regions(pdev,
+	                             pci_select_bars(pdev, IORESOURCE_MEM));
 err_pci_reg:
 err_dma:
 	pci_disable_device(pdev);
@@ -4582,7 +4555,8 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
 	iounmap(adapter->hw.hw_addr);
 	if (adapter->hw.flash_address)
 		iounmap(adapter->hw.flash_address);
-	pci_release_selected_regions(pdev, adapter->bars);
+	pci_release_selected_regions(pdev,
+	                             pci_select_bars(pdev, IORESOURCE_MEM));
 
 	free_netdev(netdev);
 
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index a66b92e..8effc31 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -27,6 +27,7 @@
 *******************************************************************************/
 
 #include <linux/netdevice.h>
+#include <linux/pci.h>
 
 #include "e1000.h"
 
@@ -162,17 +163,16 @@ static int __devinit e1000_validate_option(unsigned int *value,
 	case enable_option:
 		switch (*value) {
 		case OPTION_ENABLED:
-			ndev_info(adapter->netdev, "%s Enabled\n", opt->name);
+			e_info("%s Enabled\n", opt->name);
 			return 0;
 		case OPTION_DISABLED:
-			ndev_info(adapter->netdev, "%s Disabled\n", opt->name);
+			e_info("%s Disabled\n", opt->name);
 			return 0;
 		}
 		break;
 	case range_option:
 		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
-			ndev_info(adapter->netdev,
-					"%s set to %i\n", opt->name, *value);
+			e_info("%s set to %i\n", opt->name, *value);
 			return 0;
 		}
 		break;
@@ -184,8 +184,7 @@ static int __devinit e1000_validate_option(unsigned int *value,
 			ent = &opt->arg.l.p[i];
 			if (*value == ent->i) {
 				if (ent->str[0] != '\0')
-					ndev_info(adapter->netdev, "%s\n",
-						  ent->str);
+					e_info("%s\n", ent->str);
 				return 0;
 			}
 		}
@@ -195,8 +194,8 @@ static int __devinit e1000_validate_option(unsigned int *value,
 		BUG();
 	}
 
-	ndev_info(adapter->netdev, "Invalid %s value specified (%i) %s\n",
-	       opt->name, *value, opt->err);
+	e_info("Invalid %s value specified (%i) %s\n", opt->name, *value,
+	       opt->err);
 	*value = opt->def;
 	return -1;
 }
@@ -213,13 +212,11 @@ static int __devinit e1000_validate_option(unsigned int *value,
 void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	struct net_device *netdev = adapter->netdev;
 	int bd = adapter->bd_number;
 
 	if (bd >= E1000_MAX_NIC) {
-		ndev_notice(netdev,
-		       "Warning: no configuration for board #%i\n", bd);
-		ndev_notice(netdev, "Using defaults for all values\n");
+		e_notice("Warning: no configuration for board #%i\n", bd);
+		e_notice("Using defaults for all values\n");
 	}
 
 	{ /* Transmit Interrupt Delay */
@@ -313,19 +310,15 @@ void __devinit e1000e_check_options(struct e1000_adapter *adapter)
 			adapter->itr = InterruptThrottleRate[bd];
 			switch (adapter->itr) {
 			case 0:
-				ndev_info(netdev, "%s turned off\n",
-					opt.name);
+				e_info("%s turned off\n", opt.name);
 				break;
 			case 1:
-				ndev_info(netdev,
-					  "%s set to dynamic mode\n",
-					  opt.name);
+				e_info("%s set to dynamic mode\n", opt.name);
 				adapter->itr_setting = adapter->itr;
 				adapter->itr = 20000;
 				break;
 			case 3:
-				ndev_info(netdev,
-					"%s set to dynamic conservative mode\n",
+				e_info("%s set to dynamic conservative mode\n",
 					opt.name);
 				adapter->itr_setting = adapter->itr;
 				adapter->itr = 20000;
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index 56f5049..1f11350 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -1283,14 +1283,6 @@ set_multicast_list(struct net_device *dev)
 
 	if (dev->flags&(IFF_ALLMULTI|IFF_PROMISC) || dev->mc_count > 63)
 	{
-		/*
-		 *	We must make the kernel realise we had to move
-		 *	into promisc mode or we start all out war on
-		 *	the cable. If it was a promisc request the
-		 *	flag is already set. If not we assert it.
-		 */
-		dev->flags|=IFF_PROMISC;
-
 		eepro_sw2bank2(ioaddr); /* be CAREFUL, BANK 2 now */
 		mode = inb(ioaddr + REG2);
 		outb(mode | PRMSC_Mode, ioaddr + REG2);
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index e3dd8b1..bee8b3f 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -1356,7 +1356,6 @@ static void eth16i_multicast(struct net_device *dev)
 
 	if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
 	{
-		dev->flags|=IFF_PROMISC;	/* Must do this */
 		outb(3, ioaddr + RECEIVE_MODE_REG);
 	} else {
 		outb(2, ioaddr + RECEIVE_MODE_REG);
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 01b38b0..053971e 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -77,26 +77,27 @@
  * Hardware access:
  */
 
-#define DEV_NEED_TIMERIRQ          0x00001  /* set the timer irq flag in the irq mask */
-#define DEV_NEED_LINKTIMER         0x00002  /* poll link settings. Relies on the timer irq */
-#define DEV_HAS_LARGEDESC          0x00004  /* device supports jumbo frames and needs packet format 2 */
-#define DEV_HAS_HIGH_DMA           0x00008  /* device supports 64bit dma */
-#define DEV_HAS_CHECKSUM           0x00010  /* device supports tx and rx checksum offloads */
-#define DEV_HAS_VLAN               0x00020  /* device supports vlan tagging and striping */
-#define DEV_HAS_MSI                0x00040  /* device supports MSI */
-#define DEV_HAS_MSI_X              0x00080  /* device supports MSI-X */
-#define DEV_HAS_POWER_CNTRL        0x00100  /* device supports power savings */
-#define DEV_HAS_STATISTICS_V1      0x00200  /* device supports hw statistics version 1 */
-#define DEV_HAS_STATISTICS_V2      0x00400  /* device supports hw statistics version 2 */
-#define DEV_HAS_TEST_EXTENDED      0x00800  /* device supports extended diagnostic test */
-#define DEV_HAS_MGMT_UNIT          0x01000  /* device supports management unit */
-#define DEV_HAS_CORRECT_MACADDR    0x02000  /* device supports correct mac address order */
-#define DEV_HAS_COLLISION_FIX      0x04000  /* device supports tx collision fix */
-#define DEV_HAS_PAUSEFRAME_TX_V1   0x08000  /* device supports tx pause frames version 1 */
-#define DEV_HAS_PAUSEFRAME_TX_V2   0x10000  /* device supports tx pause frames version 2 */
-#define DEV_HAS_PAUSEFRAME_TX_V3   0x20000  /* device supports tx pause frames version 3 */
-#define DEV_NEED_TX_LIMIT          0x40000  /* device needs to limit tx */
-#define DEV_HAS_GEAR_MODE          0x80000  /* device supports gear mode */
+#define DEV_NEED_TIMERIRQ          0x000001  /* set the timer irq flag in the irq mask */
+#define DEV_NEED_LINKTIMER         0x000002  /* poll link settings. Relies on the timer irq */
+#define DEV_HAS_LARGEDESC          0x000004  /* device supports jumbo frames and needs packet format 2 */
+#define DEV_HAS_HIGH_DMA           0x000008  /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM           0x000010  /* device supports tx and rx checksum offloads */
+#define DEV_HAS_VLAN               0x000020  /* device supports vlan tagging and striping */
+#define DEV_HAS_MSI                0x000040  /* device supports MSI */
+#define DEV_HAS_MSI_X              0x000080  /* device supports MSI-X */
+#define DEV_HAS_POWER_CNTRL        0x000100  /* device supports power savings */
+#define DEV_HAS_STATISTICS_V1      0x000200  /* device supports hw statistics version 1 */
+#define DEV_HAS_STATISTICS_V2      0x000400  /* device supports hw statistics version 2 */
+#define DEV_HAS_STATISTICS_V3      0x000800  /* device supports hw statistics version 3 */
+#define DEV_HAS_TEST_EXTENDED      0x001000  /* device supports extended diagnostic test */
+#define DEV_HAS_MGMT_UNIT          0x002000  /* device supports management unit */
+#define DEV_HAS_CORRECT_MACADDR    0x004000  /* device supports correct mac address order */
+#define DEV_HAS_COLLISION_FIX      0x008000  /* device supports tx collision fix */
+#define DEV_HAS_PAUSEFRAME_TX_V1   0x010000  /* device supports tx pause frames version 1 */
+#define DEV_HAS_PAUSEFRAME_TX_V2   0x020000  /* device supports tx pause frames version 2 */
+#define DEV_HAS_PAUSEFRAME_TX_V3   0x040000  /* device supports tx pause frames version 3 */
+#define DEV_NEED_TX_LIMIT          0x080000  /* device needs to limit tx */
+#define DEV_HAS_GEAR_MODE          0x100000  /* device supports gear mode */
 
 enum {
 	NvRegIrqStatus = 0x000,
@@ -248,6 +249,8 @@ enum {
 #define NVREG_TX_PAUSEFRAME_ENABLE_V1	0x01800010
 #define NVREG_TX_PAUSEFRAME_ENABLE_V2	0x056003f0
 #define NVREG_TX_PAUSEFRAME_ENABLE_V3	0x09f00880
+	NvRegTxPauseFrameLimit = 0x174,
+#define NVREG_TX_PAUSEFRAMELIMIT_ENABLE	0x00010000
 	NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR		0x0001
 #define NVREG_MIISTAT_LINKCHANGE	0x0008
@@ -270,6 +273,9 @@ enum {
 #define NVREG_MIICTL_WRITE	0x00400
 #define NVREG_MIICTL_ADDRSHIFT	5
 	NvRegMIIData = 0x194,
+	NvRegTxUnicast = 0x1a0,
+	NvRegTxMulticast = 0x1a4,
+	NvRegTxBroadcast = 0x1a8,
 	NvRegWakeUpFlags = 0x200,
 #define NVREG_WAKEUPFLAGS_VAL		0x7770
 #define NVREG_WAKEUPFLAGS_BUSYSHIFT	24
@@ -402,6 +408,7 @@ union ring_type {
 #define NV_RX_FRAMINGERR	(1<<29)
 #define NV_RX_ERROR		(1<<30)
 #define NV_RX_AVAIL		(1<<31)
+#define NV_RX_ERROR_MASK	(NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3|NV_RX_ERROR4|NV_RX_CRCERR|NV_RX_OVERFLOW|NV_RX_FRAMINGERR)
 
 #define NV_RX2_CHECKSUMMASK	(0x1C000000)
 #define NV_RX2_CHECKSUM_IP	(0x10000000)
@@ -419,6 +426,7 @@ union ring_type {
 /* error and avail are the same for both */
 #define NV_RX2_ERROR		(1<<30)
 #define NV_RX2_AVAIL		(1<<31)
+#define NV_RX2_ERROR_MASK	(NV_RX2_ERROR1|NV_RX2_ERROR2|NV_RX2_ERROR3|NV_RX2_ERROR4|NV_RX2_CRCERR|NV_RX2_OVERFLOW|NV_RX2_FRAMINGERR)
 
 #define NV_RX3_VLAN_TAG_PRESENT (1<<16)
 #define NV_RX3_VLAN_TAG_MASK	(0x0000FFFF)
@@ -616,7 +624,12 @@ static const struct nv_ethtool_str nv_estats_str[] = {
 	{ "rx_bytes" },
 	{ "tx_pause" },
 	{ "rx_pause" },
-	{ "rx_drop_frame" }
+	{ "rx_drop_frame" },
+
+	/* version 3 stats */
+	{ "tx_unicast" },
+	{ "tx_multicast" },
+	{ "tx_broadcast" }
 };
 
 struct nv_ethtool_stats {
@@ -652,9 +665,15 @@ struct nv_ethtool_stats {
 	u64 tx_pause;
 	u64 rx_pause;
 	u64 rx_drop_frame;
+
+	/* version 3 stats */
+	u64 tx_unicast;
+	u64 tx_multicast;
+	u64 tx_broadcast;
 };
 
-#define NV_DEV_STATISTICS_V2_COUNT (sizeof(struct nv_ethtool_stats)/sizeof(u64))
+#define NV_DEV_STATISTICS_V3_COUNT (sizeof(struct nv_ethtool_stats)/sizeof(u64))
+#define NV_DEV_STATISTICS_V2_COUNT (NV_DEV_STATISTICS_V3_COUNT - 3)
 #define NV_DEV_STATISTICS_V1_COUNT (NV_DEV_STATISTICS_V2_COUNT - 6)
 
 /* diagnostics */
@@ -1628,6 +1647,12 @@ static void nv_get_hw_stats(struct net_device *dev)
 		np->estats.rx_pause += readl(base + NvRegRxPause);
 		np->estats.rx_drop_frame += readl(base + NvRegRxDropFrame);
 	}
+
+	if (np->driver_data & DEV_HAS_STATISTICS_V3) {
+		np->estats.tx_unicast += readl(base + NvRegTxUnicast);
+		np->estats.tx_multicast += readl(base + NvRegTxMulticast);
+		np->estats.tx_broadcast += readl(base + NvRegTxBroadcast);
+	}
 }
 
 /*
@@ -1641,7 +1666,7 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
 	struct fe_priv *np = netdev_priv(dev);
 
 	/* If the nic supports hw counters then retrieve latest values */
-	if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2)) {
+	if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3)) {
 		nv_get_hw_stats(dev);
 
 		/* copy to net_device stats */
@@ -2632,7 +2657,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
 			if (likely(flags & NV_RX_DESCRIPTORVALID)) {
 				len = flags & LEN_MASK_V1;
 				if (unlikely(flags & NV_RX_ERROR)) {
-					if (flags & NV_RX_ERROR4) {
+					if ((flags & NV_RX_ERROR_MASK) == NV_RX_ERROR4) {
 						len = nv_getlen(dev, skb->data, len);
 						if (len < 0) {
 							dev->stats.rx_errors++;
@@ -2641,7 +2666,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
 						}
 					}
 					/* framing errors are soft errors */
-					else if (flags & NV_RX_FRAMINGERR) {
+					else if ((flags & NV_RX_ERROR_MASK) == NV_RX_FRAMINGERR) {
 						if (flags & NV_RX_SUBSTRACT1) {
 							len--;
 						}
@@ -2667,7 +2692,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
 			if (likely(flags & NV_RX2_DESCRIPTORVALID)) {
 				len = flags & LEN_MASK_V2;
 				if (unlikely(flags & NV_RX2_ERROR)) {
-					if (flags & NV_RX2_ERROR4) {
+					if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_ERROR4) {
 						len = nv_getlen(dev, skb->data, len);
 						if (len < 0) {
 							dev->stats.rx_errors++;
@@ -2676,7 +2701,7 @@ static int nv_rx_process(struct net_device *dev, int limit)
 						}
 					}
 					/* framing errors are soft errors */
-					else if (flags & NV_RX2_FRAMINGERR) {
+					else if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_FRAMINGERR) {
 						if (flags & NV_RX2_SUBSTRACT1) {
 							len--;
 						}
@@ -2766,7 +2791,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
 		if (likely(flags & NV_RX2_DESCRIPTORVALID)) {
 			len = flags & LEN_MASK_V2;
 			if (unlikely(flags & NV_RX2_ERROR)) {
-				if (flags & NV_RX2_ERROR4) {
+				if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_ERROR4) {
 					len = nv_getlen(dev, skb->data, len);
 					if (len < 0) {
 						dev_kfree_skb(skb);
@@ -2774,7 +2799,7 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
 					}
 				}
 				/* framing errors are soft errors */
-				else if (flags & NV_RX2_FRAMINGERR) {
+				else if ((flags & NV_RX2_ERROR_MASK) == NV_RX2_FRAMINGERR) {
 					if (flags & NV_RX2_SUBSTRACT1) {
 						len--;
 					}
@@ -3053,8 +3078,11 @@ static void nv_update_pause(struct net_device *dev, u32 pause_flags)
 			u32 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V1;
 			if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V2)
 				pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V2;
-			if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V3)
+			if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V3) {
 				pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V3;
+				/* limit the number of tx pause frames to a default of 8 */
+				writel(readl(base + NvRegTxPauseFrameLimit)|NVREG_TX_PAUSEFRAMELIMIT_ENABLE, base + NvRegTxPauseFrameLimit);
+			}
 			writel(pause_enable,  base + NvRegTxPauseFrame);
 			writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1);
 			np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE;
@@ -4740,6 +4768,8 @@ static int nv_get_sset_count(struct net_device *dev, int sset)
 			return NV_DEV_STATISTICS_V1_COUNT;
 		else if (np->driver_data & DEV_HAS_STATISTICS_V2)
 			return NV_DEV_STATISTICS_V2_COUNT;
+		else if (np->driver_data & DEV_HAS_STATISTICS_V3)
+			return NV_DEV_STATISTICS_V3_COUNT;
 		else
 			return 0;
 	default:
@@ -5324,7 +5354,7 @@ static int nv_open(struct net_device *dev)
 		mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
 
 	/* start statistics timer */
-	if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2))
+	if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3))
 		mod_timer(&np->stats_poll,
 			round_jiffies(jiffies + STATS_INTERVAL));
 
@@ -5428,7 +5458,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 	if (err < 0)
 		goto out_disable;
 
-	if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V2))
+	if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_STATISTICS_V2|DEV_HAS_STATISTICS_V3))
 		np->register_size = NV_PCI_REGSZ_VER3;
 	else if (id->driver_data & DEV_HAS_STATISTICS_V1)
 		np->register_size = NV_PCI_REGSZ_VER2;
@@ -6083,35 +6113,35 @@ static struct pci_device_id pci_tbl[] = {
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{0,},
 };
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index 0a97fc2..1c7ef81 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -126,7 +126,7 @@ out:
 #define FCC_NAPI_RX_EVENT_MSK	(FCC_ENET_RXF | FCC_ENET_RXB)
 #define FCC_RX_EVENT		(FCC_ENET_RXF)
 #define FCC_TX_EVENT		(FCC_ENET_TXB)
-#define FCC_ERR_EVENT_MSK	(FCC_ENET_TXE | FCC_ENET_BSY)
+#define FCC_ERR_EVENT_MSK	(FCC_ENET_TXE)
 
 static int setup_data(struct net_device *dev)
 {
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index b8394cf..ca6cf6e 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -414,9 +414,7 @@ static int gfar_suspend(struct platform_device *pdev, pm_message_t state)
 		spin_unlock(&priv->rxlock);
 		spin_unlock_irqrestore(&priv->txlock, flags);
 
-#ifdef CONFIG_GFAR_NAPI
 		napi_disable(&priv->napi);
-#endif
 
 		if (magic_packet) {
 			/* Enable interrupt on Magic Packet */
@@ -469,9 +467,7 @@ static int gfar_resume(struct platform_device *pdev)
 
 	netif_device_attach(dev);
 
-#ifdef CONFIG_GFAR_NAPI
 	napi_enable(&priv->napi);
-#endif
 
 	return 0;
 }
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 3249df5..b8e25c4 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -548,7 +548,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 
 		printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
-		       (ax->tty->ops->chars_in_buffer(ax->tty) || ax->xleft) ?
+		       (tty_chars_in_buffer(ax->tty) || ax->xleft) ?
 		       "bad line quality" : "driver error");
 
 		ax->xleft = 0;
diff --git a/drivers/net/igb/e1000_82575.c b/drivers/net/igb/e1000_82575.c
index e098f23..bb823ac 100644
--- a/drivers/net/igb/e1000_82575.c
+++ b/drivers/net/igb/e1000_82575.c
@@ -850,7 +850,7 @@ void igb_update_mc_addr_list_82575(struct e1000_hw *hw,
 	for (; mc_addr_count > 0; mc_addr_count--) {
 		hash_value = igb_hash_mc_addr(hw, mc_addr_list);
 		hw_dbg("Hash value = 0x%03X\n", hash_value);
-		hw->mac.ops.mta_set(hw, hash_value);
+		igb_mta_set(hw, hash_value);
 		mc_addr_list += ETH_ALEN;
 	}
 }
@@ -1136,6 +1136,12 @@ static s32 igb_setup_fiber_serdes_link_82575(struct e1000_hw *hw)
 		       E1000_PCS_LCTL_FORCE_LINK;     /* Force Link */
 		hw_dbg("Configuring Forced Link; PCS_LCTL = 0x%08X\n", reg);
 	}
+
+	if (hw->mac.type == e1000_82576) {
+		reg |= E1000_PCS_LCTL_FORCE_FCTRL;
+		igb_force_mac_fc(hw);
+	}
+
 	wr32(E1000_PCS_LCTL, reg);
 
 	return 0;
@@ -1232,70 +1238,6 @@ out:
 }
 
 /**
- *  igb_translate_register_82576 - Translate the proper register offset
- *  @reg: e1000 register to be read
- *
- *  Registers in 82576 are located in different offsets than other adapters
- *  even though they function in the same manner.  This function takes in
- *  the name of the register to read and returns the correct offset for
- *  82576 silicon.
- **/
-u32 igb_translate_register_82576(u32 reg)
-{
-	/*
-	 * Some of the Kawela registers are located at different
-	 * offsets than they are in older adapters.
-	 * Despite the difference in location, the registers
-	 * function in the same manner.
-	 */
-	switch (reg) {
-	case E1000_TDBAL(0):
-		reg = 0x0E000;
-		break;
-	case E1000_TDBAH(0):
-		reg = 0x0E004;
-		break;
-	case E1000_TDLEN(0):
-		reg = 0x0E008;
-		break;
-	case E1000_TDH(0):
-		reg = 0x0E010;
-		break;
-	case E1000_TDT(0):
-		reg = 0x0E018;
-		break;
-	case E1000_TXDCTL(0):
-		reg = 0x0E028;
-		break;
-	case E1000_RDBAL(0):
-		reg = 0x0C000;
-		break;
-	case E1000_RDBAH(0):
-		reg = 0x0C004;
-		break;
-	case E1000_RDLEN(0):
-		reg = 0x0C008;
-		break;
-	case E1000_RDH(0):
-		reg = 0x0C010;
-		break;
-	case E1000_RDT(0):
-		reg = 0x0C018;
-		break;
-	case E1000_RXDCTL(0):
-		reg = 0x0C028;
-		break;
-	case E1000_SRRCTL(0):
-		reg = 0x0C00C;
-		break;
-	default:
-		break;
-	}
-
-	return reg;
-}
-
-/**
  *  igb_reset_init_script_82575 - Inits HW defaults after reset
  *  @hw: pointer to the HW structure
  *
diff --git a/drivers/net/igb/e1000_82575.h b/drivers/net/igb/e1000_82575.h
index 2f848e5..c1928b5 100644
--- a/drivers/net/igb/e1000_82575.h
+++ b/drivers/net/igb/e1000_82575.h
@@ -28,7 +28,6 @@
 #ifndef _E1000_82575_H_
 #define _E1000_82575_H_
 
-u32 igb_translate_register_82576(u32 reg);
 void igb_update_mc_addr_list_82575(struct e1000_hw*, u8*, u32, u32, u32);
 extern void igb_shutdown_fiber_serdes_link_82575(struct e1000_hw *hw);
 extern void igb_rx_fifo_flush_82575(struct e1000_hw *hw);
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index afdba3c..ce70068 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -257,6 +257,7 @@
 #define E1000_PCS_LCTL_FDV_FULL          8
 #define E1000_PCS_LCTL_FSD               0x10
 #define E1000_PCS_LCTL_FORCE_LINK        0x20
+#define E1000_PCS_LCTL_FORCE_FCTRL       0x80
 #define E1000_PCS_LCTL_AN_ENABLE         0x10000
 #define E1000_PCS_LCTL_AN_RESTART        0x20000
 #define E1000_PCS_LCTL_AN_TIMEOUT        0x40000
diff --git a/drivers/net/igb/e1000_hw.h b/drivers/net/igb/e1000_hw.h
index 19fa4ee..a65ccc3 100644
--- a/drivers/net/igb/e1000_hw.h
+++ b/drivers/net/igb/e1000_hw.h
@@ -420,7 +420,6 @@ struct e1000_mac_operations {
 	void (*rar_set)(struct e1000_hw *, u8 *, u32);
 	s32  (*read_mac_addr)(struct e1000_hw *);
 	s32  (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
-	void (*mta_set)(struct e1000_hw *, u32);
 };
 
 struct e1000_phy_operations {
diff --git a/drivers/net/igb/e1000_mac.c b/drivers/net/igb/e1000_mac.c
index 20408aa..e18747c 100644
--- a/drivers/net/igb/e1000_mac.c
+++ b/drivers/net/igb/e1000_mac.c
@@ -144,34 +144,6 @@ void igb_write_vfta(struct e1000_hw *hw, u32 offset, u32 value)
 }
 
 /**
- *  igb_init_rx_addrs - Initialize receive address's
- *  @hw: pointer to the HW structure
- *  @rar_count: receive address registers
- *
- *  Setups the receive address registers by setting the base receive address
- *  register to the devices MAC address and clearing all the other receive
- *  address registers to 0.
- **/
-void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count)
-{
-	u32 i;
-
-	/* Setup the receive address */
-	hw_dbg("Programming MAC Address into RAR[0]\n");
-
-	hw->mac.ops.rar_set(hw, hw->mac.addr, 0);
-
-	/* Zero out the other (rar_entry_count - 1) receive addresses */
-	hw_dbg("Clearing RAR[1-%u]\n", rar_count-1);
-	for (i = 1; i < rar_count; i++) {
-		array_wr32(E1000_RA, (i << 1), 0);
-		wrfl();
-		array_wr32(E1000_RA, ((i << 1) + 1), 0);
-		wrfl();
-	}
-}
-
-/**
  *  igb_check_alt_mac_addr - Check for alternate MAC addr
  *  @hw: pointer to the HW structure
  *
@@ -271,7 +243,7 @@ void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
  *  current value is read, the new bit is OR'd in and the new value is
  *  written back into the register.
  **/
-static void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
+void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
 {
 	u32 hash_bit, hash_reg, mta;
 
@@ -297,60 +269,6 @@ static void igb_mta_set(struct e1000_hw *hw, u32 hash_value)
 }
 
 /**
- *  igb_update_mc_addr_list - Update Multicast addresses
- *  @hw: pointer to the HW structure
- *  @mc_addr_list: array of multicast addresses to program
- *  @mc_addr_count: number of multicast addresses to program
- *  @rar_used_count: the first RAR register free to program
- *  @rar_count: total number of supported Receive Address Registers
- *
- *  Updates the Receive Address Registers and Multicast Table Array.
- *  The caller must have a packed mc_addr_list of multicast addresses.
- *  The parameter rar_count will usually be hw->mac.rar_entry_count
- *  unless there are workarounds that change this.
- **/
-void igb_update_mc_addr_list(struct e1000_hw *hw,
-			       u8 *mc_addr_list, u32 mc_addr_count,
-			       u32 rar_used_count, u32 rar_count)
-{
-	u32 hash_value;
-	u32 i;
-
-	/*
-	 * Load the first set of multicast addresses into the exact
-	 * filters (RAR).  If there are not enough to fill the RAR
-	 * array, clear the filters.
-	 */
-	for (i = rar_used_count; i < rar_count; i++) {
-		if (mc_addr_count) {
-			hw->mac.ops.rar_set(hw, mc_addr_list, i);
-			mc_addr_count--;
-			mc_addr_list += ETH_ALEN;
-		} else {
-			array_wr32(E1000_RA, i << 1, 0);
-			wrfl();
-			array_wr32(E1000_RA, (i << 1) + 1, 0);
-			wrfl();
-		}
-	}
-
-	/* Clear the old settings from the MTA */
-	hw_dbg("Clearing MTA\n");
-	for (i = 0; i < hw->mac.mta_reg_count; i++) {
-		array_wr32(E1000_MTA, i, 0);
-		wrfl();
-	}
-
-	/* Load any remaining multicast addresses into the hash table. */
-	for (; mc_addr_count > 0; mc_addr_count--) {
-		hash_value = igb_hash_mc_addr(hw, mc_addr_list);
-		hw_dbg("Hash value = 0x%03X\n", hash_value);
-		igb_mta_set(hw, hash_value);
-		mc_addr_list += ETH_ALEN;
-	}
-}
-
-/**
  *  igb_hash_mc_addr - Generate a multicast hash value
  *  @hw: pointer to the HW structure
  *  @mc_addr: pointer to a multicast address
diff --git a/drivers/net/igb/e1000_mac.h b/drivers/net/igb/e1000_mac.h
index dc2f8cc..cbee6af 100644
--- a/drivers/net/igb/e1000_mac.h
+++ b/drivers/net/igb/e1000_mac.h
@@ -51,9 +51,6 @@ s32  igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
 				       u16 *duplex);
 s32  igb_id_led_init(struct e1000_hw *hw);
 s32  igb_led_off(struct e1000_hw *hw);
-void igb_update_mc_addr_list(struct e1000_hw *hw,
-			       u8 *mc_addr_list, u32 mc_addr_count,
-			       u32 rar_used_count, u32 rar_count);
 s32  igb_setup_link(struct e1000_hw *hw);
 s32  igb_validate_mdi_setting(struct e1000_hw *hw);
 s32  igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
@@ -62,7 +59,7 @@ s32  igb_write_8bit_ctrl_reg(struct e1000_hw *hw, u32 reg,
 void igb_clear_hw_cntrs_base(struct e1000_hw *hw);
 void igb_clear_vfta(struct e1000_hw *hw);
 void igb_config_collision_dist(struct e1000_hw *hw);
-void igb_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
+void igb_mta_set(struct e1000_hw *hw, u32 hash_value);
 void igb_put_hw_semaphore(struct e1000_hw *hw);
 void igb_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
 s32  igb_check_alt_mac_addr(struct e1000_hw *hw);
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index b95093d..95523af 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -262,9 +262,6 @@
 #define E1000_RETA(_i)  (0x05C00 + ((_i) * 4))
 #define E1000_RSSRK(_i) (0x05C80 + ((_i) * 4)) /* RSS Random Key - RW Array */
 
-#define E1000_REGISTER(a, reg) (((a)->mac.type < e1000_82576) \
-                               ? reg : e1000_translate_register_82576(reg))
-
 #define wr32(reg, value) (writel(value, hw->hw_addr + reg))
 #define rd32(reg) (readl(hw->hw_addr + reg))
 #define wrfl() ((void)rd32(E1000_STATUS))
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index b602c4d..8f66e15 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -311,7 +311,7 @@ static void igb_assign_vector(struct igb_adapter *adapter, int rx_queue,
 		array_wr32(E1000_MSIXBM(0), msix_vector, msixbm);
 		break;
 	case e1000_82576:
-		/* Kawela uses a table-based method for assigning vectors.
+		/* The 82576 uses a table-based method for assigning vectors.
 		   Each queue has a single entry in the table to which we write
 		   a vector number along with a "valid" bit.  Sadly, the layout
 		   of the table is somewhat counterintuitive. */
@@ -720,28 +720,6 @@ static void igb_get_hw_control(struct igb_adapter *adapter)
 			ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
 }
 
-static void igb_init_manageability(struct igb_adapter *adapter)
-{
-	struct e1000_hw *hw = &adapter->hw;
-
-	if (adapter->en_mng_pt) {
-		u32 manc2h = rd32(E1000_MANC2H);
-		u32 manc = rd32(E1000_MANC);
-
-		/* enable receiving management packets to the host */
-		/* this will probably generate destination unreachable messages
-		 * from the host OS, but the packets will be handled on SMBUS */
-		manc |= E1000_MANC_EN_MNG2HOST;
-#define E1000_MNG2HOST_PORT_623 (1 << 5)
-#define E1000_MNG2HOST_PORT_664 (1 << 6)
-		manc2h |= E1000_MNG2HOST_PORT_623;
-		manc2h |= E1000_MNG2HOST_PORT_664;
-		wr32(E1000_MANC2H, manc2h);
-
-		wr32(E1000_MANC, manc);
-	}
-}
-
 /**
  * igb_configure - configure the hardware for RX and TX
  * @adapter: private board structure
@@ -755,7 +733,6 @@ static void igb_configure(struct igb_adapter *adapter)
 	igb_set_multi(netdev);
 
 	igb_restore_vlan(adapter);
-	igb_init_manageability(adapter);
 
 	igb_configure_tx(adapter);
 	igb_setup_rctl(adapter);
@@ -1372,7 +1349,8 @@ static void __devexit igb_remove(struct pci_dev *pdev)
 
 	unregister_netdev(netdev);
 
-	if (!igb_check_reset_block(&adapter->hw))
+	if (adapter->hw.phy.ops.reset_phy &&
+	    !igb_check_reset_block(&adapter->hw))
 		adapter->hw.phy.ops.reset_phy(&adapter->hw);
 
 	igb_remove_device(&adapter->hw);
@@ -4523,8 +4501,6 @@ static void igb_io_resume(struct pci_dev *pdev)
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct igb_adapter *adapter = netdev_priv(netdev);
 
-	igb_init_manageability(adapter);
-
 	if (netif_running(netdev)) {
 		if (igb_up(adapter)) {
 			dev_err(&pdev->dev, "igb_up failed after reset\n");
diff --git a/drivers/net/lp486e.c b/drivers/net/lp486e.c
index 591a7e4..83fa9d8 100644
--- a/drivers/net/lp486e.c
+++ b/drivers/net/lp486e.c
@@ -1272,8 +1272,6 @@ static void set_multicast_list(struct net_device *dev) {
 			return;
 		}
 		if (dev->mc_count == 0 && !(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
-			if (dev->flags & IFF_ALLMULTI)
-				dev->flags |= IFF_PROMISC;
 			lp->i596_config[8] &= ~0x01;
 		} else {
 			lp->i596_config[8] |= 0x01;
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index 4cb364e..0a97c26 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -100,7 +100,7 @@ static inline void load_eaddr(struct net_device *dev)
 	DPRINTK("Loading MAC Address: %s\n", print_mac(mac, dev->dev_addr));
 	macaddr = 0;
 	for (i = 0; i < 6; i++)
-		macaddr |= dev->dev_addr[i] << ((5 - i) * 8);
+		macaddr |= (u64)dev->dev_addr[i] << ((5 - i) * 8);
 
 	mace->eth.mac_addr = macaddr;
 }
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 3ab0e52..f1de38f 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -3699,6 +3699,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		dev_err(&pdev->dev, "Error %d setting DMA mask\n", status);
 		goto abort_with_netdev;
 	}
+	(void)pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
 	mgp->cmd = dma_alloc_coherent(&pdev->dev, sizeof(*mgp->cmd),
 				      &mgp->cmd_bus, GFP_KERNEL);
 	if (mgp->cmd == NULL)
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h
index fdbeeee..9937210 100644
--- a/drivers/net/myri10ge/myri10ge_mcp.h
+++ b/drivers/net/myri10ge/myri10ge_mcp.h
@@ -101,6 +101,8 @@ struct mcp_kreq_ether_recv {
 #define	MXGEFW_ETH_SEND_3	0x2c0000
 #define	MXGEFW_ETH_RECV_SMALL	0x300000
 #define	MXGEFW_ETH_RECV_BIG	0x340000
+#define	MXGEFW_ETH_SEND_GO	0x380000
+#define	MXGEFW_ETH_SEND_STOP	0x3C0000
 
 #define	MXGEFW_ETH_SEND(n)		(0x200000 + (((n) & 0x03) * 0x40000))
 #define	MXGEFW_ETH_SEND_OFFSET(n)	(MXGEFW_ETH_SEND(n) - MXGEFW_ETH_SEND_4)
@@ -120,6 +122,11 @@ enum myri10ge_mcp_cmd_type {
 	 * MXGEFW_CMD_RESET is issued */
 
 	MXGEFW_CMD_SET_INTRQ_DMA,
+	/* data0 = LSW of the host address
+	 * data1 = MSW of the host address
+	 * data2 = slice number if multiple slices are used
+	 */
+
 	MXGEFW_CMD_SET_BIG_BUFFER_SIZE,	/* in bytes, power of 2 */
 	MXGEFW_CMD_SET_SMALL_BUFFER_SIZE,	/* in bytes */
 
@@ -129,6 +136,8 @@ enum myri10ge_mcp_cmd_type {
 	MXGEFW_CMD_GET_SEND_OFFSET,
 	MXGEFW_CMD_GET_SMALL_RX_OFFSET,
 	MXGEFW_CMD_GET_BIG_RX_OFFSET,
+	/* data0 = slice number if multiple slices are used */
+
 	MXGEFW_CMD_GET_IRQ_ACK_OFFSET,
 	MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
 
@@ -200,7 +209,12 @@ enum myri10ge_mcp_cmd_type {
 	MXGEFW_CMD_SET_STATS_DMA_V2,
 	/* data0, data1 = bus addr,
 	 * data2 = sizeof(struct mcp_irq_data) from driver point of view, allows
-	 * adding new stuff to mcp_irq_data without changing the ABI */
+	 * adding new stuff to mcp_irq_data without changing the ABI
+	 *
+	 * If multiple slices are used, data2 contains both the size of the
+	 * structure (in the lower 16 bits) and the slice number
+	 * (in the upper 16 bits).
+	 */
 
 	MXGEFW_CMD_UNALIGNED_TEST,
 	/* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned
@@ -222,13 +236,18 @@ enum myri10ge_mcp_cmd_type {
 	MXGEFW_CMD_GET_MAX_RSS_QUEUES,
 	MXGEFW_CMD_ENABLE_RSS_QUEUES,
 	/* data0 = number of slices n (0, 1, ..., n-1) to enable
-	 * data1 = interrupt mode.
-	 * 0=share one INTx/MSI, 1=use one MSI-X per queue.
+	 * data1 = interrupt mode | use of multiple transmit queues.
+	 * 0=share one INTx/MSI.
+	 * 1=use one MSI-X per queue.
 	 * If all queues share one interrupt, the driver must have set
 	 * RSS_SHARED_INTERRUPT_DMA before enabling queues.
+	 * 2=enable both receive and send queues.
+	 * Without this bit set, only one send queue (slice 0's send queue)
+	 * is enabled.  The receive queues are always enabled.
 	 */
-#define MXGEFW_SLICE_INTR_MODE_SHARED 0
-#define MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE 1
+#define MXGEFW_SLICE_INTR_MODE_SHARED          0x0
+#define MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE   0x1
+#define MXGEFW_SLICE_ENABLE_MULTIPLE_TX_QUEUES 0x2
 
 	MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET,
 	MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA,
@@ -250,10 +269,13 @@ enum myri10ge_mcp_cmd_type {
 	 * 2: TCP_IPV4        (required by RSS)
 	 * 3: IPV4 | TCP_IPV4 (required by RSS)
 	 * 4: source port
+	 * 5: source port + destination port
 	 */
 #define MXGEFW_RSS_HASH_TYPE_IPV4      0x1
 #define MXGEFW_RSS_HASH_TYPE_TCP_IPV4  0x2
 #define MXGEFW_RSS_HASH_TYPE_SRC_PORT  0x4
+#define MXGEFW_RSS_HASH_TYPE_SRC_DST_PORT 0x5
+#define MXGEFW_RSS_HASH_TYPE_MAX 0x5
 
 	MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
 	/* Return data = the max. size of the entire headers of a IPv6 TSO packet.
@@ -329,6 +351,20 @@ enum myri10ge_mcp_cmd_type {
 
 	MXGEFW_CMD_GET_DCA_OFFSET,
 	/* offset of dca control for WDMAs */
+
+	/* VMWare NetQueue commands */
+	MXGEFW_CMD_NETQ_GET_FILTERS_PER_QUEUE,
+	MXGEFW_CMD_NETQ_ADD_FILTER,
+	/* data0 = filter_id << 16 | queue << 8 | type */
+	/* data1 = MS4 of MAC Addr */
+	/* data2 = LS2_MAC << 16 | VLAN_tag */
+	MXGEFW_CMD_NETQ_DEL_FILTER,
+	/* data0 = filter_id */
+	MXGEFW_CMD_NETQ_QUERY1,
+	MXGEFW_CMD_NETQ_QUERY2,
+	MXGEFW_CMD_NETQ_QUERY3,
+	MXGEFW_CMD_NETQ_QUERY4,
+
 };
 
 enum myri10ge_mcp_cmd_status {
@@ -381,4 +417,10 @@ struct mcp_irq_data {
 	u8 valid;
 };
 
+/* definitions for NETQ filter type */
+#define MXGEFW_NETQ_FILTERTYPE_NONE 0
+#define MXGEFW_NETQ_FILTERTYPE_MACADDR 1
+#define MXGEFW_NETQ_FILTERTYPE_VLAN 2
+#define MXGEFW_NETQ_FILTERTYPE_VLANMACADDR 3
+
 #endif				/* __MYRI10GE_MCP_H__ */
diff --git a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
index 07d65c2..a8662ea 100644
--- a/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
+++ b/drivers/net/myri10ge/myri10ge_mcp_gen_header.h
@@ -35,7 +35,7 @@ struct mcp_gen_header {
 	unsigned char mcp_index;
 	unsigned char disable_rabbit;
 	unsigned char unaligned_tlp;
-	unsigned char pad1;
+	unsigned char pcie_link_algo;
 	unsigned counters_addr;
 	unsigned copy_block_info;	/* for small mcps loaded with "lload -d" */
 	unsigned short handoff_id_major;	/* must be equal */
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 8e73661..93a7b9b 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -508,6 +508,8 @@ typedef enum {
 	NETXEN_BRDTYPE_P3_10000_BASE_T = 0x0027,
 	NETXEN_BRDTYPE_P3_XG_LOM = 0x0028,
 	NETXEN_BRDTYPE_P3_4_GB_MM = 0x0029,
+	NETXEN_BRDTYPE_P3_10G_SFP_CT = 0x002a,
+	NETXEN_BRDTYPE_P3_10G_SFP_QT = 0x002b,
 	NETXEN_BRDTYPE_P3_10G_CX4 = 0x0031,
 	NETXEN_BRDTYPE_P3_10G_XFP = 0x0032
 
@@ -1170,6 +1172,36 @@ typedef struct {
 	nx_nic_intr_coalesce_data_t	irq;
 } nx_nic_intr_coalesce_t;
 
+#define NX_HOST_REQUEST		0x13
+#define NX_NIC_REQUEST		0x14
+
+#define NX_MAC_EVENT		0x1
+
+enum {
+	NX_NIC_H2C_OPCODE_START = 0,
+	NX_NIC_H2C_OPCODE_CONFIG_RSS,
+	NX_NIC_H2C_OPCODE_CONFIG_RSS_TBL,
+	NX_NIC_H2C_OPCODE_CONFIG_INTR_COALESCE,
+	NX_NIC_H2C_OPCODE_CONFIG_LED,
+	NX_NIC_H2C_OPCODE_CONFIG_PROMISCUOUS,
+	NX_NIC_H2C_OPCODE_CONFIG_L2_MAC,
+	NX_NIC_H2C_OPCODE_LRO_REQUEST,
+	NX_NIC_H2C_OPCODE_GET_SNMP_STATS,
+	NX_NIC_H2C_OPCODE_PROXY_START_REQUEST,
+	NX_NIC_H2C_OPCODE_PROXY_STOP_REQUEST,
+	NX_NIC_H2C_OPCODE_PROXY_SET_MTU,
+	NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE,
+	NX_H2P_OPCODE_GET_FINGER_PRINT_REQUEST,
+	NX_H2P_OPCODE_INSTALL_LICENSE_REQUEST,
+	NX_H2P_OPCODE_GET_LICENSE_CAPABILITY_REQUEST,
+	NX_NIC_H2C_OPCODE_GET_NET_STATS,
+	NX_NIC_H2C_OPCODE_LAST
+};
+
+#define VPORT_MISS_MODE_DROP		0 /* drop all unmatched */
+#define VPORT_MISS_MODE_ACCEPT_ALL	1 /* accept all packets */
+#define VPORT_MISS_MODE_ACCEPT_MULTI	2 /* accept unmatched multicast */
+
 typedef struct {
 	u64 qhdr;
 	u64 req_hdr;
@@ -1288,7 +1320,7 @@ struct netxen_adapter {
 	int (*disable_phy_interrupts) (struct netxen_adapter *);
 	int (*macaddr_set) (struct netxen_adapter *, netxen_ethernet_macaddr_t);
 	int (*set_mtu) (struct netxen_adapter *, int);
-	int (*set_promisc) (struct netxen_adapter *, netxen_niu_prom_mode_t);
+	int (*set_promisc) (struct netxen_adapter *, u32);
 	int (*phy_read) (struct netxen_adapter *, long reg, u32 *);
 	int (*phy_write) (struct netxen_adapter *, long reg, u32 val);
 	int (*init_port) (struct netxen_adapter *, int);
@@ -1465,9 +1497,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter);
 u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
 void netxen_p2_nic_set_multi(struct net_device *netdev);
 void netxen_p3_nic_set_multi(struct net_device *netdev);
+int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32);
 int netxen_config_intr_coalesce(struct netxen_adapter *adapter);
 
-u32 nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, u32 mtu);
+int nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu);
 int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
 
 int netxen_nic_set_mac(struct net_device *netdev, void *p);
@@ -1502,7 +1535,9 @@ static const struct netxen_brdinfo netxen_boards[] = {
 	{NETXEN_BRDTYPE_P3_10G_SFP_PLUS, 2, "Dual XGb SFP+ LP"},
 	{NETXEN_BRDTYPE_P3_10000_BASE_T, 1, "XGB 10G BaseT LP"},
 	{NETXEN_BRDTYPE_P3_XG_LOM,  2, "Dual XGb LOM"},
-	{NETXEN_BRDTYPE_P3_4_GB_MM, 4, "Quad GB - March Madness"},
+	{NETXEN_BRDTYPE_P3_4_GB_MM, 4, "NX3031 Gigabit Ethernet"},
+	{NETXEN_BRDTYPE_P3_10G_SFP_CT, 2, "NX3031 10 Gigabit Ethernet"},
+	{NETXEN_BRDTYPE_P3_10G_SFP_QT, 2, "Quanta Dual XGb SFP+"},
 	{NETXEN_BRDTYPE_P3_10G_CX4, 2, "Reference Dual CX4 Option"},
 	{NETXEN_BRDTYPE_P3_10G_XFP, 1, "Reference Single XFP Option"}
 };
diff --git a/drivers/net/netxen/netxen_nic_ctx.c b/drivers/net/netxen/netxen_nic_ctx.c
index 64babc5..64b5164 100644
--- a/drivers/net/netxen/netxen_nic_ctx.c
+++ b/drivers/net/netxen/netxen_nic_ctx.c
@@ -145,8 +145,8 @@ netxen_issue_cmd(struct netxen_adapter *adapter,
 	return rcode;
 }
 
-u32
-nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, u32 mtu)
+int
+nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, int mtu)
 {
 	u32 rcode = NX_RCODE_SUCCESS;
 	struct netxen_recv_context *recv_ctx = &adapter->recv_ctx[0];
@@ -160,7 +160,10 @@ nx_fw_cmd_set_mtu(struct netxen_adapter *adapter, u32 mtu)
 				0,
 				NX_CDRP_CMD_SET_MTU);
 
-	return rcode;
+	if (rcode != NX_RCODE_SUCCESS)
+		return -EIO;
+
+	return 0;
 }
 
 static int
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index 48ee06b..4ad3e08 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -140,18 +140,33 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		if (netif_running(dev)) {
 			ecmd->speed = adapter->link_speed;
 			ecmd->duplex = adapter->link_duplex;
-		} else
-			return -EIO;	/* link absent */
+			ecmd->autoneg = adapter->link_autoneg;
+		}
+
 	} else if (adapter->ahw.board_type == NETXEN_NIC_XGBE) {
-		ecmd->supported = (SUPPORTED_TP |
-				   SUPPORTED_1000baseT_Full |
-				   SUPPORTED_10000baseT_Full);
-		ecmd->advertising = (ADVERTISED_TP |
-				     ADVERTISED_1000baseT_Full |
-				     ADVERTISED_10000baseT_Full);
+		u32 val;
+
+		adapter->hw_read_wx(adapter, NETXEN_PORT_MODE_ADDR, &val, 4);
+		if (val == NETXEN_PORT_MODE_802_3_AP) {
+			ecmd->supported = SUPPORTED_1000baseT_Full;
+			ecmd->advertising = ADVERTISED_1000baseT_Full;
+		} else {
+			ecmd->supported = SUPPORTED_10000baseT_Full;
+			ecmd->advertising = ADVERTISED_10000baseT_Full;
+		}
+
 		ecmd->port = PORT_TP;
 
-		ecmd->speed = SPEED_10000;
+		if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+			u16 pcifn = adapter->ahw.pci_func;
+
+			adapter->hw_read_wx(adapter,
+				P3_LINK_SPEED_REG(pcifn), &val, 4);
+			ecmd->speed = P3_LINK_SPEED_MHZ *
+					P3_LINK_SPEED_VAL(pcifn, val);
+		} else
+			ecmd->speed = SPEED_10000;
+
 		ecmd->duplex = DUPLEX_FULL;
 		ecmd->autoneg = AUTONEG_DISABLE;
 	} else
@@ -192,6 +207,8 @@ netxen_nic_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
 		break;
 	case NETXEN_BRDTYPE_P2_SB31_10G:
 	case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
+	case NETXEN_BRDTYPE_P3_10G_SFP_CT:
+	case NETXEN_BRDTYPE_P3_10G_SFP_QT:
 	case NETXEN_BRDTYPE_P3_10G_XFP:
 		ecmd->supported |= SUPPORTED_FIBRE;
 		ecmd->advertising |= ADVERTISED_FIBRE;
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h
index 3ce13e4..e8e8d73 100644
--- a/drivers/net/netxen/netxen_nic_hdr.h
+++ b/drivers/net/netxen/netxen_nic_hdr.h
@@ -724,6 +724,13 @@ enum {
 #define XG_LINK_STATE_P3(pcifn,val) \
 	(((val) >> ((pcifn) * 4)) & XG_LINK_STATE_P3_MASK)
 
+#define P3_LINK_SPEED_MHZ	100
+#define P3_LINK_SPEED_MASK	0xff
+#define P3_LINK_SPEED_REG(pcifn)	\
+	(CRB_PF_LINK_SPEED_1 + (((pcifn) / 4) * 4))
+#define P3_LINK_SPEED_VAL(pcifn, reg)	\
+	(((reg) >> (8 * ((pcifn) & 0x3))) & P3_LINK_SPEED_MASK)
+
 #define NETXEN_CAM_RAM_BASE	(NETXEN_CRB_CAM + 0x02000)
 #define NETXEN_CAM_RAM(reg)	(NETXEN_CAM_RAM_BASE + (reg))
 #define NETXEN_FW_VERSION_MAJOR (NETXEN_CAM_RAM(0x150))
@@ -836,9 +843,11 @@ enum {
 
 #define PCIE_SETUP_FUNCTION	(0x12040)
 #define PCIE_SETUP_FUNCTION2	(0x12048)
+#define PCIE_MISCCFG_RC         (0x1206c)
 #define PCIE_TGT_SPLIT_CHICKEN	(0x12080)
 #define PCIE_CHICKEN3		(0x120c8)
 
+#define ISR_INT_STATE_REG       (NETXEN_PCIX_PS_REG(PCIE_MISCCFG_RC))
 #define PCIE_MAX_MASTER_SPLIT	(0x14048)
 
 #define NETXEN_PORT_MODE_NONE		0
@@ -854,6 +863,7 @@ enum {
 #define NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL		(0x14)
 
 #define	ISR_MSI_INT_TRIGGER(FUNC) (NETXEN_PCIX_PS_REG(PCIX_MSI_F(FUNC)))
+#define ISR_LEGACY_INT_TRIGGERED(VAL)	(((VAL) & 0x300) == 0x200)
 
 /*
  * PCI Interrupt Vector Values.
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 96a3bc6..9aa20f9 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -285,14 +285,7 @@ static unsigned crb_hub_agt[64] =
 #define ADDR_IN_RANGE(addr, low, high)	\
 	(((addr) <= (high)) && ((addr) >= (low)))
 
-#define NETXEN_MAX_MTU		8000 + NETXEN_ENET_HEADER_SIZE + NETXEN_ETH_FCS_SIZE
-#define NETXEN_MIN_MTU		64
-#define NETXEN_ETH_FCS_SIZE     4
-#define NETXEN_ENET_HEADER_SIZE 14
 #define NETXEN_WINDOW_ONE 	0x2000000 /*CRB Window: bit 25 of CRB address */
-#define NETXEN_FIRMWARE_LEN 	((16 * 1024) / 4)
-#define NETXEN_NIU_HDRSIZE	(0x1 << 6)
-#define NETXEN_NIU_TLRSIZE	(0x1 << 5)
 
 #define NETXEN_NIC_ZERO_PAUSE_ADDR     0ULL
 #define NETXEN_NIC_UNIT_PAUSE_ADDR     0x200ULL
@@ -541,9 +534,6 @@ netxen_send_cmd_descs(struct netxen_adapter *adapter,
 	return 0;
 }
 
-#define NIC_REQUEST		0x14
-#define NETXEN_MAC_EVENT	0x1
-
 static int nx_p3_sre_macaddr_change(struct net_device *dev,
 		u8 *addr, unsigned op)
 {
@@ -553,8 +543,8 @@ static int nx_p3_sre_macaddr_change(struct net_device *dev,
 	int rv;
 
 	memset(&req, 0, sizeof(nx_nic_req_t));
-	req.qhdr |= (NIC_REQUEST << 23);
-	req.req_hdr |= NETXEN_MAC_EVENT;
+	req.qhdr |= (NX_NIC_REQUEST << 23);
+	req.req_hdr |= NX_MAC_EVENT;
 	req.req_hdr |= ((u64)adapter->portnum << 16);
 	mac_req.op = op;
 	memcpy(&mac_req.mac_addr, addr, 6);
@@ -575,31 +565,35 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
 	nx_mac_list_t *cur, *next, *del_list, *add_list = NULL;
 	struct dev_mc_list *mc_ptr;
 	u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-
-	adapter->set_promisc(adapter, NETXEN_NIU_PROMISC_MODE);
-
-	/*
-	 * Programming mac addresses will automaticly enabling L2 filtering.
-	 * HW will replace timestamp with L2 conid when L2 filtering is
-	 * enabled. This causes problem for LSA. Do not enabling L2 filtering
-	 * until that problem is fixed.
-	 */
-	if ((netdev->flags & IFF_PROMISC) ||
-			(netdev->mc_count > adapter->max_mc_count))
-		return;
+	u32 mode = VPORT_MISS_MODE_DROP;
 
 	del_list = adapter->mac_list;
 	adapter->mac_list = NULL;
 
 	nx_p3_nic_add_mac(adapter, netdev->dev_addr, &add_list, &del_list);
+	nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
+
+	if (netdev->flags & IFF_PROMISC) {
+		mode = VPORT_MISS_MODE_ACCEPT_ALL;
+		goto send_fw_cmd;
+	}
+
+	if ((netdev->flags & IFF_ALLMULTI) ||
+			(netdev->mc_count > adapter->max_mc_count)) {
+		mode = VPORT_MISS_MODE_ACCEPT_MULTI;
+		goto send_fw_cmd;
+	}
+
 	if (netdev->mc_count > 0) {
-		nx_p3_nic_add_mac(adapter, bcast_addr, &add_list, &del_list);
 		for (mc_ptr = netdev->mc_list; mc_ptr;
 		     mc_ptr = mc_ptr->next) {
 			nx_p3_nic_add_mac(adapter, mc_ptr->dmi_addr,
 					  &add_list, &del_list);
 		}
 	}
+
+send_fw_cmd:
+	adapter->set_promisc(adapter, mode);
 	for (cur = del_list; cur;) {
 		nx_p3_sre_macaddr_change(netdev, cur->mac_addr, NETXEN_MAC_DEL);
 		next = cur->next;
@@ -615,6 +609,21 @@ void netxen_p3_nic_set_multi(struct net_device *netdev)
 	}
 }
 
+int netxen_p3_nic_set_promisc(struct netxen_adapter *adapter, u32 mode)
+{
+	nx_nic_req_t req;
+
+	memset(&req, 0, sizeof(nx_nic_req_t));
+
+	req.qhdr |= (NX_HOST_REQUEST << 23);
+	req.req_hdr |= NX_NIC_H2C_OPCODE_PROXY_SET_VPORT_MISS_MODE;
+	req.req_hdr |= ((u64)adapter->portnum << 16);
+	req.words[0] = cpu_to_le64(mode);
+
+	return netxen_send_cmd_descs(adapter,
+				(struct cmd_desc_type0 *)&req, 1);
+}
+
 #define	NETXEN_CONFIG_INTR_COALESCE	3
 
 /*
@@ -627,7 +636,7 @@ int netxen_config_intr_coalesce(struct netxen_adapter *adapter)
 
 	memset(&req, 0, sizeof(nx_nic_req_t));
 
-	req.qhdr |= (NIC_REQUEST << 23);
+	req.qhdr |= (NX_NIC_REQUEST << 23);
 	req.req_hdr |= NETXEN_CONFIG_INTR_COALESCE;
 	req.req_hdr |= ((u64)adapter->portnum << 16);
 
@@ -653,6 +662,7 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
 {
 	struct netxen_adapter *adapter = netdev_priv(netdev);
 	int max_mtu;
+	int rc = 0;
 
 	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
 		max_mtu = P3_MAX_MTU;
@@ -666,16 +676,12 @@ int netxen_nic_change_mtu(struct net_device *netdev, int mtu)
 	}
 
 	if (adapter->set_mtu)
-		adapter->set_mtu(adapter, mtu);
-	netdev->mtu = mtu;
+		rc = adapter->set_mtu(adapter, mtu);
 
-	mtu += MTU_FUDGE_FACTOR;
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-		nx_fw_cmd_set_mtu(adapter, mtu);
-	else if (adapter->set_mtu)
-		adapter->set_mtu(adapter, mtu);
+	if (!rc)
+		netdev->mtu = mtu;
 
-	return 0;
+	return rc;
 }
 
 int netxen_is_flash_supported(struct netxen_adapter *adapter)
@@ -1411,7 +1417,8 @@ static int netxen_nic_pci_mem_read_direct(struct netxen_adapter *adapter,
 		(netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
 		write_unlock_irqrestore(&adapter->adapter_lock, flags);
 		printk(KERN_ERR "%s out of bound pci memory access. "
-			"offset is 0x%llx\n", netxen_nic_driver_name, off);
+			"offset is 0x%llx\n", netxen_nic_driver_name,
+			(unsigned long long)off);
 		return -1;
 	}
 
@@ -1484,7 +1491,8 @@ netxen_nic_pci_mem_write_direct(struct netxen_adapter *adapter, u64 off,
 		(netxen_nic_pci_is_same_window(adapter, off+size-1) == 0)) {
 		write_unlock_irqrestore(&adapter->adapter_lock, flags);
 		printk(KERN_ERR "%s out of bound pci memory access. "
-			"offset is 0x%llx\n", netxen_nic_driver_name, off);
+			"offset is 0x%llx\n", netxen_nic_driver_name,
+			(unsigned long long)off);
 		return -1;
 	}
 
@@ -2016,6 +2024,8 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 	case NETXEN_BRDTYPE_P3_10G_CX4_LP:
 	case NETXEN_BRDTYPE_P3_IMEZ:
 	case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
+	case NETXEN_BRDTYPE_P3_10G_SFP_CT:
+	case NETXEN_BRDTYPE_P3_10G_SFP_QT:
 	case NETXEN_BRDTYPE_P3_10G_XFP:
 	case NETXEN_BRDTYPE_P3_10000_BASE_T:
 
@@ -2034,6 +2044,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 	default:
 		printk("%s: Unknown(%x)\n", netxen_nic_driver_name,
 		       boardinfo->board_type);
+		rv = -ENODEV;
 		break;
 	}
 
@@ -2044,6 +2055,7 @@ int netxen_nic_get_board_info(struct netxen_adapter *adapter)
 
 int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
 {
+	new_mtu += MTU_FUDGE_FACTOR;
 	netxen_nic_write_w0(adapter,
 		NETXEN_NIU_GB_MAX_FRAME_SIZE(adapter->physical_port),
 		new_mtu);
@@ -2052,7 +2064,7 @@ int netxen_nic_set_mtu_gb(struct netxen_adapter *adapter, int new_mtu)
 
 int netxen_nic_set_mtu_xgb(struct netxen_adapter *adapter, int new_mtu)
 {
-	new_mtu += NETXEN_NIU_HDRSIZE + NETXEN_NIU_TLRSIZE;
+	new_mtu += MTU_FUDGE_FACTOR;
 	if (adapter->physical_port == 0)
 		netxen_nic_write_w0(adapter, NETXEN_NIU_XGE_MAX_FRAME_SIZE,
 				new_mtu);
@@ -2074,12 +2086,22 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
 	__u32 status;
 	__u32 autoneg;
 	__u32 mode;
+	__u32 port_mode;
 
 	netxen_nic_read_w0(adapter, NETXEN_NIU_MODE, &mode);
 	if (netxen_get_niu_enable_ge(mode)) {	/* Gb 10/100/1000 Mbps mode */
+
+		adapter->hw_read_wx(adapter,
+				NETXEN_PORT_MODE_ADDR, &port_mode, 4);
+		if (port_mode == NETXEN_PORT_MODE_802_3_AP) {
+			adapter->link_speed   = SPEED_1000;
+			adapter->link_duplex  = DUPLEX_FULL;
+			adapter->link_autoneg = AUTONEG_DISABLE;
+			return;
+		}
+
 		if (adapter->phy_read
-		    && adapter->
-		    phy_read(adapter,
+		    && adapter->phy_read(adapter,
 			     NETXEN_NIU_GB_MII_MGMT_ADDR_PHY_STATUS,
 			     &status) == 0) {
 			if (netxen_get_phy_link(status)) {
@@ -2109,8 +2131,7 @@ void netxen_nic_set_link_parameters(struct netxen_adapter *adapter)
 					break;
 				}
 				if (adapter->phy_read
-				    && adapter->
-				    phy_read(adapter,
+				    && adapter->phy_read(adapter,
 					     NETXEN_NIU_GB_MII_MGMT_ADDR_AUTONEG,
 					     &autoneg) != 0)
 					adapter->link_autoneg = autoneg;
diff --git a/drivers/net/netxen/netxen_nic_hw.h b/drivers/net/netxen/netxen_nic_hw.h
index b8e0030..aae737d 100644
--- a/drivers/net/netxen/netxen_nic_hw.h
+++ b/drivers/net/netxen/netxen_nic_hw.h
@@ -419,12 +419,9 @@ typedef enum {
 #define netxen_get_niu_enable_ge(config_word)	\
 		_netxen_crb_get_bit(config_word, 1)
 
-/* Promiscous mode options (GbE mode only) */
-typedef enum {
-	NETXEN_NIU_PROMISC_MODE = 0,
-	NETXEN_NIU_NON_PROMISC_MODE,
-	NETXEN_NIU_ALLMULTI_MODE
-} netxen_niu_prom_mode_t;
+#define NETXEN_NIU_NON_PROMISC_MODE	0
+#define NETXEN_NIU_PROMISC_MODE		1
+#define NETXEN_NIU_ALLMULTI_MODE	2
 
 /*
  * NIU GB Drop CRC Register
@@ -471,9 +468,9 @@ typedef enum {
 
 /* Set promiscuous mode for a GbE interface */
 int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
-				    netxen_niu_prom_mode_t mode);
+				    u32 mode);
 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
-				       netxen_niu_prom_mode_t mode);
+				       u32 mode);
 
 /* set the MAC address for a given MAC */
 int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 01ab31b..519fc86 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -364,6 +364,11 @@ void netxen_initialize_adapter_ops(struct netxen_adapter *adapter)
 	default:
 		break;
 	}
+
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		adapter->set_mtu = nx_fw_cmd_set_mtu;
+		adapter->set_promisc = netxen_p3_nic_set_promisc;
+	}
 }
 
 /*
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 91d209a..7615c71 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -166,7 +166,8 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter)
 	if (!NETXEN_IS_MSI_FAMILY(adapter)) {
 		do {
 			adapter->pci_write_immediate(adapter,
-					ISR_INT_TARGET_STATUS, 0xffffffff);
+					adapter->legacy_intr.tgt_status_reg,
+					0xffffffff);
 			mask = adapter->pci_read_immediate(adapter,
 					ISR_INT_VECTOR);
 			if (!(mask & 0x80))
@@ -175,7 +176,7 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter)
 		} while (--retries);
 
 		if (!retries) {
-			printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
+			printk(KERN_NOTICE "%s: Failed to disable interrupt\n",
 					netxen_nic_driver_name);
 		}
 	} else {
@@ -190,8 +191,6 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter)
 {
 	u32 mask;
 
-	DPRINTK(1, INFO, "Entered ISR Enable \n");
-
 	if (adapter->intr_scheme != -1 &&
 		adapter->intr_scheme != INTR_SCHEME_PERPORT) {
 		switch (adapter->ahw.board_type) {
@@ -213,16 +212,13 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter)
 
 	if (!NETXEN_IS_MSI_FAMILY(adapter)) {
 		mask = 0xbff;
-		if (adapter->intr_scheme != -1 &&
-			adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+		if (adapter->intr_scheme == INTR_SCHEME_PERPORT)
+			adapter->pci_write_immediate(adapter,
+				adapter->legacy_intr.tgt_mask_reg, mask);
+		else
 			adapter->pci_write_normalize(adapter,
 					CRB_INT_VECTOR, 0);
-		}
-		adapter->pci_write_immediate(adapter,
-				ISR_INT_TARGET_MASK, mask);
 	}
-
-	DPRINTK(1, INFO, "Done with enable Int\n");
 }
 
 static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id)
@@ -284,6 +280,8 @@ static void netxen_check_options(struct netxen_adapter *adapter)
 	case NETXEN_BRDTYPE_P3_10G_CX4_LP:
 	case NETXEN_BRDTYPE_P3_IMEZ:
 	case NETXEN_BRDTYPE_P3_10G_SFP_PLUS:
+	case NETXEN_BRDTYPE_P3_10G_SFP_QT:
+	case NETXEN_BRDTYPE_P3_10G_SFP_CT:
 	case NETXEN_BRDTYPE_P3_10G_XFP:
 	case NETXEN_BRDTYPE_P3_10000_BASE_T:
 		adapter->msix_supported = !!use_msi_x;
@@ -301,6 +299,10 @@ static void netxen_check_options(struct netxen_adapter *adapter)
 	case NETXEN_BRDTYPE_P3_REF_QG:
 	case NETXEN_BRDTYPE_P3_4_GB:
 	case NETXEN_BRDTYPE_P3_4_GB_MM:
+		adapter->msix_supported = 0;
+		adapter->max_rx_desc_count = MAX_RCV_DESCRIPTORS_10G;
+		break;
+
 	case NETXEN_BRDTYPE_P2_SB35_4G:
 	case NETXEN_BRDTYPE_P2_SB31_2G:
 		adapter->msix_supported = 0;
@@ -700,13 +702,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	adapter->status   &= ~NETXEN_NETDEV_STATUS;
 	adapter->rx_csum = 1;
 	adapter->mc_enabled = 0;
-	if (NX_IS_REVISION_P3(revision_id)) {
+	if (NX_IS_REVISION_P3(revision_id))
 		adapter->max_mc_count = 38;
-		adapter->max_rds_rings = 2;
-	} else {
+	else
 		adapter->max_mc_count = 16;
-		adapter->max_rds_rings = 3;
-	}
 
 	netdev->open		   = netxen_nic_open;
 	netdev->stop		   = netxen_nic_close;
@@ -779,10 +778,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		if (adapter->portnum == 0)
 			first_driver = 1;
 	}
-	adapter->crb_addr_cmd_producer = crb_cmd_producer[adapter->portnum];
-	adapter->crb_addr_cmd_consumer = crb_cmd_consumer[adapter->portnum];
-	netxen_nic_update_cmd_producer(adapter, 0);
-	netxen_nic_update_cmd_consumer(adapter, 0);
 
 	if (first_driver) {
 		first_boot = adapter->pci_read_normalize(adapter,
@@ -1053,6 +1048,11 @@ static int netxen_nic_open(struct net_device *netdev)
 			return -EIO;
 		}
 
+		if (adapter->fw_major < 4)
+			adapter->max_rds_rings = 3;
+		else
+			adapter->max_rds_rings = 2;
+
 		err = netxen_alloc_sw_resources(adapter);
 		if (err) {
 			printk(KERN_ERR "%s: Error in setting sw resources\n",
@@ -1074,10 +1074,10 @@ static int netxen_nic_open(struct net_device *netdev)
 				crb_cmd_producer[adapter->portnum];
 			adapter->crb_addr_cmd_consumer =
 				crb_cmd_consumer[adapter->portnum];
-		}
 
-		netxen_nic_update_cmd_producer(adapter, 0);
-		netxen_nic_update_cmd_consumer(adapter, 0);
+			netxen_nic_update_cmd_producer(adapter, 0);
+			netxen_nic_update_cmd_consumer(adapter, 0);
+		}
 
 		for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
 			for (ring = 0; ring < adapter->max_rds_rings; ring++)
@@ -1113,9 +1113,7 @@ static int netxen_nic_open(struct net_device *netdev)
 	netxen_nic_set_link_parameters(adapter);
 
 	netdev->set_multicast_list(netdev);
-	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
-		nx_fw_cmd_set_mtu(adapter, netdev->mtu);
-	else
+	if (adapter->set_mtu)
 		adapter->set_mtu(adapter, netdev->mtu);
 
 	mod_timer(&adapter->watchdog_timer, jiffies);
@@ -1410,20 +1408,17 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
 
 	port = adapter->physical_port;
 
-	if (adapter->ahw.board_type == NETXEN_NIC_GBE) {
-		val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
-		linkup = (val >> port) & 1;
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) {
+		val = adapter->pci_read_normalize(adapter, CRB_XG_STATE_P3);
+		val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
+		linkup = (val == XG_LINK_UP_P3);
 	} else {
-		if (adapter->fw_major < 4) {
-			val = adapter->pci_read_normalize(adapter,
-					CRB_XG_STATE);
+		val = adapter->pci_read_normalize(adapter, CRB_XG_STATE);
+		if (adapter->ahw.board_type == NETXEN_NIC_GBE)
+			linkup = (val >> port) & 1;
+		else {
 			val = (val >> port*8) & 0xff;
 			linkup = (val == XG_LINK_UP);
-		} else {
-			val = adapter->pci_read_normalize(adapter,
-				CRB_XG_STATE_P3);
-			val = XG_LINK_STATE_P3(adapter->ahw.pci_func, val);
-			linkup = (val == XG_LINK_UP_P3);
 		}
 	}
 
@@ -1535,15 +1530,33 @@ static irqreturn_t netxen_intr(int irq, void *data)
 	struct netxen_adapter *adapter = data;
 	u32 our_int = 0;
 
-	our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
-	/* not our interrupt */
-	if ((our_int & (0x80 << adapter->portnum)) == 0)
+	u32 status = 0;
+
+	status = adapter->pci_read_immediate(adapter, ISR_INT_VECTOR);
+
+	if (!(status & adapter->legacy_intr.int_vec_bit))
 		return IRQ_NONE;
 
-	if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
-		/* claim interrupt */
-		adapter->pci_write_normalize(adapter, CRB_INT_VECTOR,
+	if (adapter->ahw.revision_id >= NX_P3_B1) {
+		/* check interrupt state machine, to be sure */
+		status = adapter->pci_read_immediate(adapter,
+				ISR_INT_STATE_REG);
+		if (!ISR_LEGACY_INT_TRIGGERED(status))
+			return IRQ_NONE;
+
+	} else if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
+
+		our_int = adapter->pci_read_normalize(adapter, CRB_INT_VECTOR);
+		/* not our interrupt */
+		if ((our_int & (0x80 << adapter->portnum)) == 0)
+			return IRQ_NONE;
+
+		if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
+			/* claim interrupt */
+			adapter->pci_write_normalize(adapter,
+				CRB_INT_VECTOR,
 				our_int & ~((u32)(0x80 << adapter->portnum)));
+		}
 	}
 
 	netxen_handle_int(adapter);
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index 4cb8f4a..27f07f6 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -610,6 +610,9 @@ int netxen_niu_macaddr_set(struct netxen_adapter *adapter,
 	int i;
 	DECLARE_MAC_BUF(mac);
 
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		return 0;
+
 	for (i = 0; i < 10; i++) {
 		temp[0] = temp[1] = 0;
 		memcpy(temp + 2, addr, 2);
@@ -727,6 +730,9 @@ int netxen_niu_disable_gbe_port(struct netxen_adapter *adapter)
 	__u32 mac_cfg0;
 	u32 port = adapter->physical_port;
 
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		return 0;
+
 	if (port > NETXEN_NIU_MAX_GBE_PORTS)
 		return -EINVAL;
 	mac_cfg0 = 0;
@@ -743,6 +749,9 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
 	__u32 mac_cfg;
 	u32 port = adapter->physical_port;
 
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		return 0;
+
 	if (port > NETXEN_NIU_MAX_XG_PORTS)
 		return -EINVAL;
 
@@ -755,7 +764,7 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter)
 
 /* Set promiscuous mode for a GbE interface */
 int netxen_niu_set_promiscuous_mode(struct netxen_adapter *adapter,
-				    netxen_niu_prom_mode_t mode)
+		u32 mode)
 {
 	__u32 reg;
 	u32 port = adapter->physical_port;
@@ -819,6 +828,9 @@ int netxen_niu_xg_macaddr_set(struct netxen_adapter *adapter,
 	u8 temp[4];
 	u32 val;
 
+	if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
+		return 0;
+
 	if ((phy < 0) || (phy > NETXEN_NIU_MAX_XG_PORTS))
 		return -EIO;
 
@@ -894,7 +906,7 @@ int netxen_niu_xg_macaddr_get(struct netxen_adapter *adapter,
 #endif  /*  0  */
 
 int netxen_niu_xg_set_promiscuous_mode(struct netxen_adapter *adapter,
-				       netxen_niu_prom_mode_t mode)
+		u32 mode)
 {
 	__u32 reg;
 	u32 port = adapter->physical_port;
diff --git a/drivers/net/netxen/netxen_nic_phan_reg.h b/drivers/net/netxen/netxen_nic_phan_reg.h
index 3bfa51b..83e5ee5 100644
--- a/drivers/net/netxen/netxen_nic_phan_reg.h
+++ b/drivers/net/netxen/netxen_nic_phan_reg.h
@@ -95,8 +95,8 @@
 #define CRB_HOST_STS_PROD           NETXEN_NIC_REG(0xdc)
 #define CRB_HOST_STS_CONS           NETXEN_NIC_REG(0xe0)
 #define CRB_PEG_CMD_PROD            NETXEN_NIC_REG(0xe4)
-#define CRB_PEG_CMD_CONS            NETXEN_NIC_REG(0xe8)
-#define CRB_HOST_BUFFER_PROD        NETXEN_NIC_REG(0xec)
+#define CRB_PF_LINK_SPEED_1         NETXEN_NIC_REG(0xe8)
+#define CRB_PF_LINK_SPEED_2         NETXEN_NIC_REG(0xec)
 #define CRB_HOST_BUFFER_CONS        NETXEN_NIC_REG(0xf0)
 #define CRB_JUMBO_BUFFER_PROD       NETXEN_NIC_REG(0xf4)
 #define CRB_JUMBO_BUFFER_CONS       NETXEN_NIC_REG(0xf8)
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c
index a20005c..8e0ca9f 100644
--- a/drivers/net/ni5010.c
+++ b/drivers/net/ni5010.c
@@ -648,7 +648,6 @@ static void ni5010_set_multicast_list(struct net_device *dev)
 	PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name));
 
 	if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI || dev->mc_list) {
-		dev->flags |= IFF_PROMISC;
 		outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */
 		PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name));
 	} else {
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index a316dcc..b9a882d 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -621,7 +621,7 @@ static int init586(struct net_device *dev)
 		if (num_addrs > len) {
 			printk(KERN_ERR "%s: switching to promisc. mode\n",
 				dev->name);
-			dev->flags |= IFF_PROMISC;
+			writeb(0x01, &cfg_cmd->promisc);
 		}
 	}
 	if (dev->flags & IFF_PROMISC)
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
index e82b37b..3cdd07c 100644
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -38,7 +38,7 @@
 
 #define DRV_NAME  	"qla3xxx"
 #define DRV_STRING 	"QLogic ISP3XXX Network Driver"
-#define DRV_VERSION	"v2.03.00-k4"
+#define DRV_VERSION	"v2.03.00-k5"
 #define PFX		DRV_NAME " "
 
 static const char ql3xxx_driver_name[] = DRV_NAME;
@@ -3495,8 +3495,6 @@ static void ql_set_mac_info(struct ql3_adapter *qdev)
 	case ISP_CONTROL_FN0_NET:
 		qdev->mac_index = 0;
 		qdev->mac_ob_opcode = OUTBOUND_MAC_IOCB | func_number;
-		qdev->tcp_ob_opcode = OUTBOUND_TCP_IOCB | func_number;
-		qdev->update_ob_opcode = UPDATE_NCB_IOCB | func_number;
 		qdev->mb_bit_mask = FN0_MA_BITS_MASK;
 		qdev->PHYAddr = PORT0_PHY_ADDRESS;
 		if (port_status & PORT_STATUS_SM0)
@@ -3508,8 +3506,6 @@ static void ql_set_mac_info(struct ql3_adapter *qdev)
 	case ISP_CONTROL_FN1_NET:
 		qdev->mac_index = 1;
 		qdev->mac_ob_opcode = OUTBOUND_MAC_IOCB | func_number;
-		qdev->tcp_ob_opcode = OUTBOUND_TCP_IOCB | func_number;
-		qdev->update_ob_opcode = UPDATE_NCB_IOCB | func_number;
 		qdev->mb_bit_mask = FN1_MA_BITS_MASK;
 		qdev->PHYAddr = PORT1_PHY_ADDRESS;
 		if (port_status & PORT_STATUS_SM1)
@@ -3730,14 +3726,6 @@ static int ql3xxx_open(struct net_device *ndev)
 	return (ql_adapter_up(qdev));
 }
 
-static void ql3xxx_set_multicast_list(struct net_device *ndev)
-{
-	/*
-	 * We are manually parsing the list in the net_device structure.
-	 */
-	return;
-}
-
 static int ql3xxx_set_mac_address(struct net_device *ndev, void *p)
 {
 	struct ql3_adapter *qdev = (struct ql3_adapter *)netdev_priv(ndev);
@@ -4007,7 +3995,11 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
 	ndev->open = ql3xxx_open;
 	ndev->hard_start_xmit = ql3xxx_send;
 	ndev->stop = ql3xxx_close;
-	ndev->set_multicast_list = ql3xxx_set_multicast_list;
+	/* ndev->set_multicast_list
+	 * This device is one side of a two-function adapter
+	 * (NIC and iSCSI).  Promiscuous mode setting/clearing is
+	 * not allowed from the NIC side.
+	 */
 	SET_ETHTOOL_OPS(ndev, &ql3xxx_ethtool_ops);
 	ndev->set_mac_address = ql3xxx_set_mac_address;
 	ndev->tx_timeout = ql3xxx_tx_timeout;
@@ -4040,9 +4032,6 @@ static int __devinit ql3xxx_probe(struct pci_dev *pdev,
 
 	ndev->tx_queue_len = NUM_REQ_Q_ENTRIES;
 
-	/* Turn off support for multicasting */
-	ndev->flags &= ~IFF_MULTICAST;
-
 	/* Record PCI bus information. */
 	ql_get_board_info(qdev);
 
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
index 58a086f..7113e71 100644
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -14,24 +14,14 @@
 
 #define OPCODE_OB_MAC_IOCB_FN0          0x01
 #define OPCODE_OB_MAC_IOCB_FN2          0x21
-#define OPCODE_OB_TCP_IOCB_FN0          0x03
-#define OPCODE_OB_TCP_IOCB_FN2          0x23
-#define OPCODE_UPDATE_NCB_IOCB_FN0      0x00
-#define OPCODE_UPDATE_NCB_IOCB_FN2      0x20
 
-#define OPCODE_UPDATE_NCB_IOCB      0xF0
 #define OPCODE_IB_MAC_IOCB          0xF9
 #define OPCODE_IB_3032_MAC_IOCB     0x09
 #define OPCODE_IB_IP_IOCB           0xFA
 #define OPCODE_IB_3032_IP_IOCB      0x0A
-#define OPCODE_IB_TCP_IOCB          0xFB
-#define OPCODE_DUMP_PROTO_IOCB      0xFE
-#define OPCODE_BUFFER_ALERT_IOCB    0xFB
 
 #define OPCODE_FUNC_ID_MASK                 0x30
 #define OUTBOUND_MAC_IOCB                   0x01	/* plus function bits */
-#define OUTBOUND_TCP_IOCB                   0x03	/* plus function bits */
-#define UPDATE_NCB_IOCB                     0x00	/* plus function bits */
 
 #define FN0_MA_BITS_MASK    0x00
 #define FN1_MA_BITS_MASK    0x80
@@ -159,75 +149,6 @@ struct ob_ip_iocb_rsp {
 	__le32 reserved2;
 };
 
-struct ob_tcp_iocb_req {
-	u8 opcode;
-
-	u8 flags0;
-#define OB_TCP_IOCB_REQ_P       0x80
-#define OB_TCP_IOCB_REQ_CI      0x20
-#define OB_TCP_IOCB_REQ_H       0x10
-#define OB_TCP_IOCB_REQ_LN      0x08
-#define OB_TCP_IOCB_REQ_K       0x04
-#define OB_TCP_IOCB_REQ_D       0x02
-#define OB_TCP_IOCB_REQ_I       0x01
-
-	u8 flags1;
-#define OB_TCP_IOCB_REQ_OSM     0x40
-#define OB_TCP_IOCB_REQ_URG     0x20
-#define OB_TCP_IOCB_REQ_ACK     0x10
-#define OB_TCP_IOCB_REQ_PSH     0x08
-#define OB_TCP_IOCB_REQ_RST     0x04
-#define OB_TCP_IOCB_REQ_SYN     0x02
-#define OB_TCP_IOCB_REQ_FIN     0x01
-
-	u8 options_len;
-#define OB_TCP_IOCB_REQ_OMASK   0xF0
-#define OB_TCP_IOCB_REQ_SHIFT   4
-
-	__le32 transaction_id;
-	__le32 data_len;
-	__le32 hncb_ptr_low;
-	__le32 hncb_ptr_high;
-	__le32 buf_addr0_low;
-	__le32 buf_addr0_high;
-	__le32 buf_0_len;
-	__le32 buf_addr1_low;
-	__le32 buf_addr1_high;
-	__le32 buf_1_len;
-	__le32 buf_addr2_low;
-	__le32 buf_addr2_high;
-	__le32 buf_2_len;
-	__le32 time_stamp;
-	__le32 reserved1;
-};
-
-struct ob_tcp_iocb_rsp {
-	u8 opcode;
-
-	u8 flags0;
-#define OB_TCP_IOCB_RSP_C       0x20
-#define OB_TCP_IOCB_RSP_H       0x10
-#define OB_TCP_IOCB_RSP_LN      0x08
-#define OB_TCP_IOCB_RSP_K       0x04
-#define OB_TCP_IOCB_RSP_D       0x02
-#define OB_TCP_IOCB_RSP_I       0x01
-
-	u8 flags1;
-#define OB_TCP_IOCB_RSP_E       0x10
-#define OB_TCP_IOCB_RSP_W       0x08
-#define OB_TCP_IOCB_RSP_P       0x04
-#define OB_TCP_IOCB_RSP_T       0x02
-#define OB_TCP_IOCB_RSP_F       0x01
-
-	u8 state;
-#define OB_TCP_IOCB_RSP_SMASK   0xF0
-#define OB_TCP_IOCB_RSP_SHIFT   4
-
-	__le32 transaction_id;
-	__le32 local_ncb_ptr;
-	__le32 reserved0;
-};
-
 struct ib_ip_iocb_rsp {
 	u8 opcode;
 #define IB_IP_IOCB_RSP_3032_V   0x80
@@ -256,25 +177,6 @@ struct ib_ip_iocb_rsp {
 	__le32 ial_high;
 };
 
-struct ib_tcp_iocb_rsp {
-	u8 opcode;
-	u8 flags;
-#define IB_TCP_IOCB_RSP_P       0x80
-#define IB_TCP_IOCB_RSP_T       0x40
-#define IB_TCP_IOCB_RSP_D       0x20
-#define IB_TCP_IOCB_RSP_N       0x10
-#define IB_TCP_IOCB_RSP_IP      0x03
-#define IB_TCP_FLAG_MASK        0xf0
-#define IB_TCP_FLAG_IOCB_SYN    0x00
-
-#define TCP_IB_RSP_FLAGS(x) (x->flags & ~IB_TCP_FLAG_MASK)
-
-	__le16 length;
-	__le32 hncb_ref_num;
-	__le32 ial_low;
-	__le32 ial_high;
-};
-
 struct net_rsp_iocb {
 	u8 opcode;
 	u8 flags;
@@ -1266,20 +1168,13 @@ struct ql3_adapter {
 	u32 small_buf_release_cnt;
 	u32 small_buf_total_size;
 
-	/* ISR related, saves status for DPC. */
-	u32 control_status;
-
 	struct eeprom_data nvram_data;
-	struct timer_list ioctl_timer;
 	u32 port_link_state;
-	u32 last_rsp_offset;
 
 	/* 4022 specific */
 	u32 mac_index;		/* Driver's MAC number can be 0 or 1 for first and second networking functions respectively */
 	u32 PHYAddr;		/* Address of PHY 0x1e00 Port 0 and 0x1f00 Port 1 */
 	u32 mac_ob_opcode;	/* Opcode to use on mac transmission */
-	u32 tcp_ob_opcode;	/* Opcode to use on tcp transmission */
-	u32 update_ob_opcode;	/* Opcode to use for updating NCB */
 	u32 mb_bit_mask;	/* MA Bits mask to use on transmission */
 	u32 numPorts;
 	struct workqueue_struct *workqueue;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 6a06b95..25e62cf 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -34,6 +34,29 @@
 
 #include "sh_eth.h"
 
+/* CPU <-> EDMAC endian convert */
+static inline __u32 cpu_to_edmac(struct sh_eth_private *mdp, u32 x)
+{
+	switch (mdp->edmac_endian) {
+	case EDMAC_LITTLE_ENDIAN:
+		return cpu_to_le32(x);
+	case EDMAC_BIG_ENDIAN:
+		return cpu_to_be32(x);
+	}
+	return x;
+}
+
+static inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x)
+{
+	switch (mdp->edmac_endian) {
+	case EDMAC_LITTLE_ENDIAN:
+		return le32_to_cpu(x);
+	case EDMAC_BIG_ENDIAN:
+		return be32_to_cpu(x);
+	}
+	return x;
+}
+
 /*
  * Program the hardware MAC address from dev->dev_addr.
  */
@@ -240,7 +263,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
 		/* RX descriptor */
 		rxdesc = &mdp->rx_ring[i];
 		rxdesc->addr = (u32)skb->data & ~0x3UL;
-		rxdesc->status = cpu_to_le32(RD_RACT | RD_RFP);
+		rxdesc->status = cpu_to_edmac(mdp, RD_RACT | RD_RFP);
 
 		/* The size of the buffer is 16 byte boundary. */
 		rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
@@ -262,7 +285,7 @@ static void sh_eth_ring_format(struct net_device *ndev)
 	mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
 
 	/* Mark the last entry as wrapping the ring. */
-	rxdesc->status |= cpu_to_le32(RD_RDEL);
+	rxdesc->status |= cpu_to_edmac(mdp, RD_RDEL);
 
 	memset(mdp->tx_ring, 0, tx_ringsize);
 
@@ -270,10 +293,10 @@ static void sh_eth_ring_format(struct net_device *ndev)
 	for (i = 0; i < TX_RING_SIZE; i++) {
 		mdp->tx_skbuff[i] = NULL;
 		txdesc = &mdp->tx_ring[i];
-		txdesc->status = cpu_to_le32(TD_TFP);
+		txdesc->status = cpu_to_edmac(mdp, TD_TFP);
 		txdesc->buffer_length = 0;
 		if (i == 0) {
-			/* Rx descriptor address set */
+			/* Tx descriptor address set */
 			ctrl_outl((u32)txdesc, ioaddr + TDLAR);
 #if defined(CONFIG_CPU_SUBTYPE_SH7763)
 			ctrl_outl((u32)txdesc, ioaddr + TDFAR);
@@ -281,13 +304,13 @@ static void sh_eth_ring_format(struct net_device *ndev)
 		}
 	}
 
-	/* Rx descriptor address set */
+	/* Tx descriptor address set */
 #if defined(CONFIG_CPU_SUBTYPE_SH7763)
 	ctrl_outl((u32)txdesc, ioaddr + TDFXR);
 	ctrl_outl(0x1, ioaddr + TDFFR);
 #endif
 
-	txdesc->status |= cpu_to_le32(TD_TDLE);
+	txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
 }
 
 /* Get skb and descriptor buffer */
@@ -455,7 +478,7 @@ static int sh_eth_txfree(struct net_device *ndev)
 	for (; mdp->cur_tx - mdp->dirty_tx > 0; mdp->dirty_tx++) {
 		entry = mdp->dirty_tx % TX_RING_SIZE;
 		txdesc = &mdp->tx_ring[entry];
-		if (txdesc->status & cpu_to_le32(TD_TACT))
+		if (txdesc->status & cpu_to_edmac(mdp, TD_TACT))
 			break;
 		/* Free the original skb. */
 		if (mdp->tx_skbuff[entry]) {
@@ -463,9 +486,9 @@ static int sh_eth_txfree(struct net_device *ndev)
 			mdp->tx_skbuff[entry] = NULL;
 			freeNum++;
 		}
-		txdesc->status = cpu_to_le32(TD_TFP);
+		txdesc->status = cpu_to_edmac(mdp, TD_TFP);
 		if (entry >= TX_RING_SIZE - 1)
-			txdesc->status |= cpu_to_le32(TD_TDLE);
+			txdesc->status |= cpu_to_edmac(mdp, TD_TDLE);
 
 		mdp->stats.tx_packets++;
 		mdp->stats.tx_bytes += txdesc->buffer_length;
@@ -486,8 +509,8 @@ static int sh_eth_rx(struct net_device *ndev)
 	u32 desc_status, reserve = 0;
 
 	rxdesc = &mdp->rx_ring[entry];
-	while (!(rxdesc->status & cpu_to_le32(RD_RACT))) {
-		desc_status = le32_to_cpu(rxdesc->status);
+	while (!(rxdesc->status & cpu_to_edmac(mdp, RD_RACT))) {
+		desc_status = edmac_to_cpu(mdp, rxdesc->status);
 		pkt_len = rxdesc->frame_length;
 
 		if (--boguscnt < 0)
@@ -522,7 +545,7 @@ static int sh_eth_rx(struct net_device *ndev)
 			mdp->stats.rx_packets++;
 			mdp->stats.rx_bytes += pkt_len;
 		}
-		rxdesc->status |= cpu_to_le32(RD_RACT);
+		rxdesc->status |= cpu_to_edmac(mdp, RD_RACT);
 		entry = (++mdp->cur_rx) % RX_RING_SIZE;
 	}
 
@@ -552,10 +575,10 @@ static int sh_eth_rx(struct net_device *ndev)
 		}
 		if (entry >= RX_RING_SIZE - 1)
 			rxdesc->status |=
-				cpu_to_le32(RD_RACT | RD_RFP | RD_RDEL);
+				cpu_to_edmac(mdp, RD_RACT | RD_RFP | RD_RDEL);
 		else
 			rxdesc->status |=
-				cpu_to_le32(RD_RACT | RD_RFP);
+				cpu_to_edmac(mdp, RD_RACT | RD_RFP);
 	}
 
 	/* Restart Rx engine if stopped. */
@@ -931,9 +954,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 		txdesc->buffer_length = skb->len;
 
 	if (entry >= TX_RING_SIZE - 1)
-		txdesc->status |= cpu_to_le32(TD_TACT | TD_TDLE);
+		txdesc->status |= cpu_to_edmac(mdp, TD_TACT | TD_TDLE);
 	else
-		txdesc->status |= cpu_to_le32(TD_TACT);
+		txdesc->status |= cpu_to_edmac(mdp, TD_TACT);
 
 	mdp->cur_tx++;
 
@@ -1159,6 +1182,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	struct resource *res;
 	struct net_device *ndev = NULL;
 	struct sh_eth_private *mdp;
+	struct sh_eth_plat_data *pd;
 
 	/* get base addr */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1196,8 +1220,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	mdp = netdev_priv(ndev);
 	spin_lock_init(&mdp->lock);
 
+	pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
 	/* get PHY ID */
-	mdp->phy_id = (int)pdev->dev.platform_data;
+	mdp->phy_id = pd->phy;
+	/* EDMAC endian */
+	mdp->edmac_endian = pd->edmac_endian;
 
 	/* set function */
 	ndev->open = sh_eth_open;
@@ -1217,12 +1244,16 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 
 	/* First device only init */
 	if (!devno) {
+#if defined(ARSTR)
 		/* reset device */
 		ctrl_outl(ARSTR_ARSTR, ARSTR);
 		mdelay(1);
+#endif
 
+#if defined(SH_TSU_ADDR)
 		/* TSU init (Init only)*/
 		sh_eth_tsu_init(SH_TSU_ADDR);
+#endif
 	}
 
 	/* network device register */
@@ -1240,8 +1271,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	       ndev->name, CARDNAME, (u32) ndev->base_addr);
 
 	for (i = 0; i < 5; i++)
-		printk(KERN_INFO "%02X:", ndev->dev_addr[i]);
-	printk(KERN_INFO "%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);
+		printk("%02X:", ndev->dev_addr[i]);
+	printk("%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);
 
 	platform_set_drvdata(pdev, ndev);
 
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 45ad1b0..73bc718 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -30,6 +30,8 @@
 #include <linux/netdevice.h>
 #include <linux/phy.h>
 
+#include <asm/sh_eth.h>
+
 #define CARDNAME	"sh-eth"
 #define TX_TIMEOUT	(5*HZ)
 #define TX_RING_SIZE	64	/* Tx ring size */
@@ -143,10 +145,11 @@
 
 #else /* CONFIG_CPU_SUBTYPE_SH7763 */
 # define RX_OFFSET 2	/* skb offset */
+#ifndef CONFIG_CPU_SUBTYPE_SH7619
 /* Chip base address */
 # define SH_TSU_ADDR  0xA7000804
 # define ARSTR		  0xA7000800
-
+#endif
 /* Chip Registers */
 /* E-DMAC */
 # define EDMR	0x0000
@@ -384,7 +387,11 @@ enum FCFTR_BIT {
 	FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001,
 };
 #define FIFO_F_D_RFF	(FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0)
+#ifndef CONFIG_CPU_SUBTYPE_SH7619
 #define FIFO_F_D_RFD	(FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0)
+#else
+#define FIFO_F_D_RFD	(FCFTR_RFD0)
+#endif
 
 /* Transfer descriptor bit */
 enum TD_STS_BIT {
@@ -414,8 +421,10 @@ enum FELIC_MODE_BIT {
 #ifdef CONFIG_CPU_SUBTYPE_SH7763
 #define ECMR_CHG_DM	(ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF |\
 			ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
+#elif CONFIG_CPU_SUBTYPE_SH7619
+#define ECMR_CHG_DM	(ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF)
 #else
-#define ECMR_CHG_DM	(ECMR_ZPF | ECMR_PFR ECMR_RXF | ECMR_TXF | ECMR_MCT)
+#define ECMR_CHG_DM	(ECMR_ZPF | ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
 #endif
 
 /* ECSR */
@@ -485,7 +494,11 @@ enum RPADIR_BIT {
 
 /* FDR */
 enum FIFO_SIZE_BIT {
+#ifndef CONFIG_CPU_SUBTYPE_SH7619
 	FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007,
+#else
+	FIFO_SIZE_T = 0x00000100, FIFO_SIZE_R = 0x00000001,
+#endif
 };
 enum phy_offsets {
 	PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3,
@@ -601,7 +614,7 @@ struct sh_eth_txdesc {
 #endif
 	u32 addr;		/* TD2 */
 	u32 pad1;		/* padding data */
-};
+} __attribute__((aligned(2), packed));
 
 /*
  * The sh ether Rx buffer descriptors.
@@ -618,7 +631,7 @@ struct sh_eth_rxdesc {
 #endif
 	u32 addr;		/* RD2 */
 	u32 pad0;		/* padding data */
-};
+} __attribute__((aligned(2), packed));
 
 struct sh_eth_private {
 	dma_addr_t rx_desc_dma;
@@ -633,6 +646,7 @@ struct sh_eth_private {
 	u32 cur_rx, dirty_rx;	/* Producer/consumer ring indices */
 	u32 cur_tx, dirty_tx;
 	u32 rx_buf_sz;		/* Based on MTU+slack. */
+	int edmac_endian;
 	/* MII transceiver section. */
 	u32 phy_id;					/* PHY ID */
 	struct mii_bus *mii_bus;	/* MDIO bus control */
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 5257cf4..7d29edc 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -275,86 +275,6 @@ static void sky2_power_aux(struct sky2_hw *hw)
 			     PC_VAUX_ON | PC_VCC_OFF));
 }
 
-static void sky2_power_state(struct sky2_hw *hw, pci_power_t state)
-{
-	u16 power_control = sky2_pci_read16(hw, hw->pm_cap + PCI_PM_CTRL);
-	int pex = pci_find_capability(hw->pdev, PCI_CAP_ID_EXP);
-	u32 reg;
-
-	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
-
-	switch (state) {
-	case PCI_D0:
-		break;
-
-	case PCI_D1:
-		power_control |= 1;
-		break;
-
-	case PCI_D2:
-		power_control |= 2;
-		break;
-
-	case PCI_D3hot:
-	case PCI_D3cold:
-		power_control |= 3;
-		if (hw->flags & SKY2_HW_ADV_POWER_CTL) {
-			/* additional power saving measurements */
-			reg = sky2_pci_read32(hw, PCI_DEV_REG4);
-
-			/* set gating core clock for LTSSM in L1 state */
-			reg |= P_PEX_LTSSM_STAT(P_PEX_LTSSM_L1_STAT) |
-				/* auto clock gated scheme controlled by CLKREQ */
-				P_ASPM_A1_MODE_SELECT |
-				/* enable Gate Root Core Clock */
-				P_CLK_GATE_ROOT_COR_ENA;
-
-			if (pex && (hw->flags & SKY2_HW_CLK_POWER)) {
-				/* enable Clock Power Management (CLKREQ) */
-				u16 ctrl = sky2_pci_read16(hw, pex + PCI_EXP_DEVCTL);
-
-				ctrl |= PCI_EXP_DEVCTL_AUX_PME;
-				sky2_pci_write16(hw, pex + PCI_EXP_DEVCTL, ctrl);
-			} else
-				/* force CLKREQ Enable in Our4 (A1b only) */
-				reg |= P_ASPM_FORCE_CLKREQ_ENA;
-
-			/* set Mask Register for Release/Gate Clock */
-			sky2_pci_write32(hw, PCI_DEV_REG5,
-					 P_REL_PCIE_EXIT_L1_ST | P_GAT_PCIE_ENTER_L1_ST |
-					 P_REL_PCIE_RX_EX_IDLE | P_GAT_PCIE_RX_EL_IDLE |
-					 P_REL_GPHY_LINK_UP | P_GAT_GPHY_LINK_DOWN);
-		} else
-			sky2_write8(hw, B28_Y2_ASF_STAT_CMD, Y2_ASF_CLK_HALT);
-
-		/* put CPU into reset state */
-		sky2_write8(hw,  B28_Y2_ASF_STAT_CMD, HCU_CCSR_ASF_RESET);
-		if (hw->chip_id == CHIP_ID_YUKON_SUPR && hw->chip_rev == CHIP_REV_YU_SU_A0)
-			/* put CPU into halt state */
-			sky2_write8(hw, B28_Y2_ASF_STAT_CMD, HCU_CCSR_ASF_HALTED);
-
-		if (pex && !(hw->flags & SKY2_HW_RAM_BUFFER)) {
-			reg = sky2_pci_read32(hw, PCI_DEV_REG1);
-			/* force to PCIe L1 */
-			reg |= PCI_FORCE_PEX_L1;
-			sky2_pci_write32(hw, PCI_DEV_REG1, reg);
-		}
-		break;
-
-	default:
-		dev_warn(&hw->pdev->dev, PFX "Invalid power state (%d) ",
-		       state);
-		return;
-	}
-
-	power_control |= PCI_PM_CTRL_PME_ENABLE;
-	/* Finally, set the new power state. */
-	sky2_pci_write32(hw, hw->pm_cap + PCI_PM_CTRL, power_control);
-
-	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
-	sky2_pci_read32(hw, B0_CTST);
-}
-
 static void sky2_gmac_reset(struct sky2_hw *hw, unsigned port)
 {
 	u16 reg;
@@ -709,6 +629,11 @@ static void sky2_phy_power_up(struct sky2_hw *hw, unsigned port)
 	sky2_pci_write32(hw, PCI_DEV_REG1, reg1);
 	sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
 	sky2_pci_read32(hw, PCI_DEV_REG1);
+
+	if (hw->chip_id == CHIP_ID_YUKON_FE)
+		gm_phy_write(hw, port, PHY_MARV_CTRL, PHY_CT_ANE);
+	else if (hw->flags & SKY2_HW_ADV_POWER_CTL)
+		sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR);
 }
 
 static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
@@ -2855,10 +2780,6 @@ static int __devinit sky2_init(struct sky2_hw *hw)
 		hw->flags = SKY2_HW_GIGABIT
 			| SKY2_HW_NEWER_PHY
 			| SKY2_HW_ADV_POWER_CTL;
-
-		/* check for Rev. A1 dev 4200 */
-		if (sky2_read16(hw, Q_ADDR(Q_XA1, Q_WM)) == 0)
-			hw->flags |= SKY2_HW_CLK_POWER;
 		break;
 
 	case CHIP_ID_YUKON_EX:
@@ -2914,12 +2835,6 @@ static int __devinit sky2_init(struct sky2_hw *hw)
 	if (hw->pmd_type == 'L' || hw->pmd_type == 'S' || hw->pmd_type == 'P')
 		hw->flags |= SKY2_HW_FIBRE_PHY;
 
-	hw->pm_cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PM);
-	if (hw->pm_cap == 0) {
-		dev_err(&hw->pdev->dev, "cannot find PowerManagement capability\n");
-		return -EIO;
-	}
-
 	hw->ports = 1;
 	t8 = sky2_read8(hw, B2_Y2_HW_RES);
 	if ((t8 & CFG_DUAL_MAC_MSK) == CFG_DUAL_MAC_MSK) {
@@ -4512,7 +4427,7 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	pci_save_state(pdev);
 	pci_enable_wake(pdev, pci_choose_state(pdev, state), wol);
-	sky2_power_state(hw, pci_choose_state(pdev, state));
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
 	return 0;
 }
@@ -4525,7 +4440,9 @@ static int sky2_resume(struct pci_dev *pdev)
 	if (!hw)
 		return 0;
 
-	sky2_power_state(hw, PCI_D0);
+	err = pci_set_power_state(pdev, PCI_D0);
+	if (err)
+		goto out;
 
 	err = pci_restore_state(pdev);
 	if (err)
@@ -4595,7 +4512,7 @@ static void sky2_shutdown(struct pci_dev *pdev)
 	pci_enable_wake(pdev, PCI_D3cold, wol);
 
 	pci_disable_device(pdev);
-	sky2_power_state(hw, PCI_D3hot);
+	pci_set_power_state(pdev, PCI_D3hot);
 }
 
 static struct pci_driver sky2_driver = {
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 4d9c4a1..92fb24b 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -2072,9 +2072,7 @@ struct sky2_hw {
 #define SKY2_HW_NEW_LE		0x00000020	/* new LSOv2 format */
 #define SKY2_HW_AUTO_TX_SUM	0x00000040	/* new IP decode for Tx */
 #define SKY2_HW_ADV_POWER_CTL	0x00000080	/* additional PHY power regs */
-#define SKY2_HW_CLK_POWER	0x00000100	/* clock power management */
 
-	int		     pm_cap;
 	u8	     	     chip_id;
 	u8		     chip_rev;
 	u8		     pmd_type;
diff --git a/drivers/net/sun3_82586.c b/drivers/net/sun3_82586.c
index 9b2a7f7..e531302 100644
--- a/drivers/net/sun3_82586.c
+++ b/drivers/net/sun3_82586.c
@@ -425,14 +425,11 @@ static int init586(struct net_device *dev)
 		int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
 		if(num_addrs > len)	{
 			printk("%s: switching to promisc. mode\n",dev->name);
-			dev->flags|=IFF_PROMISC;
+			cfg_cmd->promisc = 1;
 		}
 	}
 	if(dev->flags&IFF_PROMISC)
-	{
-			 cfg_cmd->promisc=1;
-			 dev->flags|=IFF_PROMISC;
-	}
+		cfg_cmd->promisc = 1;
 	cfg_cmd->carr_coll	= 0x00;
 
 	p->scb->cbl_offset	= make16(cfg_cmd);
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index b588c89..a84ba48 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -1285,6 +1285,21 @@ static void check_carrier(struct work_struct *work)
 	}
 }
 
+static int pegasus_blacklisted(struct usb_device *udev)
+{
+	struct usb_device_descriptor *udd = &udev->descriptor;
+
+	/* Special quirk to keep the driver from handling the Belkin Bluetooth
+	 * dongle which happens to have the same ID.
+	 */
+	if ((udd->idVendor == VENDOR_BELKIN && udd->idProduct == 0x0121) &&
+	    (udd->bDeviceClass == USB_CLASS_WIRELESS_CONTROLLER) &&
+	    (udd->bDeviceProtocol == 1))
+		return 1;
+
+	return 0;
+}
+
 static int pegasus_probe(struct usb_interface *intf,
 			 const struct usb_device_id *id)
 {
@@ -1296,6 +1311,12 @@ static int pegasus_probe(struct usb_interface *intf,
 	DECLARE_MAC_BUF(mac);
 
 	usb_get_dev(dev);
+
+	if (pegasus_blacklisted(dev)) {
+		res = -ENODEV;
+		goto out;
+	}
+
 	net = alloc_etherdev(sizeof(struct pegasus));
 	if (!net) {
 		dev_err(&intf->dev, "can't allocate %s\n", "device");
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 370ce30..007c129 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -662,6 +662,10 @@ static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid
         spin_unlock_irq(&vptr->lock);
 }
 
+static void velocity_init_rx_ring_indexes(struct velocity_info *vptr)
+{
+	vptr->rx.dirty = vptr->rx.filled = vptr->rx.curr = 0;
+}
 
 /**
  *	velocity_rx_reset	-	handle a receive reset
@@ -677,16 +681,16 @@ static void velocity_rx_reset(struct velocity_info *vptr)
 	struct mac_regs __iomem * regs = vptr->mac_regs;
 	int i;
 
-	vptr->rd_dirty = vptr->rd_filled = vptr->rd_curr = 0;
+	velocity_init_rx_ring_indexes(vptr);
 
 	/*
 	 *	Init state, all RD entries belong to the NIC
 	 */
 	for (i = 0; i < vptr->options.numrx; ++i)
-		vptr->rd_ring[i].rdesc0.len |= OWNED_BY_NIC;
+		vptr->rx.ring[i].rdesc0.len |= OWNED_BY_NIC;
 
 	writew(vptr->options.numrx, &regs->RBRDU);
-	writel(vptr->rd_pool_dma, &regs->RDBaseLo);
+	writel(vptr->rx.pool_dma, &regs->RDBaseLo);
 	writew(0, &regs->RDIdx);
 	writew(vptr->options.numrx - 1, &regs->RDCSize);
 }
@@ -779,15 +783,15 @@ static void velocity_init_registers(struct velocity_info *vptr,
 
 		vptr->int_mask = INT_MASK_DEF;
 
-		writel(vptr->rd_pool_dma, &regs->RDBaseLo);
+		writel(vptr->rx.pool_dma, &regs->RDBaseLo);
 		writew(vptr->options.numrx - 1, &regs->RDCSize);
 		mac_rx_queue_run(regs);
 		mac_rx_queue_wake(regs);
 
 		writew(vptr->options.numtx - 1, &regs->TDCSize);
 
-		for (i = 0; i < vptr->num_txq; i++) {
-			writel(vptr->td_pool_dma[i], &regs->TDBaseLo[i]);
+		for (i = 0; i < vptr->tx.numq; i++) {
+			writel(vptr->tx.pool_dma[i], &regs->TDBaseLo[i]);
 			mac_tx_queue_run(regs, i);
 		}
 
@@ -1047,7 +1051,7 @@ static void __devinit velocity_init_info(struct pci_dev *pdev,
 
 	vptr->pdev = pdev;
 	vptr->chip_id = info->chip_id;
-	vptr->num_txq = info->txqueue;
+	vptr->tx.numq = info->txqueue;
 	vptr->multicast_limit = MCAM_SIZE;
 	spin_lock_init(&vptr->lock);
 	INIT_LIST_HEAD(&vptr->list);
@@ -1093,14 +1097,14 @@ static int __devinit velocity_get_pci_info(struct velocity_info *vptr, struct pc
 }
 
 /**
- *	velocity_init_rings	-	set up DMA rings
+ *	velocity_init_dma_rings	-	set up DMA rings
  *	@vptr: Velocity to set up
  *
  *	Allocate PCI mapped DMA rings for the receive and transmit layer
  *	to use.
  */
 
-static int velocity_init_rings(struct velocity_info *vptr)
+static int velocity_init_dma_rings(struct velocity_info *vptr)
 {
 	struct velocity_opt *opt = &vptr->options;
 	const unsigned int rx_ring_size = opt->numrx * sizeof(struct rx_desc);
@@ -1116,7 +1120,7 @@ static int velocity_init_rings(struct velocity_info *vptr)
 	 * pci_alloc_consistent() fulfills the requirement for 64 bytes
 	 * alignment
 	 */
-	pool = pci_alloc_consistent(pdev, tx_ring_size * vptr->num_txq +
+	pool = pci_alloc_consistent(pdev, tx_ring_size * vptr->tx.numq +
 				    rx_ring_size, &pool_dma);
 	if (!pool) {
 		dev_err(&pdev->dev, "%s : DMA memory allocation failed.\n",
@@ -1124,15 +1128,15 @@ static int velocity_init_rings(struct velocity_info *vptr)
 		return -ENOMEM;
 	}
 
-	vptr->rd_ring = pool;
-	vptr->rd_pool_dma = pool_dma;
+	vptr->rx.ring = pool;
+	vptr->rx.pool_dma = pool_dma;
 
 	pool += rx_ring_size;
 	pool_dma += rx_ring_size;
 
-	for (i = 0; i < vptr->num_txq; i++) {
-		vptr->td_rings[i] = pool;
-		vptr->td_pool_dma[i] = pool_dma;
+	for (i = 0; i < vptr->tx.numq; i++) {
+		vptr->tx.rings[i] = pool;
+		vptr->tx.pool_dma[i] = pool_dma;
 		pool += tx_ring_size;
 		pool_dma += tx_ring_size;
 	}
@@ -1141,18 +1145,18 @@ static int velocity_init_rings(struct velocity_info *vptr)
 }
 
 /**
- *	velocity_free_rings	-	free PCI ring pointers
+ *	velocity_free_dma_rings	-	free PCI ring pointers
  *	@vptr: Velocity to free from
  *
  *	Clean up the PCI ring buffers allocated to this velocity.
  */
 
-static void velocity_free_rings(struct velocity_info *vptr)
+static void velocity_free_dma_rings(struct velocity_info *vptr)
 {
 	const int size = vptr->options.numrx * sizeof(struct rx_desc) +
-		vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
+		vptr->options.numtx * sizeof(struct tx_desc) * vptr->tx.numq;
 
-	pci_free_consistent(vptr->pdev, size, vptr->rd_ring, vptr->rd_pool_dma);
+	pci_free_consistent(vptr->pdev, size, vptr->rx.ring, vptr->rx.pool_dma);
 }
 
 static void velocity_give_many_rx_descs(struct velocity_info *vptr)
@@ -1164,44 +1168,44 @@ static void velocity_give_many_rx_descs(struct velocity_info *vptr)
 	 * RD number must be equal to 4X per hardware spec
 	 * (programming guide rev 1.20, p.13)
 	 */
-	if (vptr->rd_filled < 4)
+	if (vptr->rx.filled < 4)
 		return;
 
 	wmb();
 
-	unusable = vptr->rd_filled & 0x0003;
-	dirty = vptr->rd_dirty - unusable;
-	for (avail = vptr->rd_filled & 0xfffc; avail; avail--) {
+	unusable = vptr->rx.filled & 0x0003;
+	dirty = vptr->rx.dirty - unusable;
+	for (avail = vptr->rx.filled & 0xfffc; avail; avail--) {
 		dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1;
-		vptr->rd_ring[dirty].rdesc0.len |= OWNED_BY_NIC;
+		vptr->rx.ring[dirty].rdesc0.len |= OWNED_BY_NIC;
 	}
 
-	writew(vptr->rd_filled & 0xfffc, &regs->RBRDU);
-	vptr->rd_filled = unusable;
+	writew(vptr->rx.filled & 0xfffc, &regs->RBRDU);
+	vptr->rx.filled = unusable;
 }
 
 static int velocity_rx_refill(struct velocity_info *vptr)
 {
-	int dirty = vptr->rd_dirty, done = 0;
+	int dirty = vptr->rx.dirty, done = 0;
 
 	do {
-		struct rx_desc *rd = vptr->rd_ring + dirty;
+		struct rx_desc *rd = vptr->rx.ring + dirty;
 
 		/* Fine for an all zero Rx desc at init time as well */
 		if (rd->rdesc0.len & OWNED_BY_NIC)
 			break;
 
-		if (!vptr->rd_info[dirty].skb) {
+		if (!vptr->rx.info[dirty].skb) {
 			if (velocity_alloc_rx_buf(vptr, dirty) < 0)
 				break;
 		}
 		done++;
 		dirty = (dirty < vptr->options.numrx - 1) ? dirty + 1 : 0;
-	} while (dirty != vptr->rd_curr);
+	} while (dirty != vptr->rx.curr);
 
 	if (done) {
-		vptr->rd_dirty = dirty;
-		vptr->rd_filled += done;
+		vptr->rx.dirty = dirty;
+		vptr->rx.filled += done;
 	}
 
 	return done;
@@ -1209,7 +1213,7 @@ static int velocity_rx_refill(struct velocity_info *vptr)
 
 static void velocity_set_rxbufsize(struct velocity_info *vptr, int mtu)
 {
-	vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
+	vptr->rx.buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
 }
 
 /**
@@ -1224,12 +1228,12 @@ static int velocity_init_rd_ring(struct velocity_info *vptr)
 {
 	int ret = -ENOMEM;
 
-	vptr->rd_info = kcalloc(vptr->options.numrx,
+	vptr->rx.info = kcalloc(vptr->options.numrx,
 				sizeof(struct velocity_rd_info), GFP_KERNEL);
-	if (!vptr->rd_info)
+	if (!vptr->rx.info)
 		goto out;
 
-	vptr->rd_filled = vptr->rd_dirty = vptr->rd_curr = 0;
+	velocity_init_rx_ring_indexes(vptr);
 
 	if (velocity_rx_refill(vptr) != vptr->options.numrx) {
 		VELOCITY_PRT(MSG_LEVEL_ERR, KERN_ERR
@@ -1255,18 +1259,18 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
 {
 	int i;
 
-	if (vptr->rd_info == NULL)
+	if (vptr->rx.info == NULL)
 		return;
 
 	for (i = 0; i < vptr->options.numrx; i++) {
-		struct velocity_rd_info *rd_info = &(vptr->rd_info[i]);
-		struct rx_desc *rd = vptr->rd_ring + i;
+		struct velocity_rd_info *rd_info = &(vptr->rx.info[i]);
+		struct rx_desc *rd = vptr->rx.ring + i;
 
 		memset(rd, 0, sizeof(*rd));
 
 		if (!rd_info->skb)
 			continue;
-		pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx_buf_sz,
+		pci_unmap_single(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
 				 PCI_DMA_FROMDEVICE);
 		rd_info->skb_dma = (dma_addr_t) NULL;
 
@@ -1274,8 +1278,8 @@ static void velocity_free_rd_ring(struct velocity_info *vptr)
 		rd_info->skb = NULL;
 	}
 
-	kfree(vptr->rd_info);
-	vptr->rd_info = NULL;
+	kfree(vptr->rx.info);
+	vptr->rx.info = NULL;
 }
 
 /**
@@ -1293,19 +1297,19 @@ static int velocity_init_td_ring(struct velocity_info *vptr)
 	unsigned int j;
 
 	/* Init the TD ring entries */
-	for (j = 0; j < vptr->num_txq; j++) {
-		curr = vptr->td_pool_dma[j];
+	for (j = 0; j < vptr->tx.numq; j++) {
+		curr = vptr->tx.pool_dma[j];
 
-		vptr->td_infos[j] = kcalloc(vptr->options.numtx,
+		vptr->tx.infos[j] = kcalloc(vptr->options.numtx,
 					    sizeof(struct velocity_td_info),
 					    GFP_KERNEL);
-		if (!vptr->td_infos[j])	{
+		if (!vptr->tx.infos[j])	{
 			while(--j >= 0)
-				kfree(vptr->td_infos[j]);
+				kfree(vptr->tx.infos[j]);
 			return -ENOMEM;
 		}
 
-		vptr->td_tail[j] = vptr->td_curr[j] = vptr->td_used[j] = 0;
+		vptr->tx.tail[j] = vptr->tx.curr[j] = vptr->tx.used[j] = 0;
 	}
 	return 0;
 }
@@ -1317,7 +1321,7 @@ static int velocity_init_td_ring(struct velocity_info *vptr)
 static void velocity_free_td_ring_entry(struct velocity_info *vptr,
 							 int q, int n)
 {
-	struct velocity_td_info * td_info = &(vptr->td_infos[q][n]);
+	struct velocity_td_info * td_info = &(vptr->tx.infos[q][n]);
 	int i;
 
 	if (td_info == NULL)
@@ -1349,15 +1353,15 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
 {
 	int i, j;
 
-	for (j = 0; j < vptr->num_txq; j++) {
-		if (vptr->td_infos[j] == NULL)
+	for (j = 0; j < vptr->tx.numq; j++) {
+		if (vptr->tx.infos[j] == NULL)
 			continue;
 		for (i = 0; i < vptr->options.numtx; i++) {
 			velocity_free_td_ring_entry(vptr, j, i);
 
 		}
-		kfree(vptr->td_infos[j]);
-		vptr->td_infos[j] = NULL;
+		kfree(vptr->tx.infos[j]);
+		vptr->tx.infos[j] = NULL;
 	}
 }
 
@@ -1374,13 +1378,13 @@ static void velocity_free_td_ring(struct velocity_info *vptr)
 static int velocity_rx_srv(struct velocity_info *vptr, int status)
 {
 	struct net_device_stats *stats = &vptr->stats;
-	int rd_curr = vptr->rd_curr;
+	int rd_curr = vptr->rx.curr;
 	int works = 0;
 
 	do {
-		struct rx_desc *rd = vptr->rd_ring + rd_curr;
+		struct rx_desc *rd = vptr->rx.ring + rd_curr;
 
-		if (!vptr->rd_info[rd_curr].skb)
+		if (!vptr->rx.info[rd_curr].skb)
 			break;
 
 		if (rd->rdesc0.len & OWNED_BY_NIC)
@@ -1412,7 +1416,7 @@ static int velocity_rx_srv(struct velocity_info *vptr, int status)
 			rd_curr = 0;
 	} while (++works <= 15);
 
-	vptr->rd_curr = rd_curr;
+	vptr->rx.curr = rd_curr;
 
 	if ((works > 0) && (velocity_rx_refill(vptr) > 0))
 		velocity_give_many_rx_descs(vptr);
@@ -1510,8 +1514,8 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 {
 	void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
 	struct net_device_stats *stats = &vptr->stats;
-	struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]);
-	struct rx_desc *rd = &(vptr->rd_ring[idx]);
+	struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
+	struct rx_desc *rd = &(vptr->rx.ring[idx]);
 	int pkt_len = le16_to_cpu(rd->rdesc0.len) & 0x3fff;
 	struct sk_buff *skb;
 
@@ -1527,7 +1531,7 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 	skb = rd_info->skb;
 
 	pci_dma_sync_single_for_cpu(vptr->pdev, rd_info->skb_dma,
-				    vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
+				    vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
 
 	/*
 	 *	Drop frame not meeting IEEE 802.3
@@ -1550,7 +1554,7 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 		rd_info->skb = NULL;
 	}
 
-	pci_action(vptr->pdev, rd_info->skb_dma, vptr->rx_buf_sz,
+	pci_action(vptr->pdev, rd_info->skb_dma, vptr->rx.buf_sz,
 		   PCI_DMA_FROMDEVICE);
 
 	skb_put(skb, pkt_len - 4);
@@ -1580,10 +1584,10 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 
 static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
 {
-	struct rx_desc *rd = &(vptr->rd_ring[idx]);
-	struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]);
+	struct rx_desc *rd = &(vptr->rx.ring[idx]);
+	struct velocity_rd_info *rd_info = &(vptr->rx.info[idx]);
 
-	rd_info->skb = netdev_alloc_skb(vptr->dev, vptr->rx_buf_sz + 64);
+	rd_info->skb = dev_alloc_skb(vptr->rx.buf_sz + 64);
 	if (rd_info->skb == NULL)
 		return -ENOMEM;
 
@@ -1592,14 +1596,15 @@ static int velocity_alloc_rx_buf(struct velocity_info *vptr, int idx)
 	 *	64byte alignment.
 	 */
 	skb_reserve(rd_info->skb, (unsigned long) rd_info->skb->data & 63);
-	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data, vptr->rx_buf_sz, PCI_DMA_FROMDEVICE);
+	rd_info->skb_dma = pci_map_single(vptr->pdev, rd_info->skb->data,
+					vptr->rx.buf_sz, PCI_DMA_FROMDEVICE);
 
 	/*
 	 *	Fill in the descriptor to match
- 	 */
+	 */
 
 	*((u32 *) & (rd->rdesc0)) = 0;
-	rd->size = cpu_to_le16(vptr->rx_buf_sz) | RX_INTEN;
+	rd->size = cpu_to_le16(vptr->rx.buf_sz) | RX_INTEN;
 	rd->pa_low = cpu_to_le32(rd_info->skb_dma);
 	rd->pa_high = 0;
 	return 0;
@@ -1625,15 +1630,15 @@ static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
 	struct velocity_td_info *tdinfo;
 	struct net_device_stats *stats = &vptr->stats;
 
-	for (qnum = 0; qnum < vptr->num_txq; qnum++) {
-		for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0;
+	for (qnum = 0; qnum < vptr->tx.numq; qnum++) {
+		for (idx = vptr->tx.tail[qnum]; vptr->tx.used[qnum] > 0;
 			idx = (idx + 1) % vptr->options.numtx) {
 
 			/*
 			 *	Get Tx Descriptor
 			 */
-			td = &(vptr->td_rings[qnum][idx]);
-			tdinfo = &(vptr->td_infos[qnum][idx]);
+			td = &(vptr->tx.rings[qnum][idx]);
+			tdinfo = &(vptr->tx.infos[qnum][idx]);
 
 			if (td->tdesc0.len & OWNED_BY_NIC)
 				break;
@@ -1657,9 +1662,9 @@ static int velocity_tx_srv(struct velocity_info *vptr, u32 status)
 				stats->tx_bytes += tdinfo->skb->len;
 			}
 			velocity_free_tx_buf(vptr, tdinfo);
-			vptr->td_used[qnum]--;
+			vptr->tx.used[qnum]--;
 		}
-		vptr->td_tail[qnum] = idx;
+		vptr->tx.tail[qnum] = idx;
 
 		if (AVAIL_TD(vptr, qnum) < 1) {
 			full = 1;
@@ -1846,6 +1851,40 @@ static void velocity_free_tx_buf(struct velocity_info *vptr, struct velocity_td_
 	tdinfo->skb = NULL;
 }
 
+static int velocity_init_rings(struct velocity_info *vptr, int mtu)
+{
+	int ret;
+
+	velocity_set_rxbufsize(vptr, mtu);
+
+	ret = velocity_init_dma_rings(vptr);
+	if (ret < 0)
+		goto out;
+
+	ret = velocity_init_rd_ring(vptr);
+	if (ret < 0)
+		goto err_free_dma_rings_0;
+
+	ret = velocity_init_td_ring(vptr);
+	if (ret < 0)
+		goto err_free_rd_ring_1;
+out:
+	return ret;
+
+err_free_rd_ring_1:
+	velocity_free_rd_ring(vptr);
+err_free_dma_rings_0:
+	velocity_free_dma_rings(vptr);
+	goto out;
+}
+
+static void velocity_free_rings(struct velocity_info *vptr)
+{
+	velocity_free_td_ring(vptr);
+	velocity_free_rd_ring(vptr);
+	velocity_free_dma_rings(vptr);
+}
+
 /**
  *	velocity_open		-	interface activation callback
  *	@dev: network layer device to open
@@ -1862,20 +1901,10 @@ static int velocity_open(struct net_device *dev)
 	struct velocity_info *vptr = netdev_priv(dev);
 	int ret;
 
-	velocity_set_rxbufsize(vptr, dev->mtu);
-
-	ret = velocity_init_rings(vptr);
+	ret = velocity_init_rings(vptr, dev->mtu);
 	if (ret < 0)
 		goto out;
 
-	ret = velocity_init_rd_ring(vptr);
-	if (ret < 0)
-		goto err_free_desc_rings;
-
-	ret = velocity_init_td_ring(vptr);
-	if (ret < 0)
-		goto err_free_rd_ring;
-
 	/* Ensure chip is running */
 	pci_set_power_state(vptr->pdev, PCI_D0);
 
@@ -1888,7 +1917,8 @@ static int velocity_open(struct net_device *dev)
 	if (ret < 0) {
 		/* Power down the chip */
 		pci_set_power_state(vptr->pdev, PCI_D3hot);
-		goto err_free_td_ring;
+		velocity_free_rings(vptr);
+		goto out;
 	}
 
 	mac_enable_int(vptr->mac_regs);
@@ -1896,14 +1926,6 @@ static int velocity_open(struct net_device *dev)
 	vptr->flags |= VELOCITY_FLAGS_OPENED;
 out:
 	return ret;
-
-err_free_td_ring:
-	velocity_free_td_ring(vptr);
-err_free_rd_ring:
-	velocity_free_rd_ring(vptr);
-err_free_desc_rings:
-	velocity_free_rings(vptr);
-	goto out;
 }
 
 /**
@@ -1919,50 +1941,72 @@ err_free_desc_rings:
 static int velocity_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
-	unsigned long flags;
-	int oldmtu = dev->mtu;
 	int ret = 0;
 
 	if ((new_mtu < VELOCITY_MIN_MTU) || new_mtu > (VELOCITY_MAX_MTU)) {
 		VELOCITY_PRT(MSG_LEVEL_ERR, KERN_NOTICE "%s: Invalid MTU.\n",
 				vptr->dev->name);
-		return -EINVAL;
+		ret = -EINVAL;
+		goto out_0;
 	}
 
 	if (!netif_running(dev)) {
 		dev->mtu = new_mtu;
-		return 0;
+		goto out_0;
 	}
 
-	if (new_mtu != oldmtu) {
+	if (dev->mtu != new_mtu) {
+		struct velocity_info *tmp_vptr;
+		unsigned long flags;
+		struct rx_info rx;
+		struct tx_info tx;
+
+		tmp_vptr = kzalloc(sizeof(*tmp_vptr), GFP_KERNEL);
+		if (!tmp_vptr) {
+			ret = -ENOMEM;
+			goto out_0;
+		}
+
+		tmp_vptr->dev = dev;
+		tmp_vptr->pdev = vptr->pdev;
+		tmp_vptr->options = vptr->options;
+		tmp_vptr->tx.numq = vptr->tx.numq;
+
+		ret = velocity_init_rings(tmp_vptr, new_mtu);
+		if (ret < 0)
+			goto out_free_tmp_vptr_1;
+
 		spin_lock_irqsave(&vptr->lock, flags);
 
 		netif_stop_queue(dev);
 		velocity_shutdown(vptr);
 
-		velocity_free_td_ring(vptr);
-		velocity_free_rd_ring(vptr);
+		rx = vptr->rx;
+		tx = vptr->tx;
 
-		dev->mtu = new_mtu;
+		vptr->rx = tmp_vptr->rx;
+		vptr->tx = tmp_vptr->tx;
 
-		velocity_set_rxbufsize(vptr, new_mtu);
+		tmp_vptr->rx = rx;
+		tmp_vptr->tx = tx;
 
-		ret = velocity_init_rd_ring(vptr);
-		if (ret < 0)
-			goto out_unlock;
+		dev->mtu = new_mtu;
 
-		ret = velocity_init_td_ring(vptr);
-		if (ret < 0)
-			goto out_unlock;
+		velocity_give_many_rx_descs(vptr);
 
 		velocity_init_registers(vptr, VELOCITY_INIT_COLD);
 
 		mac_enable_int(vptr->mac_regs);
 		netif_start_queue(dev);
-out_unlock:
+
 		spin_unlock_irqrestore(&vptr->lock, flags);
-	}
 
+		velocity_free_rings(tmp_vptr);
+
+out_free_tmp_vptr_1:
+		kfree(tmp_vptr);
+	}
+out_0:
 	return ret;
 }
 
@@ -2008,9 +2052,6 @@ static int velocity_close(struct net_device *dev)
 	/* Power down the chip */
 	pci_set_power_state(vptr->pdev, PCI_D3hot);
 
-	/* Free the resources */
-	velocity_free_td_ring(vptr);
-	velocity_free_rd_ring(vptr);
 	velocity_free_rings(vptr);
 
 	vptr->flags &= (~VELOCITY_FLAGS_OPENED);
@@ -2056,9 +2097,9 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	spin_lock_irqsave(&vptr->lock, flags);
 
-	index = vptr->td_curr[qnum];
-	td_ptr = &(vptr->td_rings[qnum][index]);
-	tdinfo = &(vptr->td_infos[qnum][index]);
+	index = vptr->tx.curr[qnum];
+	td_ptr = &(vptr->tx.rings[qnum][index]);
+	tdinfo = &(vptr->tx.infos[qnum][index]);
 
 	td_ptr->tdesc1.TCR = TCR0_TIC;
 	td_ptr->td_buf[0].size &= ~TD_QUEUE;
@@ -2071,9 +2112,9 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
 			skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
 			tdinfo->skb_dma[0] = tdinfo->buf_dma;
 			td_ptr->tdesc0.len = len;
-			td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
-			td_ptr->td_buf[0].pa_high = 0;
-			td_ptr->td_buf[0].size = len;	/* queue is 0 anyway */
+			td_ptr->tx.buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
+			td_ptr->tx.buf[0].pa_high = 0;
+			td_ptr->tx.buf[0].size = len;	/* queue is 0 anyway */
 			tdinfo->nskb_dma = 1;
 		} else {
 			int i = 0;
@@ -2084,9 +2125,9 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
 			td_ptr->tdesc0.len = len;
 
 			/* FIXME: support 48bit DMA later */
-			td_ptr->td_buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma);
-			td_ptr->td_buf[i].pa_high = 0;
-			td_ptr->td_buf[i].size = cpu_to_le16(skb_headlen(skb));
+			td_ptr->tx.buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma);
+			td_ptr->tx.buf[i].pa_high = 0;
+			td_ptr->tx.buf[i].size = cpu_to_le16(skb_headlen(skb));
 
 			for (i = 0; i < nfrags; i++) {
 				skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
@@ -2094,9 +2135,9 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
 
 				tdinfo->skb_dma[i + 1] = pci_map_single(vptr->pdev, addr, frag->size, PCI_DMA_TODEVICE);
 
-				td_ptr->td_buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
-				td_ptr->td_buf[i + 1].pa_high = 0;
-				td_ptr->td_buf[i + 1].size = cpu_to_le16(frag->size);
+				td_ptr->tx.buf[i + 1].pa_low = cpu_to_le32(tdinfo->skb_dma[i + 1]);
+				td_ptr->tx.buf[i + 1].pa_high = 0;
+				td_ptr->tx.buf[i + 1].size = cpu_to_le16(frag->size);
 			}
 			tdinfo->nskb_dma = i - 1;
 		}
@@ -2142,13 +2183,13 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
 		if (prev < 0)
 			prev = vptr->options.numtx - 1;
 		td_ptr->tdesc0.len |= OWNED_BY_NIC;
-		vptr->td_used[qnum]++;
-		vptr->td_curr[qnum] = (index + 1) % vptr->options.numtx;
+		vptr->tx.used[qnum]++;
+		vptr->tx.curr[qnum] = (index + 1) % vptr->options.numtx;
 
 		if (AVAIL_TD(vptr, qnum) < 1)
 			netif_stop_queue(dev);
 
-		td_ptr = &(vptr->td_rings[qnum][prev]);
+		td_ptr = &(vptr->tx.rings[qnum][prev]);
 		td_ptr->td_buf[0].size |= TD_QUEUE;
 		mac_tx_queue_wake(vptr->mac_regs, qnum);
 	}
@@ -3405,8 +3446,8 @@ static int velocity_resume(struct pci_dev *pdev)
 
 	velocity_tx_srv(vptr, 0);
 
-	for (i = 0; i < vptr->num_txq; i++) {
-		if (vptr->td_used[i]) {
+	for (i = 0; i < vptr->tx.numq; i++) {
+		if (vptr->tx.used[i]) {
 			mac_tx_queue_wake(vptr->mac_regs, i);
 		}
 	}
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index 8644614..1b95b04 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -1494,6 +1494,10 @@ struct velocity_opt {
 	u32 flags;
 };
 
+#define AVAIL_TD(p,q)   ((p)->options.numtx-((p)->tx.used[(q)]))
+
+#define GET_RD_BY_IDX(vptr, idx)   (vptr->rd_ring[idx])
+
 struct velocity_info {
 	struct list_head list;
 
@@ -1501,9 +1505,6 @@ struct velocity_info {
 	struct net_device *dev;
 	struct net_device_stats stats;
 
-	dma_addr_t rd_pool_dma;
-	dma_addr_t td_pool_dma[TX_QUEUE_NO];
-
 	struct vlan_group    *vlgrp;
 	u8 ip_addr[4];
 	enum chip_type chip_id;
@@ -1512,25 +1513,29 @@ struct velocity_info {
 	unsigned long memaddr;
 	unsigned long ioaddr;
 
-	u8 rev_id;
-
-#define AVAIL_TD(p,q)   ((p)->options.numtx-((p)->td_used[(q)]))
+	struct tx_info {
+		int numq;
+
+		/* FIXME: the locality of the data seems rather poor. */
+		int used[TX_QUEUE_NO];
+		int curr[TX_QUEUE_NO];
+		int tail[TX_QUEUE_NO];
+		struct tx_desc *rings[TX_QUEUE_NO];
+		struct velocity_td_info *infos[TX_QUEUE_NO];
+		dma_addr_t pool_dma[TX_QUEUE_NO];
+	} tx;
+
+	struct rx_info {
+		int buf_sz;
+
+		int dirty;
+		int curr;
+		u32 filled;
+		struct rx_desc *ring;
+		struct velocity_rd_info *info;	/* It's an array */
+		dma_addr_t pool_dma;
+	} rx;
 
-	int num_txq;
-
-	volatile int td_used[TX_QUEUE_NO];
-	int td_curr[TX_QUEUE_NO];
-	int td_tail[TX_QUEUE_NO];
-	struct tx_desc *td_rings[TX_QUEUE_NO];
-	struct velocity_td_info *td_infos[TX_QUEUE_NO];
-
-	int rd_curr;
-	int rd_dirty;
-	u32 rd_filled;
-	struct rx_desc *rd_ring;
-	struct velocity_rd_info *rd_info;	/* It's an array */
-
-#define GET_RD_BY_IDX(vptr, idx)   (vptr->rd_ring[idx])
 	u32 mib_counter[MAX_HW_MIB_COUNTER];
 	struct velocity_opt options;
 
@@ -1538,7 +1543,6 @@ struct velocity_info {
 
 	u32 flags;
 
-	int rx_buf_sz;
 	u32 mii_status;
 	u32 phy_id;
 	int multicast_limit;
@@ -1554,8 +1558,8 @@ struct velocity_info {
 	struct velocity_context context;
 
 	u32 ticks;
-	u32 rx_bytes;
 
+	u8 rev_id;
 };
 
 /**
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 846be60..2ae2ec4 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -25,7 +25,7 @@ if WAN
 # There is no way to detect a comtrol sv11 - force it modular for now.
 config HOSTESS_SV11
 	tristate "Comtrol Hostess SV-11 support"
-	depends on ISA && m && ISA_DMA_API && INET
+	depends on ISA && m && ISA_DMA_API && INET && HDLC
 	help
 	  Driver for Comtrol Hostess SV-11 network card which
 	  operates on low speed synchronous serial links at up to
@@ -37,7 +37,7 @@ config HOSTESS_SV11
 # The COSA/SRP driver has not been tested as non-modular yet.
 config COSA
 	tristate "COSA/SRP sync serial boards support"
-	depends on ISA && m && ISA_DMA_API
+	depends on ISA && m && ISA_DMA_API && HDLC
 	---help---
 	  Driver for COSA and SRP synchronous serial boards.
 
@@ -61,7 +61,7 @@ config COSA
 #
 config LANMEDIA
 	tristate "LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards"
-	depends on PCI && VIRT_TO_BUS
+	depends on PCI && VIRT_TO_BUS && HDLC
 	---help---
 	  Driver for the following Lan Media family of serial boards:
 
@@ -78,9 +78,8 @@ config LANMEDIA
 	  - LMC 5245 board connects directly to a T3 circuit saving the
 	  additional external hardware.
 
-	  To change setting such as syncPPP vs Cisco HDLC or clock source you
-	  will need lmcctl.  It is available at <ftp://ftp.lanmedia.com/>
-	  (broken link).
+	  To change setting such as clock source you will need lmcctl.
+	  It is available at <ftp://ftp.lanmedia.com/> (broken link).
 
 	  To compile this driver as a module, choose M here: the
 	  module will be called lmc.
@@ -88,7 +87,7 @@ config LANMEDIA
 # There is no way to detect a Sealevel board. Force it modular
 config SEALEVEL_4021
 	tristate "Sealevel Systems 4021 support"
-	depends on ISA && m && ISA_DMA_API && INET
+	depends on ISA && m && ISA_DMA_API && INET && HDLC
 	help
 	  This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
 
@@ -154,8 +153,6 @@ config HDLC_PPP
 	help
 	  Generic HDLC driver supporting PPP over WAN connections.
 
-	  It will be replaced by new PPP implementation in Linux 2.6.26.
-
 	  If unsure, say N.
 
 config HDLC_X25
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index d61fef3..1025496 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -21,12 +21,11 @@ pc300-y				:= pc300_drv.o
 pc300-$(CONFIG_PC300_MLPPP)	+= pc300_tty.o
 pc300-objs			:= $(pc300-y)
 
-obj-$(CONFIG_HOSTESS_SV11)	+= z85230.o	syncppp.o	hostess_sv11.o
-obj-$(CONFIG_SEALEVEL_4021)	+= z85230.o	syncppp.o	sealevel.o
-obj-$(CONFIG_COSA)		+=		syncppp.o	cosa.o
-obj-$(CONFIG_FARSYNC)		+=		syncppp.o	farsync.o
-obj-$(CONFIG_DSCC4)             +=				dscc4.o
-obj-$(CONFIG_LANMEDIA)		+=		syncppp.o
+obj-$(CONFIG_HOSTESS_SV11)	+= z85230.o	hostess_sv11.o
+obj-$(CONFIG_SEALEVEL_4021)	+= z85230.o	sealevel.o
+obj-$(CONFIG_COSA)		+= cosa.o
+obj-$(CONFIG_FARSYNC)		+= farsync.o
+obj-$(CONFIG_DSCC4)             += dscc4.o
 obj-$(CONFIG_X25_ASY)		+= x25_asy.o
 
 obj-$(CONFIG_LANMEDIA)		+= lmc/
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index f7d3349..f140515 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -2,6 +2,7 @@
 
 /*
  *  Copyright (C) 1995-1997  Jan "Yenya" Kasprzak <kas@fi.muni.cz>
+ *  Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -54,7 +55,7 @@
  *
  * The Linux driver (unlike the present *BSD drivers :-) can work even
  * for the COSA and SRP in one computer and allows each channel to work
- * in one of the three modes (character device, Cisco HDLC, Sync PPP).
+ * in one of the two modes (character or network device).
  *
  * AUTHOR
  *
@@ -72,12 +73,6 @@
  * The Comtrol Hostess SV11 driver by Alan Cox
  * The Sync PPP/Cisco HDLC layer (syncppp.c) ported to Linux by Alan Cox
  */
-/*
- *     5/25/1999 : Marcelo Tosatti <marcelo@conectiva.com.br>
- *             fixed a deadlock in cosa_sppp_open
- */
-\f
-/* ---------- Headers, macros, data structures ---------- */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -86,6 +81,7 @@
 #include <linux/fs.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
+#include <linux/hdlc.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/netdevice.h>
@@ -93,14 +89,12 @@
 #include <linux/mutex.h>
 #include <linux/device.h>
 #include <linux/smp_lock.h>
-
-#undef COSA_SLOW_IO	/* for testing purposes only */
-
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/byteorder.h>
 
-#include <net/syncppp.h>
+#undef COSA_SLOW_IO	/* for testing purposes only */
+
 #include "cosa.h"
 
 /* Maximum length of the identification string. */
@@ -112,7 +106,6 @@
 /* Per-channel data structure */
 
 struct channel_data {
-	void *if_ptr;	/* General purpose pointer (used by SPPP) */
 	int usage;	/* Usage count; >0 for chrdev, -1 for netdev */
 	int num;	/* Number of the channel */
 	struct cosa_data *cosa;	/* Pointer to the per-card structure */
@@ -136,10 +129,9 @@ struct channel_data {
 	wait_queue_head_t txwaitq, rxwaitq;
 	int tx_status, rx_status;
 
-	/* SPPP/HDLC device parts */
-	struct ppp_device pppdev;
+	/* generic HDLC device parts */
+	struct net_device *netdev;
 	struct sk_buff *rx_skb, *tx_skb;
-	struct net_device_stats stats;
 };
 
 /* cosa->firmware_status bits */
@@ -281,21 +273,19 @@ static int cosa_start_tx(struct channel_data *channel, char *buf, int size);
 static void cosa_kick(struct cosa_data *cosa);
 static int cosa_dma_able(struct channel_data *chan, char *buf, int data);
 
-/* SPPP/HDLC stuff */
-static void sppp_channel_init(struct channel_data *chan);
-static void sppp_channel_delete(struct channel_data *chan);
-static int cosa_sppp_open(struct net_device *d);
-static int cosa_sppp_close(struct net_device *d);
-static void cosa_sppp_timeout(struct net_device *d);
-static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *d);
-static char *sppp_setup_rx(struct channel_data *channel, int size);
-static int sppp_rx_done(struct channel_data *channel);
-static int sppp_tx_done(struct channel_data *channel, int size);
-static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
-static struct net_device_stats *cosa_net_stats(struct net_device *dev);
+/* Network device stuff */
+static int cosa_net_attach(struct net_device *dev, unsigned short encoding,
+			   unsigned short parity);
+static int cosa_net_open(struct net_device *d);
+static int cosa_net_close(struct net_device *d);
+static void cosa_net_timeout(struct net_device *d);
+static int cosa_net_tx(struct sk_buff *skb, struct net_device *d);
+static char *cosa_net_setup_rx(struct channel_data *channel, int size);
+static int cosa_net_rx_done(struct channel_data *channel);
+static int cosa_net_tx_done(struct channel_data *channel, int size);
+static int cosa_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 
 /* Character device */
-static void chardev_channel_init(struct channel_data *chan);
 static char *chrdev_setup_rx(struct channel_data *channel, int size);
 static int chrdev_rx_done(struct channel_data *channel);
 static int chrdev_tx_done(struct channel_data *channel, int size);
@@ -357,17 +347,17 @@ static void debug_status_in(struct cosa_data *cosa, int status);
 static void debug_status_out(struct cosa_data *cosa, int status);
 #endif
 
-\f
+static inline struct channel_data* dev_to_chan(struct net_device *dev)
+{
+	return (struct channel_data *)dev_to_hdlc(dev)->priv;
+}
+
 /* ---------- Initialization stuff ---------- */
 
 static int __init cosa_init(void)
 {
 	int i, err = 0;
 
-	printk(KERN_INFO "cosa v1.08 (c) 1997-2000 Jan Kasprzak <kas@fi.muni.cz>\n");
-#ifdef CONFIG_SMP
-	printk(KERN_INFO "cosa: SMP found. Please mail any success/failure reports to the author.\n");
-#endif
 	if (cosa_major > 0) {
 		if (register_chrdev(cosa_major, "cosa", &cosa_fops)) {
 			printk(KERN_WARNING "cosa: unable to get major %d\n",
@@ -402,7 +392,7 @@ static int __init cosa_init(void)
 				      NULL, "cosa%d", i);
 	err = 0;
 	goto out;
-	
+
 out_chrdev:
 	unregister_chrdev(cosa_major, "cosa");
 out:
@@ -414,43 +404,29 @@ static void __exit cosa_exit(void)
 {
 	struct cosa_data *cosa;
 	int i;
-	printk(KERN_INFO "Unloading the cosa module\n");
 
-	for (i=0; i<nr_cards; i++)
+	for (i = 0; i < nr_cards; i++)
 		device_destroy(cosa_class, MKDEV(cosa_major, i));
 	class_destroy(cosa_class);
-	for (cosa=cosa_cards; nr_cards--; cosa++) {
+
+	for (cosa = cosa_cards; nr_cards--; cosa++) {
 		/* Clean up the per-channel data */
-		for (i=0; i<cosa->nchannels; i++) {
+		for (i = 0; i < cosa->nchannels; i++) {
 			/* Chardev driver has no alloc'd per-channel data */
-			sppp_channel_delete(cosa->chan+i);
+			unregister_hdlc_device(cosa->chan[i].netdev);
+			free_netdev(cosa->chan[i].netdev);
 		}
 		/* Clean up the per-card data */
 		kfree(cosa->chan);
 		kfree(cosa->bouncebuf);
 		free_irq(cosa->irq, cosa);
 		free_dma(cosa->dma);
-		release_region(cosa->datareg,is_8bit(cosa)?2:4);
+		release_region(cosa->datareg, is_8bit(cosa) ? 2 : 4);
 	}
 	unregister_chrdev(cosa_major, "cosa");
 }
 module_exit(cosa_exit);
 
-/*
- * This function should register all the net devices needed for the
- * single channel.
- */
-static __inline__ void channel_init(struct channel_data *chan)
-{
-	sprintf(chan->name, "cosa%dc%d", chan->cosa->num, chan->num);
-
-	/* Initialize the chardev data structures */
-	chardev_channel_init(chan);
-
-	/* Register the sppp interface */
-	sppp_channel_init(chan);
-}
-	
 static int cosa_probe(int base, int irq, int dma)
 {
 	struct cosa_data *cosa = cosa_cards+nr_cards;
@@ -576,13 +552,43 @@ static int cosa_probe(int base, int irq, int dma)
 	/* Initialize the per-channel data */
 	cosa->chan = kcalloc(cosa->nchannels, sizeof(struct channel_data), GFP_KERNEL);
 	if (!cosa->chan) {
-	        err = -ENOMEM;
+		err = -ENOMEM;
 		goto err_out3;
 	}
-	for (i=0; i<cosa->nchannels; i++) {
-		cosa->chan[i].cosa = cosa;
-		cosa->chan[i].num = i;
-		channel_init(cosa->chan+i);
+
+	for (i = 0; i < cosa->nchannels; i++) {
+		struct channel_data *chan = &cosa->chan[i];
+
+		chan->cosa = cosa;
+		chan->num = i;
+		sprintf(chan->name, "cosa%dc%d", chan->cosa->num, i);
+
+		/* Initialize the chardev data structures */
+		mutex_init(&chan->rlock);
+		init_MUTEX(&chan->wsem);
+
+		/* Register the network interface */
+		if (!(chan->netdev = alloc_hdlcdev(chan))) {
+			printk(KERN_WARNING "%s: alloc_hdlcdev failed.\n",
+			       chan->name);
+			goto err_hdlcdev;
+		}
+		dev_to_hdlc(chan->netdev)->attach = cosa_net_attach;
+		dev_to_hdlc(chan->netdev)->xmit = cosa_net_tx;
+		chan->netdev->open = cosa_net_open;
+		chan->netdev->stop = cosa_net_close;
+		chan->netdev->do_ioctl = cosa_net_ioctl;
+		chan->netdev->tx_timeout = cosa_net_timeout;
+		chan->netdev->watchdog_timeo = TX_TIMEOUT;
+		chan->netdev->base_addr = chan->cosa->datareg;
+		chan->netdev->irq = chan->cosa->irq;
+		chan->netdev->dma = chan->cosa->dma;
+		if (register_hdlc_device(chan->netdev)) {
+			printk(KERN_WARNING "%s: register_hdlc_device()"
+			       " failed.\n", chan->netdev->name);
+			free_netdev(chan->netdev);
+			goto err_hdlcdev;
+		}
 	}
 
 	printk (KERN_INFO "cosa%d: %s (%s at 0x%x irq %d dma %d), %d channels\n",
@@ -590,13 +596,20 @@ static int cosa_probe(int base, int irq, int dma)
 		cosa->datareg, cosa->irq, cosa->dma, cosa->nchannels);
 
 	return nr_cards++;
+
+err_hdlcdev:
+	while (i-- > 0) {
+		unregister_hdlc_device(cosa->chan[i].netdev);
+		free_netdev(cosa->chan[i].netdev);
+	}
+	kfree(cosa->chan);
 err_out3:
 	kfree(cosa->bouncebuf);
 err_out2:
 	free_dma(cosa->dma);
 err_out1:
 	free_irq(cosa->irq, cosa);
-err_out:	
+err_out:
 	release_region(cosa->datareg,is_8bit(cosa)?2:4);
 	printk(KERN_NOTICE "cosa%d: allocating resources failed\n",
 	       cosa->num);
@@ -604,54 +617,19 @@ err_out:
 }
 
 \f
-/*---------- SPPP/HDLC netdevice ---------- */
+/*---------- network device ---------- */
 
-static void cosa_setup(struct net_device *d)
+static int cosa_net_attach(struct net_device *dev, unsigned short encoding,
+			   unsigned short parity)
 {
-	d->open = cosa_sppp_open;
-	d->stop = cosa_sppp_close;
-	d->hard_start_xmit = cosa_sppp_tx;
-	d->do_ioctl = cosa_sppp_ioctl;
-	d->get_stats = cosa_net_stats;
-	d->tx_timeout = cosa_sppp_timeout;
-	d->watchdog_timeo = TX_TIMEOUT;
-}
-
-static void sppp_channel_init(struct channel_data *chan)
-{
-	struct net_device *d;
-	chan->if_ptr = &chan->pppdev;
-	d = alloc_netdev(0, chan->name, cosa_setup);
-	if (!d) {
-		printk(KERN_WARNING "%s: alloc_netdev failed.\n", chan->name);
-		return;
-	}
-	chan->pppdev.dev = d;
-	d->base_addr = chan->cosa->datareg;
-	d->irq = chan->cosa->irq;
-	d->dma = chan->cosa->dma;
-	d->ml_priv = chan;
-	sppp_attach(&chan->pppdev);
-	if (register_netdev(d)) {
-		printk(KERN_WARNING "%s: register_netdev failed.\n", d->name);
-		sppp_detach(d);
-		free_netdev(d);
-		chan->pppdev.dev = NULL;
-		return;
-	}
-}
-
-static void sppp_channel_delete(struct channel_data *chan)
-{
-	unregister_netdev(chan->pppdev.dev);
-	sppp_detach(chan->pppdev.dev);
-	free_netdev(chan->pppdev.dev);
-	chan->pppdev.dev = NULL;
+	if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
+		return 0;
+	return -EINVAL;
 }
 
-static int cosa_sppp_open(struct net_device *d)
+static int cosa_net_open(struct net_device *dev)
 {
-	struct channel_data *chan = d->ml_priv;
+	struct channel_data *chan = dev_to_chan(dev);
 	int err;
 	unsigned long flags;
 
@@ -662,36 +640,35 @@ static int cosa_sppp_open(struct net_device *d)
 	}
 	spin_lock_irqsave(&chan->cosa->lock, flags);
 	if (chan->usage != 0) {
-		printk(KERN_WARNING "%s: sppp_open called with usage count %d\n",
-			chan->name, chan->usage);
+		printk(KERN_WARNING "%s: cosa_net_open called with usage count"
+		       " %d\n", chan->name, chan->usage);
 		spin_unlock_irqrestore(&chan->cosa->lock, flags);
 		return -EBUSY;
 	}
-	chan->setup_rx = sppp_setup_rx;
-	chan->tx_done = sppp_tx_done;
-	chan->rx_done = sppp_rx_done;
-	chan->usage=-1;
+	chan->setup_rx = cosa_net_setup_rx;
+	chan->tx_done = cosa_net_tx_done;
+	chan->rx_done = cosa_net_rx_done;
+	chan->usage = -1;
 	chan->cosa->usage++;
 	spin_unlock_irqrestore(&chan->cosa->lock, flags);
 
-	err = sppp_open(d);
+	err = hdlc_open(dev);
 	if (err) {
 		spin_lock_irqsave(&chan->cosa->lock, flags);
-		chan->usage=0;
+		chan->usage = 0;
 		chan->cosa->usage--;
-		
 		spin_unlock_irqrestore(&chan->cosa->lock, flags);
 		return err;
 	}
 
-	netif_start_queue(d);
+	netif_start_queue(dev);
 	cosa_enable_rx(chan);
 	return 0;
 }
 
-static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
+static int cosa_net_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	struct channel_data *chan = dev->ml_priv;
+	struct channel_data *chan = dev_to_chan(dev);
 
 	netif_stop_queue(dev);
 
@@ -700,16 +677,16 @@ static int cosa_sppp_tx(struct sk_buff *skb, struct net_device *dev)
 	return 0;
 }
 
-static void cosa_sppp_timeout(struct net_device *dev)
+static void cosa_net_timeout(struct net_device *dev)
 {
-	struct channel_data *chan = dev->ml_priv;
+	struct channel_data *chan = dev_to_chan(dev);
 
 	if (test_bit(RXBIT, &chan->cosa->rxtx)) {
-		chan->stats.rx_errors++;
-		chan->stats.rx_missed_errors++;
+		chan->netdev->stats.rx_errors++;
+		chan->netdev->stats.rx_missed_errors++;
 	} else {
-		chan->stats.tx_errors++;
-		chan->stats.tx_aborted_errors++;
+		chan->netdev->stats.tx_errors++;
+		chan->netdev->stats.tx_aborted_errors++;
 	}
 	cosa_kick(chan->cosa);
 	if (chan->tx_skb) {
@@ -719,13 +696,13 @@ static void cosa_sppp_timeout(struct net_device *dev)
 	netif_wake_queue(dev);
 }
 
-static int cosa_sppp_close(struct net_device *d)
+static int cosa_net_close(struct net_device *dev)
 {
-	struct channel_data *chan = d->ml_priv;
+	struct channel_data *chan = dev_to_chan(dev);
 	unsigned long flags;
 
-	netif_stop_queue(d);
-	sppp_close(d);
+	netif_stop_queue(dev);
+	hdlc_close(dev);
 	cosa_disable_rx(chan);
 	spin_lock_irqsave(&chan->cosa->lock, flags);
 	if (chan->rx_skb) {
@@ -736,13 +713,13 @@ static int cosa_sppp_close(struct net_device *d)
 		kfree_skb(chan->tx_skb);
 		chan->tx_skb = NULL;
 	}
-	chan->usage=0;
+	chan->usage = 0;
 	chan->cosa->usage--;
 	spin_unlock_irqrestore(&chan->cosa->lock, flags);
 	return 0;
 }
 
-static char *sppp_setup_rx(struct channel_data *chan, int size)
+static char *cosa_net_setup_rx(struct channel_data *chan, int size)
 {
 	/*
 	 * We can safely fall back to non-dma-able memory, because we have
@@ -754,66 +731,53 @@ static char *sppp_setup_rx(struct channel_data *chan, int size)
 	if (chan->rx_skb == NULL) {
 		printk(KERN_NOTICE "%s: Memory squeeze, dropping packet\n",
 			chan->name);
-		chan->stats.rx_dropped++;
+		chan->netdev->stats.rx_dropped++;
 		return NULL;
 	}
-	chan->pppdev.dev->trans_start = jiffies;
+	chan->netdev->trans_start = jiffies;
 	return skb_put(chan->rx_skb, size);
 }
 
-static int sppp_rx_done(struct channel_data *chan)
+static int cosa_net_rx_done(struct channel_data *chan)
 {
 	if (!chan->rx_skb) {
 		printk(KERN_WARNING "%s: rx_done with empty skb!\n",
 			chan->name);
-		chan->stats.rx_errors++;
-		chan->stats.rx_frame_errors++;
+		chan->netdev->stats.rx_errors++;
+		chan->netdev->stats.rx_frame_errors++;
 		return 0;
 	}
-	chan->rx_skb->protocol = htons(ETH_P_WAN_PPP);
-	chan->rx_skb->dev = chan->pppdev.dev;
+	chan->rx_skb->protocol = hdlc_type_trans(chan->rx_skb, chan->netdev);
+	chan->rx_skb->dev = chan->netdev;
 	skb_reset_mac_header(chan->rx_skb);
-	chan->stats.rx_packets++;
-	chan->stats.rx_bytes += chan->cosa->rxsize;
+	chan->netdev->stats.rx_packets++;
+	chan->netdev->stats.rx_bytes += chan->cosa->rxsize;
 	netif_rx(chan->rx_skb);
 	chan->rx_skb = NULL;
-	chan->pppdev.dev->last_rx = jiffies;
+	chan->netdev->last_rx = jiffies;
 	return 0;
 }
 
 /* ARGSUSED */
-static int sppp_tx_done(struct channel_data *chan, int size)
+static int cosa_net_tx_done(struct channel_data *chan, int size)
 {
 	if (!chan->tx_skb) {
 		printk(KERN_WARNING "%s: tx_done with empty skb!\n",
 			chan->name);
-		chan->stats.tx_errors++;
-		chan->stats.tx_aborted_errors++;
+		chan->netdev->stats.tx_errors++;
+		chan->netdev->stats.tx_aborted_errors++;
 		return 1;
 	}
 	dev_kfree_skb_irq(chan->tx_skb);
 	chan->tx_skb = NULL;
-	chan->stats.tx_packets++;
-	chan->stats.tx_bytes += size;
-	netif_wake_queue(chan->pppdev.dev);
+	chan->netdev->stats.tx_packets++;
+	chan->netdev->stats.tx_bytes += size;
+	netif_wake_queue(chan->netdev);
 	return 1;
 }
 
-static struct net_device_stats *cosa_net_stats(struct net_device *dev)
-{
-	struct channel_data *chan = dev->ml_priv;
-	return &chan->stats;
-}
-
-\f
 /*---------- Character device ---------- */
 
-static void chardev_channel_init(struct channel_data *chan)
-{
-	mutex_init(&chan->rlock);
-	init_MUTEX(&chan->wsem);
-}
-
 static ssize_t cosa_read(struct file *file,
 	char __user *buf, size_t count, loff_t *ppos)
 {
@@ -1223,16 +1187,15 @@ static int cosa_ioctl_common(struct cosa_data *cosa,
 	return -ENOIOCTLCMD;
 }
 
-static int cosa_sppp_ioctl(struct net_device *dev, struct ifreq *ifr,
-	int cmd)
+static int cosa_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	int rv;
-	struct channel_data *chan = dev->ml_priv;
-	rv = cosa_ioctl_common(chan->cosa, chan, cmd, (unsigned long)ifr->ifr_data);
-	if (rv == -ENOIOCTLCMD) {
-		return sppp_do_ioctl(dev, ifr, cmd);
-	}
-	return rv;
+	struct channel_data *chan = dev_to_chan(dev);
+	rv = cosa_ioctl_common(chan->cosa, chan, cmd,
+			       (unsigned long)ifr->ifr_data);
+	if (rv != -ENOIOCTLCMD)
+		return rv;
+	return hdlc_ioctl(dev, ifr, cmd);
 }
 
 static int cosa_chardev_ioctl(struct inode *inode, struct file *file,
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 50ef5b4..f5d55ad 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -103,7 +103,6 @@
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
 #include <linux/delay.h>
-#include <net/syncppp.h>
 #include <linux/hdlc.h>
 #include <linux/mutex.h>
 
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 754f008..9557ad0 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -47,10 +47,7 @@ MODULE_LICENSE("GPL");
 /*      Default parameters for the link
  */
 #define FST_TX_QUEUE_LEN        100	/* At 8Mbps a longer queue length is
-					 * useful, the syncppp module forces
-					 * this down assuming a slower line I
-					 * guess.
-					 */
+					 * useful */
 #define FST_TXQ_DEPTH           16	/* This one is for the buffering
 					 * of frames on the way down to the card
 					 * so that we can keep the card busy
diff --git a/drivers/net/wan/farsync.h b/drivers/net/wan/farsync.h
index d871daf..6b27e7c 100644
--- a/drivers/net/wan/farsync.h
+++ b/drivers/net/wan/farsync.h
@@ -54,9 +54,6 @@
 
 
 /*      Ioctl call command values
- *
- *      The first three private ioctls are used by the sync-PPP module,
- *      allowing a little room for expansion we start our numbering at 10.
  */
 #define FSTWRITE        (SIOCDEVPRIVATE+10)
 #define FSTCPURESET     (SIOCDEVPRIVATE+11)
@@ -202,9 +199,6 @@ struct fstioc_info {
 #define J1              7
 
 /* "proto" */
-#define FST_HDLC        1               /* Cisco compatible HDLC */
-#define FST_PPP         2               /* Sync PPP */
-#define FST_MONITOR     3               /* Monitor only (raw packet reception) */
 #define FST_RAW         4               /* Two way raw packets */
 #define FST_GEN_HDLC    5               /* Using "Generic HDLC" module */
 
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index e3a5364..1f2a140 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -22,20 +22,19 @@
  * - proto->start() and stop() are called with spin_lock_irq held.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
 #include <linux/errno.h>
+#include <linux/hdlc.h>
 #include <linux/if_arp.h>
+#include <linux/inetdevice.h>
 #include <linux/init.h>
-#include <linux/skbuff.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/notifier.h>
 #include <linux/pkt_sched.h>
-#include <linux/inetdevice.h>
-#include <linux/lapb.h>
+#include <linux/poll.h>
 #include <linux/rtnetlink.h>
-#include <linux/notifier.h>
-#include <linux/hdlc.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/net_namespace.h>
 
 
@@ -109,7 +108,7 @@ static int hdlc_device_event(struct notifier_block *this, unsigned long event,
 
 	if (dev->get_stats != hdlc_get_stats)
 		return NOTIFY_DONE; /* not an HDLC device */
- 
+
 	if (event != NETDEV_CHANGE)
 		return NOTIFY_DONE; /* Only interrested in carrier changes */
 
@@ -357,7 +356,7 @@ static struct packet_type hdlc_packet_type = {
 
 
 static struct notifier_block hdlc_notifier = {
-        .notifier_call = hdlc_device_event,
+	.notifier_call = hdlc_device_event,
 };
 
 
@@ -367,8 +366,8 @@ static int __init hdlc_module_init(void)
 
 	printk(KERN_INFO "%s\n", version);
 	if ((result = register_netdevice_notifier(&hdlc_notifier)) != 0)
-                return result;
-        dev_add_pack(&hdlc_packet_type);
+		return result;
+	dev_add_pack(&hdlc_packet_type);
 	return 0;
 }
 
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 849819c..44e64b1 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -9,19 +9,18 @@
  * as published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
 #include <linux/errno.h>
+#include <linux/hdlc.h>
 #include <linux/if_arp.h>
+#include <linux/inetdevice.h>
 #include <linux/init.h>
-#include <linux/skbuff.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pkt_sched.h>
-#include <linux/inetdevice.h>
-#include <linux/lapb.h>
+#include <linux/poll.h>
 #include <linux/rtnetlink.h>
-#include <linux/hdlc.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #undef DEBUG_HARD_HEADER
 
@@ -68,9 +67,9 @@ struct cisco_state {
 static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr);
 
 
-static inline struct cisco_state * state(hdlc_device *hdlc)
+static inline struct cisco_state* state(hdlc_device *hdlc)
 {
-	return(struct cisco_state *)(hdlc->state);
+	return (struct cisco_state *)hdlc->state;
 }
 
 
@@ -172,7 +171,7 @@ static int cisco_rx(struct sk_buff *skb)
 	    data->address != CISCO_UNICAST)
 		goto rx_error;
 
-	switch(ntohs(data->protocol)) {
+	switch (ntohs(data->protocol)) {
 	case CISCO_SYS_INFO:
 		/* Packet is not needed, drop it. */
 		dev_kfree_skb_any(skb);
@@ -336,7 +335,7 @@ static struct hdlc_proto proto = {
 static const struct header_ops cisco_header_ops = {
 	.create = cisco_hard_header,
 };
- 
+
 static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
 {
 	cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco;
@@ -359,10 +358,10 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
 		return 0;
 
 	case IF_PROTO_CISCO:
-		if(!capable(CAP_NET_ADMIN))
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
-		if(dev->flags & IFF_UP)
+		if (dev->flags & IFF_UP)
 			return -EBUSY;
 
 		if (copy_from_user(&new_settings, cisco_s, size))
@@ -372,7 +371,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
 		    new_settings.timeout < 2)
 			return -EINVAL;
 
-		result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
+		result = hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
 		if (result)
 			return result;
 
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 62e93da..d3d5055 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -33,20 +33,19 @@
 
 */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
 #include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/hdlc.h>
 #include <linux/if_arp.h>
+#include <linux/inetdevice.h>
 #include <linux/init.h>
-#include <linux/skbuff.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pkt_sched.h>
-#include <linux/inetdevice.h>
-#include <linux/lapb.h>
+#include <linux/poll.h>
 #include <linux/rtnetlink.h>
-#include <linux/etherdevice.h>
-#include <linux/hdlc.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
 
 #undef DEBUG_PKT
 #undef DEBUG_ECN
@@ -96,7 +95,7 @@ typedef struct {
 	unsigned ea1:	1;
 	unsigned cr:	1;
 	unsigned dlcih:	6;
-  
+
 	unsigned ea2:	1;
 	unsigned de:	1;
 	unsigned becn:	1;
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 0030833..4efe9e6 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -9,19 +9,18 @@
  * as published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
 #include <linux/errno.h>
+#include <linux/hdlc.h>
 #include <linux/if_arp.h>
+#include <linux/inetdevice.h>
 #include <linux/init.h>
-#include <linux/skbuff.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pkt_sched.h>
-#include <linux/inetdevice.h>
-#include <linux/lapb.h>
+#include <linux/poll.h>
 #include <linux/rtnetlink.h>
-#include <linux/hdlc.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/syncppp.h>
 
 struct ppp_state {
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index bbbb819..8612311 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -9,19 +9,18 @@
  * as published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
 #include <linux/errno.h>
+#include <linux/hdlc.h>
 #include <linux/if_arp.h>
+#include <linux/inetdevice.h>
 #include <linux/init.h>
-#include <linux/skbuff.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pkt_sched.h>
-#include <linux/inetdevice.h>
-#include <linux/lapb.h>
+#include <linux/poll.h>
 #include <linux/rtnetlink.h>
-#include <linux/hdlc.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
 
 
 static int raw_ioctl(struct net_device *dev, struct ifreq *ifr);
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index 26dee60..a13fc32 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -9,20 +9,19 @@
  * as published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
 #include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/hdlc.h>
 #include <linux/if_arp.h>
+#include <linux/inetdevice.h>
 #include <linux/init.h>
-#include <linux/skbuff.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/pkt_sched.h>
-#include <linux/inetdevice.h>
-#include <linux/lapb.h>
+#include <linux/poll.h>
 #include <linux/rtnetlink.h>
-#include <linux/etherdevice.h>
-#include <linux/hdlc.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
 
 static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr);
 
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index e808720..8b7e5d2 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -9,20 +9,19 @@
  * as published by the Free Software Foundation.
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/poll.h>
 #include <linux/errno.h>
+#include <linux/hdlc.h>
 #include <linux/if_arp.h>
-#include <linux/init.h>
-#include <linux/skbuff.h>
-#include <linux/pkt_sched.h>
 #include <linux/inetdevice.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/lapb.h>
+#include <linux/module.h>
+#include <linux/pkt_sched.h>
+#include <linux/poll.h>
 #include <linux/rtnetlink.h>
-#include <linux/hdlc.h>
-
+#include <linux/skbuff.h>
+#include <linux/slab.h>
 #include <net/x25device.h>
 
 static int x25_ioctl(struct net_device *dev, struct ifreq *ifr);
diff --git a/drivers/net/wan/hostess_sv11.c b/drivers/net/wan/hostess_sv11.c
index f3065d3..e299313 100644
--- a/drivers/net/wan/hostess_sv11.c
+++ b/drivers/net/wan/hostess_sv11.c
@@ -16,6 +16,8 @@
  *	touching control registers.
  *
  *	Port B isnt wired (why - beats me)
+ *
+ *	Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
  */
 
 #include <linux/module.h>
@@ -26,6 +28,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/delay.h>
+#include <linux/hdlc.h>
 #include <linux/ioport.h>
 #include <net/arp.h>
 
@@ -33,34 +36,31 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/byteorder.h>
-#include <net/syncppp.h>
 #include "z85230.h"
 
 static int dma;
 
-struct sv11_device
-{
-	void *if_ptr;	/* General purpose pointer (used by SPPP) */
-	struct z8530_dev sync;
-	struct ppp_device netdev;
-};
-
 /*
  *	Network driver support routines
  */
 
+static inline struct z8530_dev* dev_to_sv(struct net_device *dev)
+{
+	return (struct z8530_dev *)dev_to_hdlc(dev)->priv;
+}
+
 /*
- *	Frame receive. Simple for our card as we do sync ppp and there
+ *	Frame receive. Simple for our card as we do HDLC and there
  *	is no funny garbage involved
  */
- 
+
 static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
 {
 	/* Drop the CRC - it's not a good idea to try and negotiate it ;) */
-	skb_trim(skb, skb->len-2);
-	skb->protocol=__constant_htons(ETH_P_WAN_PPP);
+	skb_trim(skb, skb->len - 2);
+	skb->protocol = hdlc_type_trans(skb, c->netdevice);
 	skb_reset_mac_header(skb);
-	skb->dev=c->netdevice;
+	skb->dev = c->netdevice;
 	/*
 	 *	Send it to the PPP layer. We don't have time to process
 	 *	it right now.
@@ -68,56 +68,51 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
 	netif_rx(skb);
 	c->netdevice->last_rx = jiffies;
 }
- 
+
 /*
  *	We've been placed in the UP state
- */ 
- 
+ */
+
 static int hostess_open(struct net_device *d)
 {
-	struct sv11_device *sv11=d->ml_priv;
+	struct z8530_dev *sv11 = dev_to_sv(d);
 	int err = -1;
-	
+
 	/*
 	 *	Link layer up
 	 */
-	switch(dma)
-	{
+	switch (dma) {
 		case 0:
-			err=z8530_sync_open(d, &sv11->sync.chanA);
+			err = z8530_sync_open(d, &sv11->chanA);
 			break;
 		case 1:
-			err=z8530_sync_dma_open(d, &sv11->sync.chanA);
+			err = z8530_sync_dma_open(d, &sv11->chanA);
 			break;
 		case 2:
-			err=z8530_sync_txdma_open(d, &sv11->sync.chanA);
+			err = z8530_sync_txdma_open(d, &sv11->chanA);
 			break;
 	}
-	
-	if(err)
+
+	if (err)
 		return err;
-	/*
-	 *	Begin PPP
-	 */
-	err=sppp_open(d);
-	if(err)
-	{
-		switch(dma)
-		{
+
+	err = hdlc_open(d);
+	if (err) {
+		switch (dma) {
 			case 0:
-				z8530_sync_close(d, &sv11->sync.chanA);
+				z8530_sync_close(d, &sv11->chanA);
 				break;
 			case 1:
-				z8530_sync_dma_close(d, &sv11->sync.chanA);
+				z8530_sync_dma_close(d, &sv11->chanA);
 				break;
 			case 2:
-				z8530_sync_txdma_close(d, &sv11->sync.chanA);
+				z8530_sync_txdma_close(d, &sv11->chanA);
 				break;
-		}				
+		}
 		return err;
 	}
-	sv11->sync.chanA.rx_function=hostess_input;
-	
+	sv11->chanA.rx_function = hostess_input;
+
 	/*
 	 *	Go go go
 	 */
@@ -128,30 +123,24 @@ static int hostess_open(struct net_device *d)
 
 static int hostess_close(struct net_device *d)
 {
-	struct sv11_device *sv11=d->ml_priv;
+	struct z8530_dev *sv11 = dev_to_sv(d);
 	/*
 	 *	Discard new frames
 	 */
-	sv11->sync.chanA.rx_function=z8530_null_rx;
-	/*
-	 *	PPP off
-	 */
-	sppp_close(d);
-	/*
-	 *	Link layer down
-	 */
+	sv11->chanA.rx_function = z8530_null_rx;
+
+	hdlc_close(d);
 	netif_stop_queue(d);
-		
-	switch(dma)
-	{
+
+	switch (dma) {
 		case 0:
-			z8530_sync_close(d, &sv11->sync.chanA);
+			z8530_sync_close(d, &sv11->chanA);
 			break;
 		case 1:
-			z8530_sync_dma_close(d, &sv11->sync.chanA);
+			z8530_sync_dma_close(d, &sv11->chanA);
 			break;
 		case 2:
-			z8530_sync_txdma_close(d, &sv11->sync.chanA);
+			z8530_sync_txdma_close(d, &sv11->chanA);
 			break;
 	}
 	return 0;
@@ -159,232 +148,174 @@ static int hostess_close(struct net_device *d)
 
 static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
 {
-	/* struct sv11_device *sv11=d->ml_priv;
-	   z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */
-	return sppp_do_ioctl(d, ifr,cmd);
-}
-
-static struct net_device_stats *hostess_get_stats(struct net_device *d)
-{
-	struct sv11_device *sv11=d->ml_priv;
-	if(sv11)
-		return z8530_get_stats(&sv11->sync.chanA);
-	else
-		return NULL;
+	/* struct z8530_dev *sv11=dev_to_sv(d);
+	   z8530_ioctl(d,&sv11->chanA,ifr,cmd) */
+	return hdlc_ioctl(d, ifr, cmd);
 }
 
 /*
- *	Passed PPP frames, fire them downwind.
+ *	Passed network frames, fire them downwind.
  */
- 
+
 static int hostess_queue_xmit(struct sk_buff *skb, struct net_device *d)
 {
-	struct sv11_device *sv11=d->ml_priv;
-	return z8530_queue_xmit(&sv11->sync.chanA, skb);
+	return z8530_queue_xmit(&dev_to_sv(d)->chanA, skb);
 }
 
-static int hostess_neigh_setup(struct neighbour *n)
+static int hostess_attach(struct net_device *dev, unsigned short encoding,
+			  unsigned short parity)
 {
-	if (n->nud_state == NUD_NONE) {
-		n->ops = &arp_broken_ops;
-		n->output = n->ops->output;
-	}
-	return 0;
-}
-
-static int hostess_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
-{
-	if (p->tbl->family == AF_INET) {
-		p->neigh_setup = hostess_neigh_setup;
-		p->ucast_probes = 0;
-		p->mcast_probes = 0;
-	}
-	return 0;
-}
-
-static void sv11_setup(struct net_device *dev)
-{	
-	dev->open = hostess_open;
-	dev->stop = hostess_close;
-	dev->hard_start_xmit = hostess_queue_xmit;
-	dev->get_stats = hostess_get_stats;
-	dev->do_ioctl = hostess_ioctl;
-	dev->neigh_setup = hostess_neigh_setup_dev;
+	if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
+		return 0;
+	return -EINVAL;
 }
 
 /*
  *	Description block for a Comtrol Hostess SV11 card
  */
- 
-static struct sv11_device *sv11_init(int iobase, int irq)
+
+static struct z8530_dev *sv11_init(int iobase, int irq)
 {
-	struct z8530_dev *dev;
-	struct sv11_device *sv;
-	
+	struct z8530_dev *sv;
+	struct net_device *netdev;
 	/*
 	 *	Get the needed I/O space
 	 */
-	 
-	if(!request_region(iobase, 8, "Comtrol SV11"))
-	{	
-		printk(KERN_WARNING "hostess: I/O 0x%X already in use.\n", iobase);
+
+	if (!request_region(iobase, 8, "Comtrol SV11")) {
+		printk(KERN_WARNING "hostess: I/O 0x%X already in use.\n",
+		       iobase);
 		return NULL;
 	}
-	
-	sv = kzalloc(sizeof(struct sv11_device), GFP_KERNEL);
-	if(!sv)
-		goto fail3;
-			
-	sv->if_ptr=&sv->netdev;
-	
-	sv->netdev.dev = alloc_netdev(0, "hdlc%d", sv11_setup);
-	if(!sv->netdev.dev)
-		goto fail2;
-
-	dev=&sv->sync;
-	
+
+	sv = kzalloc(sizeof(struct z8530_dev), GFP_KERNEL);
+	if (!sv)
+		goto err_kzalloc;
+
 	/*
 	 *	Stuff in the I/O addressing
 	 */
-	 
-	dev->active = 0;
-	
-	dev->chanA.ctrlio=iobase+1;
-	dev->chanA.dataio=iobase+3;
-	dev->chanB.ctrlio=-1;
-	dev->chanB.dataio=-1;
-	dev->chanA.irqs=&z8530_nop;
-	dev->chanB.irqs=&z8530_nop;
-	
-	outb(0, iobase+4);		/* DMA off */
-	
+
+	sv->active = 0;
+
+	sv->chanA.ctrlio = iobase + 1;
+	sv->chanA.dataio = iobase + 3;
+	sv->chanB.ctrlio = -1;
+	sv->chanB.dataio = -1;
+	sv->chanA.irqs = &z8530_nop;
+	sv->chanB.irqs = &z8530_nop;
+
+	outb(0, iobase + 4);		/* DMA off */
+
 	/* We want a fast IRQ for this device. Actually we'd like an even faster
 	   IRQ ;) - This is one driver RtLinux is made for */
-	   
-	if(request_irq(irq, &z8530_interrupt, IRQF_DISABLED, "Hostess SV11", dev)<0)
-	{
+
+	if (request_irq(irq, &z8530_interrupt, IRQF_DISABLED,
+			"Hostess SV11", sv) < 0) {
 		printk(KERN_WARNING "hostess: IRQ %d already in use.\n", irq);
-		goto fail1;
+		goto err_irq;
 	}
-	
-	dev->irq=irq;
-	dev->chanA.private=sv;
-	dev->chanA.netdevice=sv->netdev.dev;
-	dev->chanA.dev=dev;
-	dev->chanB.dev=dev;
-	
-	if(dma)
-	{
+
+	sv->irq = irq;
+	sv->chanA.private = sv;
+	sv->chanA.dev = sv;
+	sv->chanB.dev = sv;
+
+	if (dma) {
 		/*
 		 *	You can have DMA off or 1 and 3 thats the lot
 		 *	on the Comtrol.
 		 */
-		dev->chanA.txdma=3;
-		dev->chanA.rxdma=1;
-		outb(0x03|0x08, iobase+4);		/* DMA on */
-		if(request_dma(dev->chanA.txdma, "Hostess SV/11 (TX)")!=0)
-			goto fail;
-			
-		if(dma==1)
-		{
-			if(request_dma(dev->chanA.rxdma, "Hostess SV/11 (RX)")!=0)
-				goto dmafail;
-		}
+		sv->chanA.txdma = 3;
+		sv->chanA.rxdma = 1;
+		outb(0x03 | 0x08, iobase + 4);		/* DMA on */
+		if (request_dma(sv->chanA.txdma, "Hostess SV/11 (TX)"))
+			goto err_txdma;
+
+		if (dma == 1)
+			if (request_dma(sv->chanA.rxdma, "Hostess SV/11 (RX)"))
+				goto err_rxdma;
 	}
 
 	/* Kill our private IRQ line the hostess can end up chattering
 	   until the configuration is set */
 	disable_irq(irq);
-		
+
 	/*
 	 *	Begin normal initialise
 	 */
-	 
-	if(z8530_init(dev)!=0)
-	{
+
+	if (z8530_init(sv)) {
 		printk(KERN_ERR "Z8530 series device not found.\n");
 		enable_irq(irq);
-		goto dmafail2;
+		goto free_dma;
 	}
-	z8530_channel_load(&dev->chanB, z8530_dead_port);
-	if(dev->type==Z85C30)
-		z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream);
+	z8530_channel_load(&sv->chanB, z8530_dead_port);
+	if (sv->type == Z85C30)
+		z8530_channel_load(&sv->chanA, z8530_hdlc_kilostream);
 	else
-		z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream_85230);
-	
+		z8530_channel_load(&sv->chanA, z8530_hdlc_kilostream_85230);
+
 	enable_irq(irq);
-	
 
 	/*
 	 *	Now we can take the IRQ
 	 */
-	if(dev_alloc_name(dev->chanA.netdevice,"hdlc%d")>=0)
-	{
-		struct net_device *d=dev->chanA.netdevice;
 
-		/* 
-		 *	Initialise the PPP components
-		 */
-		d->ml_priv = sv;
-		sppp_attach(&sv->netdev);
-		
-		/*
-		 *	Local fields
-		 */	
-		
-		d->base_addr = iobase;
-		d->irq = irq;
-		
-		if(register_netdev(d))
-		{
-			printk(KERN_ERR "%s: unable to register device.\n",
-				d->name);
-			sppp_detach(d);
-			goto dmafail2;
-		}
+	sv->chanA.netdevice = netdev = alloc_hdlcdev(sv);
+	if (!netdev)
+		goto free_dma;
 
-		z8530_describe(dev, "I/O", iobase);
-		dev->active=1;
-		return sv;	
+	dev_to_hdlc(netdev)->attach = hostess_attach;
+	dev_to_hdlc(netdev)->xmit = hostess_queue_xmit;
+	netdev->open = hostess_open;
+	netdev->stop = hostess_close;
+	netdev->do_ioctl = hostess_ioctl;
+	netdev->base_addr = iobase;
+	netdev->irq = irq;
+
+	if (register_hdlc_device(netdev)) {
+		printk(KERN_ERR "hostess: unable to register HDLC device.\n");
+		free_netdev(netdev);
+		goto free_dma;
 	}
-dmafail2:
-	if(dma==1)
-		free_dma(dev->chanA.rxdma);
-dmafail:
-	if(dma)
-		free_dma(dev->chanA.txdma);
-fail:
-	free_irq(irq, dev);
-fail1:
-	free_netdev(sv->netdev.dev);
-fail2:
+
+	z8530_describe(sv, "I/O", iobase);
+	sv->active = 1;
+	return sv;
+
+free_dma:
+	if (dma == 1)
+		free_dma(sv->chanA.rxdma);
+err_rxdma:
+	if (dma)
+		free_dma(sv->chanA.txdma);
+err_txdma:
+	free_irq(irq, sv);
+err_irq:
 	kfree(sv);
-fail3:
-	release_region(iobase,8);
+err_kzalloc:
+	release_region(iobase, 8);
 	return NULL;
 }
 
-static void sv11_shutdown(struct sv11_device *dev)
+static void sv11_shutdown(struct z8530_dev *dev)
 {
-	sppp_detach(dev->netdev.dev);
-	unregister_netdev(dev->netdev.dev);
-	z8530_shutdown(&dev->sync);
-	free_irq(dev->sync.irq, dev);
-	if(dma)
-	{
-		if(dma==1)
-			free_dma(dev->sync.chanA.rxdma);
-		free_dma(dev->sync.chanA.txdma);
+	unregister_hdlc_device(dev->chanA.netdevice);
+	z8530_shutdown(dev);
+	free_irq(dev->irq, dev);
+	if (dma) {
+		if (dma == 1)
+			free_dma(dev->chanA.rxdma);
+		free_dma(dev->chanA.txdma);
 	}
-	release_region(dev->sync.chanA.ctrlio-1, 8);
-	free_netdev(dev->netdev.dev);
+	release_region(dev->chanA.ctrlio - 1, 8);
+	free_netdev(dev->chanA.netdevice);
 	kfree(dev);
 }
 
-#ifdef MODULE
-
-static int io=0x200;
-static int irq=9;
+static int io = 0x200;
+static int irq = 9;
 
 module_param(io, int, 0);
 MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card");
@@ -397,22 +328,17 @@ MODULE_AUTHOR("Alan Cox");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11");
 
-static struct sv11_device *sv11_unit;
+static struct z8530_dev *sv11_unit;
 
 int init_module(void)
 {
-	printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.03.\n");
-	printk(KERN_INFO "(c) Copyright 2001, Red Hat Inc.\n");	
-	if((sv11_unit=sv11_init(io,irq))==NULL)
+	if ((sv11_unit = sv11_init(io, irq)) == NULL)
 		return -ENODEV;
 	return 0;
 }
 
 void cleanup_module(void)
 {
-	if(sv11_unit)
+	if (sv11_unit)
 		sv11_shutdown(sv11_unit);
 }
-
-#endif
-
diff --git a/drivers/net/wan/lmc/lmc.h b/drivers/net/wan/lmc/lmc.h
index 882e58c..4ced7ac 100644
--- a/drivers/net/wan/lmc/lmc.h
+++ b/drivers/net/wan/lmc/lmc.h
@@ -11,12 +11,12 @@ unsigned lmc_mii_readreg(lmc_softc_t * const sc, unsigned
       			  devaddr, unsigned regno);
 void lmc_mii_writereg(lmc_softc_t * const sc, unsigned devaddr,
 			       unsigned regno, unsigned data);
-void lmc_led_on(lmc_softc_t * const, u_int32_t);
-void lmc_led_off(lmc_softc_t * const, u_int32_t);
+void lmc_led_on(lmc_softc_t * const, u32);
+void lmc_led_off(lmc_softc_t * const, u32);
 unsigned lmc_mii_readreg(lmc_softc_t * const, unsigned, unsigned);
 void lmc_mii_writereg(lmc_softc_t * const, unsigned, unsigned, unsigned);
-void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits);
-void lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits);
+void lmc_gpio_mkinput(lmc_softc_t * const sc, u32 bits);
+void lmc_gpio_mkoutput(lmc_softc_t * const sc, u32 bits);
 
 int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 
@@ -26,8 +26,7 @@ extern lmc_media_t lmc_t1_media;
 extern lmc_media_t lmc_hssi_media;
 
 #ifdef _DBG_EVENTLOG
-static void lmcEventLog( u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3 );
+static void lmcEventLog(u32 EventNum, u32 arg2, u32 arg3);
 #endif
 
 #endif
-
diff --git a/drivers/net/wan/lmc/lmc_debug.c b/drivers/net/wan/lmc/lmc_debug.c
index 3b94352..15049d7 100644
--- a/drivers/net/wan/lmc/lmc_debug.c
+++ b/drivers/net/wan/lmc/lmc_debug.c
@@ -1,4 +1,3 @@
-
 #include <linux/types.h>
 #include <linux/netdevice.h>
 #include <linux/interrupt.h>
@@ -48,10 +47,10 @@ void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
 #endif
 
 #ifdef DEBUG
-u_int32_t lmcEventLogIndex = 0;
-u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
+u32 lmcEventLogIndex;
+u32 lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
 
-void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3)
+void lmcEventLog(u32 EventNum, u32 arg2, u32 arg3)
 {
   lmcEventLogBuf[lmcEventLogIndex++] = EventNum;
   lmcEventLogBuf[lmcEventLogIndex++] = arg2;
diff --git a/drivers/net/wan/lmc/lmc_debug.h b/drivers/net/wan/lmc/lmc_debug.h
index cf35638..2d46f12 100644
--- a/drivers/net/wan/lmc/lmc_debug.h
+++ b/drivers/net/wan/lmc/lmc_debug.h
@@ -38,15 +38,15 @@
 
 
 #ifdef DEBUG
-extern u_int32_t lmcEventLogIndex;
-extern u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
+extern u32 lmcEventLogIndex;
+extern u32 lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
 #define LMC_EVENT_LOG(x, y, z) lmcEventLog((x), (y), (z))
 #else
 #define LMC_EVENT_LOG(x,y,z)
 #endif /* end ifdef _DBG_EVENTLOG */
 
 void lmcConsoleLog(char *type, unsigned char *ucData, int iLen);
-void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3);
+void lmcEventLog(u32 EventNum, u32 arg2, u32 arg3);
 void lmc_trace(struct net_device *dev, char *msg);
 
 #endif
diff --git a/drivers/net/wan/lmc/lmc_ioctl.h b/drivers/net/wan/lmc/lmc_ioctl.h
index 57dd861..72fb113 100644
--- a/drivers/net/wan/lmc/lmc_ioctl.h
+++ b/drivers/net/wan/lmc/lmc_ioctl.h
@@ -61,7 +61,7 @@
 /*
  * IFTYPE defines
  */
-#define LMC_PPP         1               /* use sppp interface */
+#define LMC_PPP         1               /* use generic HDLC interface */
 #define LMC_NET         2               /* use direct net interface */
 #define LMC_RAW         3               /* use direct net interface */
 
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 62133ce..f80640f 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -1,6 +1,7 @@
  /*
   * Copyright (c) 1997-2000 LAN Media Corporation (LMC)
   * All rights reserved.  www.lanmedia.com
+  * Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
   *
   * This code is written by:
   * Andrew Stanley-Jones (asj@cban.com)
@@ -36,8 +37,6 @@
   *
   */
 
-/* $Id: lmc_main.c,v 1.36 2000/04/11 05:25:25 asj Exp $ */
-
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/string.h>
@@ -49,6 +48,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
+#include <linux/hdlc.h>
 #include <linux/init.h>
 #include <linux/in.h>
 #include <linux/if_arp.h>
@@ -57,9 +57,6 @@
 #include <linux/skbuff.h>
 #include <linux/inet.h>
 #include <linux/bitops.h>
-
-#include <net/syncppp.h>
-
 #include <asm/processor.h>             /* Processor type for cache alignment. */
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -78,8 +75,6 @@
 #include "lmc_debug.h"
 #include "lmc_proto.h"
 
-static int lmc_first_load = 0;
-
 static int LMC_PKT_BUF_SZ = 1542;
 
 static struct pci_device_id lmc_pci_tbl[] = {
@@ -91,11 +86,10 @@ static struct pci_device_id lmc_pci_tbl[] = {
 };
 
 MODULE_DEVICE_TABLE(pci, lmc_pci_tbl);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
 
 
 static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lmc_rx (struct net_device *dev);
 static int lmc_open(struct net_device *dev);
 static int lmc_close(struct net_device *dev);
@@ -114,20 +108,14 @@ static void lmc_driver_timeout(struct net_device *dev);
  * linux reserves 16 device specific IOCTLs.  We call them
  * LMCIOC* to control various bits of our world.
  */
-int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
+int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
 {
-    lmc_softc_t *sc;
+    lmc_softc_t *sc = dev_to_sc(dev);
     lmc_ctl_t ctl;
-    int ret;
-    u_int16_t regVal;
+    int ret = -EOPNOTSUPP;
+    u16 regVal;
     unsigned long flags;
 
-    struct sppp *sp;
-
-    ret = -EOPNOTSUPP;
-
-    sc = dev->priv;
-
     lmc_trace(dev, "lmc_ioctl in");
 
     /*
@@ -149,7 +137,6 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
         break;
 
     case LMCIOCSINFO: /*fold01*/
-        sp = &((struct ppp_device *) dev)->sppp;
         if (!capable(CAP_NET_ADMIN)) {
             ret = -EPERM;
             break;
@@ -175,25 +162,20 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
 		sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE;
         }
 
-        if (ctl.keepalive_onoff == LMC_CTL_OFF)
-            sp->pp_flags &= ~PP_KEEPALIVE;	/* Turn off */
-        else
-            sp->pp_flags |= PP_KEEPALIVE;	/* Turn on */
-
         ret = 0;
         break;
 
     case LMCIOCIFTYPE: /*fold01*/
         {
-            u_int16_t	old_type = sc->if_type;
-            u_int16_t	new_type;
+	    u16 old_type = sc->if_type;
+	    u16	new_type;
 
 	    if (!capable(CAP_NET_ADMIN)) {
 		ret = -EPERM;
 		break;
 	    }
 
-	    if (copy_from_user(&new_type, ifr->ifr_data, sizeof(u_int16_t))) {
+	    if (copy_from_user(&new_type, ifr->ifr_data, sizeof(u16))) {
 		ret = -EFAULT;
 		break;
 	    }
@@ -206,15 +188,11 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
             }
             
             lmc_proto_close(sc);
-            lmc_proto_detach(sc);
 
             sc->if_type = new_type;
-//            lmc_proto_init(sc);
             lmc_proto_attach(sc);
-            lmc_proto_open(sc);
-
-	    ret = 0 ;
-	    break ;
+	    ret = lmc_proto_open(sc);
+	    break;
 	}
 
     case LMCIOCGETXINFO: /*fold01*/
@@ -241,51 +219,53 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
 
         break;
 
-    case LMCIOCGETLMCSTATS: /*fold01*/
-        if (sc->lmc_cardtype == LMC_CARDTYPE_T1){
-            lmc_mii_writereg (sc, 0, 17, T1FRAMER_FERR_LSB);
-            sc->stats.framingBitErrorCount +=
-                lmc_mii_readreg (sc, 0, 18) & 0xff;
-            lmc_mii_writereg (sc, 0, 17, T1FRAMER_FERR_MSB);
-            sc->stats.framingBitErrorCount +=
-                (lmc_mii_readreg (sc, 0, 18) & 0xff) << 8;
-            lmc_mii_writereg (sc, 0, 17, T1FRAMER_LCV_LSB);
-            sc->stats.lineCodeViolationCount +=
-                lmc_mii_readreg (sc, 0, 18) & 0xff;
-            lmc_mii_writereg (sc, 0, 17, T1FRAMER_LCV_MSB);
-            sc->stats.lineCodeViolationCount +=
-                (lmc_mii_readreg (sc, 0, 18) & 0xff) << 8;
-            lmc_mii_writereg (sc, 0, 17, T1FRAMER_AERR);
-            regVal = lmc_mii_readreg (sc, 0, 18) & 0xff;
-
-            sc->stats.lossOfFrameCount +=
-                (regVal & T1FRAMER_LOF_MASK) >> 4;
-            sc->stats.changeOfFrameAlignmentCount +=
-                (regVal & T1FRAMER_COFA_MASK) >> 2;
-            sc->stats.severelyErroredFrameCount +=
-                regVal & T1FRAMER_SEF_MASK;
-        }
-
-        if (copy_to_user(ifr->ifr_data, &sc->stats,
-                         sizeof (struct lmc_statistics)))
-		ret = -EFAULT;
-	else
-		ret = 0;
-        break;
+    case LMCIOCGETLMCSTATS:
+	    if (sc->lmc_cardtype == LMC_CARDTYPE_T1) {
+		    lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_LSB);
+		    sc->extra_stats.framingBitErrorCount +=
+			    lmc_mii_readreg(sc, 0, 18) & 0xff;
+		    lmc_mii_writereg(sc, 0, 17, T1FRAMER_FERR_MSB);
+		    sc->extra_stats.framingBitErrorCount +=
+			    (lmc_mii_readreg(sc, 0, 18) & 0xff) << 8;
+		    lmc_mii_writereg(sc, 0, 17, T1FRAMER_LCV_LSB);
+		    sc->extra_stats.lineCodeViolationCount +=
+			    lmc_mii_readreg(sc, 0, 18) & 0xff;
+		    lmc_mii_writereg(sc, 0, 17, T1FRAMER_LCV_MSB);
+		    sc->extra_stats.lineCodeViolationCount +=
+			    (lmc_mii_readreg(sc, 0, 18) & 0xff) << 8;
+		    lmc_mii_writereg(sc, 0, 17, T1FRAMER_AERR);
+		    regVal = lmc_mii_readreg(sc, 0, 18) & 0xff;
+
+		    sc->extra_stats.lossOfFrameCount +=
+			    (regVal & T1FRAMER_LOF_MASK) >> 4;
+		    sc->extra_stats.changeOfFrameAlignmentCount +=
+			    (regVal & T1FRAMER_COFA_MASK) >> 2;
+		    sc->extra_stats.severelyErroredFrameCount +=
+			    regVal & T1FRAMER_SEF_MASK;
+	    }
+	    if (copy_to_user(ifr->ifr_data, &sc->lmc_device->stats,
+			     sizeof(sc->lmc_device->stats)) ||
+		copy_to_user(ifr->ifr_data + sizeof(sc->lmc_device->stats),
+			     &sc->extra_stats, sizeof(sc->extra_stats)))
+		    ret = -EFAULT;
+	    else
+		    ret = 0;
+	    break;
 
-    case LMCIOCCLEARLMCSTATS: /*fold01*/
-        if (!capable(CAP_NET_ADMIN)){
-            ret = -EPERM;
-            break;
-        }
+    case LMCIOCCLEARLMCSTATS:
+	    if (!capable(CAP_NET_ADMIN)) {
+		    ret = -EPERM;
+		    break;
+	    }
 
-        memset (&sc->stats, 0, sizeof (struct lmc_statistics));
-        sc->stats.check = STATCHECK;
-        sc->stats.version_size = (DRIVER_VERSION << 16) +
-            sizeof (struct lmc_statistics);
-        sc->stats.lmc_cardtype = sc->lmc_cardtype;
-        ret = 0;
-        break;
+	    memset(&sc->lmc_device->stats, 0, sizeof(sc->lmc_device->stats));
+	    memset(&sc->extra_stats, 0, sizeof(sc->extra_stats));
+	    sc->extra_stats.check = STATCHECK;
+	    sc->extra_stats.version_size = (DRIVER_VERSION << 16) +
+		    sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats);
+	    sc->extra_stats.lmc_cardtype = sc->lmc_cardtype;
+	    ret = 0;
+	    break;
 
     case LMCIOCSETCIRCUIT: /*fold01*/
         if (!capable(CAP_NET_ADMIN)){
@@ -330,7 +310,8 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
 		ret = -EFAULT;
 		break;
 	}
-        if (copy_to_user(ifr->ifr_data + sizeof (u32), lmcEventLogBuf, sizeof (lmcEventLogBuf)))
+	if (copy_to_user(ifr->ifr_data + sizeof(u32), lmcEventLogBuf,
+			 sizeof(lmcEventLogBuf)))
 		ret = -EFAULT;
 	else
 		ret = 0;
@@ -641,14 +622,12 @@ int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
 /* the watchdog process that cruises around */
 static void lmc_watchdog (unsigned long data) /*fold00*/
 {
-    struct net_device *dev = (struct net_device *) data;
-    lmc_softc_t *sc;
+    struct net_device *dev = (struct net_device *)data;
+    lmc_softc_t *sc = dev_to_sc(dev);
     int link_status;
-    u_int32_t ticks;
+    u32 ticks;
     unsigned long flags;
 
-    sc = dev->priv;
-
     lmc_trace(dev, "lmc_watchdog in");
 
     spin_lock_irqsave(&sc->lmc_lock, flags);
@@ -677,22 +656,22 @@ static void lmc_watchdog (unsigned long data) /*fold00*/
      * check for a transmit interrupt timeout
      * Has the packet xmt vs xmt serviced threshold been exceeded */
     if (sc->lmc_taint_tx == sc->lastlmc_taint_tx &&
-        sc->stats.tx_packets > sc->lasttx_packets &&
-        sc->tx_TimeoutInd == 0)
+	sc->lmc_device->stats.tx_packets > sc->lasttx_packets &&
+	sc->tx_TimeoutInd == 0)
     {
 
         /* wait for the watchdog to come around again */
         sc->tx_TimeoutInd = 1;
     }
     else if (sc->lmc_taint_tx == sc->lastlmc_taint_tx &&
-             sc->stats.tx_packets > sc->lasttx_packets &&
-             sc->tx_TimeoutInd)
+	     sc->lmc_device->stats.tx_packets > sc->lasttx_packets &&
+	     sc->tx_TimeoutInd)
     {
 
         LMC_EVENT_LOG(LMC_EVENT_XMTINTTMO, LMC_CSR_READ (sc, csr_status), 0);
 
         sc->tx_TimeoutDisplay = 1;
-        sc->stats.tx_TimeoutCnt++;
+	sc->extra_stats.tx_TimeoutCnt++;
 
         /* DEC chip is stuck, hit it with a RESET!!!! */
         lmc_running_reset (dev);
@@ -712,13 +691,11 @@ static void lmc_watchdog (unsigned long data) /*fold00*/
         /* reset the transmit timeout detection flag */
         sc->tx_TimeoutInd = 0;
         sc->lastlmc_taint_tx = sc->lmc_taint_tx;
-        sc->lasttx_packets = sc->stats.tx_packets;
-    }
-    else
-    {
+	sc->lasttx_packets = sc->lmc_device->stats.tx_packets;
+    } else {
         sc->tx_TimeoutInd = 0;
         sc->lastlmc_taint_tx = sc->lmc_taint_tx;
-        sc->lasttx_packets = sc->stats.tx_packets;
+	sc->lasttx_packets = sc->lmc_device->stats.tx_packets;
     }
 
     /* --- end time out check ----------------------------------- */
@@ -748,19 +725,7 @@ static void lmc_watchdog (unsigned long data) /*fold00*/
          sc->last_link_status = 1;
          /* lmc_reset (sc); Again why reset??? */
 
-         /* Inform the world that link protocol is back up. */
 	 netif_carrier_on(dev);
-
-         /* Now we have to tell the syncppp that we had an outage
-          * and that it should deal.  Calling sppp_reopen here
-          * should do the trick, but we may have to call sppp_close
-          * when the link goes down, and call sppp_open here.
-          * Subject to more testing.
-          * --bbraun
-          */
-
-         lmc_proto_reopen(sc);
-
      }
 
     /* Call media specific watchdog functions */
@@ -816,114 +781,93 @@ kick_timer:
 
 }
 
-static void lmc_setup(struct net_device * const dev) /*fold00*/
+static int lmc_attach(struct net_device *dev, unsigned short encoding,
+		      unsigned short parity)
 {
-    lmc_trace(dev, "lmc_setup in");
-
-    dev->type = ARPHRD_HDLC;
-    dev->hard_start_xmit = lmc_start_xmit;
-    dev->open = lmc_open;
-    dev->stop = lmc_close;
-    dev->get_stats = lmc_get_stats;
-    dev->do_ioctl = lmc_ioctl;
-    dev->tx_timeout = lmc_driver_timeout;
-    dev->watchdog_timeo = (HZ); /* 1 second */
-    
-    lmc_trace(dev, "lmc_setup out");
+	if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
+		return 0;
+	return -EINVAL;
 }
 
-
 static int __devinit lmc_init_one(struct pci_dev *pdev,
 				  const struct pci_device_id *ent)
 {
-    struct net_device *dev;
-    lmc_softc_t *sc;
-    u16 subdevice;
-    u_int16_t AdapModelNum;
-    int err = -ENOMEM;
-    static int cards_found;
-#ifndef GCOM
-    /* We name by type not by vendor */
-    static const char lmcname[] = "hdlc%d";
-#else
-    /* 
-     * GCOM uses LMC vendor name so that clients can know which card
-     * to attach to.
-     */
-    static const char lmcname[] = "lmc%d";
-#endif
-
-
-    /*
-     * Allocate our own device structure
-     */
-    dev = alloc_netdev(sizeof(lmc_softc_t), lmcname, lmc_setup);
-    if (!dev) {
-        printk (KERN_ERR "lmc:alloc_netdev for device failed\n");
-	goto out1;
-    }
- 
-    lmc_trace(dev, "lmc_init_one in");
-
-    err = pci_enable_device(pdev);
-    if (err) {
-	    printk(KERN_ERR "lmc: pci enable failed:%d\n", err);
-	    goto out2;
-    }
-    
-    if (pci_request_regions(pdev, "lmc")) {
-	    printk(KERN_ERR "lmc: pci_request_region failed\n");
-	    err = -EIO;
-	    goto out3;
-    }
-
-    pci_set_drvdata(pdev, dev);
-
-    if(lmc_first_load == 0){
-        printk(KERN_INFO "Lan Media Corporation WAN Driver Version %d.%d.%d\n",
-	       DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION,DRIVER_SUB_VERSION);
-        lmc_first_load = 1;
-    }
-    
-    sc = dev->priv;
-    sc->lmc_device = dev;
-    sc->name = dev->name;
-
-    /* Initialize the sppp layer */
-    /* An ioctl can cause a subsequent detach for raw frame interface */
-    dev->ml_priv = sc;
-    sc->if_type = LMC_PPP;
-    sc->check = 0xBEAFCAFE;
-    dev->base_addr = pci_resource_start(pdev, 0);
-    dev->irq = pdev->irq;
-
-    SET_NETDEV_DEV(dev, &pdev->dev);
-
-    /*
-     * This will get the protocol layer ready and do any 1 time init's
-     * Must have a valid sc and dev structure
-     */
-    lmc_proto_init(sc);
-
-    lmc_proto_attach(sc);
+	lmc_softc_t *sc;
+	struct net_device *dev;
+	u16 subdevice;
+	u16 AdapModelNum;
+	int err;
+	static int cards_found;
+
+	/* lmc_trace(dev, "lmc_init_one in"); */
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR "lmc: pci enable failed: %d\n", err);
+		return err;
+	}
 
-    /*
-     * Why were we changing this???
-     dev->tx_queue_len = 100;
-     */
+	err = pci_request_regions(pdev, "lmc");
+	if (err) {
+		printk(KERN_ERR "lmc: pci_request_region failed\n");
+		goto err_req_io;
+	}
 
-    /* Init the spin lock so can call it latter */
+	/*
+	 * Allocate our own device structure
+	 */
+	sc = kzalloc(sizeof(lmc_softc_t), GFP_KERNEL);
+	if (!sc) {
+		err = -ENOMEM;
+		goto err_kzalloc;
+	}
 
-    spin_lock_init(&sc->lmc_lock);
-    pci_set_master(pdev);
+	dev = alloc_hdlcdev(sc);
+	if (!dev) {
+		printk(KERN_ERR "lmc:alloc_netdev for device failed\n");
+		goto err_hdlcdev;
+	}
 
-    printk ("%s: detected at %lx, irq %d\n", dev->name,
-	    dev->base_addr, dev->irq);
 
-    if (register_netdev (dev) != 0) {
-        printk (KERN_ERR "%s: register_netdev failed.\n", dev->name);
-	goto out4;
-    }
+	dev->type = ARPHRD_HDLC;
+	dev_to_hdlc(dev)->xmit = lmc_start_xmit;
+	dev_to_hdlc(dev)->attach = lmc_attach;
+	dev->open = lmc_open;
+	dev->stop = lmc_close;
+	dev->get_stats = lmc_get_stats;
+	dev->do_ioctl = lmc_ioctl;
+	dev->tx_timeout = lmc_driver_timeout;
+	dev->watchdog_timeo = HZ; /* 1 second */
+	dev->tx_queue_len = 100;
+	sc->lmc_device = dev;
+	sc->name = dev->name;
+	sc->if_type = LMC_PPP;
+	sc->check = 0xBEAFCAFE;
+	dev->base_addr = pci_resource_start(pdev, 0);
+	dev->irq = pdev->irq;
+	pci_set_drvdata(pdev, dev);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
+	/*
+	 * This will get the protocol layer ready and do any 1 time init's
+	 * Must have a valid sc and dev structure
+	 */
+	lmc_proto_attach(sc);
+
+	/* Init the spin lock so can call it latter */
+
+	spin_lock_init(&sc->lmc_lock);
+	pci_set_master(pdev);
+
+	printk(KERN_INFO "%s: detected at %lx, irq %d\n", dev->name,
+	       dev->base_addr, dev->irq);
+
+	err = register_hdlc_device(dev);
+	if (err) {
+		printk(KERN_ERR "%s: register_netdev failed.\n", dev->name);
+		free_netdev(dev);
+		goto err_hdlcdev;
+	}
 
     sc->lmc_cardtype = LMC_CARDTYPE_UNKNOWN;
     sc->lmc_timing = LMC_CTL_CLOCK_SOURCE_EXT;
@@ -939,27 +883,27 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
 
     switch (subdevice) {
     case PCI_DEVICE_ID_LMC_HSSI:
-        printk ("%s: LMC HSSI\n", dev->name);
+	printk(KERN_INFO "%s: LMC HSSI\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_HSSI;
         sc->lmc_media = &lmc_hssi_media;
         break;
     case PCI_DEVICE_ID_LMC_DS3:
-        printk ("%s: LMC DS3\n", dev->name);
+	printk(KERN_INFO "%s: LMC DS3\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_DS3;
         sc->lmc_media = &lmc_ds3_media;
         break;
     case PCI_DEVICE_ID_LMC_SSI:
-        printk ("%s: LMC SSI\n", dev->name);
+	printk(KERN_INFO "%s: LMC SSI\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_SSI;
         sc->lmc_media = &lmc_ssi_media;
         break;
     case PCI_DEVICE_ID_LMC_T1:
-        printk ("%s: LMC T1\n", dev->name);
+	printk(KERN_INFO "%s: LMC T1\n", dev->name);
         sc->lmc_cardtype = LMC_CARDTYPE_T1;
         sc->lmc_media = &lmc_t1_media;
         break;
     default:
-        printk (KERN_WARNING "%s: LMC UNKOWN CARD!\n", dev->name);
+	printk(KERN_WARNING "%s: LMC UNKOWN CARD!\n", dev->name);
         break;
     }
 
@@ -977,32 +921,28 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
      */
     AdapModelNum = (lmc_mii_readreg (sc, 0, 3) & 0x3f0) >> 4;
 
-    if ((AdapModelNum == LMC_ADAP_T1
-         && subdevice == PCI_DEVICE_ID_LMC_T1) ||	/* detect LMC1200 */
-        (AdapModelNum == LMC_ADAP_SSI
-         && subdevice == PCI_DEVICE_ID_LMC_SSI) ||	/* detect LMC1000 */
-        (AdapModelNum == LMC_ADAP_DS3
-         && subdevice == PCI_DEVICE_ID_LMC_DS3) ||	/* detect LMC5245 */
-        (AdapModelNum == LMC_ADAP_HSSI
-         && subdevice == PCI_DEVICE_ID_LMC_HSSI))
-    {				/* detect LMC5200 */
+    if ((AdapModelNum != LMC_ADAP_T1 || /* detect LMC1200 */
+	 subdevice != PCI_DEVICE_ID_LMC_T1) &&
+	(AdapModelNum != LMC_ADAP_SSI || /* detect LMC1000 */
+	 subdevice != PCI_DEVICE_ID_LMC_SSI) &&
+	(AdapModelNum != LMC_ADAP_DS3 || /* detect LMC5245 */
+	 subdevice != PCI_DEVICE_ID_LMC_DS3) &&
+	(AdapModelNum != LMC_ADAP_HSSI || /* detect LMC5200 */
+	 subdevice != PCI_DEVICE_ID_LMC_HSSI))
+	    printk(KERN_WARNING "%s: Model number (%d) miscompare for PCI"
+		   " Subsystem ID = 0x%04x\n",
+		   dev->name, AdapModelNum, subdevice);
 
-    }
-    else {
-        printk ("%s: Model number (%d) miscompare for PCI Subsystem ID = 0x%04x\n",
-                dev->name, AdapModelNum, subdevice);
-//        return (NULL);
-    }
     /*
      * reset clock
      */
     LMC_CSR_WRITE (sc, csr_gp_timer, 0xFFFFFFFFUL);
 
     sc->board_idx = cards_found++;
-    sc->stats.check = STATCHECK;
-    sc->stats.version_size = (DRIVER_VERSION << 16) +
-        sizeof (struct lmc_statistics);
-    sc->stats.lmc_cardtype = sc->lmc_cardtype;
+    sc->extra_stats.check = STATCHECK;
+    sc->extra_stats.version_size = (DRIVER_VERSION << 16) +
+	    sizeof(sc->lmc_device->stats) + sizeof(sc->extra_stats);
+    sc->extra_stats.lmc_cardtype = sc->lmc_cardtype;
 
     sc->lmc_ok = 0;
     sc->last_link_status = 0;
@@ -1010,58 +950,51 @@ static int __devinit lmc_init_one(struct pci_dev *pdev,
     lmc_trace(dev, "lmc_init_one out");
     return 0;
 
- out4:
-    lmc_proto_detach(sc);
- out3:
-    if (pdev) {
-	    pci_release_regions(pdev);
-	    pci_set_drvdata(pdev, NULL);
-    }
- out2:
-    free_netdev(dev);
- out1:
-    return err;
+err_hdlcdev:
+	pci_set_drvdata(pdev, NULL);
+	kfree(sc);
+err_kzalloc:
+	pci_release_regions(pdev);
+err_req_io:
+	pci_disable_device(pdev);
+	return err;
 }
 
 /*
  * Called from pci when removing module.
  */
-static void __devexit lmc_remove_one (struct pci_dev *pdev)
+static void __devexit lmc_remove_one(struct pci_dev *pdev)
 {
-    struct net_device *dev = pci_get_drvdata(pdev);
-    
-    if (dev) {
-	    lmc_softc_t *sc = dev->priv;
-	    
-	    printk("%s: removing...\n", dev->name);
-	    lmc_proto_detach(sc);
-	    unregister_netdev(dev);
-	    free_netdev(dev);
-	    pci_release_regions(pdev);
-	    pci_disable_device(pdev);
-	    pci_set_drvdata(pdev, NULL);
-    }
+	struct net_device *dev = pci_get_drvdata(pdev);
+
+	if (dev) {
+		printk(KERN_DEBUG "%s: removing...\n", dev->name);
+		unregister_hdlc_device(dev);
+		free_netdev(dev);
+		pci_release_regions(pdev);
+		pci_disable_device(pdev);
+		pci_set_drvdata(pdev, NULL);
+	}
 }
 
 /* After this is called, packets can be sent.
  * Does not initialize the addresses
  */
-static int lmc_open (struct net_device *dev) /*fold00*/
+static int lmc_open(struct net_device *dev)
 {
-    lmc_softc_t *sc = dev->priv;
+    lmc_softc_t *sc = dev_to_sc(dev);
+    int err;
 
     lmc_trace(dev, "lmc_open in");
 
     lmc_led_on(sc, LMC_DS3_LED0);
 
-    lmc_dec_reset (sc);
-    lmc_reset (sc);
-
-    LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ (sc, csr_status), 0);
-    LMC_EVENT_LOG(LMC_EVENT_RESET2,
-                  lmc_mii_readreg (sc, 0, 16),
-                  lmc_mii_readreg (sc, 0, 17));
+    lmc_dec_reset(sc);
+    lmc_reset(sc);
 
+    LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ(sc, csr_status), 0);
+    LMC_EVENT_LOG(LMC_EVENT_RESET2, lmc_mii_readreg(sc, 0, 16),
+		  lmc_mii_readreg(sc, 0, 17));
 
     if (sc->lmc_ok){
         lmc_trace(dev, "lmc_open lmc_ok out");
@@ -1106,14 +1039,14 @@ static int lmc_open (struct net_device *dev) /*fold00*/
 
     /* dev->flags |= IFF_UP; */
 
-    lmc_proto_open(sc);
+    if ((err = lmc_proto_open(sc)) != 0)
+	    return err;
 
     dev->do_ioctl = lmc_ioctl;
 
 
     netif_start_queue(dev);
-    
-    sc->stats.tx_tbusy0++ ;
+    sc->extra_stats.tx_tbusy0++;
 
     /*
      * select what interrupts we want to get
@@ -1165,8 +1098,7 @@ static int lmc_open (struct net_device *dev) /*fold00*/
 
 static void lmc_running_reset (struct net_device *dev) /*fold00*/
 {
-
-    lmc_softc_t *sc = (lmc_softc_t *) dev->priv;
+    lmc_softc_t *sc = dev_to_sc(dev);
 
     lmc_trace(dev, "lmc_runnig_reset in");
 
@@ -1184,7 +1116,7 @@ static void lmc_running_reset (struct net_device *dev) /*fold00*/
     netif_wake_queue(dev);
 
     sc->lmc_txfull = 0;
-    sc->stats.tx_tbusy0++ ;
+    sc->extra_stats.tx_tbusy0++;
 
     sc->lmc_intrmask = TULIP_DEFAULT_INTR_MASK;
     LMC_CSR_WRITE (sc, csr_intr, sc->lmc_intrmask);
@@ -1200,14 +1132,13 @@ static void lmc_running_reset (struct net_device *dev) /*fold00*/
  * This disables the timer for the watchdog and keepalives,
  * and disables the irq for dev.
  */
-static int lmc_close (struct net_device *dev) /*fold00*/
+static int lmc_close(struct net_device *dev)
 {
     /* not calling release_region() as we should */
-    lmc_softc_t *sc;
+    lmc_softc_t *sc = dev_to_sc(dev);
 
     lmc_trace(dev, "lmc_close in");
-    
-    sc = dev->priv;
+
     sc->lmc_ok = 0;
     sc->lmc_media->set_link_status (sc, 0);
     del_timer (&sc->timer);
@@ -1215,7 +1146,7 @@ static int lmc_close (struct net_device *dev) /*fold00*/
     lmc_ifdown (dev);
 
     lmc_trace(dev, "lmc_close out");
-    
+
     return 0;
 }
 
@@ -1223,16 +1154,16 @@ static int lmc_close (struct net_device *dev) /*fold00*/
 /* When the interface goes down, this is called */
 static int lmc_ifdown (struct net_device *dev) /*fold00*/
 {
-    lmc_softc_t *sc = dev->priv;
+    lmc_softc_t *sc = dev_to_sc(dev);
     u32 csr6;
     int i;
 
     lmc_trace(dev, "lmc_ifdown in");
-    
+
     /* Don't let anything else go on right now */
     //    dev->start = 0;
     netif_stop_queue(dev);
-    sc->stats.tx_tbusy1++ ;
+    sc->extra_stats.tx_tbusy1++;
 
     /* stop interrupts */
     /* Clear the interrupt mask */
@@ -1244,8 +1175,8 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/
     csr6 &= ~LMC_DEC_SR;		/* Turn off the Receive bit */
     LMC_CSR_WRITE (sc, csr_command, csr6);
 
-    sc->stats.rx_missed_errors +=
-        LMC_CSR_READ (sc, csr_missed_frames) & 0xffff;
+    sc->lmc_device->stats.rx_missed_errors +=
+	    LMC_CSR_READ(sc, csr_missed_frames) & 0xffff;
 
     /* release the interrupt */
     if(sc->got_irq == 1){
@@ -1276,7 +1207,7 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/
     lmc_led_off (sc, LMC_MII16_LED_ALL);
 
     netif_wake_queue(dev);
-    sc->stats.tx_tbusy0++ ;
+    sc->extra_stats.tx_tbusy0++;
 
     lmc_trace(dev, "lmc_ifdown out");
 
@@ -1289,7 +1220,7 @@ static int lmc_ifdown (struct net_device *dev) /*fold00*/
 static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
 {
     struct net_device *dev = (struct net_device *) dev_instance;
-    lmc_softc_t *sc;
+    lmc_softc_t *sc = dev_to_sc(dev);
     u32 csr;
     int i;
     s32 stat;
@@ -1300,8 +1231,6 @@ static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
 
     lmc_trace(dev, "lmc_interrupt in");
 
-    sc = dev->priv;
-    
     spin_lock(&sc->lmc_lock);
 
     /*
@@ -1354,7 +1283,7 @@ static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
 
 	    int		n_compl = 0 ;
             /* reset the transmit timeout detection flag -baz */
-            sc->stats.tx_NoCompleteCnt = 0;
+	    sc->extra_stats.tx_NoCompleteCnt = 0;
 
             badtx = sc->lmc_taint_tx;
             i = badtx % LMC_TXDESCS;
@@ -1378,27 +1307,25 @@ static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
                 if (sc->lmc_txq[i] == NULL)
                     continue;
 
-                /*
-                 * Check the total error summary to look for any errors
-                 */
-                if (stat & 0x8000) {
-                    sc->stats.tx_errors++;
-                    if (stat & 0x4104)
-                        sc->stats.tx_aborted_errors++;
-                    if (stat & 0x0C00)
-                        sc->stats.tx_carrier_errors++;
-                    if (stat & 0x0200)
-                        sc->stats.tx_window_errors++;
-                    if (stat & 0x0002)
-                        sc->stats.tx_fifo_errors++;
-                }
-                else {
-                    
-                    sc->stats.tx_bytes += sc->lmc_txring[i].length & 0x7ff;
-                    
-                    sc->stats.tx_packets++;
+		/*
+		 * Check the total error summary to look for any errors
+		 */
+		if (stat & 0x8000) {
+			sc->lmc_device->stats.tx_errors++;
+			if (stat & 0x4104)
+				sc->lmc_device->stats.tx_aborted_errors++;
+			if (stat & 0x0C00)
+				sc->lmc_device->stats.tx_carrier_errors++;
+			if (stat & 0x0200)
+				sc->lmc_device->stats.tx_window_errors++;
+			if (stat & 0x0002)
+				sc->lmc_device->stats.tx_fifo_errors++;
+		} else {
+			sc->lmc_device->stats.tx_bytes += sc->lmc_txring[i].length & 0x7ff;
+
+			sc->lmc_device->stats.tx_packets++;
                 }
-                
+
                 //                dev_kfree_skb(sc->lmc_txq[i]);
                 dev_kfree_skb_irq(sc->lmc_txq[i]);
                 sc->lmc_txq[i] = NULL;
@@ -1415,13 +1342,13 @@ static irqreturn_t lmc_interrupt (int irq, void *dev_instance) /*fold00*/
             LMC_EVENT_LOG(LMC_EVENT_TBUSY0, n_compl, 0);
             sc->lmc_txfull = 0;
             netif_wake_queue(dev);
-            sc->stats.tx_tbusy0++ ;
+	    sc->extra_stats.tx_tbusy0++;
 
 
 #ifdef DEBUG
-            sc->stats.dirtyTx = badtx;
-            sc->stats.lmc_next_tx = sc->lmc_next_tx;
-            sc->stats.lmc_txfull = sc->lmc_txfull;
+	    sc->extra_stats.dirtyTx = badtx;
+	    sc->extra_stats.lmc_next_tx = sc->lmc_next_tx;
+	    sc->extra_stats.lmc_txfull = sc->lmc_txfull;
 #endif
             sc->lmc_taint_tx = badtx;
 
@@ -1476,9 +1403,9 @@ lmc_int_fail_out:
     return IRQ_RETVAL(handled);
 }
 
-static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00*/
+static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-    lmc_softc_t *sc;
+    lmc_softc_t *sc = dev_to_sc(dev);
     u32 flag;
     int entry;
     int ret = 0;
@@ -1486,8 +1413,6 @@ static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00
 
     lmc_trace(dev, "lmc_start_xmit in");
 
-    sc = dev->priv;
-
     spin_lock_irqsave(&sc->lmc_lock, flags);
 
     /* normal path, tbusy known to be zero */
@@ -1532,8 +1457,8 @@ static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00
     if (sc->lmc_next_tx - sc->lmc_taint_tx >= LMC_TXDESCS - 1)
     {				/* ring full, go busy */
         sc->lmc_txfull = 1;
-        netif_stop_queue(dev);
-        sc->stats.tx_tbusy1++ ;
+	netif_stop_queue(dev);
+	sc->extra_stats.tx_tbusy1++;
         LMC_EVENT_LOG(LMC_EVENT_TBUSY1, entry, 0);
     }
 #endif
@@ -1550,7 +1475,7 @@ static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00
      * the watchdog timer handler. -baz
      */
 
-    sc->stats.tx_NoCompleteCnt++;
+    sc->extra_stats.tx_NoCompleteCnt++;
     sc->lmc_next_tx++;
 
     /* give ownership to the chip */
@@ -1569,9 +1494,9 @@ static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00
 }
 
 
-static int lmc_rx (struct net_device *dev) /*fold00*/
+static int lmc_rx(struct net_device *dev)
 {
-    lmc_softc_t *sc;
+    lmc_softc_t *sc = dev_to_sc(dev);
     int i;
     int rx_work_limit = LMC_RXDESCS;
     unsigned int next_rx;
@@ -1583,8 +1508,6 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
 
     lmc_trace(dev, "lmc_rx in");
 
-    sc = dev->priv;
-
     lmc_led_on(sc, LMC_DS3_LED3);
 
     rxIntLoopCnt = 0;		/* debug -baz */
@@ -1597,39 +1520,38 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
         rxIntLoopCnt++;		/* debug -baz */
         len = ((stat & LMC_RDES_FRAME_LENGTH) >> RDES_FRAME_LENGTH_BIT_NUMBER);
         if ((stat & 0x0300) != 0x0300) {  /* Check first segment and last segment */
-            if ((stat & 0x0000ffff) != 0x7fff) {
-                /* Oversized frame */
-                sc->stats.rx_length_errors++;
-                goto skip_packet;
-            }
-        }
-
-        if(stat & 0x00000008){ /* Catch a dribbling bit error */
-            sc->stats.rx_errors++;
-            sc->stats.rx_frame_errors++;
-            goto skip_packet;
-        }
+		if ((stat & 0x0000ffff) != 0x7fff) {
+			/* Oversized frame */
+			sc->lmc_device->stats.rx_length_errors++;
+			goto skip_packet;
+		}
+	}
 
+	if (stat & 0x00000008) { /* Catch a dribbling bit error */
+		sc->lmc_device->stats.rx_errors++;
+		sc->lmc_device->stats.rx_frame_errors++;
+		goto skip_packet;
+	}
 
-        if(stat & 0x00000004){ /* Catch a CRC error by the Xilinx */
-            sc->stats.rx_errors++;
-            sc->stats.rx_crc_errors++;
-            goto skip_packet;
-        }
 
+	if (stat & 0x00000004) { /* Catch a CRC error by the Xilinx */
+		sc->lmc_device->stats.rx_errors++;
+		sc->lmc_device->stats.rx_crc_errors++;
+		goto skip_packet;
+	}
 
-        if (len > LMC_PKT_BUF_SZ){
-            sc->stats.rx_length_errors++;
-            localLengthErrCnt++;
-            goto skip_packet;
-        }
+	if (len > LMC_PKT_BUF_SZ) {
+		sc->lmc_device->stats.rx_length_errors++;
+		localLengthErrCnt++;
+		goto skip_packet;
+	}
 
-        if (len < sc->lmc_crcSize + 2) {
-            sc->stats.rx_length_errors++;
-            sc->stats.rx_SmallPktCnt++;
-            localLengthErrCnt++;
-            goto skip_packet;
-        }
+	if (len < sc->lmc_crcSize + 2) {
+		sc->lmc_device->stats.rx_length_errors++;
+		sc->extra_stats.rx_SmallPktCnt++;
+		localLengthErrCnt++;
+		goto skip_packet;
+	}
 
         if(stat & 0x00004000){
             printk(KERN_WARNING "%s: Receiver descriptor error, receiver out of sync?\n", dev->name);
@@ -1656,8 +1578,8 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
         }
         
         dev->last_rx = jiffies;
-        sc->stats.rx_packets++;
-        sc->stats.rx_bytes += len;
+	sc->lmc_device->stats.rx_packets++;
+	sc->lmc_device->stats.rx_bytes += len;
 
         LMC_CONSOLE_LOG("recv", skb->data, len);
 
@@ -1679,7 +1601,6 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
 
             skb_put (skb, len);
             skb->protocol = lmc_proto_type(sc, skb);
-            skb->protocol = htons(ETH_P_WAN_PPP);
             skb_reset_mac_header(skb);
             /* skb_reset_network_header(skb); */
             skb->dev = dev;
@@ -1704,7 +1625,7 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
                  * in which care we'll try to allocate the buffer
                  * again.  (once a second)
                  */
-                sc->stats.rx_BuffAllocErr++;
+		sc->extra_stats.rx_BuffAllocErr++;
                 LMC_EVENT_LOG(LMC_EVENT_RCVINT, stat, len);
                 sc->failed_recv_alloc = 1;
                 goto skip_out_of_mem;
@@ -1739,16 +1660,14 @@ static int lmc_rx (struct net_device *dev) /*fold00*/
      * descriptors with bogus packets
      *
     if (localLengthErrCnt > LMC_RXDESCS - 3) {
-        sc->stats.rx_BadPktSurgeCnt++;
-        LMC_EVENT_LOG(LMC_EVENT_BADPKTSURGE,
-                      localLengthErrCnt,
-                      sc->stats.rx_BadPktSurgeCnt);
+	sc->extra_stats.rx_BadPktSurgeCnt++;
+	LMC_EVENT_LOG(LMC_EVENT_BADPKTSURGE, localLengthErrCnt,
+		      sc->extra_stats.rx_BadPktSurgeCnt);
     } */
 
     /* save max count of receive descriptors serviced */
-    if (rxIntLoopCnt > sc->stats.rxIntLoopCnt) {
-        sc->stats.rxIntLoopCnt = rxIntLoopCnt;	/* debug -baz */
-    }
+    if (rxIntLoopCnt > sc->extra_stats.rxIntLoopCnt)
+	    sc->extra_stats.rxIntLoopCnt = rxIntLoopCnt; /* debug -baz */
 
 #ifdef DEBUG
     if (rxIntLoopCnt == 0)
@@ -1775,23 +1694,22 @@ skip_out_of_mem:
     return 0;
 }
 
-static struct net_device_stats *lmc_get_stats (struct net_device *dev) /*fold00*/
+static struct net_device_stats *lmc_get_stats(struct net_device *dev)
 {
-    lmc_softc_t *sc = dev->priv;
+    lmc_softc_t *sc = dev_to_sc(dev);
     unsigned long flags;
 
     lmc_trace(dev, "lmc_get_stats in");
 
-
     spin_lock_irqsave(&sc->lmc_lock, flags);
 
-    sc->stats.rx_missed_errors += LMC_CSR_READ (sc, csr_missed_frames) & 0xffff;
+    sc->lmc_device->stats.rx_missed_errors += LMC_CSR_READ(sc, csr_missed_frames) & 0xffff;
 
     spin_unlock_irqrestore(&sc->lmc_lock, flags);
 
     lmc_trace(dev, "lmc_get_stats out");
 
-    return (struct net_device_stats *) &sc->stats;
+    return &sc->lmc_device->stats;
 }
 
 static struct pci_driver lmc_driver = {
@@ -1970,7 +1888,7 @@ static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/
     {
         if (sc->lmc_txq[i] != NULL){		/* have buffer */
             dev_kfree_skb(sc->lmc_txq[i]);	/* free it */
-            sc->stats.tx_dropped++;      /* We just dropped a packet */
+	    sc->lmc_device->stats.tx_dropped++;	/* We just dropped a packet */
         }
         sc->lmc_txq[i] = NULL;
         sc->lmc_txring[i].status = 0x00000000;
@@ -1982,7 +1900,7 @@ static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/
     lmc_trace(sc->lmc_device, "lmc_softreset out");
 }
 
-void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/
+void lmc_gpio_mkinput(lmc_softc_t * const sc, u32 bits) /*fold00*/
 {
     lmc_trace(sc->lmc_device, "lmc_gpio_mkinput in");
     sc->lmc_gpio_io &= ~bits;
@@ -1990,7 +1908,7 @@ void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/
     lmc_trace(sc->lmc_device, "lmc_gpio_mkinput out");
 }
 
-void lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/
+void lmc_gpio_mkoutput(lmc_softc_t * const sc, u32 bits) /*fold00*/
 {
     lmc_trace(sc->lmc_device, "lmc_gpio_mkoutput in");
     sc->lmc_gpio_io |= bits;
@@ -1998,7 +1916,7 @@ void lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/
     lmc_trace(sc->lmc_device, "lmc_gpio_mkoutput out");
 }
 
-void lmc_led_on(lmc_softc_t * const sc, u_int32_t led) /*fold00*/
+void lmc_led_on(lmc_softc_t * const sc, u32 led) /*fold00*/
 {
     lmc_trace(sc->lmc_device, "lmc_led_on in");
     if((~sc->lmc_miireg16) & led){ /* Already on! */
@@ -2011,7 +1929,7 @@ void lmc_led_on(lmc_softc_t * const sc, u_int32_t led) /*fold00*/
     lmc_trace(sc->lmc_device, "lmc_led_on out");
 }
 
-void lmc_led_off(lmc_softc_t * const sc, u_int32_t led) /*fold00*/
+void lmc_led_off(lmc_softc_t * const sc, u32 led) /*fold00*/
 {
     lmc_trace(sc->lmc_device, "lmc_led_off in");
     if(sc->lmc_miireg16 & led){ /* Already set don't do anything */
@@ -2061,13 +1979,13 @@ static void lmc_reset(lmc_softc_t * const sc) /*fold00*/
      */
     sc->lmc_media->init(sc);
 
-    sc->stats.resetCount++;
+    sc->extra_stats.resetCount++;
     lmc_trace(sc->lmc_device, "lmc_reset out");
 }
 
 static void lmc_dec_reset(lmc_softc_t * const sc) /*fold00*/
 {
-    u_int32_t val;
+    u32 val;
     lmc_trace(sc->lmc_device, "lmc_dec_reset in");
 
     /*
@@ -2151,23 +2069,21 @@ static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base, /*fold00
     lmc_trace(sc->lmc_device, "lmc_initcsrs out");
 }
 
-static void lmc_driver_timeout(struct net_device *dev) { /*fold00*/
-    lmc_softc_t *sc;
+static void lmc_driver_timeout(struct net_device *dev)
+{
+    lmc_softc_t *sc = dev_to_sc(dev);
     u32 csr6;
     unsigned long flags;
 
     lmc_trace(dev, "lmc_driver_timeout in");
 
-    sc = dev->priv;
-
     spin_lock_irqsave(&sc->lmc_lock, flags);
 
     printk("%s: Xmitter busy|\n", dev->name);
 
-    sc->stats.tx_tbusy_calls++ ;
-    if (jiffies - dev->trans_start < TX_TIMEOUT) {
-        goto bug_out;
-    }
+    sc->extra_stats.tx_tbusy_calls++;
+    if (jiffies - dev->trans_start < TX_TIMEOUT)
+	    goto bug_out;
 
     /*
      * Chip seems to have locked up
@@ -2178,7 +2094,7 @@ static void lmc_driver_timeout(struct net_device *dev) { /*fold00*/
 
     LMC_EVENT_LOG(LMC_EVENT_XMTPRCTMO,
                   LMC_CSR_READ (sc, csr_status),
-                  sc->stats.tx_ProcTimeout);
+		  sc->extra_stats.tx_ProcTimeout);
 
     lmc_running_reset (dev);
 
@@ -2195,8 +2111,8 @@ static void lmc_driver_timeout(struct net_device *dev) { /*fold00*/
     /* immediate transmit */
     LMC_CSR_WRITE (sc, csr_txpoll, 0);
 
-    sc->stats.tx_errors++;
-    sc->stats.tx_ProcTimeout++;	/* -baz */
+    sc->lmc_device->stats.tx_errors++;
+    sc->extra_stats.tx_ProcTimeout++; /* -baz */
 
     dev->trans_start = jiffies;
 
diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c
index 8aa461c..f327674 100644
--- a/drivers/net/wan/lmc/lmc_media.c
+++ b/drivers/net/wan/lmc/lmc_media.c
@@ -16,8 +16,6 @@
 #include <linux/inet.h>
 #include <linux/bitops.h>
 
-#include <net/syncppp.h>
-
 #include <asm/processor.h>             /* Processor type for cache alignment. */
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -95,8 +93,7 @@ static void lmc_dummy_set_1 (lmc_softc_t * const, int);
 static void lmc_dummy_set2_1 (lmc_softc_t * const, lmc_ctl_t *);
 
 static inline void write_av9110_bit (lmc_softc_t *, int);
-static void write_av9110 (lmc_softc_t *, u_int32_t, u_int32_t, u_int32_t,
-			  u_int32_t, u_int32_t);
+static void write_av9110(lmc_softc_t *, u32, u32, u32, u32, u32);
 
 lmc_media_t lmc_ds3_media = {
   lmc_ds3_init,			/* special media init stuff */
@@ -427,7 +424,7 @@ lmc_ds3_set_scram (lmc_softc_t * const sc, int ie)
 static int
 lmc_ds3_get_link_status (lmc_softc_t * const sc)
 {
-    u_int16_t link_status, link_status_11;
+    u16 link_status, link_status_11;
     int ret = 1;
 
     lmc_mii_writereg (sc, 0, 17, 7);
@@ -449,7 +446,7 @@ lmc_ds3_get_link_status (lmc_softc_t * const sc)
         (link_status & LMC_FRAMER_REG0_OOFS)){
         ret = 0;
         if(sc->last_led_err[3] != 1){
-            u16 r1;
+	    u16 r1;
             lmc_mii_writereg (sc, 0, 17, 01); /* Turn on Xbit error as our cisco does */
             r1 = lmc_mii_readreg (sc, 0, 18);
             r1 &= 0xfe;
@@ -462,7 +459,7 @@ lmc_ds3_get_link_status (lmc_softc_t * const sc)
     else {
         lmc_led_off(sc, LMC_DS3_LED3);	/* turn on red LED */
         if(sc->last_led_err[3] == 1){
-            u16 r1;
+	    u16 r1;
             lmc_mii_writereg (sc, 0, 17, 01); /* Turn off Xbit error */
             r1 = lmc_mii_readreg (sc, 0, 18);
             r1 |= 0x01;
@@ -540,20 +537,19 @@ lmc_ds3_watchdog (lmc_softc_t * const sc)
  *  SSI methods
  */
 
-static void
-lmc_ssi_init (lmc_softc_t * const sc)
+static void lmc_ssi_init(lmc_softc_t * const sc)
 {
-  u_int16_t mii17;
-  int cable;
+	u16 mii17;
+	int cable;
 
-  sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1000;
+	sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1000;
 
-  mii17 = lmc_mii_readreg (sc, 0, 17);
+	mii17 = lmc_mii_readreg(sc, 0, 17);
 
-  cable = (mii17 & LMC_MII17_SSI_CABLE_MASK) >> LMC_MII17_SSI_CABLE_SHIFT;
-  sc->ictl.cable_type = cable;
+	cable = (mii17 & LMC_MII17_SSI_CABLE_MASK) >> LMC_MII17_SSI_CABLE_SHIFT;
+	sc->ictl.cable_type = cable;
 
-  lmc_gpio_mkoutput (sc, LMC_GEP_SSI_TXCLOCK);
+	lmc_gpio_mkoutput(sc, LMC_GEP_SSI_TXCLOCK);
 }
 
 static void
@@ -681,11 +677,11 @@ lmc_ssi_set_speed (lmc_softc_t * const sc, lmc_ctl_t * ctl)
 static int
 lmc_ssi_get_link_status (lmc_softc_t * const sc)
 {
-  u_int16_t link_status;
-  u_int32_t ticks;
+  u16 link_status;
+  u32 ticks;
   int ret = 1;
   int hw_hdsk = 1;
-  
+
   /*
    * missing CTS?  Hmm.  If we require CTS on, we may never get the
    * link to come up, so omit it in this test.
@@ -720,9 +716,9 @@ lmc_ssi_get_link_status (lmc_softc_t * const sc)
   }
   else if (ticks == 0 ) {				/* no clock found ? */
       ret = 0;
-      if(sc->last_led_err[3] != 1){
-          sc->stats.tx_lossOfClockCnt++;
-          printk(KERN_WARNING "%s: Lost Clock, Link Down\n", sc->name);
+      if (sc->last_led_err[3] != 1) {
+	      sc->extra_stats.tx_lossOfClockCnt++;
+	      printk(KERN_WARNING "%s: Lost Clock, Link Down\n", sc->name);
       }
       sc->last_led_err[3] = 1;
       lmc_led_on (sc, LMC_MII16_LED3);	/* turn ON red LED */
@@ -838,9 +834,7 @@ write_av9110_bit (lmc_softc_t * sc, int c)
   LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
 }
 
-static void
-write_av9110 (lmc_softc_t * sc, u_int32_t n, u_int32_t m, u_int32_t v,
-	      u_int32_t x, u_int32_t r)
+static void write_av9110(lmc_softc_t *sc, u32 n, u32 m, u32 v, u32 x, u32 r)
 {
   int i;
 
@@ -887,19 +881,13 @@ write_av9110 (lmc_softc_t * sc, u_int32_t n, u_int32_t m, u_int32_t v,
 		     | LMC_GEP_SSI_GENERATOR));
 }
 
-static void
-lmc_ssi_watchdog (lmc_softc_t * const sc)
+static void lmc_ssi_watchdog(lmc_softc_t * const sc)
 {
-  u_int16_t mii17 = lmc_mii_readreg (sc, 0, 17);
-  if (((mii17 >> 3) & 7) == 7)
-    {
-      lmc_led_off (sc, LMC_MII16_LED2);
-    }
-  else
-    {
-      lmc_led_on (sc, LMC_MII16_LED2);
-    }
-
+	u16 mii17 = lmc_mii_readreg(sc, 0, 17);
+	if (((mii17 >> 3) & 7) == 7)
+		lmc_led_off(sc, LMC_MII16_LED2);
+	else
+		lmc_led_on(sc, LMC_MII16_LED2);
 }
 
 /*
@@ -929,7 +917,7 @@ lmc_t1_read (lmc_softc_t * const sc, int a)
 static void
 lmc_t1_init (lmc_softc_t * const sc)
 {
-  u_int16_t mii16;
+  u16 mii16;
   int i;
 
   sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1200;
@@ -1028,7 +1016,7 @@ lmc_t1_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl)
  */ static int
 lmc_t1_get_link_status (lmc_softc_t * const sc)
 {
-    u_int16_t link_status;
+    u16 link_status;
     int ret = 1;
 
   /* LMC5245 (DS3) & LMC1200 (DS1) LED definitions
diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c
index 8531575..be9877f 100644
--- a/drivers/net/wan/lmc/lmc_proto.c
+++ b/drivers/net/wan/lmc/lmc_proto.c
@@ -36,9 +36,6 @@
 #include <linux/workqueue.h>
 #include <linux/proc_fs.h>
 #include <linux/bitops.h>
-
-#include <net/syncppp.h>
-
 #include <asm/processor.h>             /* Processor type for cache alignment. */
 #include <asm/io.h>
 #include <asm/dma.h>
@@ -50,48 +47,6 @@
 #include "lmc_ioctl.h"
 #include "lmc_proto.h"
 
-/*
- * The compile-time variable SPPPSTUP causes the module to be
- * compiled without referencing any of the sync ppp routines.
- */
-#ifdef SPPPSTUB
-#define SPPP_detach(d)	(void)0
-#define SPPP_open(d)	0
-#define SPPP_reopen(d)	(void)0
-#define SPPP_close(d)	(void)0
-#define SPPP_attach(d)	(void)0
-#define SPPP_do_ioctl(d,i,c)	-EOPNOTSUPP
-#else
-#define SPPP_attach(x)	sppp_attach((x)->pd)
-#define SPPP_detach(x)	sppp_detach((x)->pd->dev)
-#define SPPP_open(x)	sppp_open((x)->pd->dev)
-#define SPPP_reopen(x)	sppp_reopen((x)->pd->dev)
-#define SPPP_close(x)	sppp_close((x)->pd->dev)
-#define SPPP_do_ioctl(x, y, z)	sppp_do_ioctl((x)->pd->dev, (y), (z))
-#endif
-
-// init
-void lmc_proto_init(lmc_softc_t *sc) /*FOLD00*/
-{
-    lmc_trace(sc->lmc_device, "lmc_proto_init in");
-    switch(sc->if_type){
-    case LMC_PPP:
-        sc->pd = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
-	if (!sc->pd) {
-		printk("lmc_proto_init(): kmalloc failure!\n");
-		return;
-	}
-        sc->pd->dev = sc->lmc_device;
-        sc->if_ptr = sc->pd;
-        break;
-    case LMC_RAW:
-        break;
-    default:
-        break;
-    }
-    lmc_trace(sc->lmc_device, "lmc_proto_init out");
-}
-
 // attach
 void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
 {
@@ -100,7 +55,6 @@ void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
     case LMC_PPP:
         {
             struct net_device *dev = sc->lmc_device;
-            SPPP_attach(sc);
             dev->do_ioctl = lmc_ioctl;
         }
         break;
@@ -108,7 +62,7 @@ void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
         {
             struct net_device *dev = sc->lmc_device;
             /*
-             * They set a few basics because they don't use sync_ppp
+	     * They set a few basics because they don't use HDLC
              */
             dev->flags |= IFF_POINTOPOINT;
 
@@ -124,88 +78,39 @@ void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
     lmc_trace(sc->lmc_device, "lmc_proto_attach out");
 }
 
-// detach
-void lmc_proto_detach(lmc_softc_t *sc) /*FOLD00*/
+int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd)
 {
-    switch(sc->if_type){
-    case LMC_PPP:
-        SPPP_detach(sc);
-        break;
-    case LMC_RAW: /* Tell someone we're detaching? */
-        break;
-    default:
-        break;
-    }
-
+	lmc_trace(sc->lmc_device, "lmc_proto_ioctl");
+	if (sc->if_type == LMC_PPP)
+		return hdlc_ioctl(sc->lmc_device, ifr, cmd);
+	return -EOPNOTSUPP;
 }
 
-// reopen
-void lmc_proto_reopen(lmc_softc_t *sc) /*FOLD00*/
+int lmc_proto_open(lmc_softc_t *sc)
 {
-    lmc_trace(sc->lmc_device, "lmc_proto_reopen in");
-    switch(sc->if_type){
-    case LMC_PPP:
-        SPPP_reopen(sc);
-        break;
-    case LMC_RAW: /* Reset the interface after being down, prerape to receive packets again */
-        break;
-    default:
-        break;
-    }
-    lmc_trace(sc->lmc_device, "lmc_proto_reopen out");
-}
+	int ret = 0;
 
+	lmc_trace(sc->lmc_device, "lmc_proto_open in");
 
-// ioctl
-int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd) /*FOLD00*/
-{
-    lmc_trace(sc->lmc_device, "lmc_proto_ioctl out");
-    switch(sc->if_type){
-    case LMC_PPP:
-        return SPPP_do_ioctl (sc, ifr, cmd);
-        break;
-    default:
-        return -EOPNOTSUPP;
-        break;
-    }
-    lmc_trace(sc->lmc_device, "lmc_proto_ioctl out");
+	if (sc->if_type == LMC_PPP) {
+		ret = hdlc_open(sc->lmc_device);
+		if (ret < 0)
+			printk(KERN_WARNING "%s: HDLC open failed: %d\n",
+			       sc->name, ret);
+	}
+
+	lmc_trace(sc->lmc_device, "lmc_proto_open out");
+	return ret;
 }
 
-// open
-void lmc_proto_open(lmc_softc_t *sc) /*FOLD00*/
+void lmc_proto_close(lmc_softc_t *sc)
 {
-    int ret;
+	lmc_trace(sc->lmc_device, "lmc_proto_close in");
 
-    lmc_trace(sc->lmc_device, "lmc_proto_open in");
-    switch(sc->if_type){
-    case LMC_PPP:
-        ret = SPPP_open(sc);
-        if(ret < 0)
-            printk("%s: syncPPP open failed: %d\n", sc->name, ret);
-        break;
-    case LMC_RAW: /* We're about to start getting packets! */
-        break;
-    default:
-        break;
-    }
-    lmc_trace(sc->lmc_device, "lmc_proto_open out");
-}
-
-// close
+	if (sc->if_type == LMC_PPP)
+		hdlc_close(sc->lmc_device);
 
-void lmc_proto_close(lmc_softc_t *sc) /*FOLD00*/
-{
-    lmc_trace(sc->lmc_device, "lmc_proto_close in");
-    switch(sc->if_type){
-    case LMC_PPP:
-        SPPP_close(sc);
-        break;
-    case LMC_RAW: /* Interface going down */
-        break;
-    default:
-        break;
-    }
-    lmc_trace(sc->lmc_device, "lmc_proto_close out");
+	lmc_trace(sc->lmc_device, "lmc_proto_close out");
 }
 
 __be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
@@ -213,8 +118,8 @@ __be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
     lmc_trace(sc->lmc_device, "lmc_proto_type in");
     switch(sc->if_type){
     case LMC_PPP:
-        return htons(ETH_P_WAN_PPP);
-        break;
+	    return hdlc_type_trans(skb, sc->lmc_device);
+	    break;
     case LMC_NET:
         return htons(ETH_P_802_2);
         break;
@@ -245,4 +150,3 @@ void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
     }
     lmc_trace(sc->lmc_device, "lmc_proto_netif out");
 }
-
diff --git a/drivers/net/wan/lmc/lmc_proto.h b/drivers/net/wan/lmc/lmc_proto.h
index ccaa69e..662148c 100644
--- a/drivers/net/wan/lmc/lmc_proto.h
+++ b/drivers/net/wan/lmc/lmc_proto.h
@@ -1,16 +1,18 @@
 #ifndef _LMC_PROTO_H_
 #define _LMC_PROTO_H_
 
-void lmc_proto_init(lmc_softc_t *sc);
+#include <linux/hdlc.h>
+
 void lmc_proto_attach(lmc_softc_t *sc);
-void lmc_proto_detach(lmc_softc_t *sc);
-void lmc_proto_reopen(lmc_softc_t *sc);
 int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd);
-void lmc_proto_open(lmc_softc_t *sc);
+int lmc_proto_open(lmc_softc_t *sc);
 void lmc_proto_close(lmc_softc_t *sc);
 __be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb);
 void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb);
-int lmc_skb_rawpackets(char *buf, char **start, off_t offset, int len, int unused);
 
-#endif
+static inline lmc_softc_t* dev_to_sc(struct net_device *dev)
+{
+	return (lmc_softc_t *)dev_to_hdlc(dev)->priv;
+}
 
+#endif
diff --git a/drivers/net/wan/lmc/lmc_var.h b/drivers/net/wan/lmc/lmc_var.h
index 6d003a3..65d0197 100644
--- a/drivers/net/wan/lmc/lmc_var.h
+++ b/drivers/net/wan/lmc/lmc_var.h
@@ -1,8 +1,6 @@
 #ifndef _LMC_VAR_H_
 #define _LMC_VAR_H_
 
-/* $Id: lmc_var.h,v 1.17 2000/04/06 12:16:47 asj Exp $ */
-
  /*
   * Copyright (c) 1997-2000 LAN Media Corporation (LMC)
   * All rights reserved.  www.lanmedia.com
@@ -19,23 +17,6 @@
 
 #include <linux/timer.h>
 
-#ifndef __KERNEL__
-typedef signed char s8;
-typedef unsigned char u8;
-
-typedef signed short s16;
-typedef unsigned short u16;
-
-typedef signed int s32;
-typedef unsigned int u32;
-
-typedef signed long long s64;
-typedef unsigned long long u64;
-
-#define BITS_PER_LONG 32 
-
-#endif
-
 /*
  * basic definitions used in lmc include files
  */
@@ -45,9 +26,6 @@ typedef struct lmc___media lmc_media_t;
 typedef struct lmc___ctl lmc_ctl_t;
 
 #define lmc_csrptr_t    unsigned long
-#define u_int16_t	u16
-#define u_int8_t	u8
-#define tulip_uint32_t	u32
 
 #define LMC_REG_RANGE 0x80
 
@@ -122,45 +100,45 @@ struct lmc_regfile_t {
  *  used to define bits in the second tulip_desc_t field (length)
  *  for the transmit descriptor -baz */
 
-#define LMC_TDES_FIRST_BUFFER_SIZE       ((u_int32_t)(0x000007FF))
-#define LMC_TDES_SECOND_BUFFER_SIZE      ((u_int32_t)(0x003FF800))
-#define LMC_TDES_HASH_FILTERING          ((u_int32_t)(0x00400000))
-#define LMC_TDES_DISABLE_PADDING         ((u_int32_t)(0x00800000))
-#define LMC_TDES_SECOND_ADDR_CHAINED     ((u_int32_t)(0x01000000))
-#define LMC_TDES_END_OF_RING             ((u_int32_t)(0x02000000))
-#define LMC_TDES_ADD_CRC_DISABLE         ((u_int32_t)(0x04000000))
-#define LMC_TDES_SETUP_PACKET            ((u_int32_t)(0x08000000))
-#define LMC_TDES_INVERSE_FILTERING       ((u_int32_t)(0x10000000))
-#define LMC_TDES_FIRST_SEGMENT           ((u_int32_t)(0x20000000))
-#define LMC_TDES_LAST_SEGMENT            ((u_int32_t)(0x40000000))
-#define LMC_TDES_INTERRUPT_ON_COMPLETION ((u_int32_t)(0x80000000))
+#define LMC_TDES_FIRST_BUFFER_SIZE       ((u32)(0x000007FF))
+#define LMC_TDES_SECOND_BUFFER_SIZE      ((u32)(0x003FF800))
+#define LMC_TDES_HASH_FILTERING          ((u32)(0x00400000))
+#define LMC_TDES_DISABLE_PADDING         ((u32)(0x00800000))
+#define LMC_TDES_SECOND_ADDR_CHAINED     ((u32)(0x01000000))
+#define LMC_TDES_END_OF_RING             ((u32)(0x02000000))
+#define LMC_TDES_ADD_CRC_DISABLE         ((u32)(0x04000000))
+#define LMC_TDES_SETUP_PACKET            ((u32)(0x08000000))
+#define LMC_TDES_INVERSE_FILTERING       ((u32)(0x10000000))
+#define LMC_TDES_FIRST_SEGMENT           ((u32)(0x20000000))
+#define LMC_TDES_LAST_SEGMENT            ((u32)(0x40000000))
+#define LMC_TDES_INTERRUPT_ON_COMPLETION ((u32)(0x80000000))
 
 #define TDES_SECOND_BUFFER_SIZE_BIT_NUMBER  11
 #define TDES_COLLISION_COUNT_BIT_NUMBER     3
 
 /* Constants for the RCV descriptor RDES */
 
-#define LMC_RDES_OVERFLOW             ((u_int32_t)(0x00000001))
-#define LMC_RDES_CRC_ERROR            ((u_int32_t)(0x00000002))
-#define LMC_RDES_DRIBBLING_BIT            ((u_int32_t)(0x00000004))
-#define LMC_RDES_REPORT_ON_MII_ERR    ((u_int32_t)(0x00000008))
-#define LMC_RDES_RCV_WATCHDOG_TIMEOUT ((u_int32_t)(0x00000010))
-#define LMC_RDES_FRAME_TYPE           ((u_int32_t)(0x00000020))
-#define LMC_RDES_COLLISION_SEEN       ((u_int32_t)(0x00000040))
-#define LMC_RDES_FRAME_TOO_LONG       ((u_int32_t)(0x00000080))
-#define LMC_RDES_LAST_DESCRIPTOR      ((u_int32_t)(0x00000100))
-#define LMC_RDES_FIRST_DESCRIPTOR     ((u_int32_t)(0x00000200))
-#define LMC_RDES_MULTICAST_FRAME      ((u_int32_t)(0x00000400))
-#define LMC_RDES_RUNT_FRAME           ((u_int32_t)(0x00000800))
-#define LMC_RDES_DATA_TYPE            ((u_int32_t)(0x00003000))
-#define LMC_RDES_LENGTH_ERROR         ((u_int32_t)(0x00004000))
-#define LMC_RDES_ERROR_SUMMARY        ((u_int32_t)(0x00008000))
-#define LMC_RDES_FRAME_LENGTH         ((u_int32_t)(0x3FFF0000))
-#define LMC_RDES_OWN_BIT              ((u_int32_t)(0x80000000))
+#define LMC_RDES_OVERFLOW             ((u32)(0x00000001))
+#define LMC_RDES_CRC_ERROR            ((u32)(0x00000002))
+#define LMC_RDES_DRIBBLING_BIT        ((u32)(0x00000004))
+#define LMC_RDES_REPORT_ON_MII_ERR    ((u32)(0x00000008))
+#define LMC_RDES_RCV_WATCHDOG_TIMEOUT ((u32)(0x00000010))
+#define LMC_RDES_FRAME_TYPE           ((u32)(0x00000020))
+#define LMC_RDES_COLLISION_SEEN       ((u32)(0x00000040))
+#define LMC_RDES_FRAME_TOO_LONG       ((u32)(0x00000080))
+#define LMC_RDES_LAST_DESCRIPTOR      ((u32)(0x00000100))
+#define LMC_RDES_FIRST_DESCRIPTOR     ((u32)(0x00000200))
+#define LMC_RDES_MULTICAST_FRAME      ((u32)(0x00000400))
+#define LMC_RDES_RUNT_FRAME           ((u32)(0x00000800))
+#define LMC_RDES_DATA_TYPE            ((u32)(0x00003000))
+#define LMC_RDES_LENGTH_ERROR         ((u32)(0x00004000))
+#define LMC_RDES_ERROR_SUMMARY        ((u32)(0x00008000))
+#define LMC_RDES_FRAME_LENGTH         ((u32)(0x3FFF0000))
+#define LMC_RDES_OWN_BIT              ((u32)(0x80000000))
 
 #define RDES_FRAME_LENGTH_BIT_NUMBER       16
 
-#define LMC_RDES_ERROR_MASK ( (u_int32_t)( \
+#define LMC_RDES_ERROR_MASK ( (u32)( \
 	  LMC_RDES_OVERFLOW \
 	| LMC_RDES_DRIBBLING_BIT \
 	| LMC_RDES_REPORT_ON_MII_ERR \
@@ -172,32 +150,32 @@ struct lmc_regfile_t {
  */
 
 typedef struct {
-	u_int32_t	n;
-	u_int32_t	m;
-	u_int32_t	v;
-	u_int32_t	x;
-	u_int32_t	r;
-	u_int32_t	f;
-	u_int32_t	exact;
+	u32	n;
+	u32	m;
+	u32	v;
+	u32	x;
+	u32	r;
+	u32	f;
+	u32	exact;
 } lmc_av9110_t;
 
 /*
  * Common structure passed to the ioctl code.
  */
 struct lmc___ctl {
-	u_int32_t	cardtype;
-	u_int32_t	clock_source;		/* HSSI, T1 */
-	u_int32_t	clock_rate;		/* T1 */
-	u_int32_t	crc_length;
-	u_int32_t	cable_length;		/* DS3 */
-	u_int32_t	scrambler_onoff;	/* DS3 */
-	u_int32_t	cable_type;		/* T1 */
-	u_int32_t	keepalive_onoff;	/* protocol */
-	u_int32_t	ticks;			/* ticks/sec */
+	u32	cardtype;
+	u32	clock_source;		/* HSSI, T1 */
+	u32	clock_rate;		/* T1 */
+	u32	crc_length;
+	u32	cable_length;		/* DS3 */
+	u32	scrambler_onoff;	/* DS3 */
+	u32	cable_type;		/* T1 */
+	u32	keepalive_onoff;	/* protocol */
+	u32	ticks;			/* ticks/sec */
 	union {
 		lmc_av9110_t	ssi;
 	} cardspec;
-	u_int32_t       circuit_type;   /* T1 or E1 */
+	u32       circuit_type;   /* T1 or E1 */
 };
 
 
@@ -244,108 +222,69 @@ struct lmc___media {
 
 #define STATCHECK     0xBEEFCAFE
 
-/*  Included in this structure are first
- *   - standard net_device_stats
- *   - some other counters used for debug and driver performance
- *  evaluation -baz
- */
-struct lmc_statistics
+struct lmc_extra_statistics
 {
-        unsigned long     rx_packets;             /* total packets received       */
-        unsigned long     tx_packets;             /* total packets transmitted    */
-	unsigned long     rx_bytes;
-        unsigned long     tx_bytes;
-        
-        unsigned long     rx_errors;              /* bad packets received         */
-        unsigned long     tx_errors;              /* packet transmit problems     */
-        unsigned long     rx_dropped;             /* no space in linux buffers    */
-        unsigned long     tx_dropped;             /* no space available in linux  */
-        unsigned long     multicast;              /* multicast packets received   */
-        unsigned long     collisions;
-
-        /* detailed rx_errors: */
-        unsigned long     rx_length_errors;
-        unsigned long     rx_over_errors;         /* receiver ring buff overflow  */
-        unsigned long     rx_crc_errors;          /* recved pkt with crc error    */
-        unsigned long     rx_frame_errors;        /* recv'd frame alignment error */
-        unsigned long     rx_fifo_errors;         /* recv'r fifo overrun          */
-        unsigned long     rx_missed_errors;       /* receiver missed packet       */
-
-        /* detailed tx_errors */
-        unsigned long     tx_aborted_errors;
-        unsigned long     tx_carrier_errors;
-        unsigned long     tx_fifo_errors;
-        unsigned long     tx_heartbeat_errors;
-        unsigned long     tx_window_errors;
-
-        /* for cslip etc */
-        unsigned long rx_compressed;
-        unsigned long tx_compressed;
-
-        /* -------------------------------------
-         * Custom stats & counters follow -baz */
-        u_int32_t       version_size;
-        u_int32_t       lmc_cardtype;
-
-        u_int32_t       tx_ProcTimeout;
-        u_int32_t       tx_IntTimeout;
-        u_int32_t       tx_NoCompleteCnt;
-        u_int32_t       tx_MaxXmtsB4Int;
-        u_int32_t       tx_TimeoutCnt;
-        u_int32_t       tx_OutOfSyncPtr;
-        u_int32_t       tx_tbusy0;
-        u_int32_t       tx_tbusy1;
-        u_int32_t       tx_tbusy_calls;
-        u_int32_t       resetCount;
-        u_int32_t       lmc_txfull;
-        u_int32_t       tbusy;
-        u_int32_t       dirtyTx;
-        u_int32_t       lmc_next_tx;
-        u_int32_t       otherTypeCnt;
-        u_int32_t       lastType;
-        u_int32_t       lastTypeOK;
-        u_int32_t       txLoopCnt;
-        u_int32_t       usedXmtDescripCnt;
-        u_int32_t       txIndexCnt;
-        u_int32_t       rxIntLoopCnt;
-
-        u_int32_t       rx_SmallPktCnt;
-        u_int32_t       rx_BadPktSurgeCnt;
-        u_int32_t       rx_BuffAllocErr;
-        u_int32_t       tx_lossOfClockCnt;
-
-        /* T1 error counters */
-        u_int32_t       framingBitErrorCount;
-        u_int32_t       lineCodeViolationCount;
-
-        u_int32_t       lossOfFrameCount;
-        u_int32_t       changeOfFrameAlignmentCount;
-        u_int32_t       severelyErroredFrameCount;
-
-        u_int32_t       check;
+	u32       version_size;
+	u32       lmc_cardtype;
+
+	u32       tx_ProcTimeout;
+	u32       tx_IntTimeout;
+	u32       tx_NoCompleteCnt;
+	u32       tx_MaxXmtsB4Int;
+	u32       tx_TimeoutCnt;
+	u32       tx_OutOfSyncPtr;
+	u32       tx_tbusy0;
+	u32       tx_tbusy1;
+	u32       tx_tbusy_calls;
+	u32       resetCount;
+	u32       lmc_txfull;
+	u32       tbusy;
+	u32       dirtyTx;
+	u32       lmc_next_tx;
+	u32       otherTypeCnt;
+	u32       lastType;
+	u32       lastTypeOK;
+	u32       txLoopCnt;
+	u32       usedXmtDescripCnt;
+	u32       txIndexCnt;
+	u32       rxIntLoopCnt;
+
+	u32       rx_SmallPktCnt;
+	u32       rx_BadPktSurgeCnt;
+	u32       rx_BuffAllocErr;
+	u32       tx_lossOfClockCnt;
+
+	/* T1 error counters */
+	u32       framingBitErrorCount;
+	u32       lineCodeViolationCount;
+
+	u32       lossOfFrameCount;
+	u32       changeOfFrameAlignmentCount;
+	u32       severelyErroredFrameCount;
+
+	u32       check;
 };
 
-
 typedef struct lmc_xinfo {
-        u_int32_t       Magic0;                         /* BEEFCAFE */
+	u32       Magic0;                         /* BEEFCAFE */
 
-        u_int32_t       PciCardType;
-        u_int32_t       PciSlotNumber;          /* PCI slot number       */
+	u32       PciCardType;
+	u32       PciSlotNumber;          /* PCI slot number       */
 
-        u_int16_t       DriverMajorVersion;
-        u_int16_t       DriverMinorVersion;
-        u_int16_t       DriverSubVersion;
+	u16	       DriverMajorVersion;
+	u16	       DriverMinorVersion;
+	u16	       DriverSubVersion;
 
-        u_int16_t       XilinxRevisionNumber;
-        u_int16_t       MaxFrameSize;
+	u16	       XilinxRevisionNumber;
+	u16	       MaxFrameSize;
 
-        u_int16_t       t1_alarm1_status;
-        u_int16_t       t1_alarm2_status;
+	u16     	  t1_alarm1_status;
+	u16       	t1_alarm2_status;
 
-        int                     link_status;
-        u_int32_t       mii_reg16;
+	int             link_status;
+	u32       mii_reg16;
 
-        u_int32_t       Magic1;                         /* DEADBEEF */
+	u32       Magic1;                         /* DEADBEEF */
 } LMC_XINFO;
 
 
@@ -353,23 +292,22 @@ typedef struct lmc_xinfo {
  * forward decl
  */
 struct lmc___softc {
-        void *if_ptr;   /* General purpose pointer (used by SPPP) */
 	char                   *name;
 	u8			board_idx;
-	struct lmc_statistics   stats;
-	struct net_device          *lmc_device;
+	struct lmc_extra_statistics extra_stats;
+	struct net_device      *lmc_device;
 
 	int                     hang, rxdesc, bad_packet, some_counter;
-	u_int32_t               txgo;
+	u32  	         	txgo;
 	struct lmc_regfile_t	lmc_csrs;
-	volatile u_int32_t	lmc_txtick;
-	volatile u_int32_t	lmc_rxtick;
-	u_int32_t		lmc_flags;
-	u_int32_t		lmc_intrmask;	/* our copy of csr_intr */
-	u_int32_t		lmc_cmdmode;	/* our copy of csr_cmdmode */
-	u_int32_t		lmc_busmode;	/* our copy of csr_busmode */
-	u_int32_t		lmc_gpio_io;	/* state of in/out settings */
-	u_int32_t		lmc_gpio;	/* state of outputs */
+	volatile u32		lmc_txtick;
+	volatile u32		lmc_rxtick;
+	u32			lmc_flags;
+	u32			lmc_intrmask;	/* our copy of csr_intr */
+	u32			lmc_cmdmode;	/* our copy of csr_cmdmode */
+	u32			lmc_busmode;	/* our copy of csr_busmode */
+	u32			lmc_gpio_io;	/* state of in/out settings */
+	u32			lmc_gpio;	/* state of outputs */
 	struct sk_buff*		lmc_txq[LMC_TXDESCS];
 	struct sk_buff*		lmc_rxq[LMC_RXDESCS];
 	volatile
@@ -381,42 +319,41 @@ struct lmc___softc {
 	unsigned int		lmc_taint_tx, lmc_taint_rx;
 	int			lmc_tx_start, lmc_txfull;
 	int			lmc_txbusy;
-	u_int16_t		lmc_miireg16;
+	u16			lmc_miireg16;
 	int			lmc_ok;
 	int			last_link_status;
 	int			lmc_cardtype;
-	u_int32_t               last_frameerr;
+	u32               	last_frameerr;
 	lmc_media_t	       *lmc_media;
 	struct timer_list	timer;
 	lmc_ctl_t		ictl;
-	u_int32_t		TxDescriptControlInit;  
+	u32			TxDescriptControlInit;
 
 	int                     tx_TimeoutInd; /* additional driver state */
 	int                     tx_TimeoutDisplay;
 	unsigned int		lastlmc_taint_tx;
 	int                     lasttx_packets;
-	u_int32_t		tx_clockState;
-	u_int32_t		lmc_crcSize;
-	LMC_XINFO		lmc_xinfo; 
+	u32			tx_clockState;
+	u32			lmc_crcSize;
+	LMC_XINFO		lmc_xinfo;
 	char                    lmc_yel, lmc_blue, lmc_red; /* for T1 and DS3 */
-        char                    lmc_timing; /* for HSSI and SSI */
-        int                     got_irq;
+	char                    lmc_timing; /* for HSSI and SSI */
+	int                     got_irq;
 
-        char                    last_led_err[4];
+	char                    last_led_err[4];
 
-        u32                     last_int;
-        u32                     num_int;
+	u32                     last_int;
+	u32                     num_int;
 
 	spinlock_t              lmc_lock;
-        u_int16_t               if_type;       /* PPP or NET */
-        struct ppp_device       *pd;
+	u16			if_type;       /* HDLC/PPP or NET */
 
-        /* Failure cases */
-        u8                       failed_ring;
-        u8                       failed_recv_alloc;
+	/* Failure cases */
+	u8			failed_ring;
+	u8			failed_recv_alloc;
 
-        /* Structure check */
-        u32                     check;
+	/* Structure check */
+	u32                     check;
 };
 
 #define LMC_PCI_TIME 1
@@ -512,8 +449,8 @@ struct lmc___softc {
   | TULIP_STS_TXUNDERFLOW\
   | TULIP_STS_RXSTOPPED )
 
-#define DESC_OWNED_BY_SYSTEM   ((u_int32_t)(0x00000000))
-#define DESC_OWNED_BY_DC21X4   ((u_int32_t)(0x80000000))
+#define DESC_OWNED_BY_SYSTEM   ((u32)(0x00000000))
+#define DESC_OWNED_BY_DC21X4   ((u32)(0x80000000))
 
 #ifndef TULIP_CMD_RECEIVEALL
 #define TULIP_CMD_RECEIVEALL 0x40000000L
@@ -525,46 +462,9 @@ struct lmc___softc {
 #define LMC_ADAP_SSI            4
 #define LMC_ADAP_T1             5
 
-#define HDLC_HDR_LEN  4
-#define HDLC_ADDR_LEN 1
-#define HDLC_SLARP    0x8035
 #define LMC_MTU 1500
-#define SLARP_LINECHECK 2
 
 #define LMC_CRC_LEN_16 2  /* 16-bit CRC */
 #define LMC_CRC_LEN_32 4
 
-#ifdef LMC_HDLC
-/* definition of an hdlc header. */
-struct hdlc_hdr
-{
-	u8  address;
-	u8  control;
-	u16 type;
-};
-
-/* definition of a slarp header. */
-struct slarp
-{
-	long code;
-	union sl
-	{
-		struct
-		{
-			ulong address;
-			ulong mask;
-			ushort unused;
-		} add;
-		struct
-		{
-			ulong mysequence;
-			ulong yoursequence;
-			ushort reliability;
-			ulong time;
-		} chk;
-	} t;
-};
-#endif /* LMC_HDLC */
-
-
 #endif /* _LMC_VAR_H_ */
diff --git a/drivers/net/wan/pc300.h b/drivers/net/wan/pc300.h
index 63e9fcf..2e4f84f 100644
--- a/drivers/net/wan/pc300.h
+++ b/drivers/net/wan/pc300.h
@@ -100,31 +100,14 @@
 #define	_PC300_H
 
 #include <linux/hdlc.h>
-#include <net/syncppp.h>
 #include "hd64572.h"
 #include "pc300-falc-lh.h"
 
-#ifndef CY_TYPES
-#define CY_TYPES
-typedef	__u64	ucdouble;	/* 64 bits, unsigned */
-typedef	__u32	uclong;		/* 32 bits, unsigned */
-typedef	__u16	ucshort;	/* 16 bits, unsigned */
-typedef	__u8	ucchar;		/* 8 bits, unsigned */
-#endif /* CY_TYPES */
+#define PC300_PROTO_MLPPP 1
 
-#define PC300_PROTO_MLPPP 1		
-
-#define PC300_KERNEL	"2.4.x"	/* Kernel supported by this driver */
-
-#define	PC300_DEVNAME	"hdlc"	/* Dev. name base (for hdlc0, hdlc1, etc.) */
-#define PC300_MAXINDEX	100	/* Max dev. name index (the '0' in hdlc0) */
-
-#define	PC300_MAXCARDS	4	/* Max number of cards per system */
 #define	PC300_MAXCHAN	2	/* Number of channels per card */
 
-#define	PC300_PLX_WIN	0x80    /* PLX control window size (128b) */
 #define	PC300_RAMSIZE	0x40000 /* RAM window size (256Kb) */
-#define	PC300_SCASIZE	0x400   /* SCA window size (1Kb) */
 #define	PC300_FALCSIZE	0x400	/* FALC window size (1Kb) */
 
 #define PC300_OSC_CLOCK	24576000
@@ -160,26 +143,14 @@ typedef	__u8	ucchar;		/* 8 bits, unsigned */
  * Memory access functions/macros      *
  * (required to support Alpha systems) *
  ***************************************/
-#ifdef __KERNEL__
-#define cpc_writeb(port,val)	{writeb((ucchar)(val),(port)); mb();}
+#define cpc_writeb(port,val)	{writeb((u8)(val),(port)); mb();}
 #define cpc_writew(port,val)	{writew((ushort)(val),(port)); mb();}
-#define cpc_writel(port,val)	{writel((uclong)(val),(port)); mb();}
+#define cpc_writel(port,val)	{writel((u32)(val),(port)); mb();}
 
 #define cpc_readb(port)		readb(port)
 #define cpc_readw(port)		readw(port)
 #define cpc_readl(port)		readl(port)
 
-#else /* __KERNEL__ */
-#define cpc_writeb(port,val)	(*(volatile ucchar *)(port) = (ucchar)(val))
-#define cpc_writew(port,val)	(*(volatile ucshort *)(port) = (ucshort)(val))
-#define cpc_writel(port,val)	(*(volatile uclong *)(port) = (uclong)(val))
-
-#define cpc_readb(port)		(*(volatile ucchar *)(port))
-#define cpc_readw(port)		(*(volatile ucshort *)(port))
-#define cpc_readl(port)		(*(volatile uclong *)(port))
-
-#endif /* __KERNEL__ */
-
 /****** Data Structures *****************************************************/
 
 /*
@@ -188,15 +159,15 @@ typedef	__u8	ucchar;		/* 8 bits, unsigned */
  *      (memory mapped).
  */
 struct RUNTIME_9050 {
-	uclong	loc_addr_range[4];	/* 00-0Ch : Local Address Ranges */
-	uclong	loc_rom_range;		/* 10h : Local ROM Range */
-	uclong	loc_addr_base[4];	/* 14-20h : Local Address Base Addrs */
-	uclong	loc_rom_base;		/* 24h : Local ROM Base */
-	uclong	loc_bus_descr[4];	/* 28-34h : Local Bus Descriptors */
-	uclong	rom_bus_descr;		/* 38h : ROM Bus Descriptor */
-	uclong	cs_base[4];		/* 3C-48h : Chip Select Base Addrs */
-	uclong	intr_ctrl_stat;		/* 4Ch : Interrupt Control/Status */
-	uclong	init_ctrl;		/* 50h : EEPROM ctrl, Init Ctrl, etc */
+	u32 loc_addr_range[4];	/* 00-0Ch : Local Address Ranges */
+	u32 loc_rom_range;	/* 10h : Local ROM Range */
+	u32 loc_addr_base[4];	/* 14-20h : Local Address Base Addrs */
+	u32 loc_rom_base;	/* 24h : Local ROM Base */
+	u32 loc_bus_descr[4];	/* 28-34h : Local Bus Descriptors */
+	u32 rom_bus_descr;	/* 38h : ROM Bus Descriptor */
+	u32 cs_base[4];		/* 3C-48h : Chip Select Base Addrs */
+	u32 intr_ctrl_stat;	/* 4Ch : Interrupt Control/Status */
+	u32 init_ctrl;		/* 50h : EEPROM ctrl, Init Ctrl, etc */
 };
 
 #define PLX_9050_LINT1_ENABLE	0x01
@@ -240,66 +211,66 @@ struct RUNTIME_9050 {
 #define PC300_FALC_MAXLOOP	0x0000ffff	/* for falc_issue_cmd() */
 
 typedef struct falc {
-	ucchar sync;		/* If true FALC is synchronized */
-	ucchar active;		/* if TRUE then already active */
-	ucchar loop_active;	/* if TRUE a line loopback UP was received */
-	ucchar loop_gen;	/* if TRUE a line loopback UP was issued */
+	u8 sync;	/* If true FALC is synchronized */
+	u8 active;	/* if TRUE then already active */
+	u8 loop_active;	/* if TRUE a line loopback UP was received */
+	u8 loop_gen;	/* if TRUE a line loopback UP was issued */
 
-	ucchar num_channels;
-	ucchar offset;		/* 1 for T1, 0 for E1 */
-	ucchar full_bandwidth;
+	u8 num_channels;
+	u8 offset;	/* 1 for T1, 0 for E1 */
+	u8 full_bandwidth;
 
-	ucchar xmb_cause;
-	ucchar multiframe_mode;
+	u8 xmb_cause;
+	u8 multiframe_mode;
 
 	/* Statistics */
-	ucshort pden;	/* Pulse Density violation count */
-	ucshort los;	/* Loss of Signal count */
-	ucshort losr;	/* Loss of Signal recovery count */
-	ucshort lfa;	/* Loss of frame alignment count */
-	ucshort farec;	/* Frame Alignment Recovery count */
-	ucshort lmfa;	/* Loss of multiframe alignment count */
-	ucshort ais;	/* Remote Alarm indication Signal count */
-	ucshort sec;	/* One-second timer */
-	ucshort es;	/* Errored second */
-	ucshort rai;	/* remote alarm received */
-	ucshort bec;
-	ucshort fec;
-	ucshort cvc;
-	ucshort cec;
-	ucshort ebc;
+	u16 pden;	/* Pulse Density violation count */
+	u16 los;	/* Loss of Signal count */
+	u16 losr;	/* Loss of Signal recovery count */
+	u16 lfa;	/* Loss of frame alignment count */
+	u16 farec;	/* Frame Alignment Recovery count */
+	u16 lmfa;	/* Loss of multiframe alignment count */
+	u16 ais;	/* Remote Alarm indication Signal count */
+	u16 sec;	/* One-second timer */
+	u16 es;		/* Errored second */
+	u16 rai;	/* remote alarm received */
+	u16 bec;
+	u16 fec;
+	u16 cvc;
+	u16 cec;
+	u16 ebc;
 
 	/* Status */
-	ucchar red_alarm;
-	ucchar blue_alarm;
-	ucchar loss_fa;
-	ucchar yellow_alarm;
-	ucchar loss_mfa;
-	ucchar prbs;
+	u8 red_alarm;
+	u8 blue_alarm;
+	u8 loss_fa;
+	u8 yellow_alarm;
+	u8 loss_mfa;
+	u8 prbs;
 } falc_t;
 
 typedef struct falc_status {
-	ucchar sync;  /* If true FALC is synchronized */
-	ucchar red_alarm;
-	ucchar blue_alarm;
-	ucchar loss_fa;
-	ucchar yellow_alarm;
-	ucchar loss_mfa;
-	ucchar prbs;
+	u8 sync;	/* If true FALC is synchronized */
+	u8 red_alarm;
+	u8 blue_alarm;
+	u8 loss_fa;
+	u8 yellow_alarm;
+	u8 loss_mfa;
+	u8 prbs;
 } falc_status_t;
 
 typedef struct rsv_x21_status {
-	ucchar dcd;
-	ucchar dsr;
-	ucchar cts;
-	ucchar rts;
-	ucchar dtr;
+	u8 dcd;
+	u8 dsr;
+	u8 cts;
+	u8 rts;
+	u8 dtr;
 } rsv_x21_status_t;
 
 typedef struct pc300stats {
 	int hw_type;
-	uclong line_on;
-	uclong line_off;
+	u32 line_on;
+	u32 line_off;
 	struct net_device_stats gen_stats;
 	falc_t te_stats;
 } pc300stats_t;
@@ -317,28 +288,19 @@ typedef struct pc300loopback {
 
 typedef struct pc300patterntst {
 	char patrntst_on;       /* 0 - off; 1 - on; 2 - read num_errors */
-	ucshort num_errors;
+	u16 num_errors;
 } pc300patterntst_t;
 
 typedef struct pc300dev {
-	void *if_ptr;		/* General purpose pointer */
 	struct pc300ch *chan;
-	ucchar trace_on;
-	uclong line_on;		/* DCD(X.21, RSV) / sync(TE) change counters */
-	uclong line_off;
-#ifdef __KERNEL__
+	u8 trace_on;
+	u32 line_on;		/* DCD(X.21, RSV) / sync(TE) change counters */
+	u32 line_off;
 	char name[16];
 	struct net_device *dev;
-
-	void *private;
-	struct sk_buff *tx_skb;
-	union {	/* This union has all the protocol-specific structures */
-		struct ppp_device pppdev;
-	}ifu;
 #ifdef CONFIG_PC300_MLPPP
 	void *cpc_tty;	/* information to PC300 TTY driver */
 #endif
-#endif /* __KERNEL__ */
 }pc300dev_t;
 
 typedef struct pc300hw {
@@ -346,43 +308,42 @@ typedef struct pc300hw {
 	int bus;		/* Bus (PCI, PMC, etc.) */
 	int nchan;		/* number of channels */
 	int irq;		/* interrupt request level */
-	uclong clock;		/* Board clock */
-	ucchar cpld_id;		/* CPLD ID (TE only) */
-	ucshort cpld_reg1;	/* CPLD reg 1 (TE only) */
-	ucshort cpld_reg2;	/* CPLD reg 2 (TE only) */
-	ucshort gpioc_reg;	/* PLX GPIOC reg */
-	ucshort intctl_reg;	/* PLX Int Ctrl/Status reg */
-	uclong iophys;		/* PLX registers I/O base */
-	uclong iosize;		/* PLX registers I/O size */
-	uclong plxphys;		/* PLX registers MMIO base (physical) */
+	u32 clock;		/* Board clock */
+	u8 cpld_id;		/* CPLD ID (TE only) */
+	u16 cpld_reg1;		/* CPLD reg 1 (TE only) */
+	u16 cpld_reg2;		/* CPLD reg 2 (TE only) */
+	u16 gpioc_reg;		/* PLX GPIOC reg */
+	u16 intctl_reg;		/* PLX Int Ctrl/Status reg */
+	u32 iophys;		/* PLX registers I/O base */
+	u32 iosize;		/* PLX registers I/O size */
+	u32 plxphys;		/* PLX registers MMIO base (physical) */
 	void __iomem * plxbase;	/* PLX registers MMIO base (virtual) */
-	uclong plxsize;		/* PLX registers MMIO size */
-	uclong scaphys;		/* SCA registers MMIO base (physical) */
+	u32 plxsize;		/* PLX registers MMIO size */
+	u32 scaphys;		/* SCA registers MMIO base (physical) */
 	void __iomem * scabase;	/* SCA registers MMIO base (virtual) */
-	uclong scasize;		/* SCA registers MMIO size */
-	uclong ramphys;		/* On-board RAM MMIO base (physical) */
+	u32 scasize;		/* SCA registers MMIO size */
+	u32 ramphys;		/* On-board RAM MMIO base (physical) */
 	void __iomem * rambase;	/* On-board RAM MMIO base (virtual) */
-	uclong alloc_ramsize;	/* RAM MMIO size allocated by the PCI bridge */
-	uclong ramsize;		/* On-board RAM MMIO size */
-	uclong falcphys;	/* FALC registers MMIO base (physical) */
+	u32 alloc_ramsize;	/* RAM MMIO size allocated by the PCI bridge */
+	u32 ramsize;		/* On-board RAM MMIO size */
+	u32 falcphys;		/* FALC registers MMIO base (physical) */
 	void __iomem * falcbase;/* FALC registers MMIO base (virtual) */
-	uclong falcsize;	/* FALC registers MMIO size */
+	u32 falcsize;		/* FALC registers MMIO size */
 } pc300hw_t;
 
 typedef struct pc300chconf {
-	sync_serial_settings	phys_settings;	/* Clock type/rate (in bps), 
+	sync_serial_settings	phys_settings;	/* Clock type/rate (in bps),
 						   loopback mode */
 	raw_hdlc_proto		proto_settings;	/* Encoding, parity (CRC) */
-	uclong media;		/* HW media (RS232, V.35, etc.) */
-	uclong proto;		/* Protocol (PPP, X.25, etc.) */
-	ucchar monitor;		/* Monitor mode (0 = off, !0 = on) */
+	u32 media;		/* HW media (RS232, V.35, etc.) */
+	u32 proto;		/* Protocol (PPP, X.25, etc.) */
 
 	/* TE-specific parameters */
-	ucchar lcode;		/* Line Code (AMI, B8ZS, etc.) */
-	ucchar fr_mode;		/* Frame Mode (ESF, D4, etc.) */
-	ucchar lbo;		/* Line Build Out */
-	ucchar rx_sens;		/* Rx Sensitivity (long- or short-haul) */
-	uclong tslot_bitmap;	/* bit[i]=1  =>  timeslot _i_ is active */
+	u8 lcode;		/* Line Code (AMI, B8ZS, etc.) */
+	u8 fr_mode;		/* Frame Mode (ESF, D4, etc.) */
+	u8 lbo;			/* Line Build Out */
+	u8 rx_sens;		/* Rx Sensitivity (long- or short-haul) */
+	u32 tslot_bitmap;	/* bit[i]=1  =>  timeslot _i_ is active */
 } pc300chconf_t;
 
 typedef struct pc300ch {
@@ -390,20 +351,18 @@ typedef struct pc300ch {
 	int channel;
 	pc300dev_t d;
 	pc300chconf_t conf;
-	ucchar tx_first_bd;	/* First TX DMA block descr. w/ data */
-	ucchar tx_next_bd;	/* Next free TX DMA block descriptor */
-	ucchar rx_first_bd;	/* First free RX DMA block descriptor */
-	ucchar rx_last_bd;	/* Last free RX DMA block descriptor */
-	ucchar nfree_tx_bd;	/* Number of free TX DMA block descriptors */
-	falc_t falc;		/* FALC structure (TE only) */
+	u8 tx_first_bd;	/* First TX DMA block descr. w/ data */
+	u8 tx_next_bd;	/* Next free TX DMA block descriptor */
+	u8 rx_first_bd;	/* First free RX DMA block descriptor */
+	u8 rx_last_bd;	/* Last free RX DMA block descriptor */
+	u8 nfree_tx_bd;	/* Number of free TX DMA block descriptors */
+	falc_t falc;	/* FALC structure (TE only) */
 } pc300ch_t;
 
 typedef struct pc300 {
 	pc300hw_t hw;			/* hardware config. */
 	pc300ch_t chan[PC300_MAXCHAN];
-#ifdef __KERNEL__
 	spinlock_t card_lock;
-#endif /* __KERNEL__ */
 } pc300_t;
 
 typedef struct pc300conf {
@@ -471,12 +430,7 @@ enum pc300_loopback_cmds {
 #define PC300_TX_QUEUE_LEN	100
 #define	PC300_DEF_MTU		1600
 
-#ifdef __KERNEL__
 /* Function Prototypes */
-void tx_dma_start(pc300_t *, int);
 int cpc_open(struct net_device *dev);
-int cpc_set_media(hdlc_device *, int);
-#endif /* __KERNEL__ */
 
 #endif	/* _PC300_H */
-
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 3341705..d0a8d1e 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -227,8 +227,6 @@ static char rcsid[] =
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
 #include <linux/if.h>
-
-#include <net/syncppp.h>
 #include <net/arp.h>
 
 #include <asm/io.h>
@@ -285,8 +283,8 @@ static void rx_dma_buf_init(pc300_t *, int);
 static void tx_dma_buf_check(pc300_t *, int);
 static void rx_dma_buf_check(pc300_t *, int);
 static irqreturn_t cpc_intr(int, void *);
-static int clock_rate_calc(uclong, uclong, int *);
-static uclong detect_ram(pc300_t *);
+static int clock_rate_calc(u32, u32, int *);
+static u32 detect_ram(pc300_t *);
 static void plx_init(pc300_t *);
 static void cpc_trace(struct net_device *, struct sk_buff *, char);
 static int cpc_attach(struct net_device *, unsigned short, unsigned short);
@@ -311,10 +309,10 @@ static void tx_dma_buf_pt_init(pc300_t * card, int ch)
 			               + DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
 
 	for (i = 0; i < N_DMA_TX_BUF; i++, ptdescr++) {
-		cpc_writel(&ptdescr->next, (uclong) (DMA_TX_BD_BASE +
+		cpc_writel(&ptdescr->next, (u32)(DMA_TX_BD_BASE +
 			(ch_factor + ((i + 1) & (N_DMA_TX_BUF - 1))) * sizeof(pcsca_bd_t)));
-		cpc_writel(&ptdescr->ptbuf, 
-						(uclong) (DMA_TX_BASE + (ch_factor + i) * BD_DEF_LEN));
+		cpc_writel(&ptdescr->ptbuf,
+			   (u32)(DMA_TX_BASE + (ch_factor + i) * BD_DEF_LEN));
 	}
 }
 
@@ -341,10 +339,10 @@ static void rx_dma_buf_pt_init(pc300_t * card, int ch)
 				       + DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
 
 	for (i = 0; i < N_DMA_RX_BUF; i++, ptdescr++) {
-		cpc_writel(&ptdescr->next, (uclong) (DMA_RX_BD_BASE +
-	     	(ch_factor + ((i + 1) & (N_DMA_RX_BUF - 1))) * sizeof(pcsca_bd_t)));
+		cpc_writel(&ptdescr->next, (u32)(DMA_RX_BD_BASE +
+			(ch_factor + ((i + 1) & (N_DMA_RX_BUF - 1))) * sizeof(pcsca_bd_t)));
 		cpc_writel(&ptdescr->ptbuf,
-			   (uclong) (DMA_RX_BASE + (ch_factor + i) * BD_DEF_LEN));
+			   (u32)(DMA_RX_BASE + (ch_factor + i) * BD_DEF_LEN));
 	}
 }
 
@@ -367,8 +365,8 @@ static void tx_dma_buf_check(pc300_t * card, int ch)
 {
 	volatile pcsca_bd_t __iomem *ptdescr;
 	int i;
-	ucshort first_bd = card->chan[ch].tx_first_bd;
-	ucshort next_bd = card->chan[ch].tx_next_bd;
+	u16 first_bd = card->chan[ch].tx_first_bd;
+	u16 next_bd = card->chan[ch].tx_next_bd;
 
 	printk("#CH%d: f_bd = %d(0x%08zx), n_bd = %d(0x%08zx)\n", ch,
 	       first_bd, TX_BD_ADDR(ch, first_bd),
@@ -392,9 +390,9 @@ static void tx1_dma_buf_check(pc300_t * card, int ch)
 {
 	volatile pcsca_bd_t __iomem *ptdescr;
 	int i;
-	ucshort first_bd = card->chan[ch].tx_first_bd;
-	ucshort next_bd = card->chan[ch].tx_next_bd;
-	uclong scabase = card->hw.scabase;
+	u16 first_bd = card->chan[ch].tx_first_bd;
+	u16 next_bd = card->chan[ch].tx_next_bd;
+	u32 scabase = card->hw.scabase;
 
 	printk ("\nnfree_tx_bd = %d \n", card->chan[ch].nfree_tx_bd);
 	printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch,
@@ -413,13 +411,13 @@ static void tx1_dma_buf_check(pc300_t * card, int ch)
 	printk("\n");
 }
 #endif
-			 
+
 static void rx_dma_buf_check(pc300_t * card, int ch)
 {
 	volatile pcsca_bd_t __iomem *ptdescr;
 	int i;
-	ucshort first_bd = card->chan[ch].rx_first_bd;
-	ucshort last_bd = card->chan[ch].rx_last_bd;
+	u16 first_bd = card->chan[ch].rx_first_bd;
+	u16 last_bd = card->chan[ch].rx_last_bd;
 	int ch_factor;
 
 	ch_factor = ch * N_DMA_RX_BUF;
@@ -440,9 +438,9 @@ static void rx_dma_buf_check(pc300_t * card, int ch)
 static int dma_get_rx_frame_size(pc300_t * card, int ch)
 {
 	volatile pcsca_bd_t __iomem *ptdescr;
-	ucshort first_bd = card->chan[ch].rx_first_bd;
+	u16 first_bd = card->chan[ch].rx_first_bd;
 	int rcvd = 0;
-	volatile ucchar status;
+	volatile u8 status;
 
 	ptdescr = (card->hw.rambase + RX_BD_ADDR(ch, first_bd));
 	while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
@@ -462,12 +460,12 @@ static int dma_get_rx_frame_size(pc300_t * card, int ch)
  * dma_buf_write: writes a frame to the Tx DMA buffers
  * NOTE: this function writes one frame at a time.
  */
-static int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
+static int dma_buf_write(pc300_t *card, int ch, u8 *ptdata, int len)
 {
 	int i, nchar;
 	volatile pcsca_bd_t __iomem *ptdescr;
 	int tosend = len;
-	ucchar nbuf = ((len - 1) / BD_DEF_LEN) + 1;
+	u8 nbuf = ((len - 1) / BD_DEF_LEN) + 1;
 
 	if (nbuf >= card->chan[ch].nfree_tx_bd) {
 		return -ENOMEM;
@@ -509,7 +507,7 @@ static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	volatile pcsca_bd_t __iomem *ptdescr;
 	int rcvd = 0;
-	volatile ucchar status;
+	volatile u8 status;
 
 	ptdescr = (card->hw.rambase +
 				  RX_BD_ADDR(ch, chan->rx_first_bd));
@@ -563,8 +561,8 @@ static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
 static void tx_dma_stop(pc300_t * card, int ch)
 {
 	void __iomem *scabase = card->hw.scabase;
-	ucchar drr_ena_bit = 1 << (5 + 2 * ch);
-	ucchar drr_rst_bit = 1 << (1 + 2 * ch);
+	u8 drr_ena_bit = 1 << (5 + 2 * ch);
+	u8 drr_rst_bit = 1 << (1 + 2 * ch);
 
 	/* Disable DMA */
 	cpc_writeb(scabase + DRR, drr_ena_bit);
@@ -574,8 +572,8 @@ static void tx_dma_stop(pc300_t * card, int ch)
 static void rx_dma_stop(pc300_t * card, int ch)
 {
 	void __iomem *scabase = card->hw.scabase;
-	ucchar drr_ena_bit = 1 << (4 + 2 * ch);
-	ucchar drr_rst_bit = 1 << (2 * ch);
+	u8 drr_ena_bit = 1 << (4 + 2 * ch);
+	u8 drr_rst_bit = 1 << (2 * ch);
 
 	/* Disable DMA */
 	cpc_writeb(scabase + DRR, drr_ena_bit);
@@ -607,7 +605,7 @@ static void rx_dma_start(pc300_t * card, int ch)
 /*************************/
 /***   FALC Routines   ***/
 /*************************/
-static void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
+static void falc_issue_cmd(pc300_t *card, int ch, u8 cmd)
 {
 	void __iomem *falcbase = card->hw.falcbase;
 	unsigned long i = 0;
@@ -675,7 +673,7 @@ static void falc_intr_enable(pc300_t * card, int ch)
 static void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
 {
 	void __iomem *falcbase = card->hw.falcbase;
-	ucchar tshf = card->chan[ch].falc.offset;
+	u8 tshf = card->chan[ch].falc.offset;
 
 	cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch),
 		   cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) & 
@@ -691,7 +689,7 @@ static void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
 static void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
 {
 	void __iomem *falcbase = card->hw.falcbase;
-	ucchar tshf = card->chan[ch].falc.offset;
+	u8 tshf = card->chan[ch].falc.offset;
 
 	cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch),
 		   cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf) / 8), ch)) | 
@@ -812,7 +810,7 @@ static void falc_init_t1(pc300_t * card, int ch)
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
 	falc_t *pfalc = (falc_t *) & chan->falc;
 	void __iomem *falcbase = card->hw.falcbase;
-	ucchar dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0);
+	u8 dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0);
 
 	/* Switch to T1 mode (PCM 24) */
 	cpc_writeb(falcbase + F_REG(FMR1, ch), FMR1_PMOD);
@@ -981,7 +979,7 @@ static void falc_init_e1(pc300_t * card, int ch)
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
 	falc_t *pfalc = (falc_t *) & chan->falc;
 	void __iomem *falcbase = card->hw.falcbase;
-	ucchar dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0);
+	u8 dja = (ch ? (LIM2_DJA2 | LIM2_DJA1) : 0);
 
 	/* Switch to E1 mode (PCM 30) */
 	cpc_writeb(falcbase + F_REG(FMR1, ch),
@@ -1187,7 +1185,7 @@ static void te_config(pc300_t * card, int ch)
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
 	falc_t *pfalc = (falc_t *) & chan->falc;
 	void __iomem *falcbase = card->hw.falcbase;
-	ucchar dummy;
+	u8 dummy;
 	unsigned long flags;
 
 	memset(pfalc, 0, sizeof(falc_t));
@@ -1403,7 +1401,7 @@ static void falc_update_stats(pc300_t * card, int ch)
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
 	falc_t *pfalc = (falc_t *) & chan->falc;
 	void __iomem *falcbase = card->hw.falcbase;
-	ucshort counter;
+	u16 counter;
 
 	counter = cpc_readb(falcbase + F_REG(FECL, ch));
 	counter |= cpc_readb(falcbase + F_REG(FECH, ch)) << 8;
@@ -1729,7 +1727,7 @@ static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
  * Description:	This routine returns the bit error counter value
  *----------------------------------------------------------------------------
  */
-static ucshort falc_pattern_test_error(pc300_t * card, int ch)
+static u16 falc_pattern_test_error(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
@@ -1776,7 +1774,7 @@ static void cpc_tx_timeout(struct net_device *dev)
 	pc300_t *card = (pc300_t *) chan->card;
 	int ch = chan->channel;
 	unsigned long flags;
-	ucchar ilar;
+	u8 ilar;
 
 	dev->stats.tx_errors++;
 	dev->stats.tx_aborted_errors++;
@@ -1807,11 +1805,7 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 	int i;
 #endif
 
-	if (chan->conf.monitor) {
-		/* In monitor mode no Tx is done: ignore packet */
-		dev_kfree_skb(skb);
-		return 0;
-	} else if (!netif_carrier_ok(dev)) {
+	if (!netif_carrier_ok(dev)) {
 		/* DCD must be OFF: drop packet */
 		dev_kfree_skb(skb);
 		dev->stats.tx_errors++;
@@ -1836,7 +1830,7 @@ static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	/* Write buffer to DMA buffers */
-	if (dma_buf_write(card, ch, (ucchar *) skb->data, skb->len) != 0) {
+	if (dma_buf_write(card, ch, (u8 *)skb->data, skb->len) != 0) {
 //		printk("%s: write error. Dropping TX packet.\n", dev->name);
 		netif_stop_queue(dev);
 		dev_kfree_skb(skb);
@@ -2001,7 +1995,7 @@ static void sca_tx_intr(pc300dev_t *dev)
 static void sca_intr(pc300_t * card)
 {
 	void __iomem *scabase = card->hw.scabase;
-	volatile uclong status;
+	volatile u32 status;
 	int ch;
 	int intr_count = 0;
 	unsigned char dsr_rx;
@@ -2016,7 +2010,7 @@ static void sca_intr(pc300_t * card)
 
 	    /**** Reception ****/
 			if (status & IR0_DRX((IR0_DMIA | IR0_DMIB), ch)) {
-				ucchar drx_stat = cpc_readb(scabase + DSR_RX(ch));
+				u8 drx_stat = cpc_readb(scabase + DSR_RX(ch));
 
 				/* Clear RX interrupts */
 				cpc_writeb(scabase + DSR_RX(ch), drx_stat | DSR_DWE);
@@ -2090,7 +2084,7 @@ static void sca_intr(pc300_t * card)
 
 	    /**** Transmission ****/
 			if (status & IR0_DTX((IR0_EFT | IR0_DMIA | IR0_DMIB), ch)) {
-				ucchar dtx_stat = cpc_readb(scabase + DSR_TX(ch));
+				u8 dtx_stat = cpc_readb(scabase + DSR_TX(ch));
 
 				/* Clear TX interrupts */
 				cpc_writeb(scabase + DSR_TX(ch), dtx_stat | DSR_DWE);
@@ -2134,7 +2128,7 @@ static void sca_intr(pc300_t * card)
 
 	    /**** MSCI ****/
 			if (status & IR0_M(IR0_RXINTA, ch)) {
-				ucchar st1 = cpc_readb(scabase + M_REG(ST1, ch));
+				u8 st1 = cpc_readb(scabase + M_REG(ST1, ch));
 
 				/* Clear MSCI interrupts */
 				cpc_writeb(scabase + M_REG(ST1, ch), st1);
@@ -2176,7 +2170,7 @@ static void sca_intr(pc300_t * card)
 	}
 }
 
-static void falc_t1_loop_detection(pc300_t * card, int ch, ucchar frs1)
+static void falc_t1_loop_detection(pc300_t *card, int ch, u8 frs1)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
@@ -2201,7 +2195,7 @@ static void falc_t1_loop_detection(pc300_t * card, int ch, ucchar frs1)
 	}
 }
 
-static void falc_e1_loop_detection(pc300_t * card, int ch, ucchar rsp)
+static void falc_e1_loop_detection(pc300_t *card, int ch, u8 rsp)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
@@ -2231,8 +2225,8 @@ static void falc_t1_intr(pc300_t * card, int ch)
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
 	void __iomem *falcbase = card->hw.falcbase;
-	ucchar isr0, isr3, gis;
-	ucchar dummy;
+	u8 isr0, isr3, gis;
+	u8 dummy;
 
 	while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) {
 		if (gis & GIS_ISR0) {
@@ -2278,8 +2272,8 @@ static void falc_e1_intr(pc300_t * card, int ch)
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
 	void __iomem *falcbase = card->hw.falcbase;
-	ucchar isr1, isr2, isr3, gis, rsp;
-	ucchar dummy;
+	u8 isr1, isr2, isr3, gis, rsp;
+	u8 dummy;
 
 	while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) {
 		rsp = cpc_readb(falcbase + F_REG(RSP, ch));
@@ -2361,7 +2355,7 @@ static void falc_intr(pc300_t * card)
 static irqreturn_t cpc_intr(int irq, void *dev_id)
 {
 	pc300_t *card = dev_id;
-	volatile ucchar plx_status;
+	volatile u8 plx_status;
 
 	if (!card) {
 #ifdef PC300_DEBUG_INTR
@@ -2400,7 +2394,7 @@ static irqreturn_t cpc_intr(int irq, void *dev_id)
 
 static void cpc_sca_status(pc300_t * card, int ch)
 {
-	ucchar ilar;
+	u8 ilar;
 	void __iomem *scabase = card->hw.scabase;
 	unsigned long flags;
 
@@ -2818,7 +2812,7 @@ static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	}
 }
 
-static int clock_rate_calc(uclong rate, uclong clock, int *br_io)
+static int clock_rate_calc(u32 rate, u32 clock, int *br_io)
 {
 	int br, tc;
 	int br_pwr, error;
@@ -2855,12 +2849,12 @@ static int ch_config(pc300dev_t * d)
 	void __iomem *scabase = card->hw.scabase;
 	void __iomem *plxbase = card->hw.plxbase;
 	int ch = chan->channel;
-	uclong clkrate = chan->conf.phys_settings.clock_rate;
-	uclong clktype = chan->conf.phys_settings.clock_type;
-	ucshort encoding = chan->conf.proto_settings.encoding;
-	ucshort parity = chan->conf.proto_settings.parity;   
-	ucchar md0, md2;
-    
+	u32 clkrate = chan->conf.phys_settings.clock_rate;
+	u32 clktype = chan->conf.phys_settings.clock_type;
+	u16 encoding = chan->conf.proto_settings.encoding;
+	u16 parity = chan->conf.proto_settings.parity;
+	u8 md0, md2;
+
 	/* Reset the channel */
 	cpc_writeb(scabase + M_REG(CMD, ch), CMD_CH_RST);
 
@@ -3152,19 +3146,10 @@ int cpc_open(struct net_device *dev)
 	printk("pc300: cpc_open");
 #endif
 
-#ifdef FIXME
-	if (hdlc->proto.id == IF_PROTO_PPP) {
-		d->if_ptr = &hdlc->state.ppp.pppdev;
-	}
-#endif
-
 	result = hdlc_open(dev);
-	if (/* FIXME hdlc->proto.id == IF_PROTO_PPP*/ 0) {
-		dev->priv = d;
-	}
-	if (result) {
+
+	if (result)
 		return result;
-	}
 
 	sprintf(ifr.ifr_name, "%s", dev->name);
 	result = cpc_opench(d);
@@ -3197,9 +3182,7 @@ static int cpc_close(struct net_device *dev)
 	CPC_UNLOCK(card, flags);
 
 	hdlc_close(dev);
-	if (/* FIXME hdlc->proto.id == IF_PROTO_PPP*/ 0) {
-		d->if_ptr = NULL;
-	}
+
 #ifdef CONFIG_PC300_MLPPP
 	if (chan->conf.proto == PC300_PROTO_MLPPP) {
 		cpc_tty_unregister_service(d);
@@ -3210,16 +3193,16 @@ static int cpc_close(struct net_device *dev)
 	return 0;
 }
 
-static uclong detect_ram(pc300_t * card)
+static u32 detect_ram(pc300_t * card)
 {
-	uclong i;
-	ucchar data;
+	u32 i;
+	u8 data;
 	void __iomem *rambase = card->hw.rambase;
 
 	card->hw.ramsize = PC300_RAMSIZE;
 	/* Let's find out how much RAM is present on this board */
 	for (i = 0; i < card->hw.ramsize; i++) {
-		data = (ucchar) (i & 0xff);
+		data = (u8)(i & 0xff);
 		cpc_writeb(rambase + i, data);
 		if (cpc_readb(rambase + i) != data) {
 			break;
@@ -3296,7 +3279,7 @@ static void cpc_init_card(pc300_t * card)
 	cpc_writeb(card->hw.scabase + DMER, 0x80);
 
 	if (card->hw.type == PC300_TE) {
-		ucchar reg1;
+		u8 reg1;
 
 		/* Check CPLD version */
 		reg1 = cpc_readb(card->hw.falcbase + CPLD_REG1);
@@ -3360,7 +3343,6 @@ static void cpc_init_card(pc300_t * card)
 		chan->nfree_tx_bd = N_DMA_TX_BUF;
 
 		d->chan = chan;
-		d->tx_skb = NULL;
 		d->trace_on = 0;
 		d->line_on = 0;
 		d->line_off = 0;
@@ -3431,7 +3413,7 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
 	static int first_time = 1;
 	int err, eeprom_outdated = 0;
-	ucshort device_id;
+	u16 device_id;
 	pc300_t *card;
 
 	if (first_time) {
diff --git a/drivers/net/wan/sealevel.c b/drivers/net/wan/sealevel.c
index 44a89df..c023584 100644
--- a/drivers/net/wan/sealevel.c
+++ b/drivers/net/wan/sealevel.c
@@ -8,6 +8,7 @@
  *
  *	(c) Copyright 1999, 2001 Alan Cox
  *	(c) Copyright 2001 Red Hat Inc.
+ *	Generic HDLC port Copyright (C) 2008 Krzysztof Halasa <khc@pm.waw.pl>
  *
  */
 
@@ -19,6 +20,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/delay.h>
+#include <linux/hdlc.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <net/arp.h>
@@ -27,22 +29,19 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/byteorder.h>
-#include <net/syncppp.h>
 #include "z85230.h"
 
 
 struct slvl_device
 {
-	void *if_ptr;	/* General purpose pointer (used by SPPP) */
 	struct z8530_channel *chan;
-	struct ppp_device pppdev;
 	int channel;
 };
 
 
 struct slvl_board
 {
-	struct slvl_device *dev[2];
+	struct slvl_device dev[2];
 	struct z8530_dev board;
 	int iobase;
 };
@@ -51,72 +50,69 @@ struct slvl_board
  *	Network driver support routines
  */
 
+static inline struct slvl_device* dev_to_chan(struct net_device *dev)
+{
+	return (struct slvl_device *)dev_to_hdlc(dev)->priv;
+}
+
 /*
- *	Frame receive. Simple for our card as we do sync ppp and there
+ *	Frame receive. Simple for our card as we do HDLC and there
  *	is no funny garbage involved
  */
- 
+
 static void sealevel_input(struct z8530_channel *c, struct sk_buff *skb)
 {
 	/* Drop the CRC - it's not a good idea to try and negotiate it ;) */
-	skb_trim(skb, skb->len-2);
-	skb->protocol=htons(ETH_P_WAN_PPP);
+	skb_trim(skb, skb->len - 2);
+	skb->protocol = hdlc_type_trans(skb, c->netdevice);
 	skb_reset_mac_header(skb);
-	skb->dev=c->netdevice;
-	/*
-	 *	Send it to the PPP layer. We don't have time to process
-	 *	it right now.
-	 */
+	skb->dev = c->netdevice;
 	netif_rx(skb);
 	c->netdevice->last_rx = jiffies;
 }
- 
+
 /*
  *	We've been placed in the UP state
- */ 
- 
+ */
+
 static int sealevel_open(struct net_device *d)
 {
-	struct slvl_device *slvl=d->priv;
+	struct slvl_device *slvl = dev_to_chan(d);
 	int err = -1;
 	int unit = slvl->channel;
-	
+
 	/*
-	 *	Link layer up. 
+	 *	Link layer up.
 	 */
 
-	switch(unit)
+	switch (unit)
 	{
 		case 0:
-			err=z8530_sync_dma_open(d, slvl->chan);
+			err = z8530_sync_dma_open(d, slvl->chan);
 			break;
 		case 1:
-			err=z8530_sync_open(d, slvl->chan);
+			err = z8530_sync_open(d, slvl->chan);
 			break;
 	}
-	
-	if(err)
+
+	if (err)
 		return err;
-	/*
-	 *	Begin PPP
-	 */
-	err=sppp_open(d);
-	if(err)
-	{
-		switch(unit)
-		{
+
+	err = hdlc_open(d);
+	if (err) {
+		switch (unit) {
 			case 0:
 				z8530_sync_dma_close(d, slvl->chan);
 				break;
 			case 1:
 				z8530_sync_close(d, slvl->chan);
 				break;
-		}				
+		}
 		return err;
 	}
-	
-	slvl->chan->rx_function=sealevel_input;
-	
+
+	slvl->chan->rx_function = sealevel_input;
+
 	/*
 	 *	Go go go
 	 */
@@ -126,26 +122,19 @@ static int sealevel_open(struct net_device *d)
 
 static int sealevel_close(struct net_device *d)
 {
-	struct slvl_device *slvl=d->priv;
+	struct slvl_device *slvl = dev_to_chan(d);
 	int unit = slvl->channel;
-	
+
 	/*
 	 *	Discard new frames
 	 */
-	
-	slvl->chan->rx_function=z8530_null_rx;
-		
-	/*
-	 *	PPP off
-	 */
-	sppp_close(d);
-	/*
-	 *	Link layer down
-	 */
 
+	slvl->chan->rx_function = z8530_null_rx;
+
+	hdlc_close(d);
 	netif_stop_queue(d);
-		
-	switch(unit)
+
+	switch (unit)
 	{
 		case 0:
 			z8530_sync_dma_close(d, slvl->chan);
@@ -159,210 +148,153 @@ static int sealevel_close(struct net_device *d)
 
 static int sealevel_ioctl(struct net_device *d, struct ifreq *ifr, int cmd)
 {
-	/* struct slvl_device *slvl=d->priv;
+	/* struct slvl_device *slvl=dev_to_chan(d);
 	   z8530_ioctl(d,&slvl->sync.chanA,ifr,cmd) */
-	return sppp_do_ioctl(d, ifr,cmd);
-}
-
-static struct net_device_stats *sealevel_get_stats(struct net_device *d)
-{
-	struct slvl_device *slvl=d->priv;
-	if(slvl)
-		return z8530_get_stats(slvl->chan);
-	else
-		return NULL;
+	return hdlc_ioctl(d, ifr, cmd);
 }
 
 /*
- *	Passed PPP frames, fire them downwind.
+ *	Passed network frames, fire them downwind.
  */
- 
+
 static int sealevel_queue_xmit(struct sk_buff *skb, struct net_device *d)
 {
-	struct slvl_device *slvl=d->priv;
-	return z8530_queue_xmit(slvl->chan, skb);
+	return z8530_queue_xmit(dev_to_chan(d)->chan, skb);
 }
 
-static int sealevel_neigh_setup(struct neighbour *n)
+static int sealevel_attach(struct net_device *dev, unsigned short encoding,
+			   unsigned short parity)
 {
-	if (n->nud_state == NUD_NONE) {
-		n->ops = &arp_broken_ops;
-		n->output = n->ops->output;
-	}
-	return 0;
+	if (encoding == ENCODING_NRZ && parity == PARITY_CRC16_PR1_CCITT)
+		return 0;
+	return -EINVAL;
 }
 
-static int sealevel_neigh_setup_dev(struct net_device *dev, struct neigh_parms *p)
+static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
 {
-	if (p->tbl->family == AF_INET) {
-		p->neigh_setup = sealevel_neigh_setup;
-		p->ucast_probes = 0;
-		p->mcast_probes = 0;
+	struct net_device *dev = alloc_hdlcdev(sv);
+	if (!dev)
+		return -1;
+
+	dev_to_hdlc(dev)->attach = sealevel_attach;
+	dev_to_hdlc(dev)->xmit = sealevel_queue_xmit;
+	dev->open = sealevel_open;
+	dev->stop = sealevel_close;
+	dev->do_ioctl = sealevel_ioctl;
+	dev->base_addr = iobase;
+	dev->irq = irq;
+
+	if (register_hdlc_device(dev)) {
+		printk(KERN_ERR "sealevel: unable to register HDLC device\n");
+		free_netdev(dev);
+		return -1;
 	}
-	return 0;
-}
 
-static int sealevel_attach(struct net_device *dev)
-{
-	struct slvl_device *sv = dev->priv;
-	sppp_attach(&sv->pppdev);
+	sv->chan->netdevice = dev;
 	return 0;
 }
 
-static void sealevel_detach(struct net_device *dev)
-{
-	sppp_detach(dev);
-}
-		
-static void slvl_setup(struct net_device *d)
-{
-	d->open = sealevel_open;
-	d->stop = sealevel_close;
-	d->init = sealevel_attach;
-	d->uninit = sealevel_detach;
-	d->hard_start_xmit = sealevel_queue_xmit;
-	d->get_stats = sealevel_get_stats;
-	d->set_multicast_list = NULL;
-	d->do_ioctl = sealevel_ioctl;
-	d->neigh_setup = sealevel_neigh_setup_dev;
-	d->set_mac_address = NULL;
-
-}
-
-static inline struct slvl_device *slvl_alloc(int iobase, int irq)
-{
-	struct net_device *d;
-	struct slvl_device *sv;
-
-	d = alloc_netdev(sizeof(struct slvl_device), "hdlc%d",
-			 slvl_setup);
-
-	if (!d) 
-		return NULL;
-
-	sv = d->priv;
-	d->ml_priv = sv;
-	sv->if_ptr = &sv->pppdev;
-	sv->pppdev.dev = d;
-	d->base_addr = iobase;
-	d->irq = irq;
-		
-	return sv;
-}
-
 
 /*
  *	Allocate and setup Sealevel board.
  */
- 
-static __init struct slvl_board *slvl_init(int iobase, int irq, 
+
+static __init struct slvl_board *slvl_init(int iobase, int irq,
 					   int txdma, int rxdma, int slow)
 {
 	struct z8530_dev *dev;
 	struct slvl_board *b;
-	
+
 	/*
 	 *	Get the needed I/O space
 	 */
 
-	if(!request_region(iobase, 8, "Sealevel 4021")) 
-	{	
-		printk(KERN_WARNING "sealevel: I/O 0x%X already in use.\n", iobase);
+	if (!request_region(iobase, 8, "Sealevel 4021")) {
+		printk(KERN_WARNING "sealevel: I/O 0x%X already in use.\n",
+		       iobase);
 		return NULL;
 	}
-	
-	b = kzalloc(sizeof(struct slvl_board), GFP_KERNEL);
-	if(!b)
-		goto fail3;
 
-	if (!(b->dev[0]= slvl_alloc(iobase, irq)))
-		goto fail2;
+	b = kzalloc(sizeof(struct slvl_board), GFP_KERNEL);
+	if (!b)
+		goto err_kzalloc;
 
-	b->dev[0]->chan = &b->board.chanA;	
-	b->dev[0]->channel = 0;
-	
-	if (!(b->dev[1] = slvl_alloc(iobase, irq)))
-		goto fail1_0;
+	b->dev[0].chan = &b->board.chanA;
+	b->dev[0].channel = 0;
 
-	b->dev[1]->chan = &b->board.chanB;
-	b->dev[1]->channel = 1;
+	b->dev[1].chan = &b->board.chanB;
+	b->dev[1].channel = 1;
 
 	dev = &b->board;
-	
+
 	/*
 	 *	Stuff in the I/O addressing
 	 */
-	 
+
 	dev->active = 0;
 
 	b->iobase = iobase;
-	
+
 	/*
 	 *	Select 8530 delays for the old board
 	 */
-	 
-	if(slow)
+
+	if (slow)
 		iobase |= Z8530_PORT_SLEEP;
-		
-	dev->chanA.ctrlio=iobase+1;
-	dev->chanA.dataio=iobase;
-	dev->chanB.ctrlio=iobase+3;
-	dev->chanB.dataio=iobase+2;
-	
-	dev->chanA.irqs=&z8530_nop;
-	dev->chanB.irqs=&z8530_nop;
-	
+
+	dev->chanA.ctrlio = iobase + 1;
+	dev->chanA.dataio = iobase;
+	dev->chanB.ctrlio = iobase + 3;
+	dev->chanB.dataio = iobase + 2;
+
+	dev->chanA.irqs = &z8530_nop;
+	dev->chanB.irqs = &z8530_nop;
+
 	/*
 	 *	Assert DTR enable DMA
 	 */
-	 
-	outb(3|(1<<7), b->iobase+4);	
-	
+
+	outb(3 | (1 << 7), b->iobase + 4);
+
 
 	/* We want a fast IRQ for this device. Actually we'd like an even faster
 	   IRQ ;) - This is one driver RtLinux is made for */
-   
-	if(request_irq(irq, &z8530_interrupt, IRQF_DISABLED, "SeaLevel", dev)<0)
-	{
+
+	if (request_irq(irq, &z8530_interrupt, IRQF_DISABLED,
+			"SeaLevel", dev) < 0) {
 		printk(KERN_WARNING "sealevel: IRQ %d already in use.\n", irq);
-		goto fail1_1;
+		goto err_request_irq;
 	}
-	
-	dev->irq=irq;
-	dev->chanA.private=&b->dev[0];
-	dev->chanB.private=&b->dev[1];
-	dev->chanA.netdevice=b->dev[0]->pppdev.dev;
-	dev->chanB.netdevice=b->dev[1]->pppdev.dev;
-	dev->chanA.dev=dev;
-	dev->chanB.dev=dev;
-
-	dev->chanA.txdma=3;
-	dev->chanA.rxdma=1;
-	if(request_dma(dev->chanA.txdma, "SeaLevel (TX)")!=0)
-		goto fail;
-		
-	if(request_dma(dev->chanA.rxdma, "SeaLevel (RX)")!=0)
-		goto dmafail;
-	
+
+	dev->irq = irq;
+	dev->chanA.private = &b->dev[0];
+	dev->chanB.private = &b->dev[1];
+	dev->chanA.dev = dev;
+	dev->chanB.dev = dev;
+
+	dev->chanA.txdma = 3;
+	dev->chanA.rxdma = 1;
+	if (request_dma(dev->chanA.txdma, "SeaLevel (TX)"))
+		goto err_dma_tx;
+
+	if (request_dma(dev->chanA.rxdma, "SeaLevel (RX)"))
+		goto err_dma_rx;
+
 	disable_irq(irq);
-		
+
 	/*
 	 *	Begin normal initialise
 	 */
-	 
-	if(z8530_init(dev)!=0)
-	{
+
+	if (z8530_init(dev) != 0) {
 		printk(KERN_ERR "Z8530 series device not found.\n");
 		enable_irq(irq);
-		goto dmafail2;
+		goto free_hw;
 	}
-	if(dev->type==Z85C30)
-	{
+	if (dev->type == Z85C30) {
 		z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream);
 		z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream);
-	}
-	else
-	{
+	} else {
 		z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream_85230);
 		z8530_channel_load(&dev->chanB, z8530_hdlc_kilostream_85230);
 	}
@@ -370,36 +302,31 @@ static __init struct slvl_board *slvl_init(int iobase, int irq,
 	/*
 	 *	Now we can take the IRQ
 	 */
-	
+
 	enable_irq(irq);
 
-	if (register_netdev(b->dev[0]->pppdev.dev)) 
-		goto dmafail2;
-		
-	if (register_netdev(b->dev[1]->pppdev.dev)) 
-		goto fail_unit;
+	if (slvl_setup(&b->dev[0], iobase, irq))
+		goto free_hw;
+	if (slvl_setup(&b->dev[1], iobase, irq))
+		goto free_netdev0;
 
 	z8530_describe(dev, "I/O", iobase);
-	dev->active=1;
+	dev->active = 1;
 	return b;
 
-fail_unit:
-	unregister_netdev(b->dev[0]->pppdev.dev);
-	
-dmafail2:
+free_netdev0:
+	unregister_hdlc_device(b->dev[0].chan->netdevice);
+	free_netdev(b->dev[0].chan->netdevice);
+free_hw:
 	free_dma(dev->chanA.rxdma);
-dmafail:
+err_dma_rx:
 	free_dma(dev->chanA.txdma);
-fail:
+err_dma_tx:
 	free_irq(irq, dev);
-fail1_1:
-	free_netdev(b->dev[1]->pppdev.dev);
-fail1_0:
-	free_netdev(b->dev[0]->pppdev.dev);
-fail2:
+err_request_irq:
 	kfree(b);
-fail3:
-	release_region(iobase,8);
+err_kzalloc:
+	release_region(iobase, 8);
 	return NULL;
 }
 
@@ -408,14 +335,14 @@ static void __exit slvl_shutdown(struct slvl_board *b)
 	int u;
 
 	z8530_shutdown(&b->board);
-	
-	for(u=0; u<2; u++)
+
+	for (u = 0; u < 2; u++)
 	{
-		struct net_device *d = b->dev[u]->pppdev.dev;
-		unregister_netdev(d);
+		struct net_device *d = b->dev[u].chan->netdevice;
+		unregister_hdlc_device(d);
 		free_netdev(d);
 	}
-	
+
 	free_irq(b->board.irq, &b->board);
 	free_dma(b->board.chanA.rxdma);
 	free_dma(b->board.chanA.txdma);
@@ -451,10 +378,6 @@ static struct slvl_board *slvl_unit;
 
 static int __init slvl_init_module(void)
 {
-#ifdef MODULE
-	printk(KERN_INFO "SeaLevel Z85230 Synchronous Driver v 0.02.\n");
-	printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");
-#endif
 	slvl_unit = slvl_init(io, irq, txdma, rxdma, slow);
 
 	return slvl_unit ? 0 : -ENODEV;
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index 29b4b94..327d585 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -230,13 +230,6 @@ static void sppp_input (struct net_device *dev, struct sk_buff *skb)
 	skb->dev=dev;
 	skb_reset_mac_header(skb);
 
-	if (dev->flags & IFF_RUNNING)
-	{
-		/* Count received bytes, add FCS and one flag */
-		sp->ibytes+= skb->len + 3;
-		sp->ipkts++;
-	}
-
 	if (!pskb_may_pull(skb, PPP_HEADER_LEN)) {
 		/* Too small packet, drop it. */
 		if (sp->pp_flags & PP_DEBUG)
@@ -832,7 +825,6 @@ static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,
 			sppp_print_bytes ((u8*) (lh+1), len);
 		printk (">\n");
 	}
-	sp->obytes += skb->len;
 	/* Control is high priority so it doesn't get queued behind data */
 	skb->priority=TC_PRIO_CONTROL;
 	skb->dev = dev;
@@ -875,7 +867,6 @@ static void sppp_cisco_send (struct sppp *sp, int type, u32 par1, u32 par2)
 		printk (KERN_WARNING "%s: cisco output: <%xh %xh %xh %xh %xh-%xh>\n",
 			dev->name,  ntohl (ch->type), ch->par1,
 			ch->par2, ch->rel, ch->time0, ch->time1);
-	sp->obytes += skb->len;
 	skb->priority=TC_PRIO_CONTROL;
 	skb->dev = dev;
 	skb_queue_tail(&tx_queue, skb);
diff --git a/drivers/net/wan/z85230.c b/drivers/net/wan/z85230.c
index 98ef400..243bd8d 100644
--- a/drivers/net/wan/z85230.c
+++ b/drivers/net/wan/z85230.c
@@ -43,6 +43,7 @@
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 #include <linux/delay.h>
+#include <linux/hdlc.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
 #include <asm/dma.h>
@@ -51,7 +52,6 @@
 #define RT_UNLOCK
 #include <linux/spinlock.h>
 
-#include <net/syncppp.h>
 #include "z85230.h"
 
 
@@ -440,51 +440,46 @@ static void z8530_tx(struct z8530_channel *c)
  *	A status event occurred in PIO synchronous mode. There are several
  *	reasons the chip will bother us here. A transmit underrun means we
  *	failed to feed the chip fast enough and just broke a packet. A DCD
- *	change is a line up or down. We communicate that back to the protocol
- *	layer for synchronous PPP to renegotiate.
+ *	change is a line up or down.
  */
 
 static void z8530_status(struct z8530_channel *chan)
 {
 	u8 status, altered;
 
-	status=read_zsreg(chan, R0);
-	altered=chan->status^status;
-	
-	chan->status=status;
-	
-	if(status&TxEOM)
-	{
+	status = read_zsreg(chan, R0);
+	altered = chan->status ^ status;
+
+	chan->status = status;
+
+	if (status & TxEOM) {
 /*		printk("%s: Tx underrun.\n", chan->dev->name); */
-		chan->stats.tx_fifo_errors++;
+		chan->netdevice->stats.tx_fifo_errors++;
 		write_zsctrl(chan, ERR_RES);
 		z8530_tx_done(chan);
 	}
-		
-	if(altered&chan->dcdcheck)
+
+	if (altered & chan->dcdcheck)
 	{
-		if(status&chan->dcdcheck)
-		{
+		if (status & chan->dcdcheck) {
 			printk(KERN_INFO "%s: DCD raised\n", chan->dev->name);
-			write_zsreg(chan, R3, chan->regs[3]|RxENABLE);
-			if(chan->netdevice &&
-			    ((chan->netdevice->type == ARPHRD_HDLC) ||
-			    (chan->netdevice->type == ARPHRD_PPP)))
-				sppp_reopen(chan->netdevice);
-		}
-		else
-		{
+			write_zsreg(chan, R3, chan->regs[3] | RxENABLE);
+			if (chan->netdevice)
+				netif_carrier_on(chan->netdevice);
+		} else {
 			printk(KERN_INFO "%s: DCD lost\n", chan->dev->name);
-			write_zsreg(chan, R3, chan->regs[3]&~RxENABLE);
+			write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE);
 			z8530_flush_fifo(chan);
+			if (chan->netdevice)
+				netif_carrier_off(chan->netdevice);
 		}
-		
-	}	
+
+	}
 	write_zsctrl(chan, RES_EXT_INT);
 	write_zsctrl(chan, RES_H_IUS);
 }
 
-struct z8530_irqhandler z8530_sync=
+struct z8530_irqhandler z8530_sync =
 {
 	z8530_rx,
 	z8530_tx,
@@ -556,8 +551,7 @@ static void z8530_dma_tx(struct z8530_channel *chan)
  *	
  *	A status event occurred on the Z8530. We receive these for two reasons
  *	when in DMA mode. Firstly if we finished a packet transfer we get one
- *	and kick the next packet out. Secondly we may see a DCD change and
- *	have to poke the protocol layer.
+ *	and kick the next packet out. Secondly we may see a DCD change.
  *
  */
  
@@ -586,24 +580,21 @@ static void z8530_dma_status(struct z8530_channel *chan)
 		}
 	}
 
-	if(altered&chan->dcdcheck)
+	if (altered & chan->dcdcheck)
 	{
-		if(status&chan->dcdcheck)
-		{
+		if (status & chan->dcdcheck) {
 			printk(KERN_INFO "%s: DCD raised\n", chan->dev->name);
-			write_zsreg(chan, R3, chan->regs[3]|RxENABLE);
-			if(chan->netdevice &&
-			    ((chan->netdevice->type == ARPHRD_HDLC) ||
-			    (chan->netdevice->type == ARPHRD_PPP)))
-				sppp_reopen(chan->netdevice);
-		}
-		else
-		{
+			write_zsreg(chan, R3, chan->regs[3] | RxENABLE);
+			if (chan->netdevice)
+				netif_carrier_on(chan->netdevice);
+		} else {
 			printk(KERN_INFO "%s:DCD lost\n", chan->dev->name);
-			write_zsreg(chan, R3, chan->regs[3]&~RxENABLE);
+			write_zsreg(chan, R3, chan->regs[3] & ~RxENABLE);
 			z8530_flush_fifo(chan);
+			if (chan->netdevice)
+				netif_carrier_off(chan->netdevice);
 		}
-	}	
+	}
 
 	write_zsctrl(chan, RES_EXT_INT);
 	write_zsctrl(chan, RES_H_IUS);
@@ -1459,10 +1450,10 @@ static void z8530_tx_begin(struct z8530_channel *c)
 			/*
 			 *	Check if we crapped out.
 			 */
-			if(get_dma_residue(c->txdma))
+			if (get_dma_residue(c->txdma))
 			{
-				c->stats.tx_dropped++;
-				c->stats.tx_fifo_errors++;
+				c->netdevice->stats.tx_dropped++;
+				c->netdevice->stats.tx_fifo_errors++;
 			}
 			release_dma_lock(flags);
 		}
@@ -1534,21 +1525,21 @@ static void z8530_tx_begin(struct z8530_channel *c)
  *	packet. This code is fairly timing sensitive.
  *
  *	Called with the register lock held.
- */ 
- 
+ */
+
 static void z8530_tx_done(struct z8530_channel *c)
 {
 	struct sk_buff *skb;
 
 	/* Actually this can happen.*/
-	if(c->tx_skb==NULL)
+	if (c->tx_skb == NULL)
 		return;
 
-	skb=c->tx_skb;
-	c->tx_skb=NULL;
+	skb = c->tx_skb;
+	c->tx_skb = NULL;
 	z8530_tx_begin(c);
-	c->stats.tx_packets++;
-	c->stats.tx_bytes+=skb->len;
+	c->netdevice->stats.tx_packets++;
+	c->netdevice->stats.tx_bytes += skb->len;
 	dev_kfree_skb_irq(skb);
 }
 
@@ -1558,7 +1549,7 @@ static void z8530_tx_done(struct z8530_channel *c)
  *	@skb: The buffer
  *
  *	We point the receive handler at this function when idle. Instead
- *	of syncppp processing the frames we get to throw them away.
+ *	of processing the frames we get to throw them away.
  */
  
 void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb)
@@ -1635,10 +1626,11 @@ static void z8530_rx_done(struct z8530_channel *c)
 		else
 			/* Can't occur as we dont reenable the DMA irq until
 			   after the flip is done */
-			printk(KERN_WARNING "%s: DMA flip overrun!\n", c->netdevice->name);
-			
+			printk(KERN_WARNING "%s: DMA flip overrun!\n",
+			       c->netdevice->name);
+
 		release_dma_lock(flags);
-		
+
 		/*
 		 *	Shove the old buffer into an sk_buff. We can't DMA
 		 *	directly into one on a PC - it might be above the 16Mb
@@ -1646,27 +1638,23 @@ static void z8530_rx_done(struct z8530_channel *c)
 		 *	can avoid the copy. Optimisation 2 - make the memcpy
 		 *	a copychecksum.
 		 */
-		 
-		skb=dev_alloc_skb(ct);
-		if(skb==NULL)
-		{
-			c->stats.rx_dropped++;
-			printk(KERN_WARNING "%s: Memory squeeze.\n", c->netdevice->name);
-		}
-		else
-		{
+
+		skb = dev_alloc_skb(ct);
+		if (skb == NULL) {
+			c->netdevice->stats.rx_dropped++;
+			printk(KERN_WARNING "%s: Memory squeeze.\n",
+			       c->netdevice->name);
+		} else {
 			skb_put(skb, ct);
 			skb_copy_to_linear_data(skb, rxb, ct);
-			c->stats.rx_packets++;
-			c->stats.rx_bytes+=ct;
+			c->netdevice->stats.rx_packets++;
+			c->netdevice->stats.rx_bytes += ct;
 		}
-		c->dma_ready=1;
-	}
-	else
-	{
-		RT_LOCK;	
-		skb=c->skb;
-		
+		c->dma_ready = 1;
+	} else {
+		RT_LOCK;
+		skb = c->skb;
+
 		/*
 		 *	The game we play for non DMA is similar. We want to
 		 *	get the controller set up for the next packet as fast
@@ -1677,48 +1665,39 @@ static void z8530_rx_done(struct z8530_channel *c)
 		 *	if you build a system where the sync irq isnt blocked
 		 *	by the kernel IRQ disable then you need only block the
 		 *	sync IRQ for the RT_LOCK area.
-		 *	
+		 *
 		 */
 		ct=c->count;
-		
+
 		c->skb = c->skb2;
 		c->count = 0;
 		c->max = c->mtu;
-		if(c->skb)
-		{
+		if (c->skb) {
 			c->dptr = c->skb->data;
 			c->max = c->mtu;
-		}
-		else
-		{
-			c->count= 0;
+		} else {
+			c->count = 0;
 			c->max = 0;
 		}
 		RT_UNLOCK;
 
 		c->skb2 = dev_alloc_skb(c->mtu);
-		if(c->skb2==NULL)
+		if (c->skb2 == NULL)
 			printk(KERN_WARNING "%s: memory squeeze.\n",
-				c->netdevice->name);
+			       c->netdevice->name);
 		else
-		{
-			skb_put(c->skb2,c->mtu);
-		}
-		c->stats.rx_packets++;
-		c->stats.rx_bytes+=ct;
-		
+			skb_put(c->skb2, c->mtu);
+		c->netdevice->stats.rx_packets++;
+		c->netdevice->stats.rx_bytes += ct;
 	}
 	/*
 	 *	If we received a frame we must now process it.
 	 */
-	if(skb)
-	{
+	if (skb) {
 		skb_trim(skb, ct);
-		c->rx_function(c,skb);
-	}
-	else
-	{
-		c->stats.rx_dropped++;
+		c->rx_function(c, skb);
+	} else {
+		c->netdevice->stats.rx_dropped++;
 		printk(KERN_ERR "%s: Lost a frame\n", c->netdevice->name);
 	}
 }
@@ -1730,7 +1709,7 @@ static void z8530_rx_done(struct z8530_channel *c)
  *	Returns true if the buffer cross a DMA boundary on a PC. The poor
  *	thing can only DMA within a 64K block not across the edges of it.
  */
- 
+
 static inline int spans_boundary(struct sk_buff *skb)
 {
 	unsigned long a=(unsigned long)skb->data;
@@ -1799,24 +1778,6 @@ int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb)
 
 EXPORT_SYMBOL(z8530_queue_xmit);
 
-/**
- *	z8530_get_stats - Get network statistics
- *	@c: The channel to use
- *
- *	Get the statistics block. We keep the statistics in software as
- *	the chip doesn't do it for us.
- *
- *	Locking is ignored here - we could lock for a copy but its
- *	not likely to be that big an issue
- */
- 
-struct net_device_stats *z8530_get_stats(struct z8530_channel *c)
-{
-	return &c->stats;
-}
-
-EXPORT_SYMBOL(z8530_get_stats);
-
 /*
  *	Module support
  */
diff --git a/drivers/net/wan/z85230.h b/drivers/net/wan/z85230.h
index 158aea7..4f37239 100644
--- a/drivers/net/wan/z85230.h
+++ b/drivers/net/wan/z85230.h
@@ -325,7 +325,6 @@ struct z8530_channel
 
 	void		*private;	/* For our owner */
 	struct net_device	*netdevice;	/* Network layer device */
-	struct net_device_stats stats;	/* Network layer statistics */
 
 	/*
 	 *	Async features
@@ -366,13 +365,13 @@ struct z8530_channel
 	unsigned char		tx_active; /* character is being xmitted */
 	unsigned char		tx_stopped; /* output is suspended */
 
-	spinlock_t		*lock;	  /* Devicr lock */
-};	
+	spinlock_t		*lock;	  /* Device lock */
+};
 
 /*
  *	Each Z853x0 device.
- */	
- 
+ */
+
 struct z8530_dev
 {
 	char *name;	/* Device instance name */
@@ -408,7 +407,6 @@ extern int z8530_sync_txdma_open(struct net_device *, struct z8530_channel *);
 extern int z8530_sync_txdma_close(struct net_device *, struct z8530_channel *);
 extern int z8530_channel_load(struct z8530_channel *, u8 *);
 extern int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb);
-extern struct net_device_stats *z8530_get_stats(struct z8530_channel *c);
 extern void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb);
 
 
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index b047306..1ebcafe 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -1998,13 +1998,6 @@ __orinoco_set_multicast_list(struct net_device *dev)
 		else
 			priv->mc_count = mc_count;
 	}
-
-	/* Since we can set the promiscuous flag when it wasn't asked
-	   for, make sure the net_device knows about it. */
-	if (priv->promiscuous)
-		dev->flags |= IFF_PROMISC;
-	else
-		dev->flags &= ~IFF_PROMISC;
 }
 
 /* This must be called from user context, without locks held - use
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 49ae970..136220b 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -1409,9 +1409,6 @@ static void wavelan_set_multicast_list(struct net_device * dev)
 			lp->mc_count = 0;
 
 			wv_82586_reconfig(dev);
-
-			/* Tell the kernel that we are doing a really bad job. */
-			dev->flags |= IFF_PROMISC;
 		}
 	} else
 		/* Are there multicast addresses to send? */
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index b584c0e..00a3559 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -1412,9 +1412,6 @@ wavelan_set_multicast_list(struct net_device *	dev)
 	  lp->mc_count = 0;
 
 	  wv_82593_reconfig(dev);
-
-	  /* Tell the kernel that we are doing a really bad job... */
-	  dev->flags |= IFF_PROMISC;
 	}
     }
   else
@@ -1433,9 +1430,6 @@ wavelan_set_multicast_list(struct net_device *	dev)
 	    lp->mc_count = 0;
 
 	    wv_82593_reconfig(dev);
-
-	    /* Tell the kernel that we are doing a really bad job... */
-	    dev->flags |= IFF_ALLMULTI;
 	  }
       }
     else
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index 902bbe7..c749bdb 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -329,7 +329,7 @@ static int xennet_open(struct net_device *dev)
 	}
 	spin_unlock_bh(&np->rx_lock);
 
-	xennet_maybe_wake_tx(dev);
+	netif_start_queue(dev);
 
 	return 0;
 }
diff --git a/include/linux/dm9000.h b/include/linux/dm9000.h
index fc82446..c30879c 100644
--- a/include/linux/dm9000.h
+++ b/include/linux/dm9000.h
@@ -27,6 +27,7 @@
 
 struct dm9000_plat_data {
 	unsigned int	flags;
+	unsigned char	dev_addr[6];
 
 	/* allow replacement IO routines */
 
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 8bb5e87..b4b038b 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -27,9 +27,24 @@ struct ethtool_cmd {
 	__u8	autoneg;	/* Enable or disable autonegotiation */
 	__u32	maxtxpkt;	/* Tx pkts before generating tx int */
 	__u32	maxrxpkt;	/* Rx pkts before generating rx int */
-	__u32	reserved[4];
+	__u16	speed_hi;
+	__u16	reserved2;
+	__u32	reserved[3];
 };
 
+static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
+						__u32 speed)
+{
+
+	ep->speed = (__u16)speed;
+	ep->speed_hi = (__u16)(speed >> 16);
+}
+
+static inline __u32 ethtool_cmd_speed(struct ethtool_cmd *ep)
+{
+	return (ep->speed_hi << 16) | ep->speed;
+}
+
 #define ETHTOOL_BUSINFO_LEN	32
 /* these strings are set to whatever the driver author decides... */
 struct ethtool_drvinfo {
diff --git a/include/net/syncppp.h b/include/net/syncppp.h
index e43f407..9e306f7 100644
--- a/include/net/syncppp.h
+++ b/include/net/syncppp.h
@@ -43,8 +43,6 @@ struct sppp
 	u32		pp_rseq;	/* remote sequence number */
 	struct slcp	lcp;		/* LCP params */
 	struct sipcp	ipcp;		/* IPCP params */
-	u32		ibytes,obytes;	/* Bytes in/out */
-	u32		ipkts,opkts;	/* Packets in/out */
 	struct timer_list	pp_timer;
 	struct net_device	*pp_if;
 	char		pp_link_state;	/* Link status */
diff --git a/net/core/dev.c b/net/core/dev.c
index 01993ad..600bb23 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1939,22 +1939,6 @@ int netif_rx_ni(struct sk_buff *skb)
 
 EXPORT_SYMBOL(netif_rx_ni);
 
-static inline struct net_device *skb_bond(struct sk_buff *skb)
-{
-	struct net_device *dev = skb->dev;
-
-	if (dev->master) {
-		if (skb_bond_should_drop(skb)) {
-			kfree_skb(skb);
-			return NULL;
-		}
-		skb->dev = dev->master;
-	}
-
-	return dev;
-}
-
-
 static void net_tx_action(struct softirq_action *h)
 {
 	struct softnet_data *sd = &__get_cpu_var(softnet_data);
@@ -2181,6 +2165,7 @@ int netif_receive_skb(struct sk_buff *skb)
 {
 	struct packet_type *ptype, *pt_prev;
 	struct net_device *orig_dev;
+	struct net_device *null_or_orig;
 	int ret = NET_RX_DROP;
 	__be16 type;
 
@@ -2194,10 +2179,14 @@ int netif_receive_skb(struct sk_buff *skb)
 	if (!skb->iif)
 		skb->iif = skb->dev->ifindex;
 
-	orig_dev = skb_bond(skb);
-
-	if (!orig_dev)
-		return NET_RX_DROP;
+	null_or_orig = NULL;
+	orig_dev = skb->dev;
+	if (orig_dev->master) {
+		if (skb_bond_should_drop(skb))
+			null_or_orig = orig_dev; /* deliver only exact match */
+		else
+			skb->dev = orig_dev->master;
+	}
 
 	__get_cpu_var(netdev_rx_stat).total++;
 
@@ -2221,7 +2210,8 @@ int netif_receive_skb(struct sk_buff *skb)
 #endif
 
 	list_for_each_entry_rcu(ptype, &ptype_all, list) {
-		if (!ptype->dev || ptype->dev == skb->dev) {
+		if (ptype->dev == null_or_orig || ptype->dev == skb->dev ||
+		    ptype->dev == orig_dev) {
 			if (pt_prev)
 				ret = deliver_skb(skb, pt_prev, orig_dev);
 			pt_prev = ptype;
@@ -2246,7 +2236,8 @@ ncls:
 	list_for_each_entry_rcu(ptype,
 			&ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
 		if (ptype->type == type &&
-		    (!ptype->dev || ptype->dev == skb->dev)) {
+		    (ptype->dev == null_or_orig || ptype->dev == skb->dev ||
+		     ptype->dev == orig_dev)) {
 			if (pt_prev)
 				ret = deliver_skb(skb, pt_prev, orig_dev);
 			pt_prev = ptype;
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
index b210a88..7f07152 100644
--- a/net/wanrouter/wanmain.c
+++ b/net/wanrouter/wanmain.c
@@ -57,7 +57,6 @@
 #include <linux/vmalloc.h>	/* vmalloc, vfree */
 #include <asm/uaccess.h>        /* copy_to/from_user */
 #include <linux/init.h>         /* __initfunc et al. */
-#include <net/syncppp.h>
 
 #define KMEM_SAFETYZONE 8
 
@@ -567,9 +566,6 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
 {
 	wanif_conf_t *cnf;
 	struct net_device *dev = NULL;
-#ifdef CONFIG_WANPIPE_MULTPPP
-	struct ppp_device *pppdev=NULL;
-#endif
 	int err;
 
 	if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))
@@ -588,25 +584,10 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
 		goto out;
 
 	if (cnf->config_id == WANCONFIG_MPPP) {
-#ifdef CONFIG_WANPIPE_MULTPPP
-		pppdev = kzalloc(sizeof(struct ppp_device), GFP_KERNEL);
-		err = -ENOBUFS;
-		if (pppdev == NULL)
-			goto out;
-		pppdev->dev = kzalloc(sizeof(struct net_device), GFP_KERNEL);
-		if (pppdev->dev == NULL) {
-			kfree(pppdev);
-			err = -ENOBUFS;
-			goto out;
-		}
-		err = wandev->new_if(wandev, (struct net_device *)pppdev, cnf);
-		dev = pppdev->dev;
-#else
 		printk(KERN_INFO "%s: Wanpipe Mulit-Port PPP support has not been compiled in!\n",
 				wandev->name);
 		err = -EPROTONOSUPPORT;
 		goto out;
-#endif
 	} else {
 		dev = kzalloc(sizeof(struct net_device), GFP_KERNEL);
 		err = -ENOBUFS;
@@ -661,17 +642,9 @@ static int wanrouter_device_new_if(struct wan_device *wandev,
 	kfree(dev->priv);
 	dev->priv = NULL;
 
-#ifdef CONFIG_WANPIPE_MULTPPP
-	if (cnf->config_id == WANCONFIG_MPPP)
-		kfree(pppdev);
-	else
-		kfree(dev);
-#else
 	/* Sync PPP is disabled */
 	if (cnf->config_id != WANCONFIG_MPPP)
 		kfree(dev);
-#endif
-
 out:
 	kfree(cnf);
 	return err;

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-07-30 21:41 Jeff Garzik
@ 2008-07-30 22:49 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2008-07-30 22:49 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Wed, 30 Jul 2008 17:41:21 -0400

> Still working through the queue...  here's the first part
> 
> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

Pulled and pushed back out to net-2.6 on kernel.org, thanks Jeff!

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2008-07-30 21:41 Jeff Garzik
  2008-07-30 22:49 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2008-07-30 21:41 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


Still working through the queue...  here's the first part

Please pull from 'upstream-davem' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

to receive the following updates:

 arch/arm/mach-kirkwood/rd88f6281-setup.c     |    3 +
 arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c |    3 +
 arch/arm/mach-orion5x/rd88f5181l-ge-setup.c  |    3 +
 arch/arm/mach-orion5x/wnr854t-setup.c        |    3 +
 arch/arm/mach-orion5x/wrt350n-v2-setup.c     |    3 +
 drivers/net/Kconfig                          |    4 +-
 drivers/net/bfin_mac.c                       |  111 +++++--
 drivers/net/cxgb3/t3_hw.c                    |    2 +-
 drivers/net/ehea/ehea_main.c                 |    4 +-
 drivers/net/enc28j60.c                       |    6 +-
 drivers/net/forcedeth.c                      |   64 ++++-
 drivers/net/mv643xx_eth.c                    |  358 ++++++++++++++--------
 drivers/net/ne.c                             |    6 +-
 drivers/net/s2io.c                           |   29 ++-
 drivers/net/sh_eth.c                         |  202 ++++++++++---
 drivers/net/sh_eth.h                         |  426 +++++++++++++++++++-------
 drivers/net/usb/dm9601.c                     |   52 +++-
 drivers/net/wd.c                             |    2 +-
 18 files changed, 948 insertions(+), 333 deletions(-)

Alan Cox (1):
      [netdrvr] wd: fix build breakage with new NS8390p API

Ayaz Abdulla (1):
      forcedeth bug fix: realtek phy 8211c errata

Breno Leitao (1):
      S2io: fix statistics flush after a MTU change

Bryan Wu (1):
      Blackfin EMAC Driver: enable TXDWA new feature for new silicon (rev > 0.2)

David Brownell (1):
      enc28j60: don't specify (wrong) IRQ type

Julia Lawall (1):
      drivers/net/ehea/ehea_main.c: Release mutex in error handling code

Lennert Buytenhek (12):
      mv643xx_eth: fix TX hang erratum workaround
      mv643xx_eth: prevent breakage when link goes down during transmit
      mv643xx_eth: fix transmit-reclaim-in-napi-poll
      mv643xx_eth: don't fiddle with maximum receive packet size setting
      mv643xx_eth: also check TX_IN_PROGRESS when disabling transmit path
      mv643xx_eth: use longer DMA bursts
      mv643xx_eth: use symbolic MII register addresses and values
      mv643xx_eth: print driver version on init
      mv643xx_eth: use auto phy polling for configuring (R)(G)MII interface
      mv643xx_eth: print message on link status change
      mv643xx_eth: enable hardware TX checksumming with vlan tags
      mv643xx_eth: bump version to 1.2

Michael Hennerich (1):
      Blackfin EMAC Driver: Functional power management support

Mikael Pettersson (1):
      fix NE2000 linkage error

Mike Frysinger (1):
      Blackfin EMAC Driver: add proper __devinit/__devexit markings

Nobuhiro Iwamatsu (1):
      sh_eth: Add support of SH7763 to sh_eth

Peter Korsgaard (1):
      dm9601: don't do usb transfers of data on stack

Stephen Hemminger (1):
      blackfin_mac: unneeded assignment

Steve Wise (1):
      cxgb3: Allow 64KB firmware images.

diff --git a/arch/arm/mach-kirkwood/rd88f6281-setup.c b/arch/arm/mach-kirkwood/rd88f6281-setup.c
index e1f8de2..b6437f4 100644
--- a/arch/arm/mach-kirkwood/rd88f6281-setup.c
+++ b/arch/arm/mach-kirkwood/rd88f6281-setup.c
@@ -18,6 +18,7 @@
 #include <linux/timer.h>
 #include <linux/ata_platform.h>
 #include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/pci.h>
@@ -69,6 +70,8 @@ static struct platform_device rd88f6281_nand_flash = {
 
 static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
 	.phy_addr	= -1,
+	.speed		= SPEED_1000,
+	.duplex		= DUPLEX_FULL,
 };
 
 static struct mv_sata_platform_data rd88f6281_sata_data = {
diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
index d50e365..73e9242 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
@@ -15,6 +15,7 @@
 #include <linux/irq.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
 #include <asm/mach-types.h>
 #include <asm/gpio.h>
 #include <asm/leds.h>
@@ -88,6 +89,8 @@ static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = {
 
 static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
 	.phy_addr	= -1,
+	.speed		= SPEED_1000,
+	.duplex		= DUPLEX_FULL,
 };
 
 static void __init rd88f5181l_fxo_init(void)
diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
index b56447d..ac48201 100644
--- a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
@@ -15,6 +15,7 @@
 #include <linux/irq.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
 #include <linux/i2c.h>
 #include <asm/mach-types.h>
 #include <asm/gpio.h>
@@ -89,6 +90,8 @@ static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = {
 
 static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
 	.phy_addr	= -1,
+	.speed		= SPEED_1000,
+	.duplex		= DUPLEX_FULL,
 };
 
 static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c
index 1af093f..25568c2 100644
--- a/arch/arm/mach-orion5x/wnr854t-setup.c
+++ b/arch/arm/mach-orion5x/wnr854t-setup.c
@@ -14,6 +14,7 @@
 #include <linux/delay.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
 #include <asm/mach-types.h>
 #include <asm/gpio.h>
 #include <asm/mach/arch.h>
@@ -92,6 +93,8 @@ static struct platform_device wnr854t_nor_flash = {
 
 static struct mv643xx_eth_platform_data wnr854t_eth_data = {
 	.phy_addr	= -1,
+	.speed		= SPEED_1000,
+	.duplex		= DUPLEX_FULL,
 };
 
 static void __init wnr854t_init(void)
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
index aeab55c..9b8ee8c 100644
--- a/arch/arm/mach-orion5x/wrt350n-v2-setup.c
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -14,6 +14,7 @@
 #include <linux/delay.h>
 #include <linux/mtd/physmap.h>
 #include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
 #include <asm/mach-types.h>
 #include <asm/gpio.h>
 #include <asm/mach/arch.h>
@@ -100,6 +101,8 @@ static struct platform_device wrt350n_v2_nor_flash = {
 
 static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
 	.phy_addr	= -1,
+	.speed		= SPEED_1000,
+	.duplex		= DUPLEX_FULL,
 };
 
 static void __init wrt350n_v2_init(void)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index fa533c2..8a03875 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -510,14 +510,14 @@ config STNIC
 config SH_ETH
 	tristate "Renesas SuperH Ethernet support"
 	depends on SUPERH && \
-		(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712)
+		(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || CPU_SUBTYPE_SH7763)
 	select CRC32
 	select MII
 	select MDIO_BITBANG
 	select PHYLIB
 	help
 	  Renesas SuperH Ethernet device driver.
-	  This driver support SH7710 and SH7712.
+	  This driver support SH7710, SH7712 and SH7763.
 
 config SUNLANCE
 	tristate "Sun LANCE support"
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index a8ec60e..3db7db1 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -605,36 +605,87 @@ adjust_head:
 static int bfin_mac_hard_start_xmit(struct sk_buff *skb,
 				struct net_device *dev)
 {
-	unsigned int data;
+	u16 *data;
 
 	current_tx_ptr->skb = skb;
 
-	/*
-	 * Is skb->data always 16-bit aligned?
-	 * Do we need to memcpy((char *)(tail->packet + 2), skb->data, len)?
-	 */
-	if ((((unsigned int)(skb->data)) & 0x02) == 2) {
-		/* move skb->data to current_tx_ptr payload */
-		data = (unsigned int)(skb->data) - 2;
-		*((unsigned short *)data) = (unsigned short)(skb->len);
-		current_tx_ptr->desc_a.start_addr = (unsigned long)data;
-		/* this is important! */
-		blackfin_dcache_flush_range(data, (data + (skb->len)) + 2);
-
+	if (ANOMALY_05000285) {
+		/*
+		 * TXDWA feature is not avaible to older revision < 0.3 silicon
+		 * of BF537
+		 *
+		 * Only if data buffer is ODD WORD alignment, we do not
+		 * need to memcpy
+		 */
+		u32 data_align = (u32)(skb->data) & 0x3;
+		if (data_align == 0x2) {
+			/* move skb->data to current_tx_ptr payload */
+			data = (u16 *)(skb->data) - 1;
+			*data = (u16)(skb->len);
+			current_tx_ptr->desc_a.start_addr = (u32)data;
+			/* this is important! */
+			blackfin_dcache_flush_range((u32)data,
+					(u32)((u8 *)data + skb->len + 4));
+		} else {
+			*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
+			memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
+				skb->len);
+			current_tx_ptr->desc_a.start_addr =
+				(u32)current_tx_ptr->packet;
+			if (current_tx_ptr->status.status_word != 0)
+				current_tx_ptr->status.status_word = 0;
+			blackfin_dcache_flush_range(
+				(u32)current_tx_ptr->packet,
+				(u32)(current_tx_ptr->packet + skb->len + 2));
+		}
 	} else {
-		*((unsigned short *)(current_tx_ptr->packet)) =
-		    (unsigned short)(skb->len);
-		memcpy((char *)(current_tx_ptr->packet + 2), skb->data,
-		       (skb->len));
-		current_tx_ptr->desc_a.start_addr =
-		    (unsigned long)current_tx_ptr->packet;
-		if (current_tx_ptr->status.status_word != 0)
-			current_tx_ptr->status.status_word = 0;
-		blackfin_dcache_flush_range((unsigned int)current_tx_ptr->
-					    packet,
-					    (unsigned int)(current_tx_ptr->
-							   packet + skb->len) +
-					    2);
+		/*
+		 * TXDWA feature is avaible to revision < 0.3 silicon of
+		 * BF537 and always avaible to BF52x
+		 */
+		u32 data_align = (u32)(skb->data) & 0x3;
+		if (data_align == 0x0) {
+			u16 sysctl = bfin_read_EMAC_SYSCTL();
+			sysctl |= TXDWA;
+			bfin_write_EMAC_SYSCTL(sysctl);
+
+			/* move skb->data to current_tx_ptr payload */
+			data = (u16 *)(skb->data) - 2;
+			*data = (u16)(skb->len);
+			current_tx_ptr->desc_a.start_addr = (u32)data;
+			/* this is important! */
+			blackfin_dcache_flush_range(
+					(u32)data,
+					(u32)((u8 *)data + skb->len + 4));
+		} else if (data_align == 0x2) {
+			u16 sysctl = bfin_read_EMAC_SYSCTL();
+			sysctl &= ~TXDWA;
+			bfin_write_EMAC_SYSCTL(sysctl);
+
+			/* move skb->data to current_tx_ptr payload */
+			data = (u16 *)(skb->data) - 1;
+			*data = (u16)(skb->len);
+			current_tx_ptr->desc_a.start_addr = (u32)data;
+			/* this is important! */
+			blackfin_dcache_flush_range(
+					(u32)data,
+					(u32)((u8 *)data + skb->len + 4));
+		} else {
+			u16 sysctl = bfin_read_EMAC_SYSCTL();
+			sysctl &= ~TXDWA;
+			bfin_write_EMAC_SYSCTL(sysctl);
+
+			*((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len);
+			memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data,
+				skb->len);
+			current_tx_ptr->desc_a.start_addr =
+				(u32)current_tx_ptr->packet;
+			if (current_tx_ptr->status.status_word != 0)
+				current_tx_ptr->status.status_word = 0;
+			blackfin_dcache_flush_range(
+				(u32)current_tx_ptr->packet,
+				(u32)(current_tx_ptr->packet + skb->len + 2));
+		}
 	}
 
 	/* enable this packet's dma */
@@ -691,7 +742,6 @@ static void bfin_mac_rx(struct net_device *dev)
 					 (unsigned long)skb->tail);
 
 	dev->last_rx = jiffies;
-	skb->dev = dev;
 	skb->protocol = eth_type_trans(skb, dev);
 #if defined(BFIN_MAC_CSUM_OFFLOAD)
 	skb->csum = current_rx_ptr->status.ip_payload_csum;
@@ -920,6 +970,7 @@ static int bfin_mac_open(struct net_device *dev)
 	phy_start(lp->phydev);
 	phy_write(lp->phydev, MII_BMCR, BMCR_RESET);
 	setup_system_regs(dev);
+	setup_mac_addr(dev->dev_addr);
 	bfin_mac_disable();
 	bfin_mac_enable();
 	pr_debug("hardware init finished\n");
@@ -955,7 +1006,7 @@ static int bfin_mac_close(struct net_device *dev)
 	return 0;
 }
 
-static int __init bfin_mac_probe(struct platform_device *pdev)
+static int __devinit bfin_mac_probe(struct platform_device *pdev)
 {
 	struct net_device *ndev;
 	struct bfin_mac_local *lp;
@@ -1081,7 +1132,7 @@ out_err_probe_mac:
 	return rc;
 }
 
-static int bfin_mac_remove(struct platform_device *pdev)
+static int __devexit bfin_mac_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
 	struct bfin_mac_local *lp = netdev_priv(ndev);
@@ -1128,7 +1179,7 @@ static int bfin_mac_resume(struct platform_device *pdev)
 
 static struct platform_driver bfin_mac_driver = {
 	.probe = bfin_mac_probe,
-	.remove = bfin_mac_remove,
+	.remove = __devexit_p(bfin_mac_remove),
 	.resume = bfin_mac_resume,
 	.suspend = bfin_mac_suspend,
 	.driver = {
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 47d5178..04c0e90 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -683,7 +683,7 @@ enum {
 	SF_ERASE_SECTOR = 0xd8,	/* erase sector */
 
 	FW_FLASH_BOOT_ADDR = 0x70000,	/* start address of FW in flash */
-	FW_VERS_ADDR = 0x77ffc,    /* flash address holding FW version */
+	FW_VERS_ADDR = 0x7fffc,    /* flash address holding FW version */
 	FW_MIN_SIZE = 8            /* at least version and csum */
 };
 
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 0920b79..b70c531 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2937,9 +2937,9 @@ static void ehea_rereg_mrs(struct work_struct *work)
 				}
 			}
 		}
-       mutex_unlock(&dlpar_mem_lock);
-       ehea_info("re-initializing driver complete");
+	ehea_info("re-initializing driver complete");
 out:
+	mutex_unlock(&dlpar_mem_lock);
 	return;
 }
 
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index c05cb15..aa0bf6e 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -1547,8 +1547,10 @@ static int __devinit enc28j60_probe(struct spi_device *spi)
 	random_ether_addr(dev->dev_addr);
 	enc28j60_set_hw_macaddr(dev);
 
-	ret = request_irq(spi->irq, enc28j60_irq, IRQF_TRIGGER_FALLING,
-			  DRV_NAME, priv);
+	/* Board setup must set the relevant edge trigger type;
+	 * level triggers won't currently work.
+	 */
+	ret = request_irq(spi->irq, enc28j60_irq, 0, DRV_NAME, priv);
 	if (ret < 0) {
 		if (netif_msg_probe(priv))
 			dev_err(&spi->dev, DRV_NAME ": request irq %d failed "
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 4ed89fa..01b38b0 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -333,6 +333,7 @@ enum {
 	NvRegPowerState2 = 0x600,
 #define NVREG_POWERSTATE2_POWERUP_MASK		0x0F11
 #define NVREG_POWERSTATE2_POWERUP_REV_A3	0x0001
+#define NVREG_POWERSTATE2_PHY_RESET		0x0004
 };
 
 /* Big endian: should work, but is untested */
@@ -529,6 +530,7 @@ union ring_type {
 #define PHY_REALTEK_INIT_REG4	0x14
 #define PHY_REALTEK_INIT_REG5	0x18
 #define PHY_REALTEK_INIT_REG6	0x11
+#define PHY_REALTEK_INIT_REG7	0x01
 #define PHY_REALTEK_INIT1	0x0000
 #define PHY_REALTEK_INIT2	0x8e00
 #define PHY_REALTEK_INIT3	0x0001
@@ -537,6 +539,9 @@ union ring_type {
 #define PHY_REALTEK_INIT6	0xf5c7
 #define PHY_REALTEK_INIT7	0x1000
 #define PHY_REALTEK_INIT8	0x0003
+#define PHY_REALTEK_INIT9	0x0008
+#define PHY_REALTEK_INIT10	0x0005
+#define PHY_REALTEK_INIT11	0x0200
 #define PHY_REALTEK_INIT_MSK1	0x0003
 
 #define PHY_GIGABIT	0x0100
@@ -1149,6 +1154,42 @@ static int phy_init(struct net_device *dev)
 				return PHY_ERROR;
 			}
 		}
+		if (np->phy_model == PHY_MODEL_REALTEK_8211 &&
+		    np->phy_rev == PHY_REV_REALTEK_8211C) {
+			u32 powerstate = readl(base + NvRegPowerState2);
+
+			/* need to perform hw phy reset */
+			powerstate |= NVREG_POWERSTATE2_PHY_RESET;
+			writel(powerstate, base + NvRegPowerState2);
+			msleep(25);
+
+			powerstate &= ~NVREG_POWERSTATE2_PHY_RESET;
+			writel(powerstate, base + NvRegPowerState2);
+			msleep(25);
+
+			reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
+			reg |= PHY_REALTEK_INIT9;
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, reg)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT10)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			reg = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, MII_READ);
+			if (!(reg & PHY_REALTEK_INIT11)) {
+				reg |= PHY_REALTEK_INIT11;
+				if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG7, reg)) {
+					printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+					return PHY_ERROR;
+				}
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+		}
 		if (np->phy_model == PHY_MODEL_REALTEK_8201) {
 			if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
 			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
@@ -1201,12 +1242,23 @@ static int phy_init(struct net_device *dev)
 	mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
 	mii_control |= BMCR_ANENABLE;
 
-	/* reset the phy
-	 * (certain phys need bmcr to be setup with reset)
-	 */
-	if (phy_reset(dev, mii_control)) {
-		printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev));
-		return PHY_ERROR;
+	if (np->phy_oui == PHY_OUI_REALTEK &&
+	    np->phy_model == PHY_MODEL_REALTEK_8211 &&
+	    np->phy_rev == PHY_REV_REALTEK_8211C) {
+		/* start autoneg since we already performed hw reset above */
+		mii_control |= BMCR_ANRESTART;
+		if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) {
+			printk(KERN_INFO "%s: phy init failed\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+	} else {
+		/* reset the phy
+		 * (certain phys need bmcr to be setup with reset)
+		 */
+		if (phy_reset(dev, mii_control)) {
+			printk(KERN_INFO "%s: phy reset failed\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
 	}
 
 	/* phy vendor specific configuration */
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 8a97a00..46819af 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -55,7 +55,7 @@
 #include <asm/system.h>
 
 static char mv643xx_eth_driver_name[] = "mv643xx_eth";
-static char mv643xx_eth_driver_version[] = "1.1";
+static char mv643xx_eth_driver_version[] = "1.2";
 
 #define MV643XX_ETH_CHECKSUM_OFFLOAD_TX
 #define MV643XX_ETH_NAPI
@@ -90,12 +90,21 @@ static char mv643xx_eth_driver_version[] = "1.1";
 #define PORT_SERIAL_CONTROL(p)		(0x043c + ((p) << 10))
 #define PORT_STATUS(p)			(0x0444 + ((p) << 10))
 #define  TX_FIFO_EMPTY			0x00000400
+#define  TX_IN_PROGRESS			0x00000080
+#define  PORT_SPEED_MASK		0x00000030
+#define  PORT_SPEED_1000		0x00000010
+#define  PORT_SPEED_100			0x00000020
+#define  PORT_SPEED_10			0x00000000
+#define  FLOW_CONTROL_ENABLED		0x00000008
+#define  FULL_DUPLEX			0x00000004
+#define  LINK_UP			0x00000002
 #define TXQ_COMMAND(p)			(0x0448 + ((p) << 10))
 #define TXQ_FIX_PRIO_CONF(p)		(0x044c + ((p) << 10))
 #define TX_BW_RATE(p)			(0x0450 + ((p) << 10))
 #define TX_BW_MTU(p)			(0x0458 + ((p) << 10))
 #define TX_BW_BURST(p)			(0x045c + ((p) << 10))
 #define INT_CAUSE(p)			(0x0460 + ((p) << 10))
+#define  INT_TX_END_0			0x00080000
 #define  INT_TX_END			0x07f80000
 #define  INT_RX				0x0007fbfc
 #define  INT_EXT			0x00000002
@@ -127,21 +136,21 @@ static char mv643xx_eth_driver_version[] = "1.1";
 /*
  * SDMA configuration register.
  */
-#define RX_BURST_SIZE_4_64BIT		(2 << 1)
+#define RX_BURST_SIZE_16_64BIT		(4 << 1)
 #define BLM_RX_NO_SWAP			(1 << 4)
 #define BLM_TX_NO_SWAP			(1 << 5)
-#define TX_BURST_SIZE_4_64BIT		(2 << 22)
+#define TX_BURST_SIZE_16_64BIT		(4 << 22)
 
 #if defined(__BIG_ENDIAN)
 #define PORT_SDMA_CONFIG_DEFAULT_VALUE		\
-		RX_BURST_SIZE_4_64BIT	|	\
-		TX_BURST_SIZE_4_64BIT
+		RX_BURST_SIZE_16_64BIT	|	\
+		TX_BURST_SIZE_16_64BIT
 #elif defined(__LITTLE_ENDIAN)
 #define PORT_SDMA_CONFIG_DEFAULT_VALUE		\
-		RX_BURST_SIZE_4_64BIT	|	\
+		RX_BURST_SIZE_16_64BIT	|	\
 		BLM_RX_NO_SWAP		|	\
 		BLM_TX_NO_SWAP		|	\
-		TX_BURST_SIZE_4_64BIT
+		TX_BURST_SIZE_16_64BIT
 #else
 #error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
 #endif
@@ -153,9 +162,7 @@ static char mv643xx_eth_driver_version[] = "1.1";
 #define SET_MII_SPEED_TO_100			(1 << 24)
 #define SET_GMII_SPEED_TO_1000			(1 << 23)
 #define SET_FULL_DUPLEX_MODE			(1 << 21)
-#define MAX_RX_PACKET_1522BYTE			(1 << 17)
 #define MAX_RX_PACKET_9700BYTE			(5 << 17)
-#define MAX_RX_PACKET_MASK			(7 << 17)
 #define DISABLE_AUTO_NEG_SPEED_GMII		(1 << 13)
 #define DO_NOT_FORCE_LINK_FAIL			(1 << 10)
 #define SERIAL_PORT_CONTROL_RESERVED		(1 << 9)
@@ -228,6 +235,8 @@ struct tx_desc {
 #define GEN_IP_V4_CHECKSUM		0x00040000
 #define GEN_TCP_UDP_CHECKSUM		0x00020000
 #define UDP_FRAME			0x00010000
+#define MAC_HDR_EXTRA_4_BYTES		0x00008000
+#define MAC_HDR_EXTRA_8_BYTES		0x00000200
 
 #define TX_IHL_SHIFT			11
 
@@ -404,6 +413,17 @@ static void rxq_disable(struct rx_queue *rxq)
 		udelay(10);
 }
 
+static void txq_reset_hw_ptr(struct tx_queue *txq)
+{
+	struct mv643xx_eth_private *mp = txq_to_mp(txq);
+	int off = TXQ_CURRENT_DESC_PTR(mp->port_num, txq->index);
+	u32 addr;
+
+	addr = (u32)txq->tx_desc_dma;
+	addr += txq->tx_curr_desc * sizeof(struct tx_desc);
+	wrl(mp, off, addr);
+}
+
 static void txq_enable(struct tx_queue *txq)
 {
 	struct mv643xx_eth_private *mp = txq_to_mp(txq);
@@ -614,6 +634,12 @@ static int mv643xx_eth_poll(struct napi_struct *napi, int budget)
 		for (i = 0; i < 8; i++)
 			if (mp->txq_mask & (1 << i))
 				txq_reclaim(mp->txq + i, 0);
+
+		if (netif_carrier_ok(mp->dev)) {
+			spin_lock(&mp->lock);
+			__txq_maybe_wake(mp->txq + mp->txq_primary);
+			spin_unlock(&mp->lock);
+		}
 	}
 #endif
 
@@ -706,6 +732,7 @@ static inline __be16 sum16_as_be(__sum16 sum)
 
 static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
 {
+	struct mv643xx_eth_private *mp = txq_to_mp(txq);
 	int nr_frags = skb_shinfo(skb)->nr_frags;
 	int tx_index;
 	struct tx_desc *desc;
@@ -732,12 +759,36 @@ static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
 	desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		BUG_ON(skb->protocol != htons(ETH_P_IP));
+		int mac_hdr_len;
+
+		BUG_ON(skb->protocol != htons(ETH_P_IP) &&
+		       skb->protocol != htons(ETH_P_8021Q));
 
 		cmd_sts |= GEN_TCP_UDP_CHECKSUM |
 			   GEN_IP_V4_CHECKSUM   |
 			   ip_hdr(skb)->ihl << TX_IHL_SHIFT;
 
+		mac_hdr_len = (void *)ip_hdr(skb) - (void *)skb->data;
+		switch (mac_hdr_len - ETH_HLEN) {
+		case 0:
+			break;
+		case 4:
+			cmd_sts |= MAC_HDR_EXTRA_4_BYTES;
+			break;
+		case 8:
+			cmd_sts |= MAC_HDR_EXTRA_8_BYTES;
+			break;
+		case 12:
+			cmd_sts |= MAC_HDR_EXTRA_4_BYTES;
+			cmd_sts |= MAC_HDR_EXTRA_8_BYTES;
+			break;
+		default:
+			if (net_ratelimit())
+				dev_printk(KERN_ERR, &txq_to_mp(txq)->dev->dev,
+				   "mac header length is %d?!\n", mac_hdr_len);
+			break;
+		}
+
 		switch (ip_hdr(skb)->protocol) {
 		case IPPROTO_UDP:
 			cmd_sts |= UDP_FRAME;
@@ -759,6 +810,10 @@ static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
 	wmb();
 	desc->cmd_sts = cmd_sts;
 
+	/* clear TX_END interrupt status */
+	wrl(mp, INT_CAUSE(mp->port_num), ~(INT_TX_END_0 << txq->index));
+	rdl(mp, INT_CAUSE(mp->port_num));
+
 	/* ensure all descriptors are written before poking hardware */
 	wmb();
 	txq_enable(txq);
@@ -1112,10 +1167,28 @@ static int mv643xx_eth_get_settings(struct net_device *dev, struct ethtool_cmd *
 
 static int mv643xx_eth_get_settings_phyless(struct net_device *dev, struct ethtool_cmd *cmd)
 {
+	struct mv643xx_eth_private *mp = netdev_priv(dev);
+	u32 port_status;
+
+	port_status = rdl(mp, PORT_STATUS(mp->port_num));
+
 	cmd->supported = SUPPORTED_MII;
 	cmd->advertising = ADVERTISED_MII;
-	cmd->speed = SPEED_1000;
-	cmd->duplex = DUPLEX_FULL;
+	switch (port_status & PORT_SPEED_MASK) {
+	case PORT_SPEED_10:
+		cmd->speed = SPEED_10;
+		break;
+	case PORT_SPEED_100:
+		cmd->speed = SPEED_100;
+		break;
+	case PORT_SPEED_1000:
+		cmd->speed = SPEED_1000;
+		break;
+	default:
+		cmd->speed = -1;
+		break;
+	}
+	cmd->duplex = (port_status & FULL_DUPLEX) ? DUPLEX_FULL : DUPLEX_HALF;
 	cmd->port = PORT_MII;
 	cmd->phy_address = 0;
 	cmd->transceiver = XCVR_INTERNAL;
@@ -1539,8 +1612,11 @@ static int txq_init(struct mv643xx_eth_private *mp, int index)
 
 	tx_desc = (struct tx_desc *)txq->tx_desc_area;
 	for (i = 0; i < txq->tx_ring_size; i++) {
+		struct tx_desc *txd = tx_desc + i;
 		int nexti = (i + 1) % txq->tx_ring_size;
-		tx_desc[i].next_desc_ptr = txq->tx_desc_dma +
+
+		txd->cmd_sts = 0;
+		txd->next_desc_ptr = txq->tx_desc_dma +
 					nexti * sizeof(struct tx_desc);
 	}
 
@@ -1577,8 +1653,11 @@ static void txq_reclaim(struct tx_queue *txq, int force)
 		desc = &txq->tx_desc_area[tx_index];
 		cmd_sts = desc->cmd_sts;
 
-		if (!force && (cmd_sts & BUFFER_OWNED_BY_DMA))
-			break;
+		if (cmd_sts & BUFFER_OWNED_BY_DMA) {
+			if (!force)
+				break;
+			desc->cmd_sts = cmd_sts & ~BUFFER_OWNED_BY_DMA;
+		}
 
 		txq->tx_used_desc = (tx_index + 1) % txq->tx_ring_size;
 		txq->tx_desc_count--;
@@ -1632,49 +1711,61 @@ static void txq_deinit(struct tx_queue *txq)
 
 
 /* netdev ops and related ***************************************************/
-static void update_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
+static void handle_link_event(struct mv643xx_eth_private *mp)
 {
-	u32 pscr_o;
-	u32 pscr_n;
-
-	pscr_o = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
+	struct net_device *dev = mp->dev;
+	u32 port_status;
+	int speed;
+	int duplex;
+	int fc;
+
+	port_status = rdl(mp, PORT_STATUS(mp->port_num));
+	if (!(port_status & LINK_UP)) {
+		if (netif_carrier_ok(dev)) {
+			int i;
 
-	/* clear speed, duplex and rx buffer size fields */
-	pscr_n = pscr_o & ~(SET_MII_SPEED_TO_100   |
-			    SET_GMII_SPEED_TO_1000 |
-			    SET_FULL_DUPLEX_MODE   |
-			    MAX_RX_PACKET_MASK);
+			printk(KERN_INFO "%s: link down\n", dev->name);
 
-	if (speed == SPEED_1000) {
-		pscr_n |= SET_GMII_SPEED_TO_1000 | MAX_RX_PACKET_9700BYTE;
-	} else {
-		if (speed == SPEED_100)
-			pscr_n |= SET_MII_SPEED_TO_100;
-		pscr_n |= MAX_RX_PACKET_1522BYTE;
-	}
+			netif_carrier_off(dev);
+			netif_stop_queue(dev);
 
-	if (duplex == DUPLEX_FULL)
-		pscr_n |= SET_FULL_DUPLEX_MODE;
+			for (i = 0; i < 8; i++) {
+				struct tx_queue *txq = mp->txq + i;
 
-	if (pscr_n != pscr_o) {
-		if ((pscr_o & SERIAL_PORT_ENABLE) == 0)
-			wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_n);
-		else {
-			int i;
+				if (mp->txq_mask & (1 << i)) {
+					txq_reclaim(txq, 1);
+					txq_reset_hw_ptr(txq);
+				}
+			}
+		}
+		return;
+	}
 
-			for (i = 0; i < 8; i++)
-				if (mp->txq_mask & (1 << i))
-					txq_disable(mp->txq + i);
+	switch (port_status & PORT_SPEED_MASK) {
+	case PORT_SPEED_10:
+		speed = 10;
+		break;
+	case PORT_SPEED_100:
+		speed = 100;
+		break;
+	case PORT_SPEED_1000:
+		speed = 1000;
+		break;
+	default:
+		speed = -1;
+		break;
+	}
+	duplex = (port_status & FULL_DUPLEX) ? 1 : 0;
+	fc = (port_status & FLOW_CONTROL_ENABLED) ? 1 : 0;
 
-			pscr_o &= ~SERIAL_PORT_ENABLE;
-			wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_o);
-			wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_n);
-			wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr_n);
+	printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
+			 "flow control %sabled\n", dev->name,
+			 speed, duplex ? "full" : "half",
+			 fc ? "en" : "dis");
 
-			for (i = 0; i < 8; i++)
-				if (mp->txq_mask & (1 << i))
-					txq_enable(mp->txq + i);
-		}
+	if (!netif_carrier_ok(dev)) {
+		netif_carrier_on(dev);
+		netif_wake_queue(dev);
 	}
 }
 
@@ -1684,7 +1775,6 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
 	struct mv643xx_eth_private *mp = netdev_priv(dev);
 	u32 int_cause;
 	u32 int_cause_ext;
-	u32 txq_active;
 
 	int_cause = rdl(mp, INT_CAUSE(mp->port_num)) &
 			(INT_TX_END | INT_RX | INT_EXT);
@@ -1698,30 +1788,8 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
 		wrl(mp, INT_CAUSE_EXT(mp->port_num), ~int_cause_ext);
 	}
 
-	if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK)) {
-		if (mp->phy_addr == -1 || mii_link_ok(&mp->mii)) {
-			int i;
-
-			if (mp->phy_addr != -1) {
-				struct ethtool_cmd cmd;
-
-				mii_ethtool_gset(&mp->mii, &cmd);
-				update_pscr(mp, cmd.speed, cmd.duplex);
-			}
-
-			for (i = 0; i < 8; i++)
-				if (mp->txq_mask & (1 << i))
-					txq_enable(mp->txq + i);
-
-			if (!netif_carrier_ok(dev)) {
-				netif_carrier_on(dev);
-				__txq_maybe_wake(mp->txq + mp->txq_primary);
-			}
-		} else if (netif_carrier_ok(dev)) {
-			netif_stop_queue(dev);
-			netif_carrier_off(dev);
-		}
-	}
+	if (int_cause_ext & (INT_EXT_PHY | INT_EXT_LINK))
+		handle_link_event(mp);
 
 	/*
 	 * RxBuffer or RxError set for any of the 8 queues?
@@ -1743,8 +1811,6 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
 	}
 #endif
 
-	txq_active = rdl(mp, TXQ_COMMAND(mp->port_num));
-
 	/*
 	 * TxBuffer or TxError set for any of the 8 queues?
 	 */
@@ -1754,6 +1820,16 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
 		for (i = 0; i < 8; i++)
 			if (mp->txq_mask & (1 << i))
 				txq_reclaim(mp->txq + i, 0);
+
+		/*
+		 * Enough space again in the primary TX queue for a
+		 * full packet?
+		 */
+		if (netif_carrier_ok(dev)) {
+			spin_lock(&mp->lock);
+			__txq_maybe_wake(mp->txq + mp->txq_primary);
+			spin_unlock(&mp->lock);
+		}
 	}
 
 	/*
@@ -1763,19 +1839,25 @@ static irqreturn_t mv643xx_eth_irq(int irq, void *dev_id)
 		int i;
 
 		wrl(mp, INT_CAUSE(mp->port_num), ~(int_cause & INT_TX_END));
+
+		spin_lock(&mp->lock);
 		for (i = 0; i < 8; i++) {
 			struct tx_queue *txq = mp->txq + i;
-			if (txq->tx_desc_count && !((txq_active >> i) & 1))
+			u32 hw_desc_ptr;
+			u32 expected_ptr;
+
+			if ((int_cause & (INT_TX_END_0 << i)) == 0)
+				continue;
+
+			hw_desc_ptr =
+				rdl(mp, TXQ_CURRENT_DESC_PTR(mp->port_num, i));
+			expected_ptr = (u32)txq->tx_desc_dma +
+				txq->tx_curr_desc * sizeof(struct tx_desc);
+
+			if (hw_desc_ptr != expected_ptr)
 				txq_enable(txq);
 		}
-	}
-
-	/*
-	 * Enough space again in the primary TX queue for a full packet?
-	 */
-	if (int_cause_ext & INT_EXT_TX) {
-		struct tx_queue *txq = mp->txq + mp->txq_primary;
-		__txq_maybe_wake(txq);
+		spin_unlock(&mp->lock);
 	}
 
 	return IRQ_HANDLED;
@@ -1785,14 +1867,14 @@ static void phy_reset(struct mv643xx_eth_private *mp)
 {
 	unsigned int data;
 
-	smi_reg_read(mp, mp->phy_addr, 0, &data);
-	data |= 0x8000;
-	smi_reg_write(mp, mp->phy_addr, 0, data);
+	smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);
+	data |= BMCR_RESET;
+	smi_reg_write(mp, mp->phy_addr, MII_BMCR, data);
 
 	do {
 		udelay(1);
-		smi_reg_read(mp, mp->phy_addr, 0, &data);
-	} while (data & 0x8000);
+		smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);
+	} while (data & BMCR_RESET);
 }
 
 static void port_start(struct mv643xx_eth_private *mp)
@@ -1801,23 +1883,6 @@ static void port_start(struct mv643xx_eth_private *mp)
 	int i;
 
 	/*
-	 * Configure basic link parameters.
-	 */
-	pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
-	pscr &= ~(SERIAL_PORT_ENABLE | FORCE_LINK_PASS);
-	wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
-	pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
-		DISABLE_AUTO_NEG_SPEED_GMII    |
-		DISABLE_AUTO_NEG_FOR_DUPLEX    |
-		DO_NOT_FORCE_LINK_FAIL	       |
-		SERIAL_PORT_CONTROL_RESERVED;
-	wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
-	pscr |= SERIAL_PORT_ENABLE;
-	wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
-
-	wrl(mp, SDMA_CONFIG(mp->port_num), PORT_SDMA_CONFIG_DEFAULT_VALUE);
-
-	/*
 	 * Perform PHY reset, if there is a PHY.
 	 */
 	if (mp->phy_addr != -1) {
@@ -1829,21 +1894,31 @@ static void port_start(struct mv643xx_eth_private *mp)
 	}
 
 	/*
+	 * Configure basic link parameters.
+	 */
+	pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
+
+	pscr |= SERIAL_PORT_ENABLE;
+	wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
+
+	pscr |= DO_NOT_FORCE_LINK_FAIL;
+	if (mp->phy_addr == -1)
+		pscr |= FORCE_LINK_PASS;
+	wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
+
+	wrl(mp, SDMA_CONFIG(mp->port_num), PORT_SDMA_CONFIG_DEFAULT_VALUE);
+
+	/*
 	 * Configure TX path and queues.
 	 */
 	tx_set_rate(mp, 1000000000, 16777216);
 	for (i = 0; i < 8; i++) {
 		struct tx_queue *txq = mp->txq + i;
-		int off = TXQ_CURRENT_DESC_PTR(mp->port_num, i);
-		u32 addr;
 
 		if ((mp->txq_mask & (1 << i)) == 0)
 			continue;
 
-		addr = (u32)txq->tx_desc_dma;
-		addr += txq->tx_curr_desc * sizeof(struct tx_desc);
-		wrl(mp, off, addr);
-
+		txq_reset_hw_ptr(txq);
 		txq_set_rate(txq, 1000000000, 16777216);
 		txq_set_fixed_prio_mode(txq);
 	}
@@ -1965,6 +2040,9 @@ static int mv643xx_eth_open(struct net_device *dev)
 	napi_enable(&mp->napi);
 #endif
 
+	netif_carrier_off(dev);
+	netif_stop_queue(dev);
+
 	port_start(mp);
 
 	set_rx_coal(mp, 0);
@@ -1999,8 +2077,14 @@ static void port_reset(struct mv643xx_eth_private *mp)
 		if (mp->txq_mask & (1 << i))
 			txq_disable(mp->txq + i);
 	}
-	while (!(rdl(mp, PORT_STATUS(mp->port_num)) & TX_FIFO_EMPTY))
+
+	while (1) {
+		u32 ps = rdl(mp, PORT_STATUS(mp->port_num));
+
+		if ((ps & (TX_IN_PROGRESS | TX_FIFO_EMPTY)) == TX_FIFO_EMPTY)
+			break;
 		udelay(10);
+	}
 
 	/* Reset the Enable bit in the Configuration Register */
 	data = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
@@ -2202,7 +2286,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 	int ret;
 
 	if (!mv643xx_eth_version_printed++)
-		printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n");
+		printk(KERN_NOTICE "MV-643xx 10/100/1000 ethernet "
+			"driver version %s\n", mv643xx_eth_driver_version);
 
 	ret = -EINVAL;
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -2338,14 +2423,14 @@ static int phy_detect(struct mv643xx_eth_private *mp)
 	unsigned int data;
 	unsigned int data2;
 
-	smi_reg_read(mp, mp->phy_addr, 0, &data);
-	smi_reg_write(mp, mp->phy_addr, 0, data ^ 0x1000);
+	smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data);
+	smi_reg_write(mp, mp->phy_addr, MII_BMCR, data ^ BMCR_ANENABLE);
 
-	smi_reg_read(mp, mp->phy_addr, 0, &data2);
-	if (((data ^ data2) & 0x1000) == 0)
+	smi_reg_read(mp, mp->phy_addr, MII_BMCR, &data2);
+	if (((data ^ data2) & BMCR_ANENABLE) == 0)
 		return -ENODEV;
 
-	smi_reg_write(mp, mp->phy_addr, 0, data);
+	smi_reg_write(mp, mp->phy_addr, MII_BMCR, data);
 
 	return 0;
 }
@@ -2393,12 +2478,39 @@ static int phy_init(struct mv643xx_eth_private *mp,
 		cmd.duplex = pd->duplex;
 	}
 
-	update_pscr(mp, cmd.speed, cmd.duplex);
 	mv643xx_eth_set_settings(mp->dev, &cmd);
 
 	return 0;
 }
 
+static void init_pscr(struct mv643xx_eth_private *mp, int speed, int duplex)
+{
+	u32 pscr;
+
+	pscr = rdl(mp, PORT_SERIAL_CONTROL(mp->port_num));
+	if (pscr & SERIAL_PORT_ENABLE) {
+		pscr &= ~SERIAL_PORT_ENABLE;
+		wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
+	}
+
+	pscr = MAX_RX_PACKET_9700BYTE | SERIAL_PORT_CONTROL_RESERVED;
+	if (mp->phy_addr == -1) {
+		pscr |= DISABLE_AUTO_NEG_SPEED_GMII;
+		if (speed == SPEED_1000)
+			pscr |= SET_GMII_SPEED_TO_1000;
+		else if (speed == SPEED_100)
+			pscr |= SET_MII_SPEED_TO_100;
+
+		pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL;
+
+		pscr |= DISABLE_AUTO_NEG_FOR_DUPLEX;
+		if (duplex == DUPLEX_FULL)
+			pscr |= SET_FULL_DUPLEX_MODE;
+	}
+
+	wrl(mp, PORT_SERIAL_CONTROL(mp->port_num), pscr);
+}
+
 static int mv643xx_eth_probe(struct platform_device *pdev)
 {
 	struct mv643xx_eth_platform_data *pd;
@@ -2452,6 +2564,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 	} else {
 		SET_ETHTOOL_OPS(dev, &mv643xx_eth_ethtool_ops_phyless);
 	}
+	init_pscr(mp, pd->speed, pd->duplex);
 
 
 	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
@@ -2478,6 +2591,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 	 * have to map the buffers to ISA memory which is only 16 MB
 	 */
 	dev->features = NETIF_F_SG | NETIF_F_IP_CSUM;
+	dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM;
 #endif
 
 	SET_NETDEV_DEV(dev, &pdev->dev);
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index 2fec612..42443d6 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -536,7 +536,7 @@ static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	dev->poll_controller = eip_poll;
 #endif
-	NS8390_init(dev, 0);
+	NS8390p_init(dev, 0);
 
 	ret = register_netdev(dev);
 	if (ret)
@@ -794,7 +794,7 @@ retry:
 		if (time_after(jiffies, dma_start + 2*HZ/100)) {		/* 20ms */
 			printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
 			ne_reset_8390(dev);
-			NS8390_init(dev,1);
+			NS8390p_init(dev, 1);
 			break;
 		}
 
@@ -855,7 +855,7 @@ static int ne_drv_resume(struct platform_device *pdev)
 
 	if (netif_running(dev)) {
 		ne_reset_8390(dev);
-		NS8390_init(dev, 1);
+		NS8390p_init(dev, 1);
 		netif_device_attach(dev);
 	}
 	return 0;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 86d77d0..a2b0730 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3143,7 +3143,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
 		pkt_cnt++;
 
 		/* Updating the statistics block */
-		nic->stats.tx_bytes += skb->len;
+		nic->dev->stats.tx_bytes += skb->len;
 		nic->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
 		dev_kfree_skb_irq(skb);
 
@@ -4896,25 +4896,42 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev)
 	/* Configure Stats for immediate updt */
 	s2io_updt_stats(sp);
 
+	/* Using sp->stats as a staging area, because reset (due to mtu
+	   change, for example) will clear some hardware counters */
+	dev->stats.tx_packets +=
+		le32_to_cpu(mac_control->stats_info->tmac_frms) - 
+		sp->stats.tx_packets;
 	sp->stats.tx_packets =
 		le32_to_cpu(mac_control->stats_info->tmac_frms);
+	dev->stats.tx_errors +=
+		le32_to_cpu(mac_control->stats_info->tmac_any_err_frms) -
+		sp->stats.tx_errors;
 	sp->stats.tx_errors =
 		le32_to_cpu(mac_control->stats_info->tmac_any_err_frms);
+	dev->stats.rx_errors +=
+		le64_to_cpu(mac_control->stats_info->rmac_drop_frms) -
+		sp->stats.rx_errors;
 	sp->stats.rx_errors =
 		le64_to_cpu(mac_control->stats_info->rmac_drop_frms);
+	dev->stats.multicast =
+		le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms) - 
+		sp->stats.multicast;
 	sp->stats.multicast =
 		le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms);
+	dev->stats.rx_length_errors =
+		le64_to_cpu(mac_control->stats_info->rmac_long_frms) - 
+		sp->stats.rx_length_errors;
 	sp->stats.rx_length_errors =
 		le64_to_cpu(mac_control->stats_info->rmac_long_frms);
 
 	/* collect per-ring rx_packets and rx_bytes */
-	sp->stats.rx_packets = sp->stats.rx_bytes = 0;
+	dev->stats.rx_packets = dev->stats.rx_bytes = 0;
 	for (i = 0; i < config->rx_ring_num; i++) {
-		sp->stats.rx_packets += mac_control->rings[i].rx_packets;
-		sp->stats.rx_bytes += mac_control->rings[i].rx_bytes;
+		dev->stats.rx_packets += mac_control->rings[i].rx_packets;
+		dev->stats.rx_bytes += mac_control->rings[i].rx_bytes;
 	}
 
-	return (&sp->stats);
+	return (&dev->stats);
 }
 
 /**
@@ -7419,7 +7436,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 		if (err_mask != 0x5) {
 			DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%x\n",
 				dev->name, err_mask);
-			sp->stats.rx_crc_errors++;
+			dev->stats.rx_crc_errors++;
 			sp->mac_control.stats_info->sw_stat.mem_freed
 				+= skb->truesize;
 			dev_kfree_skb(skb);
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index c69ba13..6a06b95 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -1,7 +1,7 @@
 /*
  *  SuperH Ethernet device driver
  *
- *  Copyright (C) 2006,2007 Nobuhiro Iwamatsu
+ *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
  *  Copyright (C) 2008 Renesas Solutions Corp.
  *
  *  This program is free software; you can redistribute it and/or modify it
@@ -143,13 +143,39 @@ static struct mdiobb_ops bb_ops = {
 	.get_mdio_data = sh_get_mdio,
 };
 
+/* Chip Reset */
 static void sh_eth_reset(struct net_device *ndev)
 {
 	u32 ioaddr = ndev->base_addr;
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+	int cnt = 100;
+
+	ctrl_outl(EDSR_ENALL, ioaddr + EDSR);
+	ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+	while (cnt > 0) {
+		if (!(ctrl_inl(ioaddr + EDMR) & 0x3))
+			break;
+		mdelay(1);
+		cnt--;
+	}
+	if (cnt < 0)
+		printk(KERN_ERR "Device reset fail\n");
+
+	/* Table Init */
+	ctrl_outl(0x0, ioaddr + TDLAR);
+	ctrl_outl(0x0, ioaddr + TDFAR);
+	ctrl_outl(0x0, ioaddr + TDFXR);
+	ctrl_outl(0x0, ioaddr + TDFFR);
+	ctrl_outl(0x0, ioaddr + RDLAR);
+	ctrl_outl(0x0, ioaddr + RDFAR);
+	ctrl_outl(0x0, ioaddr + RDFXR);
+	ctrl_outl(0x0, ioaddr + RDFFR);
+#else
 	ctrl_outl(ctrl_inl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
 	mdelay(3);
 	ctrl_outl(ctrl_inl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
+#endif
 }
 
 /* free skb and descriptor buffer */
@@ -180,6 +206,7 @@ static void sh_eth_ring_free(struct net_device *ndev)
 /* format skb and descriptor buffer */
 static void sh_eth_ring_format(struct net_device *ndev)
 {
+	u32 ioaddr = ndev->base_addr, reserve = 0;
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 	int i;
 	struct sk_buff *skb;
@@ -201,9 +228,15 @@ static void sh_eth_ring_format(struct net_device *ndev)
 		mdp->rx_skbuff[i] = skb;
 		if (skb == NULL)
 			break;
-		skb->dev = ndev;	/* Mark as being used by this device. */
+		skb->dev = ndev; /* Mark as being used by this device. */
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+		reserve = SH7763_SKB_ALIGN
+			- ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
+		if (reserve)
+			skb_reserve(skb, reserve);
+#else
 		skb_reserve(skb, RX_OFFSET);
-
+#endif
 		/* RX descriptor */
 		rxdesc = &mdp->rx_ring[i];
 		rxdesc->addr = (u32)skb->data & ~0x3UL;
@@ -211,12 +244,25 @@ static void sh_eth_ring_format(struct net_device *ndev)
 
 		/* The size of the buffer is 16 byte boundary. */
 		rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
+		/* Rx descriptor address set */
+		if (i == 0) {
+			ctrl_outl((u32)rxdesc, ioaddr + RDLAR);
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+			ctrl_outl((u32)rxdesc, ioaddr + RDFAR);
+#endif
+		}
 	}
 
+	/* Rx descriptor address set */
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+	ctrl_outl((u32)rxdesc, ioaddr + RDFXR);
+	ctrl_outl(0x1, ioaddr + RDFFR);
+#endif
+
 	mdp->dirty_rx = (u32) (i - RX_RING_SIZE);
 
 	/* Mark the last entry as wrapping the ring. */
-	rxdesc->status |= cpu_to_le32(RC_RDEL);
+	rxdesc->status |= cpu_to_le32(RD_RDEL);
 
 	memset(mdp->tx_ring, 0, tx_ringsize);
 
@@ -226,8 +272,21 @@ static void sh_eth_ring_format(struct net_device *ndev)
 		txdesc = &mdp->tx_ring[i];
 		txdesc->status = cpu_to_le32(TD_TFP);
 		txdesc->buffer_length = 0;
+		if (i == 0) {
+			/* Rx descriptor address set */
+			ctrl_outl((u32)txdesc, ioaddr + TDLAR);
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+			ctrl_outl((u32)txdesc, ioaddr + TDFAR);
+#endif
+		}
 	}
 
+	/* Rx descriptor address set */
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+	ctrl_outl((u32)txdesc, ioaddr + TDFXR);
+	ctrl_outl(0x1, ioaddr + TDFFR);
+#endif
+
 	txdesc->status |= cpu_to_le32(TD_TDLE);
 }
 
@@ -311,31 +370,43 @@ static int sh_eth_dev_init(struct net_device *ndev)
 	/* Soft Reset */
 	sh_eth_reset(ndev);
 
-	ctrl_outl(RPADIR_PADS1, ioaddr + RPADIR);	/* SH7712-DMA-RX-PAD2 */
+	/* Descriptor format */
+	sh_eth_ring_format(ndev);
+	ctrl_outl(RPADIR_INIT, ioaddr + RPADIR);
 
 	/* all sh_eth int mask */
 	ctrl_outl(0, ioaddr + EESIPR);
 
-	/* FIFO size set */
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+	ctrl_outl(EDMR_EL, ioaddr + EDMR);
+#else
 	ctrl_outl(0, ioaddr + EDMR);	/* Endian change */
+#endif
 
+	/* FIFO size set */
 	ctrl_outl((FIFO_SIZE_T | FIFO_SIZE_R), ioaddr + FDR);
 	ctrl_outl(0, ioaddr + TFTR);
 
+	/* Frame recv control */
 	ctrl_outl(0, ioaddr + RMCR);
 
 	rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
 	tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
 	ctrl_outl(rx_int_var | tx_int_var, ioaddr + TRSCER);
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+	/* Burst sycle set */
+	ctrl_outl(0x800, ioaddr + BCULR);
+#endif
+
 	ctrl_outl((FIFO_F_D_RFF | FIFO_F_D_RFD), ioaddr + FCFTR);
-	ctrl_outl(0, ioaddr + TRIMD);
 
-	/* Descriptor format */
-	sh_eth_ring_format(ndev);
+#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
+	ctrl_outl(0, ioaddr + TRIMD);
+#endif
 
-	ctrl_outl((u32)mdp->rx_ring, ioaddr + RDLAR);
-	ctrl_outl((u32)mdp->tx_ring, ioaddr + TDLAR);
+	/* Recv frame limit set register */
+	ctrl_outl(RFLR_VALUE, ioaddr + RFLR);
 
 	ctrl_outl(ctrl_inl(ioaddr + EESR), ioaddr + EESR);
 	ctrl_outl((DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff), ioaddr + EESIPR);
@@ -345,21 +416,26 @@ static int sh_eth_dev_init(struct net_device *ndev)
 		ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;
 
 	ctrl_outl(val, ioaddr + ECMR);
-	ctrl_outl(ECSR_BRCRX | ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD |
-		  ECSIPR_MPDIP, ioaddr + ECSR);
-	ctrl_outl(ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP |
-		  ECSIPR_ICDIP | ECSIPR_MPDIP, ioaddr + ECSIPR);
+
+	/* E-MAC Status Register clear */
+	ctrl_outl(ECSR_INIT, ioaddr + ECSR);
+
+	/* E-MAC Interrupt Enable register */
+	ctrl_outl(ECSIPR_INIT, ioaddr + ECSIPR);
 
 	/* Set MAC address */
 	update_mac_address(ndev);
 
 	/* mask reset */
-#if defined(CONFIG_CPU_SUBTYPE_SH7710)
+#if defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7763)
 	ctrl_outl(APR_AP, ioaddr + APR);
 	ctrl_outl(MPR_MP, ioaddr + MPR);
 	ctrl_outl(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
+#endif
+#if defined(CONFIG_CPU_SUBTYPE_SH7710)
 	ctrl_outl(BCFR_UNLIMITED, ioaddr + BCFR);
 #endif
+
 	/* Setting the Rx mode will start the Rx process. */
 	ctrl_outl(EDRRR_R, ioaddr + EDRRR);
 
@@ -407,7 +483,7 @@ static int sh_eth_rx(struct net_device *ndev)
 	int boguscnt = (mdp->dirty_rx + RX_RING_SIZE) - mdp->cur_rx;
 	struct sk_buff *skb;
 	u16 pkt_len = 0;
-	u32 desc_status;
+	u32 desc_status, reserve = 0;
 
 	rxdesc = &mdp->rx_ring[entry];
 	while (!(rxdesc->status & cpu_to_le32(RD_RACT))) {
@@ -454,28 +530,38 @@ static int sh_eth_rx(struct net_device *ndev)
 	for (; mdp->cur_rx - mdp->dirty_rx > 0; mdp->dirty_rx++) {
 		entry = mdp->dirty_rx % RX_RING_SIZE;
 		rxdesc = &mdp->rx_ring[entry];
+		/* The size of the buffer is 16 byte boundary. */
+		rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
+
 		if (mdp->rx_skbuff[entry] == NULL) {
 			skb = dev_alloc_skb(mdp->rx_buf_sz);
 			mdp->rx_skbuff[entry] = skb;
 			if (skb == NULL)
 				break;	/* Better luck next round. */
 			skb->dev = ndev;
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+			reserve = SH7763_SKB_ALIGN
+				- ((uint32_t)skb->data & (SH7763_SKB_ALIGN-1));
+			if (reserve)
+				skb_reserve(skb, reserve);
+#else
 			skb_reserve(skb, RX_OFFSET);
+#endif
+			skb->ip_summed = CHECKSUM_NONE;
 			rxdesc->addr = (u32)skb->data & ~0x3UL;
 		}
-		/* The size of the buffer is 16 byte boundary. */
-		rxdesc->buffer_length = (mdp->rx_buf_sz + 16) & ~0x0F;
 		if (entry >= RX_RING_SIZE - 1)
 			rxdesc->status |=
-			cpu_to_le32(RD_RACT | RD_RFP | RC_RDEL);
+				cpu_to_le32(RD_RACT | RD_RFP | RD_RDEL);
 		else
 			rxdesc->status |=
-			cpu_to_le32(RD_RACT | RD_RFP);
+				cpu_to_le32(RD_RACT | RD_RFP);
 	}
 
 	/* Restart Rx engine if stopped. */
 	/* If we don't need to check status, don't. -KDU */
-	ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR);
+	if (!(ctrl_inl(ndev->base_addr + EDRRR) & EDRRR_R))
+		ctrl_outl(EDRRR_R, ndev->base_addr + EDRRR);
 
 	return 0;
 }
@@ -529,13 +615,14 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 			printk(KERN_ERR "Receive Frame Overflow\n");
 		}
 	}
-
+#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
 	if (intr_status & EESR_ADE) {
 		if (intr_status & EESR_TDE) {
 			if (intr_status & EESR_TFE)
 				mdp->stats.tx_fifo_errors++;
 		}
 	}
+#endif
 
 	if (intr_status & EESR_RDE) {
 		/* Receive Descriptor Empty int */
@@ -550,8 +637,11 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 		mdp->stats.rx_fifo_errors++;
 		printk(KERN_ERR "Receive FIFO Overflow\n");
 	}
-	if (intr_status &
-	    (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE)) {
+	if (intr_status & (EESR_TWB | EESR_TABT |
+#if !defined(CONFIG_CPU_SUBTYPE_SH7763)
+			EESR_ADE |
+#endif
+			EESR_TDE | EESR_TFE)) {
 		/* Tx error */
 		u32 edtrr = ctrl_inl(ndev->base_addr + EDTRR);
 		/* dmesg */
@@ -582,17 +672,23 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
 	ioaddr = ndev->base_addr;
 	spin_lock(&mdp->lock);
 
+	/* Get interrpt stat */
 	intr_status = ctrl_inl(ioaddr + EESR);
 	/* Clear interrupt */
 	ctrl_outl(intr_status, ioaddr + EESR);
 
-	if (intr_status & (EESR_FRC | EESR_RINT8 |
-			   EESR_RINT5 | EESR_RINT4 | EESR_RINT3 | EESR_RINT2 |
-			   EESR_RINT1))
+	if (intr_status & (EESR_FRC | /* Frame recv*/
+			EESR_RMAF | /* Multi cast address recv*/
+			EESR_RRF  | /* Bit frame recv */
+			EESR_RTLF | /* Long frame recv*/
+			EESR_RTSF | /* short frame recv */
+			EESR_PRE  | /* PHY-LSI recv error */
+			EESR_CERF)){ /* recv frame CRC error */
 		sh_eth_rx(ndev);
-	if (intr_status & (EESR_FTC |
-			   EESR_TINT4 | EESR_TINT3 | EESR_TINT2 | EESR_TINT1)) {
+	}
 
+	/* Tx Check */
+	if (intr_status & TX_CHECK) {
 		sh_eth_txfree(ndev);
 		netif_wake_queue(ndev);
 	}
@@ -631,11 +727,32 @@ static void sh_eth_adjust_link(struct net_device *ndev)
 		if (phydev->duplex != mdp->duplex) {
 			new_state = 1;
 			mdp->duplex = phydev->duplex;
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+			if (mdp->duplex) { /*  FULL */
+				ctrl_outl(ctrl_inl(ioaddr + ECMR) | ECMR_DM,
+						ioaddr + ECMR);
+			} else {	/* Half */
+				ctrl_outl(ctrl_inl(ioaddr + ECMR) & ~ECMR_DM,
+						ioaddr + ECMR);
+			}
+#endif
 		}
 
 		if (phydev->speed != mdp->speed) {
 			new_state = 1;
 			mdp->speed = phydev->speed;
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+			switch (mdp->speed) {
+			case 10: /* 10BASE */
+				ctrl_outl(GECMR_10, ioaddr + GECMR); break;
+			case 100:/* 100BASE */
+				ctrl_outl(GECMR_100, ioaddr + GECMR); break;
+			case 1000: /* 1000BASE */
+				ctrl_outl(GECMR_1000, ioaddr + GECMR); break;
+			default:
+				break;
+			}
+#endif
 		}
 		if (mdp->link == PHY_DOWN) {
 			ctrl_outl((ctrl_inl(ioaddr + ECMR) & ~ECMR_TXF)
@@ -730,7 +847,7 @@ static int sh_eth_open(struct net_device *ndev)
 	/* Set the timer to check for link beat. */
 	init_timer(&mdp->timer);
 	mdp->timer.expires = (jiffies + (24 * HZ)) / 10;/* 2.4 sec. */
-	setup_timer(&mdp->timer, sh_eth_timer, ndev);
+	setup_timer(&mdp->timer, sh_eth_timer, (unsigned long)ndev);
 
 	return ret;
 
@@ -820,7 +937,9 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 
 	mdp->cur_tx++;
 
-	ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR);
+	if (!(ctrl_inl(ndev->base_addr + EDTRR) & EDTRR_TRNS))
+		ctrl_outl(EDTRR_TRNS, ndev->base_addr + EDTRR);
+
 	ndev->trans_start = jiffies;
 
 	return 0;
@@ -877,9 +996,15 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
 	ctrl_outl(0, ioaddr + CDCR);	/* (write clear) */
 	mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + LCCR);
 	ctrl_outl(0, ioaddr + LCCR);	/* (write clear) */
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+	mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CERCR);/* CERCR */
+	ctrl_outl(0, ioaddr + CERCR);	/* (write clear) */
+	mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CEECR);/* CEECR */
+	ctrl_outl(0, ioaddr + CEECR);	/* (write clear) */
+#else
 	mdp->stats.tx_carrier_errors += ctrl_inl(ioaddr + CNDCR);
 	ctrl_outl(0, ioaddr + CNDCR);	/* (write clear) */
-
+#endif
 	return &mdp->stats;
 }
 
@@ -929,8 +1054,13 @@ static void sh_eth_tsu_init(u32 ioaddr)
 	ctrl_outl(0, ioaddr + TSU_FWSL0);
 	ctrl_outl(0, ioaddr + TSU_FWSL1);
 	ctrl_outl(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC);
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+	ctrl_outl(0, ioaddr + TSU_QTAG0);	/* Disable QTAG(0->1) */
+	ctrl_outl(0, ioaddr + TSU_QTAG1);	/* Disable QTAG(1->0) */
+#else
 	ctrl_outl(0, ioaddr + TSU_QTAGM0);	/* Disable QTAG(0->1) */
 	ctrl_outl(0, ioaddr + TSU_QTAGM1);	/* Disable QTAG(1->0) */
+#endif
 	ctrl_outl(0, ioaddr + TSU_FWSR);	/* all interrupt status clear */
 	ctrl_outl(0, ioaddr + TSU_FWINMK);	/* Disable all interrupt */
 	ctrl_outl(0, ioaddr + TSU_TEN);	/* Disable all CAM entry */
@@ -1088,7 +1218,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	/* First device only init */
 	if (!devno) {
 		/* reset device */
-		ctrl_outl(ARSTR_ARSTR, ndev->base_addr + ARSTR);
+		ctrl_outl(ARSTR_ARSTR, ARSTR);
 		mdelay(1);
 
 		/* TSU init (Init only)*/
@@ -1110,8 +1240,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	       ndev->name, CARDNAME, (u32) ndev->base_addr);
 
 	for (i = 0; i < 5; i++)
-		printk(KERN_INFO "%2.2x:", ndev->dev_addr[i]);
-	printk(KERN_INFO "%2.2x, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);
+		printk(KERN_INFO "%02X:", ndev->dev_addr[i]);
+	printk(KERN_INFO "%02X, IRQ %d.\n", ndev->dev_addr[i], ndev->irq);
 
 	platform_set_drvdata(pdev, ndev);
 
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index e01e1c3..45ad1b0 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -32,118 +32,249 @@
 
 #define CARDNAME	"sh-eth"
 #define TX_TIMEOUT	(5*HZ)
-
-#define TX_RING_SIZE	128	/* Tx ring size */
-#define RX_RING_SIZE	128	/* Rx ring size */
-#define RX_OFFSET		2	/* skb offset */
+#define TX_RING_SIZE	64	/* Tx ring size */
+#define RX_RING_SIZE	64	/* Rx ring size */
 #define ETHERSMALL		60
 #define PKT_BUF_SZ		1538
 
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+
+#define SH7763_SKB_ALIGN 32
 /* Chip Base Address */
-#define SH_TSU_ADDR 0xA7000804
+# define SH_TSU_ADDR  0xFFE01800
+# define ARSTR 		  0xFFE01800
+
+/* Chip Registers */
+/* E-DMAC */
+# define EDSR    0x000
+# define EDMR    0x400
+# define EDTRR   0x408
+# define EDRRR   0x410
+# define EESR    0x428
+# define EESIPR  0x430
+# define TDLAR   0x010
+# define TDFAR   0x014
+# define TDFXR   0x018
+# define TDFFR   0x01C
+# define RDLAR   0x030
+# define RDFAR   0x034
+# define RDFXR   0x038
+# define RDFFR   0x03C
+# define TRSCER  0x438
+# define RMFCR   0x440
+# define TFTR    0x448
+# define FDR     0x450
+# define RMCR    0x458
+# define RPADIR  0x460
+# define FCFTR   0x468
+
+/* Ether Register */
+# define ECMR    0x500
+# define ECSR    0x510
+# define ECSIPR  0x518
+# define PIR     0x520
+# define PSR     0x528
+# define PIPR    0x52C
+# define RFLR    0x508
+# define APR     0x554
+# define MPR     0x558
+# define PFTCR	 0x55C
+# define PFRCR	 0x560
+# define TPAUSER 0x564
+# define GECMR   0x5B0
+# define BCULR   0x5B4
+# define MAHR    0x5C0
+# define MALR    0x5C8
+# define TROCR   0x700
+# define CDCR    0x708
+# define LCCR    0x710
+# define CEFCR   0x740
+# define FRECR   0x748
+# define TSFRCR  0x750
+# define TLFRCR  0x758
+# define RFCR    0x760
+# define CERCR   0x768
+# define CEECR   0x770
+# define MAFCR   0x778
+
+/* TSU Absolute Address */
+# define TSU_CTRST       0x004
+# define TSU_FWEN0       0x010
+# define TSU_FWEN1       0x014
+# define TSU_FCM         0x18
+# define TSU_BSYSL0      0x20
+# define TSU_BSYSL1      0x24
+# define TSU_PRISL0      0x28
+# define TSU_PRISL1      0x2C
+# define TSU_FWSL0       0x30
+# define TSU_FWSL1       0x34
+# define TSU_FWSLC       0x38
+# define TSU_QTAG0       0x40
+# define TSU_QTAG1       0x44
+# define TSU_FWSR        0x50
+# define TSU_FWINMK      0x54
+# define TSU_ADQT0       0x48
+# define TSU_ADQT1       0x4C
+# define TSU_VTAG0       0x58
+# define TSU_VTAG1       0x5C
+# define TSU_ADSBSY      0x60
+# define TSU_TEN         0x64
+# define TSU_POST1       0x70
+# define TSU_POST2       0x74
+# define TSU_POST3       0x78
+# define TSU_POST4       0x7C
+# define TSU_ADRH0       0x100
+# define TSU_ADRL0       0x104
+# define TSU_ADRH31      0x1F8
+# define TSU_ADRL31      0x1FC
+
+# define TXNLCR0         0x80
+# define TXALCR0         0x84
+# define RXNLCR0         0x88
+# define RXALCR0         0x8C
+# define FWNLCR0         0x90
+# define FWALCR0         0x94
+# define TXNLCR1         0xA0
+# define TXALCR1         0xA4
+# define RXNLCR1         0xA8
+# define RXALCR1         0xAC
+# define FWNLCR1         0xB0
+# define FWALCR1         0x40
+
+#else /* CONFIG_CPU_SUBTYPE_SH7763 */
+# define RX_OFFSET 2	/* skb offset */
+/* Chip base address */
+# define SH_TSU_ADDR  0xA7000804
+# define ARSTR		  0xA7000800
 
 /* Chip Registers */
 /* E-DMAC */
-#define EDMR	0x0000
-#define EDTRR	0x0004
-#define EDRRR	0x0008
-#define TDLAR	0x000C
-#define RDLAR	0x0010
-#define EESR	0x0014
-#define EESIPR	0x0018
-#define TRSCER	0x001C
-#define RMFCR	0x0020
-#define TFTR	0x0024
-#define FDR		0x0028
-#define RMCR	0x002C
-#define EDOCR	0x0030
-#define FCFTR	0x0034
-#define RPADIR	0x0038
-#define TRIMD	0x003C
-#define RBWAR	0x0040
-#define RDFAR	0x0044
-#define TBRAR	0x004C
-#define TDFAR	0x0050
+# define EDMR	0x0000
+# define EDTRR	0x0004
+# define EDRRR	0x0008
+# define TDLAR	0x000C
+# define RDLAR	0x0010
+# define EESR	0x0014
+# define EESIPR	0x0018
+# define TRSCER	0x001C
+# define RMFCR	0x0020
+# define TFTR	0x0024
+# define FDR	0x0028
+# define RMCR	0x002C
+# define EDOCR	0x0030
+# define FCFTR	0x0034
+# define RPADIR	0x0038
+# define TRIMD	0x003C
+# define RBWAR	0x0040
+# define RDFAR	0x0044
+# define TBRAR	0x004C
+# define TDFAR	0x0050
+
 /* Ether Register */
-#define ECMR	0x0160
-#define ECSR	0x0164
-#define ECSIPR	0x0168
-#define PIR		0x016C
-#define MAHR	0x0170
-#define MALR	0x0174
-#define RFLR	0x0178
-#define PSR		0x017C
-#define TROCR	0x0180
-#define CDCR	0x0184
-#define LCCR	0x0188
-#define CNDCR	0x018C
-#define CEFCR	0x0194
-#define FRECR	0x0198
-#define TSFRCR	0x019C
-#define TLFRCR	0x01A0
-#define RFCR	0x01A4
-#define MAFCR	0x01A8
-#define IPGR	0x01B4
-#if defined(CONFIG_CPU_SUBTYPE_SH7710)
-#define APR		0x01B8
-#define MPR 	0x01BC
-#define TPAUSER 0x1C4
-#define BCFR	0x1CC
-#endif /* CONFIG_CPU_SH7710 */
-
-#define ARSTR	0x0800
+# define ECMR	0x0160
+# define ECSR	0x0164
+# define ECSIPR	0x0168
+# define PIR	0x016C
+# define MAHR	0x0170
+# define MALR	0x0174
+# define RFLR	0x0178
+# define PSR	0x017C
+# define TROCR	0x0180
+# define CDCR	0x0184
+# define LCCR	0x0188
+# define CNDCR	0x018C
+# define CEFCR	0x0194
+# define FRECR	0x0198
+# define TSFRCR	0x019C
+# define TLFRCR	0x01A0
+# define RFCR	0x01A4
+# define MAFCR	0x01A8
+# define IPGR	0x01B4
+# if defined(CONFIG_CPU_SUBTYPE_SH7710)
+# define APR	0x01B8
+# define MPR 	0x01BC
+# define TPAUSER 0x1C4
+# define BCFR	0x1CC
+# endif /* CONFIG_CPU_SH7710 */
 
 /* TSU */
-#define TSU_CTRST	0x004
-#define TSU_FWEN0	0x010
-#define TSU_FWEN1	0x014
-#define TSU_FCM		0x018
-#define TSU_BSYSL0	0x020
-#define TSU_BSYSL1	0x024
-#define TSU_PRISL0	0x028
-#define TSU_PRISL1	0x02C
-#define TSU_FWSL0	0x030
-#define TSU_FWSL1	0x034
-#define TSU_FWSLC	0x038
-#define TSU_QTAGM0	0x040
-#define TSU_QTAGM1	0x044
-#define TSU_ADQT0 	0x048
-#define TSU_ADQT1	0x04C
-#define TSU_FWSR	0x050
-#define TSU_FWINMK	0x054
-#define TSU_ADSBSY	0x060
-#define TSU_TEN		0x064
-#define TSU_POST1	0x070
-#define TSU_POST2	0x074
-#define TSU_POST3	0x078
-#define TSU_POST4	0x07C
-#define TXNLCR0		0x080
-#define TXALCR0		0x084
-#define RXNLCR0		0x088
-#define RXALCR0		0x08C
-#define FWNLCR0		0x090
-#define FWALCR0		0x094
-#define TXNLCR1		0x0A0
-#define TXALCR1		0x0A4
-#define RXNLCR1		0x0A8
-#define RXALCR1		0x0AC
-#define FWNLCR1		0x0B0
-#define FWALCR1		0x0B4
+# define TSU_CTRST	0x004
+# define TSU_FWEN0	0x010
+# define TSU_FWEN1	0x014
+# define TSU_FCM	0x018
+# define TSU_BSYSL0	0x020
+# define TSU_BSYSL1	0x024
+# define TSU_PRISL0	0x028
+# define TSU_PRISL1	0x02C
+# define TSU_FWSL0	0x030
+# define TSU_FWSL1	0x034
+# define TSU_FWSLC	0x038
+# define TSU_QTAGM0	0x040
+# define TSU_QTAGM1	0x044
+# define TSU_ADQT0 	0x048
+# define TSU_ADQT1	0x04C
+# define TSU_FWSR	0x050
+# define TSU_FWINMK	0x054
+# define TSU_ADSBSY	0x060
+# define TSU_TEN	0x064
+# define TSU_POST1	0x070
+# define TSU_POST2	0x074
+# define TSU_POST3	0x078
+# define TSU_POST4	0x07C
+# define TXNLCR0	0x080
+# define TXALCR0	0x084
+# define RXNLCR0	0x088
+# define RXALCR0	0x08C
+# define FWNLCR0	0x090
+# define FWALCR0	0x094
+# define TXNLCR1	0x0A0
+# define TXALCR1	0x0A4
+# define RXNLCR1	0x0A8
+# define RXALCR1	0x0AC
+# define FWNLCR1	0x0B0
+# define FWALCR1	0x0B4
 
 #define TSU_ADRH0	0x0100
 #define TSU_ADRL0	0x0104
 #define TSU_ADRL31	0x01FC
 
-/* Register's bits */
+#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
+
+/*
+ * Register's bits
+ */
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+/* EDSR */
+enum EDSR_BIT {
+	EDSR_ENT = 0x01, EDSR_ENR = 0x02,
+};
+#define EDSR_ENALL (EDSR_ENT|EDSR_ENR)
+
+/* GECMR */
+enum GECMR_BIT {
+	GECMR_10 = 0x0, GECMR_100 = 0x04, GECMR_1000 = 0x01,
+};
+#endif
 
 /* EDMR */
 enum DMAC_M_BIT {
-	EDMR_DL1 = 0x20, EDMR_DL0 = 0x10, EDMR_SRST = 0x01,
+	EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+	EDMR_SRST	= 0x03,
+	EMDR_DESC_R	= 0x30, /* Descriptor reserve size */
+	EDMR_EL		= 0x40, /* Litte endian */
+#else /* CONFIG_CPU_SUBTYPE_SH7763 */
+	EDMR_SRST = 0x01,
+#endif
 };
 
 /* EDTRR */
 enum DMAC_T_BIT {
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+	EDTRR_TRNS = 0x03,
+#else
 	EDTRR_TRNS = 0x01,
+#endif
 };
 
 /* EDRRR*/
@@ -173,21 +304,47 @@ enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, };
 
 /* EESR */
 enum EESR_BIT {
-	EESR_TWB = 0x40000000, EESR_TABT = 0x04000000,
+#ifndef CONFIG_CPU_SUBTYPE_SH7763
+	EESR_TWB  = 0x40000000,
+#else
+	EESR_TWB  = 0xC0000000,
+	EESR_TC1  = 0x20000000,
+	EESR_TUC  = 0x10000000,
+	EESR_ROC  = 0x80000000,
+#endif
+	EESR_TABT = 0x04000000,
 	EESR_RABT = 0x02000000, EESR_RFRMER = 0x01000000,
-	EESR_ADE = 0x00800000, EESR_ECI = 0x00400000,
-	EESR_FTC = 0x00200000, EESR_TDE = 0x00100000,
-	EESR_TFE = 0x00080000, EESR_FRC = 0x00040000,
-	EESR_RDE = 0x00020000, EESR_RFE = 0x00010000,
-	EESR_TINT4 = 0x00000800, EESR_TINT3 = 0x00000400,
-	EESR_TINT2 = 0x00000200, EESR_TINT1 = 0x00000100,
-	EESR_RINT8 = 0x00000080, EESR_RINT5 = 0x00000010,
-	EESR_RINT4 = 0x00000008, EESR_RINT3 = 0x00000004,
-	EESR_RINT2 = 0x00000002, EESR_RINT1 = 0x00000001,
-};
-
-#define EESR_ERR_CHECK	(EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
+#ifndef CONFIG_CPU_SUBTYPE_SH7763
+	EESR_ADE  = 0x00800000,
+#endif
+	EESR_ECI  = 0x00400000,
+	EESR_FTC  = 0x00200000, EESR_TDE  = 0x00100000,
+	EESR_TFE  = 0x00080000, EESR_FRC  = 0x00040000,
+	EESR_RDE  = 0x00020000, EESR_RFE  = 0x00010000,
+#ifndef CONFIG_CPU_SUBTYPE_SH7763
+	EESR_CND  = 0x00000800,
+#endif
+	EESR_DLC  = 0x00000400,
+	EESR_CD   = 0x00000200, EESR_RTO  = 0x00000100,
+	EESR_RMAF = 0x00000080, EESR_CEEF = 0x00000040,
+	EESR_CELF = 0x00000020, EESR_RRF  = 0x00000010,
+	EESR_RTLF = 0x00000008, EESR_RTSF = 0x00000004,
+	EESR_PRE  = 0x00000002, EESR_CERF = 0x00000001,
+};
+
+
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+# define TX_CHECK (EESR_TC1 | EESR_FTC)
+# define EESR_ERR_CHECK	(EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
+		| EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI)
+# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE)
+
+#else
+# define TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO)
+# define EESR_ERR_CHECK	(EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \
 		| EESR_RFRMER | EESR_ADE | EESR_TFE | EESR_TDE | EESR_ECI)
+# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE)
+#endif
 
 /* EESIPR */
 enum DMAC_IM_BIT {
@@ -207,8 +364,8 @@ enum DMAC_IM_BIT {
 
 /* Receive descriptor bit */
 enum RD_STS_BIT {
-	RD_RACT = 0x80000000, RC_RDEL = 0x40000000,
-	RC_RFP1 = 0x20000000, RC_RFP0 = 0x10000000,
+	RD_RACT = 0x80000000, RD_RDEL = 0x40000000,
+	RD_RFP1 = 0x20000000, RD_RFP0 = 0x10000000,
 	RD_RFE = 0x08000000, RD_RFS10 = 0x00000200,
 	RD_RFS9 = 0x00000100, RD_RFS8 = 0x00000080,
 	RD_RFS7 = 0x00000040, RD_RFS6 = 0x00000020,
@@ -216,9 +373,9 @@ enum RD_STS_BIT {
 	RD_RFS3 = 0x00000004, RD_RFS2 = 0x00000002,
 	RD_RFS1 = 0x00000001,
 };
-#define RDF1ST	RC_RFP1
-#define RDFEND	RC_RFP0
-#define RD_RFP	(RC_RFP1|RC_RFP0)
+#define RDF1ST	RD_RFP1
+#define RDFEND	RD_RFP0
+#define RD_RFP	(RD_RFP1|RD_RFP0)
 
 /* FCFTR */
 enum FCFTR_BIT {
@@ -231,7 +388,8 @@ enum FCFTR_BIT {
 
 /* Transfer descriptor bit */
 enum TD_STS_BIT {
-	TD_TACT = 0x80000000, TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000,
+	TD_TACT = 0x80000000,
+	TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000,
 	TD_TFP0 = 0x10000000,
 };
 #define TDF1ST	TD_TFP1
@@ -242,6 +400,10 @@ enum TD_STS_BIT {
 enum RECV_RST_BIT { RMCR_RST = 0x01, };
 /* ECMR */
 enum FELIC_MODE_BIT {
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+	ECMR_TRCCM = 0x04000000, ECMR_RCSC = 0x00800000,
+	ECMR_DPAD = 0x00200000, ECMR_RZPF = 0x00100000,
+#endif
 	ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000,
 	ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000,
 	ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020,
@@ -249,18 +411,45 @@ enum FELIC_MODE_BIT {
 	ECMR_PRM = 0x00000001,
 };
 
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+#define ECMR_CHG_DM	(ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF |\
+			ECMR_PFR | ECMR_RXF | ECMR_TXF | ECMR_MCT)
+#else
+#define ECMR_CHG_DM	(ECMR_ZPF | ECMR_PFR ECMR_RXF | ECMR_TXF | ECMR_MCT)
+#endif
+
 /* ECSR */
 enum ECSR_STATUS_BIT {
-	ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10, ECSR_LCHNG = 0x04,
+#ifndef CONFIG_CPU_SUBTYPE_SH7763
+	ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10,
+#endif
+	ECSR_LCHNG = 0x04,
 	ECSR_MPD = 0x02, ECSR_ICD = 0x01,
 };
 
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+# define ECSR_INIT (ECSR_ICD | ECSIPR_MPDIP)
+#else
+# define ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | \
+			ECSR_LCHNG | ECSR_ICD | ECSIPR_MPDIP)
+#endif
+
 /* ECSIPR */
 enum ECSIPR_STATUS_MASK_BIT {
-	ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10, ECSIPR_LCHNGIP = 0x04,
+#ifndef CONFIG_CPU_SUBTYPE_SH7763
+	ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10,
+#endif
+	ECSIPR_LCHNGIP = 0x04,
 	ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01,
 };
 
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+# define ECSIPR_INIT (ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP)
+#else
+# define ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | \
+				ECSIPR_ICDIP | ECSIPR_MPDIP)
+#endif
+
 /* APR */
 enum APR_BIT {
 	APR_AP = 0x00000001,
@@ -285,6 +474,15 @@ enum RPADIR_BIT {
 	RPADIR_PADR = 0x0003f,
 };
 
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+# define RPADIR_INIT (0x00)
+#else
+# define RPADIR_INIT (RPADIR_PADS1)
+#endif
+
+/* RFLR */
+#define RFLR_VALUE 0x1000
+
 /* FDR */
 enum FIFO_SIZE_BIT {
 	FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007,
@@ -316,7 +514,7 @@ enum PHY_ANA_BIT {
 	PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000,
 	PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100,
 	PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020,
-	PHY_A_SEL = 0x001f,
+	PHY_A_SEL = 0x001e,
 };
 /* PHY_ANL */
 enum PHY_ANL_BIT {
@@ -449,6 +647,10 @@ struct sh_eth_private {
 	struct net_device_stats tsu_stats;	/* TSU forward status */
 };
 
+#ifdef CONFIG_CPU_SUBTYPE_SH7763
+/* SH7763 has endian control register */
+#define swaps(x, y)
+#else
 static void swaps(char *src, int len)
 {
 #ifdef __LITTLE_ENDIAN__
@@ -460,5 +662,5 @@ static void swaps(char *src, int len)
 		*p = swab32(*p);
 #endif
 }
-
+#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
 #endif
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index f7319d3..78df2be 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -55,12 +55,28 @@
 
 static int dm_read(struct usbnet *dev, u8 reg, u16 length, void *data)
 {
+	void *buf;
+	int err = -ENOMEM;
+
 	devdbg(dev, "dm_read() reg=0x%02x length=%d", reg, length);
-	return usb_control_msg(dev->udev,
-			       usb_rcvctrlpipe(dev->udev, 0),
-			       DM_READ_REGS,
-			       USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
-			       0, reg, data, length, USB_CTRL_SET_TIMEOUT);
+
+	buf = kmalloc(length, GFP_KERNEL);
+	if (!buf)
+		goto out;
+
+	err = usb_control_msg(dev->udev,
+			      usb_rcvctrlpipe(dev->udev, 0),
+			      DM_READ_REGS,
+			      USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+			      0, reg, buf, length, USB_CTRL_SET_TIMEOUT);
+	if (err == length)
+		memcpy(data, buf, length);
+	else if (err >= 0)
+		err = -EINVAL;
+	kfree(buf);
+
+ out:
+	return err;
 }
 
 static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value)
@@ -70,12 +86,28 @@ static int dm_read_reg(struct usbnet *dev, u8 reg, u8 *value)
 
 static int dm_write(struct usbnet *dev, u8 reg, u16 length, void *data)
 {
+	void *buf = NULL;
+	int err = -ENOMEM;
+
 	devdbg(dev, "dm_write() reg=0x%02x, length=%d", reg, length);
-	return usb_control_msg(dev->udev,
-			       usb_sndctrlpipe(dev->udev, 0),
-			       DM_WRITE_REGS,
-			       USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
-			       0, reg, data, length, USB_CTRL_SET_TIMEOUT);
+
+	if (data) {
+		buf = kmalloc(length, GFP_KERNEL);
+		if (!buf)
+			goto out;
+		memcpy(buf, data, length);
+	}
+
+	err = usb_control_msg(dev->udev,
+			      usb_sndctrlpipe(dev->udev, 0),
+			      DM_WRITE_REGS,
+			      USB_DIR_OUT | USB_TYPE_VENDOR |USB_RECIP_DEVICE,
+			      0, reg, buf, length, USB_CTRL_SET_TIMEOUT);
+	kfree(buf);
+	if (err >= 0 && err < length)
+		err = -EINVAL;
+ out:
+	return err;
 }
 
 static int dm_write_reg(struct usbnet *dev, u8 reg, u8 value)
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index fa14255..6f9aa16 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -337,7 +337,7 @@ static int __init wd_probe1(struct net_device *dev, int ioaddr)
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	dev->poll_controller = ei_poll;
 #endif
-	NS8390_init(dev, 0);
+	NS8390p_init(dev, 0);
 
 #if 1
 	/* Enable interrupt generation on softconfig cards -- M.U */

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-05-06 16:42 Jeff Garzik
@ 2008-05-08  9:49 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2008-05-08  9:49 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Tue, 6 May 2008 12:42:57 -0400

> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

Pulled, thanks a lot Jeff.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2008-05-06 16:42 Jeff Garzik
  2008-05-08  9:49 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2008-05-06 16:42 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


various fixes, two cleanups (pcnet32, 3c59x)

Please pull from 'upstream-davem' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

to receive the following updates:

 arch/arm/mach-orion5x/common.c            |    2 +
 arch/powerpc/platforms/chrp/pegasos_eth.c |    4 +
 arch/powerpc/sysdev/mv64x60_dev.c         |    2 +
 arch/ppc/syslib/mv64x60.c                 |    3 +
 drivers/net/3c59x.c                       |   73 +++----
 drivers/net/Kconfig                       |   14 --
 drivers/net/appletalk/cops.c              |   16 +-
 drivers/net/bonding/bond_main.c           |   24 ++-
 drivers/net/bonding/bond_sysfs.c          |   16 +-
 drivers/net/cxgb3/cxgb3_main.c            |    4 +-
 drivers/net/e1000e/defines.h              |   10 +
 drivers/net/e1000e/e1000.h                |    7 +-
 drivers/net/e1000e/ethtool.c              |   45 +++-
 drivers/net/e1000e/hw.h                   |   22 ++
 drivers/net/e1000e/ich8lan.c              |   83 +++++++-
 drivers/net/e1000e/netdev.c               |  330 ++++++++++++++++++++++++++++-
 drivers/net/e1000e/phy.c                  |  278 ++++++++++++++++++++++++
 drivers/net/eexpress.c                    |   11 +-
 drivers/net/fs_enet/mii-fec.c             |    3 +-
 drivers/net/gianfar.c                     |    5 +-
 drivers/net/gianfar.h                     |    3 +
 drivers/net/gianfar_sysfs.c               |   10 +-
 drivers/net/mv643xx_eth.c                 |  160 +++++++++++----
 drivers/net/pcnet32.c                     |   61 +-----
 drivers/net/phy/phy.c                     |    2 +-
 drivers/net/tulip/uli526x.c               |   38 ++--
 drivers/net/ucc_geth.c                    |  278 +++++++++++++------------
 drivers/net/ucc_geth.h                    |   48 +++--
 drivers/net/ucc_geth_ethtool.c            |    6 -
 drivers/net/ucc_geth_mii.c                |    4 +-
 include/linux/mv643xx_eth.h               |   16 ++-
 include/linux/phy.h                       |    5 +
 32 files changed, 1193 insertions(+), 390 deletions(-)

Alan Cox (1):
      cxgb3: Use CAP_SYS_RAWIO for firmware

Andy Fleming (3):
      gianfar: Fix a locking bug in gianfar's sysfs code
      phylib: Fix some sparse warnings
      ucc_geth: Fix a bunch of sparse warnings

Anton Vorontsov (2):
      uli526x: initialize the hardware prior to requesting interrupts
      uli526x: fix endianness issues in the setup frame

Bruce Allan (1):
      e1000e: Add support for BM PHYs on ICH9

Bruce Robson (1):
      [netdrvr] eexpress: IPv6 fails - multicast problems

Don Fry (1):
      pcnet32: delete non NAPI code from driver.

Gunnar Larisch (1):
      3c980-TX needs EXTRA_PREAMBLE

Jay Vosburgh (2):
      bonding: fix error unwind in bonding_store_bonds
      bonding: fix enslavement error unwinds

Jeff Garzik (1):
      fix warning in drivers/net/appletalk/cops.c

Joakim Tjernlund (1):
      ucc_geth: Don't use RX clock as TX clock.

Kok, Auke (1):
      e1000e: don't return half-read eeprom on error

Lennert Buytenhek (5):
      mv643xx_eth: get rid of static variables, allow multiple instances
      mv643xx_eth: mbus decode window support
      mv643xx_eth: configurable t_clk
      mv643xx_eth: shorten shared platform driver name
      mv643xx_eth: inter-mv643xx SMI port sharing

Paulius Zaleckas (1):
      3c59x: use netstats in net_device structure

Pavel Emelyanov (2):
      bonding: Do not call free_netdev for already registered device.
      bonding: Deadlock between bonding_store_bonds and bond_destroy_sysfs.

Scott Wood (1):
      fs_enet: Fix a memory leak in fs_enet_mdio_probe

diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 968deb5..0ecff5a 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -223,7 +223,9 @@ static struct platform_device orion5x_eth = {
 
 void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
 {
+	eth_data->shared = &orion5x_eth_shared;
 	orion5x_eth.dev.platform_data = eth_data;
+
 	platform_device_register(&orion5x_eth_shared);
 	platform_device_register(&orion5x_eth);
 }
diff --git a/arch/powerpc/platforms/chrp/pegasos_eth.c b/arch/powerpc/platforms/chrp/pegasos_eth.c
index 5bcc58d..130ff72 100644
--- a/arch/powerpc/platforms/chrp/pegasos_eth.c
+++ b/arch/powerpc/platforms/chrp/pegasos_eth.c
@@ -58,7 +58,9 @@ static struct resource mv643xx_eth0_resources[] = {
 
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+	.shared		= &mv643xx_eth_shared_device,
 	.port_number	= 0,
+
 	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH0,
 	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
 	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
@@ -88,7 +90,9 @@ static struct resource mv643xx_eth1_resources[] = {
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+	.shared		= &mv643xx_eth_shared_device,
 	.port_number	= 1,
+
 	.tx_sram_addr = PEGASOS2_SRAM_BASE_ETH1,
 	.tx_sram_size = PEGASOS2_SRAM_TXRING_SIZE,
 	.tx_queue_size = PEGASOS2_SRAM_TXRING_SIZE/16,
diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c
index 41af122..a132e0d 100644
--- a/arch/powerpc/sysdev/mv64x60_dev.c
+++ b/arch/powerpc/sysdev/mv64x60_dev.c
@@ -239,6 +239,8 @@ static int __init mv64x60_eth_device_setup(struct device_node *np, int id,
 
 	memset(&pdata, 0, sizeof(pdata));
 
+	pdata.shared = shared_pdev;
+
 	prop = of_get_property(np, "reg", NULL);
 	if (!prop)
 		return -ENODEV;
diff --git a/arch/ppc/syslib/mv64x60.c b/arch/ppc/syslib/mv64x60.c
index 90fe904..418f305 100644
--- a/arch/ppc/syslib/mv64x60.c
+++ b/arch/ppc/syslib/mv64x60.c
@@ -341,6 +341,7 @@ static struct resource mv64x60_eth0_resources[] = {
 };
 
 static struct mv643xx_eth_platform_data eth0_pd = {
+	.shared		= &mv64x60_eth_shared_device;
 	.port_number	= 0,
 };
 
@@ -366,6 +367,7 @@ static struct resource mv64x60_eth1_resources[] = {
 };
 
 static struct mv643xx_eth_platform_data eth1_pd = {
+	.shared		= &mv64x60_eth_shared_device;
 	.port_number	= 1,
 };
 
@@ -391,6 +393,7 @@ static struct resource mv64x60_eth2_resources[] = {
 };
 
 static struct mv643xx_eth_platform_data eth2_pd = {
+	.shared		= &mv64x60_eth_shared_device;
 	.port_number	= 2,
 };
 
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 6f8e7d4..2edda8c 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -319,7 +319,7 @@ static struct vortex_chip_info {
 	{"3c920B-EMB-WNM (ATI Radeon 9100 IGP)",
 	 PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, },
 	{"3c980 Cyclone",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 
 	{"3c980C Python-T",
 	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
@@ -600,7 +600,6 @@ struct vortex_private {
 	struct sk_buff* tx_skbuff[TX_RING_SIZE];
 	unsigned int cur_rx, cur_tx;		/* The next free ring entry */
 	unsigned int dirty_rx, dirty_tx;	/* The ring entries to be free()ed. */
-	struct net_device_stats stats;		/* Generic stats */
 	struct vortex_extra_stats xstats;	/* NIC-specific extra stats */
 	struct sk_buff *tx_skb;				/* Packet being eaten by bus master ctrl.  */
 	dma_addr_t tx_skb_dma;				/* Allocated DMA address for bus master ctrl DMA.   */
@@ -1875,7 +1874,7 @@ static void vortex_tx_timeout(struct net_device *dev)
 
 	issue_and_wait(dev, TxReset);
 
-	vp->stats.tx_errors++;
+	dev->stats.tx_errors++;
 	if (vp->full_bus_master_tx) {
 		printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
 		if (vp->cur_tx - vp->dirty_tx > 0  &&  ioread32(ioaddr + DownListPtr) == 0)
@@ -1887,7 +1886,7 @@ static void vortex_tx_timeout(struct net_device *dev)
 			iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
 		iowrite16(DownUnstall, ioaddr + EL3_CMD);
 	} else {
-		vp->stats.tx_dropped++;
+		dev->stats.tx_dropped++;
 		netif_wake_queue(dev);
 	}
 
@@ -1928,8 +1927,8 @@ vortex_error(struct net_device *dev, int status)
 			}
 			dump_tx_ring(dev);
 		}
-		if (tx_status & 0x14)  vp->stats.tx_fifo_errors++;
-		if (tx_status & 0x38)  vp->stats.tx_aborted_errors++;
+		if (tx_status & 0x14)  dev->stats.tx_fifo_errors++;
+		if (tx_status & 0x38)  dev->stats.tx_aborted_errors++;
 		if (tx_status & 0x08)  vp->xstats.tx_max_collisions++;
 		iowrite8(0, ioaddr + TxStatus);
 		if (tx_status & 0x30) {			/* txJabber or txUnderrun */
@@ -2051,8 +2050,8 @@ vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 				if (vortex_debug > 2)
 				  printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
 						 dev->name, tx_status);
-				if (tx_status & 0x04) vp->stats.tx_fifo_errors++;
-				if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
+				if (tx_status & 0x04) dev->stats.tx_fifo_errors++;
+				if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
 				if (tx_status & 0x30) {
 					issue_and_wait(dev, TxReset);
 				}
@@ -2350,7 +2349,7 @@ boomerang_interrupt(int irq, void *dev_id)
 				} else {
 					printk(KERN_DEBUG "boomerang_interrupt: no skb!\n");
 				}
-				/* vp->stats.tx_packets++;  Counted below. */
+				/* dev->stats.tx_packets++;  Counted below. */
 				dirty_tx++;
 			}
 			vp->dirty_tx = dirty_tx;
@@ -2409,12 +2408,12 @@ static int vortex_rx(struct net_device *dev)
 			unsigned char rx_error = ioread8(ioaddr + RxErrors);
 			if (vortex_debug > 2)
 				printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
-			vp->stats.rx_errors++;
-			if (rx_error & 0x01)  vp->stats.rx_over_errors++;
-			if (rx_error & 0x02)  vp->stats.rx_length_errors++;
-			if (rx_error & 0x04)  vp->stats.rx_frame_errors++;
-			if (rx_error & 0x08)  vp->stats.rx_crc_errors++;
-			if (rx_error & 0x10)  vp->stats.rx_length_errors++;
+			dev->stats.rx_errors++;
+			if (rx_error & 0x01)  dev->stats.rx_over_errors++;
+			if (rx_error & 0x02)  dev->stats.rx_length_errors++;
+			if (rx_error & 0x04)  dev->stats.rx_frame_errors++;
+			if (rx_error & 0x08)  dev->stats.rx_crc_errors++;
+			if (rx_error & 0x10)  dev->stats.rx_length_errors++;
 		} else {
 			/* The packet length: up to 4.5K!. */
 			int pkt_len = rx_status & 0x1fff;
@@ -2446,7 +2445,7 @@ static int vortex_rx(struct net_device *dev)
 				skb->protocol = eth_type_trans(skb, dev);
 				netif_rx(skb);
 				dev->last_rx = jiffies;
-				vp->stats.rx_packets++;
+				dev->stats.rx_packets++;
 				/* Wait a limited time to go to next packet. */
 				for (i = 200; i >= 0; i--)
 					if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
@@ -2455,7 +2454,7 @@ static int vortex_rx(struct net_device *dev)
 			} else if (vortex_debug > 0)
 				printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
 					   "size %d.\n", dev->name, pkt_len);
-			vp->stats.rx_dropped++;
+			dev->stats.rx_dropped++;
 		}
 		issue_and_wait(dev, RxDiscard);
 	}
@@ -2482,12 +2481,12 @@ boomerang_rx(struct net_device *dev)
 			unsigned char rx_error = rx_status >> 16;
 			if (vortex_debug > 2)
 				printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
-			vp->stats.rx_errors++;
-			if (rx_error & 0x01)  vp->stats.rx_over_errors++;
-			if (rx_error & 0x02)  vp->stats.rx_length_errors++;
-			if (rx_error & 0x04)  vp->stats.rx_frame_errors++;
-			if (rx_error & 0x08)  vp->stats.rx_crc_errors++;
-			if (rx_error & 0x10)  vp->stats.rx_length_errors++;
+			dev->stats.rx_errors++;
+			if (rx_error & 0x01)  dev->stats.rx_over_errors++;
+			if (rx_error & 0x02)  dev->stats.rx_length_errors++;
+			if (rx_error & 0x04)  dev->stats.rx_frame_errors++;
+			if (rx_error & 0x08)  dev->stats.rx_crc_errors++;
+			if (rx_error & 0x10)  dev->stats.rx_length_errors++;
 		} else {
 			/* The packet length: up to 4.5K!. */
 			int pkt_len = rx_status & 0x1fff;
@@ -2529,7 +2528,7 @@ boomerang_rx(struct net_device *dev)
 			}
 			netif_rx(skb);
 			dev->last_rx = jiffies;
-			vp->stats.rx_packets++;
+			dev->stats.rx_packets++;
 		}
 		entry = (++vp->cur_rx) % RX_RING_SIZE;
 	}
@@ -2591,7 +2590,7 @@ vortex_down(struct net_device *dev, int final_down)
 	del_timer_sync(&vp->rx_oom_timer);
 	del_timer_sync(&vp->timer);
 
-	/* Turn off statistics ASAP.  We update vp->stats below. */
+	/* Turn off statistics ASAP.  We update dev->stats below. */
 	iowrite16(StatsDisable, ioaddr + EL3_CMD);
 
 	/* Disable the receiver and transmitter. */
@@ -2728,7 +2727,7 @@ static struct net_device_stats *vortex_get_stats(struct net_device *dev)
 		update_stats(ioaddr, dev);
 		spin_unlock_irqrestore (&vp->lock, flags);
 	}
-	return &vp->stats;
+	return &dev->stats;
 }
 
 /*  Update statistics.
@@ -2748,18 +2747,18 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev)
 	/* Unlike the 3c5x9 we need not turn off stats updates while reading. */
 	/* Switch to the stats window, and read everything. */
 	EL3WINDOW(6);
-	vp->stats.tx_carrier_errors		+= ioread8(ioaddr + 0);
-	vp->stats.tx_heartbeat_errors		+= ioread8(ioaddr + 1);
-	vp->stats.tx_window_errors		+= ioread8(ioaddr + 4);
-	vp->stats.rx_fifo_errors		+= ioread8(ioaddr + 5);
-	vp->stats.tx_packets			+= ioread8(ioaddr + 6);
-	vp->stats.tx_packets			+= (ioread8(ioaddr + 9)&0x30) << 4;
+	dev->stats.tx_carrier_errors		+= ioread8(ioaddr + 0);
+	dev->stats.tx_heartbeat_errors		+= ioread8(ioaddr + 1);
+	dev->stats.tx_window_errors		+= ioread8(ioaddr + 4);
+	dev->stats.rx_fifo_errors		+= ioread8(ioaddr + 5);
+	dev->stats.tx_packets			+= ioread8(ioaddr + 6);
+	dev->stats.tx_packets			+= (ioread8(ioaddr + 9)&0x30) << 4;
 	/* Rx packets	*/			ioread8(ioaddr + 7);   /* Must read to clear */
 	/* Don't bother with register 9, an extension of registers 6&7.
 	   If we do use the 6&7 values the atomic update assumption above
 	   is invalid. */
-	vp->stats.rx_bytes 			+= ioread16(ioaddr + 10);
-	vp->stats.tx_bytes 			+= ioread16(ioaddr + 12);
+	dev->stats.rx_bytes 			+= ioread16(ioaddr + 10);
+	dev->stats.tx_bytes 			+= ioread16(ioaddr + 12);
 	/* Extra stats for get_ethtool_stats() */
 	vp->xstats.tx_multiple_collisions	+= ioread8(ioaddr + 2);
 	vp->xstats.tx_single_collisions         += ioread8(ioaddr + 3);
@@ -2767,14 +2766,14 @@ static void update_stats(void __iomem *ioaddr, struct net_device *dev)
 	EL3WINDOW(4);
 	vp->xstats.rx_bad_ssd			+= ioread8(ioaddr + 12);
 
-	vp->stats.collisions = vp->xstats.tx_multiple_collisions
+	dev->stats.collisions = vp->xstats.tx_multiple_collisions
 		+ vp->xstats.tx_single_collisions
 		+ vp->xstats.tx_max_collisions;
 
 	{
 		u8 up = ioread8(ioaddr + 13);
-		vp->stats.rx_bytes += (up & 0x0f) << 16;
-		vp->stats.tx_bytes += (up & 0xf0) << 12;
+		dev->stats.rx_bytes += (up & 0x0f) << 16;
+		dev->stats.tx_bytes += (up & 0xf0) << 12;
 	}
 
 	EL3WINDOW(old_window >> 13);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index af46341..d27f54a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1273,20 +1273,6 @@ config PCNET32
 	  To compile this driver as a module, choose M here. The module
 	  will be called pcnet32.
 
-config PCNET32_NAPI
-	bool "Use RX polling (NAPI)"
-	depends on PCNET32
-	help
-	  NAPI is a new driver API designed to reduce CPU and interrupt load
-	  when the driver is receiving lots of packets from the card. It is
-	  still somewhat experimental and thus not yet enabled by default.
-
-	  If your estimated Rx load is 10kpps or more, or if the card will be
-	  deployed on potentially unfriendly networks (e.g. in a firewall),
-	  then say Y here.
-
-	  If in doubt, say N.
-
 config AMD8111_ETH
 	tristate "AMD 8111 (new PCI lance) support"
 	depends on NET_PCI && PCI
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c
index 82e9a5b..a0b4c85 100644
--- a/drivers/net/appletalk/cops.c
+++ b/drivers/net/appletalk/cops.c
@@ -499,19 +499,13 @@ static void cops_reset(struct net_device *dev, int sleep)
         {
                 outb(0, ioaddr+DAYNA_RESET);	/* Assert the reset port */
                 inb(ioaddr+DAYNA_RESET);	/* Clear the reset */
-                if(sleep)
-                {
-                        long snap=jiffies;
-
-			/* Let card finish initializing, about 1/3 second */
-			while (time_before(jiffies, snap + HZ/3))
-                                schedule();
-                }
-                else
-                        mdelay(333);
+		if (sleep)
+			msleep(333);
+		else
+			mdelay(333);
         }
+
 	netif_wake_queue(dev);
-	return;
 }
 
 static void cops_load (struct net_device *dev)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6425603..50a40e4 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1425,13 +1425,13 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 	res = netdev_set_master(slave_dev, bond_dev);
 	if (res) {
 		dprintk("Error %d calling netdev_set_master\n", res);
-		goto err_close;
+		goto err_restore_mac;
 	}
 	/* open the slave since the application closed it */
 	res = dev_open(slave_dev);
 	if (res) {
 		dprintk("Openning slave %s failed\n", slave_dev->name);
-		goto err_restore_mac;
+		goto err_unset_master;
 	}
 
 	new_slave->dev = slave_dev;
@@ -1444,7 +1444,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 		 */
 		res = bond_alb_init_slave(bond, new_slave);
 		if (res) {
-			goto err_unset_master;
+			goto err_close;
 		}
 	}
 
@@ -1619,7 +1619,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
 	res = bond_create_slave_symlinks(bond_dev, slave_dev);
 	if (res)
-		goto err_unset_master;
+		goto err_close;
 
 	printk(KERN_INFO DRV_NAME
 	       ": %s: enslaving %s as a%s interface with a%s link.\n",
@@ -1631,12 +1631,12 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 	return 0;
 
 /* Undo stages on error */
-err_unset_master:
-	netdev_set_master(slave_dev, NULL);
-
 err_close:
 	dev_close(slave_dev);
 
+err_unset_master:
+	netdev_set_master(slave_dev, NULL);
+
 err_restore_mac:
 	if (!bond->params.fail_over_mac) {
 		memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
@@ -4936,7 +4936,9 @@ int bond_create(char *name, struct bond_params *params, struct bonding **newbond
 	if (res < 0) {
 		rtnl_lock();
 		down_write(&bonding_rwsem);
-		goto out_bond;
+		bond_deinit(bond_dev);
+		unregister_netdevice(bond_dev);
+		goto out_rtnl;
 	}
 
 	return 0;
@@ -4990,9 +4992,10 @@ err:
 		destroy_workqueue(bond->wq);
 	}
 
+	bond_destroy_sysfs();
+
 	rtnl_lock();
 	bond_free_all();
-	bond_destroy_sysfs();
 	rtnl_unlock();
 out:
 	return res;
@@ -5004,9 +5007,10 @@ static void __exit bonding_exit(void)
 	unregister_netdevice_notifier(&bond_netdev_notifier);
 	unregister_inetaddr_notifier(&bond_inetaddr_notifier);
 
+	bond_destroy_sysfs();
+
 	rtnl_lock();
 	bond_free_all();
-	bond_destroy_sysfs();
 	rtnl_unlock();
 }
 
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 979c2d0..68c41a0 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -146,29 +146,29 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
 						": Unable remove bond %s due to open references.\n",
 						ifname);
 					res = -EPERM;
-					goto out;
+					goto out_unlock;
 				}
 				printk(KERN_INFO DRV_NAME
 					": %s is being deleted...\n",
 					bond->dev->name);
 				bond_destroy(bond);
-				up_write(&bonding_rwsem);
-				rtnl_unlock();
-				goto out;
+				goto out_unlock;
 			}
 
 		printk(KERN_ERR DRV_NAME
 			": unable to delete non-existent bond %s\n", ifname);
 		res = -ENODEV;
-		up_write(&bonding_rwsem);
-		rtnl_unlock();
-		goto out;
+		goto out_unlock;
 	}
 
 err_no_cmd:
 	printk(KERN_ERR DRV_NAME
 		": no command found in bonding_masters. Use +ifname or -ifname.\n");
-	res = -EPERM;
+	return -EPERM;
+
+out_unlock:
+	up_write(&bonding_rwsem);
+	rtnl_unlock();
 
 	/* Always return either count or an error.  If you return 0, you'll
 	 * get called forever, which is bad.
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 05e5f59..ce949d5 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -1894,11 +1894,11 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
 		u8 *fw_data;
 		struct ch_mem_range t;
 
-		if (!capable(CAP_NET_ADMIN))
+		if (!capable(CAP_SYS_RAWIO))
 			return -EPERM;
 		if (copy_from_user(&t, useraddr, sizeof(t)))
 			return -EFAULT;
-
+		/* Check t.len sanity ? */
 		fw_data = kmalloc(t.len, GFP_KERNEL);
 		if (!fw_data)
 			return -ENOMEM;
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 2a53875..f823b8b 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -648,6 +648,8 @@
 #define IFE_E_PHY_ID         0x02A80330
 #define IFE_PLUS_E_PHY_ID    0x02A80320
 #define IFE_C_E_PHY_ID       0x02A80310
+#define BME1000_E_PHY_ID     0x01410CB0
+#define BME1000_E_PHY_ID_R2  0x01410CB1
 
 /* M88E1000 Specific Registers */
 #define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
@@ -701,6 +703,14 @@
 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK  0x0E00
 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X    0x0800
 
+/* BME1000 PHY Specific Control Register */
+#define BME1000_PSCR_ENABLE_DOWNSHIFT   0x0800 /* 1 = enable downshift */
+
+
+#define PHY_PAGE_SHIFT 5
+#define PHY_REG(page, reg) (((page) << PHY_PAGE_SHIFT) | \
+                           ((reg) & MAX_PHY_REG_ADDRESS))
+
 /*
  * Bits...
  * 15-5: page
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 38bfd0d..d3bc6f8 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -127,7 +127,7 @@ struct e1000_buffer {
 		/* arrays of page information for packet split */
 		struct e1000_ps_page *ps_pages;
 	};
-
+	struct page *page;
 };
 
 struct e1000_ring {
@@ -304,6 +304,7 @@ struct e1000_info {
 #define FLAG_HAS_CTRLEXT_ON_LOAD          (1 << 5)
 #define FLAG_HAS_SWSM_ON_LOAD             (1 << 6)
 #define FLAG_HAS_JUMBO_FRAMES             (1 << 7)
+#define FLAG_IS_ICH                       (1 << 9)
 #define FLAG_HAS_SMART_POWER_DOWN         (1 << 11)
 #define FLAG_IS_QUAD_PORT_A               (1 << 12)
 #define FLAG_IS_QUAD_PORT                 (1 << 13)
@@ -386,6 +387,7 @@ extern void e1000e_set_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw,
 						 bool state);
 extern void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw);
 extern void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw);
+extern void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw);
 
 extern s32 e1000e_check_for_copper_link(struct e1000_hw *hw);
 extern s32 e1000e_check_for_fiber_link(struct e1000_hw *hw);
@@ -443,6 +445,9 @@ extern s32 e1000e_get_phy_info_m88(struct e1000_hw *hw);
 extern s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data);
 extern s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data);
 extern enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id);
+extern s32 e1000e_determine_phy_address(struct e1000_hw *hw);
+extern s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data);
+extern s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data);
 extern void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl);
 extern s32 e1000e_write_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 data);
 extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index ce045ac..a14561f 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -494,8 +494,12 @@ static int e1000_get_eeprom(struct net_device *netdev,
 		for (i = 0; i < last_word - first_word + 1; i++) {
 			ret_val = e1000_read_nvm(hw, first_word + i, 1,
 						      &eeprom_buff[i]);
-			if (ret_val)
+			if (ret_val) {
+				/* a read error occurred, throw away the
+				 * result */
+				memset(eeprom_buff, 0xff, sizeof(eeprom_buff));
 				break;
+			}
 		}
 	}
 
@@ -803,8 +807,7 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 	/* restore previous status */
 	ew32(STATUS, before);
 
-	if ((mac->type != e1000_ich8lan) &&
-	    (mac->type != e1000_ich9lan)) {
+	if (!(adapter->flags & FLAG_IS_ICH)) {
 		REG_PATTERN_TEST(E1000_FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
 		REG_PATTERN_TEST(E1000_FCAH, 0x0000FFFF, 0xFFFFFFFF);
 		REG_PATTERN_TEST(E1000_FCT, 0x0000FFFF, 0xFFFFFFFF);
@@ -824,15 +827,13 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 
 	REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000);
 
-	before = (((mac->type == e1000_ich8lan) ||
-		   (mac->type == e1000_ich9lan)) ? 0x06C3B33E : 0x06DFB3FE);
+	before = ((adapter->flags & FLAG_IS_ICH) ? 0x06C3B33E : 0x06DFB3FE);
 	REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB);
 	REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000);
 
 	REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF);
 	REG_PATTERN_TEST(E1000_RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
-	if ((mac->type != e1000_ich8lan) &&
-	    (mac->type != e1000_ich9lan))
+	if (!(adapter->flags & FLAG_IS_ICH))
 		REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF);
 	REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
 	REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF);
@@ -911,9 +912,7 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
 
 	/* Test each interrupt */
 	for (i = 0; i < 10; i++) {
-
-		if (((adapter->hw.mac.type == e1000_ich8lan) ||
-		     (adapter->hw.mac.type == e1000_ich9lan)) && i == 8)
+		if ((adapter->flags & FLAG_IS_ICH) && (i == 8))
 			continue;
 
 		/* Interrupt to test */
@@ -1184,6 +1183,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 	u32 ctrl_reg = 0;
 	u32 stat_reg = 0;
+	u16 phy_reg = 0;
 
 	hw->mac.autoneg = 0;
 
@@ -1211,6 +1211,28 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
 			     E1000_CTRL_SPD_100 |/* Force Speed to 100 */
 			     E1000_CTRL_FD);	 /* Force Duplex to FULL */
 		break;
+	case e1000_phy_bm:
+		/* Set Default MAC Interface speed to 1GB */
+		e1e_rphy(hw, PHY_REG(2, 21), &phy_reg);
+		phy_reg &= ~0x0007;
+		phy_reg |= 0x006;
+		e1e_wphy(hw, PHY_REG(2, 21), phy_reg);
+		/* Assert SW reset for above settings to take effect */
+		e1000e_commit_phy(hw);
+		mdelay(1);
+		/* Force Full Duplex */
+		e1e_rphy(hw, PHY_REG(769, 16), &phy_reg);
+		e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x000C);
+		/* Set Link Up (in force link) */
+		e1e_rphy(hw, PHY_REG(776, 16), &phy_reg);
+		e1e_wphy(hw, PHY_REG(776, 16), phy_reg | 0x0040);
+		/* Force Link */
+		e1e_rphy(hw, PHY_REG(769, 16), &phy_reg);
+		e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x0040);
+		/* Set Early Link Enable */
+		e1e_rphy(hw, PHY_REG(769, 20), &phy_reg);
+		e1e_wphy(hw, PHY_REG(769, 20), phy_reg | 0x0400);
+		/* fall through */
 	default:
 		/* force 1000, set loopback */
 		e1e_wphy(hw, PHY_CONTROL, 0x4140);
@@ -1224,8 +1246,7 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
 			     E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
 			     E1000_CTRL_FD);	 /* Force Duplex to FULL */
 
-		if ((adapter->hw.mac.type == e1000_ich8lan) ||
-		    (adapter->hw.mac.type == e1000_ich9lan))
+		if (adapter->flags & FLAG_IS_ICH)
 			ctrl_reg |= E1000_CTRL_SLU;	/* Set Link Up */
 	}
 
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index a930e6d..74f263a 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -216,6 +216,21 @@ enum e1e_registers {
 #define IGP01E1000_PHY_LINK_HEALTH	0x13 /* PHY Link Health */
 #define IGP02E1000_PHY_POWER_MGMT	0x19 /* Power Management */
 #define IGP01E1000_PHY_PAGE_SELECT	0x1F /* Page Select */
+#define BM_PHY_PAGE_SELECT		22   /* Page Select for BM */
+#define IGP_PAGE_SHIFT			5
+#define PHY_REG_MASK			0x1F
+
+#define BM_WUC_PAGE			800
+#define BM_WUC_ADDRESS_OPCODE		0x11
+#define BM_WUC_DATA_OPCODE		0x12
+#define BM_WUC_ENABLE_PAGE		769
+#define BM_WUC_ENABLE_REG		17
+#define BM_WUC_ENABLE_BIT		(1 << 2)
+#define BM_WUC_HOST_WU_BIT		(1 << 4)
+
+#define BM_WUC	PHY_REG(BM_WUC_PAGE, 1)
+#define BM_WUFC PHY_REG(BM_WUC_PAGE, 2)
+#define BM_WUS	PHY_REG(BM_WUC_PAGE, 3)
 
 #define IGP01E1000_PHY_PCS_INIT_REG	0x00B4
 #define IGP01E1000_PHY_POLARITY_MASK	0x0078
@@ -331,10 +346,16 @@ enum e1e_registers {
 #define E1000_DEV_ID_ICH8_IFE_G			0x10C5
 #define E1000_DEV_ID_ICH8_IGP_M			0x104D
 #define E1000_DEV_ID_ICH9_IGP_AMT		0x10BD
+#define E1000_DEV_ID_ICH9_IGP_M_AMT		0x10F5
+#define E1000_DEV_ID_ICH9_IGP_M			0x10BF
+#define E1000_DEV_ID_ICH9_IGP_M_V		0x10CB
 #define E1000_DEV_ID_ICH9_IGP_C			0x294C
 #define E1000_DEV_ID_ICH9_IFE			0x10C0
 #define E1000_DEV_ID_ICH9_IFE_GT		0x10C3
 #define E1000_DEV_ID_ICH9_IFE_G			0x10C2
+#define E1000_DEV_ID_ICH10_R_BM_LM		0x10CC
+#define E1000_DEV_ID_ICH10_R_BM_LF		0x10CD
+#define E1000_DEV_ID_ICH10_R_BM_V		0x10CE
 
 #define E1000_FUNC_1 1
 
@@ -378,6 +399,7 @@ enum e1000_phy_type {
 	e1000_phy_gg82563,
 	e1000_phy_igp_3,
 	e1000_phy_ife,
+	e1000_phy_bm,
 };
 
 enum e1000_bus_width {
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 768485d..9e38452 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -38,6 +38,12 @@
  * 82566DM Gigabit Network Connection
  * 82566MC Gigabit Network Connection
  * 82566MM Gigabit Network Connection
+ * 82567LM Gigabit Network Connection
+ * 82567LF Gigabit Network Connection
+ * 82567LM-2 Gigabit Network Connection
+ * 82567LF-2 Gigabit Network Connection
+ * 82567V-2 Gigabit Network Connection
+ * 82562GT-3 10/100 Network Connection
  */
 
 #include <linux/netdevice.h>
@@ -198,6 +204,19 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
 	phy->addr			= 1;
 	phy->reset_delay_us		= 100;
 
+	/*
+	 * We may need to do this twice - once for IGP and if that fails,
+	 * we'll set BM func pointers and try again
+	 */
+	ret_val = e1000e_determine_phy_address(hw);
+	if (ret_val) {
+		hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm;
+		hw->phy.ops.read_phy_reg  = e1000e_read_phy_reg_bm;
+		ret_val = e1000e_determine_phy_address(hw);
+		if (ret_val)
+			return ret_val;
+	}
+
 	phy->id = 0;
 	while ((e1000_phy_unknown == e1000e_get_phy_type_from_id(phy->id)) &&
 	       (i++ < 100)) {
@@ -219,6 +238,13 @@ static s32 e1000_init_phy_params_ich8lan(struct e1000_hw *hw)
 		phy->type = e1000_phy_ife;
 		phy->autoneg_mask = E1000_ALL_NOT_GIG;
 		break;
+	case BME1000_E_PHY_ID:
+		phy->type = e1000_phy_bm;
+		phy->autoneg_mask = AUTONEG_ADVERTISE_SPEED_DEFAULT;
+		hw->phy.ops.read_phy_reg = e1000e_read_phy_reg_bm;
+		hw->phy.ops.write_phy_reg = e1000e_write_phy_reg_bm;
+		hw->phy.ops.commit_phy = e1000e_phy_sw_reset;
+		break;
 	default:
 		return -E1000_ERR_PHY;
 		break;
@@ -664,6 +690,7 @@ static s32 e1000_get_phy_info_ich8lan(struct e1000_hw *hw)
 		return e1000_get_phy_info_ife_ich8lan(hw);
 		break;
 	case e1000_phy_igp_3:
+	case e1000_phy_bm:
 		return e1000e_get_phy_info_igp(hw);
 		break;
 	default:
@@ -728,7 +755,7 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
 	s32 ret_val = 0;
 	u16 data;
 
-	if (phy->type != e1000_phy_igp_3)
+	if (phy->type == e1000_phy_ife)
 		return ret_val;
 
 	phy_ctrl = er32(PHY_CTRL);
@@ -1918,8 +1945,35 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
 		ret_val = e1000e_copper_link_setup_igp(hw);
 		if (ret_val)
 			return ret_val;
+	} else if (hw->phy.type == e1000_phy_bm) {
+		ret_val = e1000e_copper_link_setup_m88(hw);
+		if (ret_val)
+			return ret_val;
 	}
 
+	if (hw->phy.type == e1000_phy_ife) {
+		ret_val = e1e_rphy(hw, IFE_PHY_MDIX_CONTROL, &reg_data);
+		if (ret_val)
+			return ret_val;
+
+		reg_data &= ~IFE_PMC_AUTO_MDIX;
+
+		switch (hw->phy.mdix) {
+		case 1:
+			reg_data &= ~IFE_PMC_FORCE_MDIX;
+			break;
+		case 2:
+			reg_data |= IFE_PMC_FORCE_MDIX;
+			break;
+		case 0:
+		default:
+			reg_data |= IFE_PMC_AUTO_MDIX;
+			break;
+		}
+		ret_val = e1e_wphy(hw, IFE_PHY_MDIX_CONTROL, reg_data);
+		if (ret_val)
+			return ret_val;
+	}
 	return e1000e_setup_copper_link(hw);
 }
 
@@ -2127,6 +2181,31 @@ void e1000e_gig_downshift_workaround_ich8lan(struct e1000_hw *hw)
 }
 
 /**
+ *  e1000e_disable_gig_wol_ich8lan - disable gig during WoL
+ *  @hw: pointer to the HW structure
+ *
+ *  During S0 to Sx transition, it is possible the link remains at gig
+ *  instead of negotiating to a lower speed.  Before going to Sx, set
+ *  'LPLU Enabled' and 'Gig Disable' to force link speed negotiation
+ *  to a lower speed.
+ *
+ *  Should only be called for ICH9 devices.
+ **/
+void e1000e_disable_gig_wol_ich8lan(struct e1000_hw *hw)
+{
+	u32 phy_ctrl;
+
+	if (hw->mac.type == e1000_ich9lan) {
+		phy_ctrl = er32(PHY_CTRL);
+		phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU |
+		            E1000_PHY_CTRL_GBE_DISABLE;
+		ew32(PHY_CTRL, phy_ctrl);
+	}
+
+	return;
+}
+
+/**
  *  e1000_cleanup_led_ich8lan - Restore the default LED operation
  *  @hw: pointer to the HW structure
  *
@@ -2247,6 +2326,7 @@ static struct e1000_nvm_operations ich8_nvm_ops = {
 struct e1000_info e1000_ich8_info = {
 	.mac			= e1000_ich8lan,
 	.flags			= FLAG_HAS_WOL
+				  | FLAG_IS_ICH
 				  | FLAG_RX_CSUM_ENABLED
 				  | FLAG_HAS_CTRLEXT_ON_LOAD
 				  | FLAG_HAS_AMT
@@ -2262,6 +2342,7 @@ struct e1000_info e1000_ich8_info = {
 struct e1000_info e1000_ich9_info = {
 	.mac			= e1000_ich9lan,
 	.flags			= FLAG_HAS_JUMBO_FRAMES
+				  | FLAG_IS_ICH
 				  | FLAG_HAS_WOL
 				  | FLAG_RX_CSUM_ENABLED
 				  | FLAG_HAS_CTRLEXT_ON_LOAD
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 8991ab8..8cbb40f 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -43,10 +43,11 @@
 #include <linux/if_vlan.h>
 #include <linux/cpu.h>
 #include <linux/smp.h>
+#include <linux/pm_qos_params.h>
 
 #include "e1000.h"
 
-#define DRV_VERSION "0.2.1"
+#define DRV_VERSION "0.3.3.3-k2"
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -341,6 +342,89 @@ no_buffers:
 }
 
 /**
+ * e1000_alloc_jumbo_rx_buffers - Replace used jumbo receive buffers
+ * @adapter: address of board private structure
+ * @rx_ring: pointer to receive ring structure
+ * @cleaned_count: number of buffers to allocate this pass
+ **/
+
+static void e1000_alloc_jumbo_rx_buffers(struct e1000_adapter *adapter,
+                                         int cleaned_count)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	struct e1000_rx_desc *rx_desc;
+	struct e1000_ring *rx_ring = adapter->rx_ring;
+	struct e1000_buffer *buffer_info;
+	struct sk_buff *skb;
+	unsigned int i;
+	unsigned int bufsz = 256 -
+	                     16 /* for skb_reserve */ -
+	                     NET_IP_ALIGN;
+
+	i = rx_ring->next_to_use;
+	buffer_info = &rx_ring->buffer_info[i];
+
+	while (cleaned_count--) {
+		skb = buffer_info->skb;
+		if (skb) {
+			skb_trim(skb, 0);
+			goto check_page;
+		}
+
+		skb = netdev_alloc_skb(netdev, bufsz);
+		if (unlikely(!skb)) {
+			/* Better luck next round */
+			adapter->alloc_rx_buff_failed++;
+			break;
+		}
+
+		/* Make buffer alignment 2 beyond a 16 byte boundary
+		 * this will result in a 16 byte aligned IP header after
+		 * the 14 byte MAC header is removed
+		 */
+		skb_reserve(skb, NET_IP_ALIGN);
+
+		buffer_info->skb = skb;
+check_page:
+		/* allocate a new page if necessary */
+		if (!buffer_info->page) {
+			buffer_info->page = alloc_page(GFP_ATOMIC);
+			if (unlikely(!buffer_info->page)) {
+				adapter->alloc_rx_buff_failed++;
+				break;
+			}
+		}
+
+		if (!buffer_info->dma)
+			buffer_info->dma = pci_map_page(pdev,
+			                                buffer_info->page, 0,
+			                                PAGE_SIZE,
+			                                PCI_DMA_FROMDEVICE);
+
+		rx_desc = E1000_RX_DESC(*rx_ring, i);
+		rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+
+		if (unlikely(++i == rx_ring->count))
+			i = 0;
+		buffer_info = &rx_ring->buffer_info[i];
+	}
+
+	if (likely(rx_ring->next_to_use != i)) {
+		rx_ring->next_to_use = i;
+		if (unlikely(i-- == 0))
+			i = (rx_ring->count - 1);
+
+		/* Force memory writes to complete before letting h/w
+		 * know there are new descriptors to fetch.  (Only
+		 * applicable for weak-ordered memory model archs,
+		 * such as IA-64). */
+		wmb();
+		writel(i, adapter->hw.hw_addr + rx_ring->tail);
+	}
+}
+
+/**
  * e1000_clean_rx_irq - Send received data up the network stack; legacy
  * @adapter: board private structure
  *
@@ -783,6 +867,186 @@ next_desc:
 }
 
 /**
+ * e1000_consume_page - helper function
+ **/
+static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
+                               u16 length)
+{
+	bi->page = NULL;
+	skb->len += length;
+	skb->data_len += length;
+	skb->truesize += length;
+}
+
+/**
+ * e1000_clean_jumbo_rx_irq - Send received data up the network stack; legacy
+ * @adapter: board private structure
+ *
+ * the return value indicates whether actual cleaning was done, there
+ * is no guarantee that everything was cleaned
+ **/
+
+static bool e1000_clean_jumbo_rx_irq(struct e1000_adapter *adapter,
+                                     int *work_done, int work_to_do)
+{
+	struct net_device *netdev = adapter->netdev;
+	struct pci_dev *pdev = adapter->pdev;
+	struct e1000_ring *rx_ring = adapter->rx_ring;
+	struct e1000_rx_desc *rx_desc, *next_rxd;
+	struct e1000_buffer *buffer_info, *next_buffer;
+	u32 length;
+	unsigned int i;
+	int cleaned_count = 0;
+	bool cleaned = false;
+	unsigned int total_rx_bytes=0, total_rx_packets=0;
+
+	i = rx_ring->next_to_clean;
+	rx_desc = E1000_RX_DESC(*rx_ring, i);
+	buffer_info = &rx_ring->buffer_info[i];
+
+	while (rx_desc->status & E1000_RXD_STAT_DD) {
+		struct sk_buff *skb;
+		u8 status;
+
+		if (*work_done >= work_to_do)
+			break;
+		(*work_done)++;
+
+		status = rx_desc->status;
+		skb = buffer_info->skb;
+		buffer_info->skb = NULL;
+
+		++i;
+		if (i == rx_ring->count)
+			i = 0;
+		next_rxd = E1000_RX_DESC(*rx_ring, i);
+		prefetch(next_rxd);
+
+		next_buffer = &rx_ring->buffer_info[i];
+
+		cleaned = true;
+		cleaned_count++;
+		pci_unmap_page(pdev, buffer_info->dma, PAGE_SIZE,
+		               PCI_DMA_FROMDEVICE);
+		buffer_info->dma = 0;
+
+		length = le16_to_cpu(rx_desc->length);
+
+		/* errors is only valid for DD + EOP descriptors */
+		if (unlikely((status & E1000_RXD_STAT_EOP) &&
+		    (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK))) {
+				/* recycle both page and skb */
+				buffer_info->skb = skb;
+				/* an error means any chain goes out the window
+				 * too */
+				if (rx_ring->rx_skb_top)
+					dev_kfree_skb(rx_ring->rx_skb_top);
+				rx_ring->rx_skb_top = NULL;
+				goto next_desc;
+		}
+
+#define rxtop rx_ring->rx_skb_top
+		if (!(status & E1000_RXD_STAT_EOP)) {
+			/* this descriptor is only the beginning (or middle) */
+			if (!rxtop) {
+				/* this is the beginning of a chain */
+				rxtop = skb;
+				skb_fill_page_desc(rxtop, 0, buffer_info->page,
+				                   0, length);
+			} else {
+				/* this is the middle of a chain */
+				skb_fill_page_desc(rxtop,
+				    skb_shinfo(rxtop)->nr_frags,
+				    buffer_info->page, 0, length);
+				/* re-use the skb, only consumed the page */
+				buffer_info->skb = skb;
+			}
+			e1000_consume_page(buffer_info, rxtop, length);
+			goto next_desc;
+		} else {
+			if (rxtop) {
+				/* end of the chain */
+				skb_fill_page_desc(rxtop,
+				    skb_shinfo(rxtop)->nr_frags,
+				    buffer_info->page, 0, length);
+				/* re-use the current skb, we only consumed the
+				 * page */
+				buffer_info->skb = skb;
+				skb = rxtop;
+				rxtop = NULL;
+				e1000_consume_page(buffer_info, skb, length);
+			} else {
+				/* no chain, got EOP, this buf is the packet
+				 * copybreak to save the put_page/alloc_page */
+				if (length <= copybreak &&
+				    skb_tailroom(skb) >= length) {
+					u8 *vaddr;
+					vaddr = kmap_atomic(buffer_info->page,
+					                   KM_SKB_DATA_SOFTIRQ);
+					memcpy(skb_tail_pointer(skb), vaddr,
+					       length);
+					kunmap_atomic(vaddr,
+					              KM_SKB_DATA_SOFTIRQ);
+					/* re-use the page, so don't erase
+					 * buffer_info->page */
+					skb_put(skb, length);
+				} else {
+					skb_fill_page_desc(skb, 0,
+					                   buffer_info->page, 0,
+				                           length);
+					e1000_consume_page(buffer_info, skb,
+					                   length);
+				}
+			}
+		}
+
+		/* Receive Checksum Offload XXX recompute due to CRC strip? */
+		e1000_rx_checksum(adapter,
+		                  (u32)(status) |
+		                  ((u32)(rx_desc->errors) << 24),
+		                  le16_to_cpu(rx_desc->csum), skb);
+
+		/* probably a little skewed due to removing CRC */
+		total_rx_bytes += skb->len;
+		total_rx_packets++;
+
+		/* eth type trans needs skb->data to point to something */
+		if (!pskb_may_pull(skb, ETH_HLEN)) {
+			ndev_err(netdev, "pskb_may_pull failed.\n");
+			dev_kfree_skb(skb);
+			goto next_desc;
+		}
+
+		e1000_receive_skb(adapter, netdev, skb, status,
+		                  rx_desc->special);
+
+next_desc:
+		rx_desc->status = 0;
+
+		/* return some buffers to hardware, one at a time is too slow */
+		if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) {
+			adapter->alloc_rx_buf(adapter, cleaned_count);
+			cleaned_count = 0;
+		}
+
+		/* use prefetched values */
+		rx_desc = next_rxd;
+		buffer_info = next_buffer;
+	}
+	rx_ring->next_to_clean = i;
+
+	cleaned_count = e1000_desc_unused(rx_ring);
+	if (cleaned_count)
+		adapter->alloc_rx_buf(adapter, cleaned_count);
+
+	adapter->total_rx_bytes += total_rx_bytes;
+	adapter->total_rx_packets += total_rx_packets;
+	adapter->net_stats.rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
+	return cleaned;
+}
+
+/**
  * e1000_clean_rx_ring - Free Rx Buffers per Queue
  * @adapter: board private structure
  **/
@@ -802,6 +1066,10 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
 				pci_unmap_single(pdev, buffer_info->dma,
 						 adapter->rx_buffer_len,
 						 PCI_DMA_FROMDEVICE);
+			else if (adapter->clean_rx == e1000_clean_jumbo_rx_irq)
+				pci_unmap_page(pdev, buffer_info->dma,
+				               PAGE_SIZE,
+				               PCI_DMA_FROMDEVICE);
 			else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
 				pci_unmap_single(pdev, buffer_info->dma,
 						 adapter->rx_ps_bsize0,
@@ -809,6 +1077,11 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
 			buffer_info->dma = 0;
 		}
 
+		if (buffer_info->page) {
+			put_page(buffer_info->page);
+			buffer_info->page = NULL;
+		}
+
 		if (buffer_info->skb) {
 			dev_kfree_skb(buffer_info->skb);
 			buffer_info->skb = NULL;
@@ -1755,10 +2028,12 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 	 * a lot of memory, since we allocate 3 pages at all times
 	 * per packet.
 	 */
-	adapter->rx_ps_pages = 0;
 	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
-	if ((pages <= 3) && (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
+	if (!(adapter->flags & FLAG_IS_ICH) && (pages <= 3) &&
+	    (PAGE_SIZE <= 16384) && (rctl & E1000_RCTL_LPE))
 		adapter->rx_ps_pages = pages;
+	else
+		adapter->rx_ps_pages = 0;
 
 	if (adapter->rx_ps_pages) {
 		/* Configure extra packet-split registers */
@@ -1819,9 +2094,12 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 			sizeof(union e1000_rx_desc_packet_split);
 		adapter->clean_rx = e1000_clean_rx_irq_ps;
 		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
+	} else if (adapter->netdev->mtu > ETH_FRAME_LEN + ETH_FCS_LEN) {
+		rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
+		adapter->clean_rx = e1000_clean_jumbo_rx_irq;
+		adapter->alloc_rx_buf = e1000_alloc_jumbo_rx_buffers;
 	} else {
-		rdlen = rx_ring->count *
-			sizeof(struct e1000_rx_desc);
+		rdlen = rx_ring->count * sizeof(struct e1000_rx_desc);
 		adapter->clean_rx = e1000_clean_rx_irq;
 		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
 	}
@@ -1885,8 +2163,21 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 	 * units), e.g. using jumbo frames when setting to E1000_ERT_2048
 	 */
 	if ((adapter->flags & FLAG_HAS_ERT) &&
-	    (adapter->netdev->mtu > ETH_DATA_LEN))
-		ew32(ERT, E1000_ERT_2048);
+	    (adapter->netdev->mtu > ETH_DATA_LEN)) {
+		u32 rxdctl = er32(RXDCTL(0));
+		ew32(RXDCTL(0), rxdctl | 0x3);
+		ew32(ERT, E1000_ERT_2048 | (1 << 13));
+		/*
+		 * With jumbo frames and early-receive enabled, excessive
+		 * C4->C2 latencies result in dropped transactions.
+		 */
+		pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
+					  e1000e_driver_name, 55);
+	} else {
+		pm_qos_update_requirement(PM_QOS_CPU_DMA_LATENCY,
+					  e1000e_driver_name,
+					  PM_QOS_DEFAULT_VALUE);
+	}
 
 	/* Enable Receives */
 	ew32(RCTL, rctl);
@@ -2155,6 +2446,14 @@ void e1000e_reset(struct e1000_adapter *adapter)
 
 	/* Allow time for pending master requests to run */
 	mac->ops.reset_hw(hw);
+
+	/*
+	 * For parts with AMT enabled, let the firmware know
+	 * that the network interface is in control
+	 */
+	if ((adapter->flags & FLAG_HAS_AMT) && e1000e_check_mng_mode(hw))
+		e1000_get_hw_control(adapter);
+
 	ew32(WUC, 0);
 
 	if (mac->ops.init_hw(hw))
@@ -3469,6 +3768,8 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 	 * means we reserve 2 more, this pushes us to allocate from the next
 	 * larger slab size.
 	 * i.e. RXBUFFER_2048 --> size-4096 slab
+	 * However with the new *_jumbo_rx* routines, jumbo receives will use
+	 * fragmented skbs
 	 */
 
 	if (max_frame <= 256)
@@ -3626,6 +3927,9 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 			ew32(CTRL_EXT, ctrl_ext);
 		}
 
+		if (adapter->flags & FLAG_IS_ICH)
+			e1000e_disable_gig_wol_ich8lan(&adapter->hw);
+
 		/* Allow time for pending master requests to run */
 		e1000e_disable_pcie_master(&adapter->hw);
 
@@ -4292,6 +4596,13 @@ static struct pci_device_id e1000_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_AMT), board_ich9lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_C), board_ich9lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M), board_ich9lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_AMT), board_ich9lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IGP_M_V), board_ich9lan },
+
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LM), board_ich9lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_LF), board_ich9lan },
+	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH10_R_BM_V), board_ich9lan },
 
 	{ }	/* terminate list */
 };
@@ -4326,7 +4637,9 @@ static int __init e1000_init_module(void)
 	printk(KERN_INFO "%s: Copyright (c) 1999-2008 Intel Corporation.\n",
 	       e1000e_driver_name);
 	ret = pci_register_driver(&e1000_driver);
-
+	pm_qos_add_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name,
+			       PM_QOS_DEFAULT_VALUE);
+				
 	return ret;
 }
 module_init(e1000_init_module);
@@ -4340,6 +4653,7 @@ module_init(e1000_init_module);
 static void __exit e1000_exit_module(void)
 {
 	pci_unregister_driver(&e1000_driver);
+	pm_qos_remove_requirement(PM_QOS_CPU_DMA_LATENCY, e1000e_driver_name);
 }
 module_exit(e1000_exit_module);
 
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index e102332..b133dcf 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -34,6 +34,9 @@ static s32 e1000_get_phy_cfg_done(struct e1000_hw *hw);
 static s32 e1000_phy_force_speed_duplex(struct e1000_hw *hw);
 static s32 e1000_set_d0_lplu_state(struct e1000_hw *hw, bool active);
 static s32 e1000_wait_autoneg(struct e1000_hw *hw);
+static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg);
+static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
+					  u16 *data, bool read);
 
 /* Cable length tables */
 static const u16 e1000_m88_cable_length_table[] =
@@ -465,6 +468,10 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
 	if (phy->disable_polarity_correction == 1)
 		phy_data |= M88E1000_PSCR_POLARITY_REVERSAL;
 
+	/* Enable downshift on BM (disabled by default) */
+	if (phy->type == e1000_phy_bm)
+		phy_data |= BME1000_PSCR_ENABLE_DOWNSHIFT;
+
 	ret_val = e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
 	if (ret_val)
 		return ret_val;
@@ -1776,6 +1783,10 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
 	case IFE_C_E_PHY_ID:
 		phy_type = e1000_phy_ife;
 		break;
+	case BME1000_E_PHY_ID:
+	case BME1000_E_PHY_ID_R2:
+		phy_type = e1000_phy_bm;
+		break;
 	default:
 		phy_type = e1000_phy_unknown;
 		break;
@@ -1784,6 +1795,273 @@ enum e1000_phy_type e1000e_get_phy_type_from_id(u32 phy_id)
 }
 
 /**
+ *  e1000e_determine_phy_address - Determines PHY address.
+ *  @hw: pointer to the HW structure
+ *
+ *  This uses a trial and error method to loop through possible PHY
+ *  addresses. It tests each by reading the PHY ID registers and
+ *  checking for a match.
+ **/
+s32 e1000e_determine_phy_address(struct e1000_hw *hw)
+{
+	s32 ret_val = -E1000_ERR_PHY_TYPE;
+	u32 phy_addr= 0;
+	u32 i = 0;
+	enum e1000_phy_type phy_type = e1000_phy_unknown;
+
+	do {
+		for (phy_addr = 0; phy_addr < 4; phy_addr++) {
+			hw->phy.addr = phy_addr;
+			e1000e_get_phy_id(hw);
+			phy_type = e1000e_get_phy_type_from_id(hw->phy.id);
+
+			/* 
+			 * If phy_type is valid, break - we found our
+			 * PHY address
+			 */
+			if (phy_type  != e1000_phy_unknown) {
+				ret_val = 0;
+				break;
+			}
+		}
+		i++;
+	} while ((ret_val != 0) && (i < 100));
+
+	return ret_val;
+}
+
+/**
+ *  e1000_get_phy_addr_for_bm_page - Retrieve PHY page address
+ *  @page: page to access
+ *
+ *  Returns the phy address for the page requested.
+ **/
+static u32 e1000_get_phy_addr_for_bm_page(u32 page, u32 reg)
+{
+	u32 phy_addr = 2;
+
+	if ((page >= 768) || (page == 0 && reg == 25) || (reg == 31))
+		phy_addr = 1;
+
+	return phy_addr;
+}
+
+/**
+ *  e1000e_write_phy_reg_bm - Write BM PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to write to
+ *  @data: data to write at register offset
+ *
+ *  Acquires semaphore, if necessary, then writes the data to PHY register
+ *  at the offset.  Release any acquired semaphores before exiting.
+ **/
+s32 e1000e_write_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 data)
+{
+	s32 ret_val;
+	u32 page_select = 0;
+	u32 page = offset >> IGP_PAGE_SHIFT;
+	u32 page_shift = 0;
+
+	/* Page 800 works differently than the rest so it has its own func */
+	if (page == BM_WUC_PAGE) {
+		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, &data,
+							 false);
+		goto out;
+	}
+
+	ret_val = hw->phy.ops.acquire_phy(hw);
+	if (ret_val)
+		goto out;
+
+	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
+
+	if (offset > MAX_PHY_MULTI_PAGE_REG) {
+		/*
+		 * Page select is register 31 for phy address 1 and 22 for
+		 * phy address 2 and 3. Page select is shifted only for
+		 * phy address 1.
+		 */
+		if (hw->phy.addr == 1) {
+			page_shift = IGP_PAGE_SHIFT;
+			page_select = IGP01E1000_PHY_PAGE_SELECT;
+		} else {
+			page_shift = 0;
+			page_select = BM_PHY_PAGE_SELECT;
+		}
+
+		/* Page is shifted left, PHY expects (page x 32) */
+		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
+		                                    (page << page_shift));
+		if (ret_val) {
+			hw->phy.ops.release_phy(hw);
+			goto out;
+		}
+	}
+
+	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+	                                    data);
+
+	hw->phy.ops.release_phy(hw);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000e_read_phy_reg_bm - Read BM PHY register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read
+ *  @data: pointer to the read data
+ *
+ *  Acquires semaphore, if necessary, then reads the PHY register at offset
+ *  and storing the retrieved information in data.  Release any acquired
+ *  semaphores before exiting.
+ **/
+s32 e1000e_read_phy_reg_bm(struct e1000_hw *hw, u32 offset, u16 *data)
+{
+	s32 ret_val;
+	u32 page_select = 0;
+	u32 page = offset >> IGP_PAGE_SHIFT;
+	u32 page_shift = 0;
+
+	/* Page 800 works differently than the rest so it has its own func */
+	if (page == BM_WUC_PAGE) {
+		ret_val = e1000_access_phy_wakeup_reg_bm(hw, offset, data,
+							 true);
+		goto out;
+	}
+
+	ret_val = hw->phy.ops.acquire_phy(hw);
+	if (ret_val)
+		goto out;
+
+	hw->phy.addr = e1000_get_phy_addr_for_bm_page(page, offset);
+
+	if (offset > MAX_PHY_MULTI_PAGE_REG) {
+		/*
+		 * Page select is register 31 for phy address 1 and 22 for
+		 * phy address 2 and 3. Page select is shifted only for
+		 * phy address 1.
+		 */
+		if (hw->phy.addr == 1) {
+			page_shift = IGP_PAGE_SHIFT;
+			page_select = IGP01E1000_PHY_PAGE_SELECT;
+		} else {
+			page_shift = 0;
+			page_select = BM_PHY_PAGE_SELECT;
+		}
+
+		/* Page is shifted left, PHY expects (page x 32) */
+		ret_val = e1000e_write_phy_reg_mdic(hw, page_select,
+		                                    (page << page_shift));
+		if (ret_val) {
+			hw->phy.ops.release_phy(hw);
+			goto out;
+		}
+	}
+
+	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+	                                   data);
+	hw->phy.ops.release_phy(hw);
+
+out:
+	return ret_val;
+}
+
+/**
+ *  e1000_access_phy_wakeup_reg_bm - Read BM PHY wakeup register
+ *  @hw: pointer to the HW structure
+ *  @offset: register offset to be read or written
+ *  @data: pointer to the data to read or write
+ *  @read: determines if operation is read or write
+ *
+ *  Acquires semaphore, if necessary, then reads the PHY register at offset
+ *  and storing the retrieved information in data.  Release any acquired
+ *  semaphores before exiting. Note that procedure to read the wakeup
+ *  registers are different. It works as such:
+ *  1) Set page 769, register 17, bit 2 = 1
+ *  2) Set page to 800 for host (801 if we were manageability)
+ *  3) Write the address using the address opcode (0x11)
+ *  4) Read or write the data using the data opcode (0x12)
+ *  5) Restore 769_17.2 to its original value
+ **/
+static s32 e1000_access_phy_wakeup_reg_bm(struct e1000_hw *hw, u32 offset,
+					  u16 *data, bool read)
+{
+	s32 ret_val;
+	u16 reg = ((u16)offset) & PHY_REG_MASK;
+	u16 phy_reg = 0;
+	u8  phy_acquired = 1;
+
+
+	ret_val = hw->phy.ops.acquire_phy(hw);
+	if (ret_val) {
+		phy_acquired = 0;
+		goto out;
+	}
+
+	/* All operations in this function are phy address 1 */
+	hw->phy.addr = 1;
+
+	/* Set page 769 */
+	e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+	                          (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
+
+	ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, &phy_reg);
+	if (ret_val)
+		goto out;
+
+	/* First clear bit 4 to avoid a power state change */
+	phy_reg &= ~(BM_WUC_HOST_WU_BIT);
+	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
+	if (ret_val)
+		goto out;
+
+	/* Write bit 2 = 1, and clear bit 4 to 769_17 */
+	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG,
+	                                    phy_reg | BM_WUC_ENABLE_BIT);
+	if (ret_val)
+		goto out;
+
+	/* Select page 800 */
+	ret_val = e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+	                                    (BM_WUC_PAGE << IGP_PAGE_SHIFT));
+
+	/* Write the page 800 offset value using opcode 0x11 */
+	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ADDRESS_OPCODE, reg);
+	if (ret_val)
+		goto out;
+
+	if (read) {
+	        /* Read the page 800 value using opcode 0x12 */
+		ret_val = e1000e_read_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
+		                                   data);
+	} else {
+	        /* Read the page 800 value using opcode 0x12 */
+		ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_DATA_OPCODE,
+						    *data);
+	}
+
+	if (ret_val)
+		goto out;
+
+	/*
+	 * Restore 769_17.2 to its original value
+	 * Set page 769
+	 */
+	e1000e_write_phy_reg_mdic(hw, IGP01E1000_PHY_PAGE_SELECT,
+	                          (BM_WUC_ENABLE_PAGE << IGP_PAGE_SHIFT));
+
+	/* Clear 769_17.2 */
+	ret_val = e1000e_write_phy_reg_mdic(hw, BM_WUC_ENABLE_REG, phy_reg);
+
+out:
+	if (phy_acquired == 1)
+		hw->phy.ops.release_phy(hw);
+	return ret_val;
+}
+
+/**
  *  e1000e_commit_phy - Soft PHY reset
  *  @hw: pointer to the HW structure
  *
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index 2eb82ab..795c594 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -202,7 +202,7 @@ static unsigned short start_code[] = {
 	0x0000,Cmd_MCast,
 	0x0076,                 /* link to next command */
 #define CONF_NR_MULTICAST 0x44
-	0x0000,                 /* number of multicast addresses */
+	0x0000,                 /* number of bytes in multicast address(es) */
 #define CONF_MULTICAST 0x46
 	0x0000, 0x0000, 0x0000, /* some addresses */
 	0x0000, 0x0000, 0x0000,
@@ -1569,7 +1569,7 @@ static void eexp_hw_init586(struct net_device *dev)
 
 static void eexp_setup_filter(struct net_device *dev)
 {
-	struct dev_mc_list *dmi = dev->mc_list;
+	struct dev_mc_list *dmi;
 	unsigned short ioaddr = dev->base_addr;
 	int count = dev->mc_count;
 	int i;
@@ -1580,9 +1580,9 @@ static void eexp_setup_filter(struct net_device *dev)
 	}
 
 	outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR);
-	outw(count, ioaddr+SHADOW(CONF_NR_MULTICAST));
-	for (i = 0; i < count; i++) {
-		unsigned short *data = (unsigned short *)dmi->dmi_addr;
+	outw(6*count, ioaddr+SHADOW(CONF_NR_MULTICAST));
+	for (i = 0, dmi = dev->mc_list; i < count; i++, dmi = dmi->next) {
+		unsigned short *data;
 		if (!dmi) {
 			printk(KERN_INFO "%s: too few multicast addresses\n", dev->name);
 			break;
@@ -1591,6 +1591,7 @@ static void eexp_setup_filter(struct net_device *dev)
 			printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);
 			continue;
 		}
+		data = (unsigned short *)dmi->dmi_addr;
 		outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR);
 		outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i)));
 		outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR);
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index ba75efc..f0014cf 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -194,7 +194,7 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
 
 	ret = of_address_to_resource(ofdev->node, 0, &res);
 	if (ret)
-		return ret;
+		goto out_res;
 
 	snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start);
 
@@ -236,6 +236,7 @@ out_free_irqs:
 	kfree(new_bus->irq);
 out_unmap_regs:
 	iounmap(fec->fecp);
+out_res:
 out_fec:
 	kfree(fec);
 out_mii:
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 587afe7..6f22f06 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -138,6 +138,7 @@ static int gfar_poll(struct napi_struct *napi, int budget);
 static void gfar_netpoll(struct net_device *dev);
 #endif
 int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
+static int gfar_clean_tx_ring(struct net_device *dev);
 static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length);
 static void gfar_vlan_rx_register(struct net_device *netdev,
 		                struct vlan_group *grp);
@@ -1141,7 +1142,7 @@ static int gfar_close(struct net_device *dev)
 }
 
 /* Changes the mac address if the controller is not running. */
-int gfar_set_mac_address(struct net_device *dev)
+static int gfar_set_mac_address(struct net_device *dev)
 {
 	gfar_set_mac_for_addr(dev, 0, dev->dev_addr);
 
@@ -1260,7 +1261,7 @@ static void gfar_timeout(struct net_device *dev)
 }
 
 /* Interrupt Handler for Transmit complete */
-int gfar_clean_tx_ring(struct net_device *dev)
+static int gfar_clean_tx_ring(struct net_device *dev)
 {
 	struct txbd8 *bdp;
 	struct gfar_private *priv = netdev_priv(dev);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index fd487be..27f37c8 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -782,5 +782,8 @@ extern void gfar_halt(struct net_device *dev);
 extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
 		int enable, u32 regnum, u32 read);
 void gfar_init_sysfs(struct net_device *dev);
+int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
+			  int regnum, u16 value);
+int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
 
 #endif /* __GIANFAR_H */
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index 230878b..5116f68 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -103,10 +103,10 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev,
 
 	spin_lock_irqsave(&priv->rxlock, flags);
 	if (length > priv->rx_buffer_size)
-		return count;
+		goto out;
 
 	if (length == priv->rx_stash_size)
-		return count;
+		goto out;
 
 	priv->rx_stash_size = length;
 
@@ -125,6 +125,7 @@ static ssize_t gfar_set_rx_stash_size(struct device *dev,
 
 	gfar_write(&priv->regs->attr, temp);
 
+out:
 	spin_unlock_irqrestore(&priv->rxlock, flags);
 
 	return count;
@@ -154,10 +155,10 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev,
 
 	spin_lock_irqsave(&priv->rxlock, flags);
 	if (index > priv->rx_stash_size)
-		return count;
+		goto out;
 
 	if (index == priv->rx_stash_index)
-		return count;
+		goto out;
 
 	priv->rx_stash_index = index;
 
@@ -166,6 +167,7 @@ static ssize_t gfar_set_rx_stash_index(struct device *dev,
 	temp |= ATTRELI_EI(index);
 	gfar_write(&priv->regs->attreli, flags);
 
+out:
 	spin_unlock_irqrestore(&priv->rxlock, flags);
 
 	return count;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 381b36e..b7915cd 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -91,6 +91,11 @@
  */
 #define PHY_ADDR_REG				0x0000
 #define SMI_REG					0x0004
+#define WINDOW_BASE(i)				(0x0200 + ((i) << 3))
+#define WINDOW_SIZE(i)				(0x0204 + ((i) << 3))
+#define WINDOW_REMAP_HIGH(i)			(0x0280 + ((i) << 2))
+#define WINDOW_BAR_ENABLE			0x0290
+#define WINDOW_PROTECT(i)			(0x0294 + ((i) << 4))
 
 /*
  * Per-port registers.
@@ -507,9 +512,23 @@ struct mv643xx_mib_counters {
 	u32 late_collision;
 };
 
+struct mv643xx_shared_private {
+	void __iomem *eth_base;
+
+	/* used to protect SMI_REG, which is shared across ports */
+	spinlock_t phy_lock;
+
+	u32 win_protect;
+
+	unsigned int t_clk;
+};
+
 struct mv643xx_private {
+	struct mv643xx_shared_private *shared;
 	int port_num;			/* User Ethernet port number	*/
 
+	struct mv643xx_shared_private *shared_smi;
+
 	u32 rx_sram_addr;		/* Base address of rx sram area */
 	u32 rx_sram_size;		/* Size of rx sram area		*/
 	u32 tx_sram_addr;		/* Base address of tx sram area */
@@ -614,19 +633,14 @@ static const struct ethtool_ops mv643xx_ethtool_ops;
 static char mv643xx_driver_name[] = "mv643xx_eth";
 static char mv643xx_driver_version[] = "1.0";
 
-static void __iomem *mv643xx_eth_base;
-
-/* used to protect SMI_REG, which is shared across ports */
-static DEFINE_SPINLOCK(mv643xx_eth_phy_lock);
-
 static inline u32 rdl(struct mv643xx_private *mp, int offset)
 {
-	return readl(mv643xx_eth_base + offset);
+	return readl(mp->shared->eth_base + offset);
 }
 
 static inline void wrl(struct mv643xx_private *mp, int offset, u32 data)
 {
-	writel(data, mv643xx_eth_base + offset);
+	writel(data, mp->shared->eth_base + offset);
 }
 
 /*
@@ -1119,7 +1133,6 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id)
  *
  * INPUT:
  *	struct mv643xx_private *mp	Ethernet port
- *	unsigned int t_clk		t_clk of the MV-643xx chip in HZ units
  *	unsigned int delay		Delay in usec
  *
  * OUTPUT:
@@ -1130,10 +1143,10 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id)
  *
  */
 static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp,
-					unsigned int t_clk, unsigned int delay)
+					unsigned int delay)
 {
 	unsigned int port_num = mp->port_num;
-	unsigned int coal = ((t_clk / 1000000) * delay) / 64;
+	unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
 
 	/* Set RX Coalescing mechanism */
 	wrl(mp, SDMA_CONFIG_REG(port_num),
@@ -1158,7 +1171,6 @@ static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp,
  *
  * INPUT:
  *	struct mv643xx_private *mp	Ethernet port
- *	unsigned int t_clk		t_clk of the MV-643xx chip in HZ units
  *	unsigned int delay		Delay in uSeconds
  *
  * OUTPUT:
@@ -1169,9 +1181,9 @@ static unsigned int eth_port_set_rx_coal(struct mv643xx_private *mp,
  *
  */
 static unsigned int eth_port_set_tx_coal(struct mv643xx_private *mp,
-					unsigned int t_clk, unsigned int delay)
+					unsigned int delay)
 {
-	unsigned int coal = ((t_clk / 1000000) * delay) / 64;
+	unsigned int coal = ((mp->shared->t_clk / 1000000) * delay) / 64;
 
 	/* Set TX Coalescing mechanism */
 	wrl(mp, TX_FIFO_URGENT_THRESHOLD_REG(mp->port_num), coal << 4);
@@ -1413,11 +1425,11 @@ static int mv643xx_eth_open(struct net_device *dev)
 
 #ifdef MV643XX_COAL
 	mp->rx_int_coal =
-		eth_port_set_rx_coal(mp, 133000000, MV643XX_RX_COAL);
+		eth_port_set_rx_coal(mp, MV643XX_RX_COAL);
 #endif
 
 	mp->tx_int_coal =
-		eth_port_set_tx_coal(mp, 133000000, MV643XX_TX_COAL);
+		eth_port_set_tx_coal(mp, MV643XX_TX_COAL);
 
 	/* Unmask phy and link status changes interrupts */
 	wrl(mp, INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT);
@@ -1827,6 +1839,11 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 		return -ENODEV;
 	}
 
+	if (pd->shared == NULL) {
+		printk(KERN_ERR "No mv643xx_eth_platform_data->shared\n");
+		return -ENODEV;
+	}
+
 	dev = alloc_etherdev(sizeof(struct mv643xx_private));
 	if (!dev)
 		return -ENOMEM;
@@ -1877,8 +1894,16 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 
 	spin_lock_init(&mp->lock);
 
+	mp->shared = platform_get_drvdata(pd->shared);
 	port_num = mp->port_num = pd->port_number;
 
+	if (mp->shared->win_protect)
+		wrl(mp, WINDOW_PROTECT(port_num), mp->shared->win_protect);
+
+	mp->shared_smi = mp->shared;
+	if (pd->shared_smi != NULL)
+		mp->shared_smi = platform_get_drvdata(pd->shared_smi);
+
 	/* set default config values */
 	eth_port_uc_addr_get(mp, dev->dev_addr);
 	mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE;
@@ -1983,30 +2008,91 @@ static int mv643xx_eth_remove(struct platform_device *pdev)
 	return 0;
 }
 
+static void mv643xx_eth_conf_mbus_windows(struct mv643xx_shared_private *msp,
+					  struct mbus_dram_target_info *dram)
+{
+	void __iomem *base = msp->eth_base;
+	u32 win_enable;
+	u32 win_protect;
+	int i;
+
+	for (i = 0; i < 6; i++) {
+		writel(0, base + WINDOW_BASE(i));
+		writel(0, base + WINDOW_SIZE(i));
+		if (i < 4)
+			writel(0, base + WINDOW_REMAP_HIGH(i));
+	}
+
+	win_enable = 0x3f;
+	win_protect = 0;
+
+	for (i = 0; i < dram->num_cs; i++) {
+		struct mbus_dram_window *cs = dram->cs + i;
+
+		writel((cs->base & 0xffff0000) |
+			(cs->mbus_attr << 8) |
+			dram->mbus_dram_target_id, base + WINDOW_BASE(i));
+		writel((cs->size - 1) & 0xffff0000, base + WINDOW_SIZE(i));
+
+		win_enable &= ~(1 << i);
+		win_protect |= 3 << (2 * i);
+	}
+
+	writel(win_enable, base + WINDOW_BAR_ENABLE);
+	msp->win_protect = win_protect;
+}
+
 static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 {
 	static int mv643xx_version_printed = 0;
+	struct mv643xx_eth_shared_platform_data *pd = pdev->dev.platform_data;
+	struct mv643xx_shared_private *msp;
 	struct resource *res;
+	int ret;
 
 	if (!mv643xx_version_printed++)
 		printk(KERN_NOTICE "MV-643xx 10/100/1000 Ethernet Driver\n");
 
+	ret = -EINVAL;
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (res == NULL)
-		return -ENODEV;
+		goto out;
 
-	mv643xx_eth_base = ioremap(res->start, res->end - res->start + 1);
-	if (mv643xx_eth_base == NULL)
-		return -ENOMEM;
+	ret = -ENOMEM;
+	msp = kmalloc(sizeof(*msp), GFP_KERNEL);
+	if (msp == NULL)
+		goto out;
+	memset(msp, 0, sizeof(*msp));
+
+	msp->eth_base = ioremap(res->start, res->end - res->start + 1);
+	if (msp->eth_base == NULL)
+		goto out_free;
+
+	spin_lock_init(&msp->phy_lock);
+	msp->t_clk = (pd != NULL && pd->t_clk != 0) ? pd->t_clk : 133000000;
+
+	platform_set_drvdata(pdev, msp);
+
+	/*
+	 * (Re-)program MBUS remapping windows if we are asked to.
+	 */
+	if (pd != NULL && pd->dram != NULL)
+		mv643xx_eth_conf_mbus_windows(msp, pd->dram);
 
 	return 0;
 
+out_free:
+	kfree(msp);
+out:
+	return ret;
 }
 
 static int mv643xx_eth_shared_remove(struct platform_device *pdev)
 {
-	iounmap(mv643xx_eth_base);
-	mv643xx_eth_base = NULL;
+	struct mv643xx_shared_private *msp = platform_get_drvdata(pdev);
+
+	iounmap(msp->eth_base);
+	kfree(msp);
 
 	return 0;
 }
@@ -2906,15 +2992,16 @@ static void eth_port_reset(struct mv643xx_private *mp)
 static void eth_port_read_smi_reg(struct mv643xx_private *mp,
 				unsigned int phy_reg, unsigned int *value)
 {
+	void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG;
 	int phy_addr = ethernet_phy_get(mp);
 	unsigned long flags;
 	int i;
 
 	/* the SMI register is a shared resource */
-	spin_lock_irqsave(&mv643xx_eth_phy_lock, flags);
+	spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);
 
 	/* wait for the SMI register to become available */
-	for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) {
+	for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) {
 		if (i == PHY_WAIT_ITERATIONS) {
 			printk("%s: PHY busy timeout\n", mp->dev->name);
 			goto out;
@@ -2922,11 +3009,11 @@ static void eth_port_read_smi_reg(struct mv643xx_private *mp,
 		udelay(PHY_WAIT_MICRO_SECONDS);
 	}
 
-	wrl(mp, SMI_REG,
-		(phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ);
+	writel((phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ,
+		smi_reg);
 
 	/* now wait for the data to be valid */
-	for (i = 0; !(rdl(mp, SMI_REG) & ETH_SMI_READ_VALID); i++) {
+	for (i = 0; !(readl(smi_reg) & ETH_SMI_READ_VALID); i++) {
 		if (i == PHY_WAIT_ITERATIONS) {
 			printk("%s: PHY read timeout\n", mp->dev->name);
 			goto out;
@@ -2934,9 +3021,9 @@ static void eth_port_read_smi_reg(struct mv643xx_private *mp,
 		udelay(PHY_WAIT_MICRO_SECONDS);
 	}
 
-	*value = rdl(mp, SMI_REG) & 0xffff;
+	*value = readl(smi_reg) & 0xffff;
 out:
-	spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
+	spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);
 }
 
 /*
@@ -2962,17 +3049,16 @@ out:
 static void eth_port_write_smi_reg(struct mv643xx_private *mp,
 				   unsigned int phy_reg, unsigned int value)
 {
-	int phy_addr;
-	int i;
+	void __iomem *smi_reg = mp->shared_smi->eth_base + SMI_REG;
+	int phy_addr = ethernet_phy_get(mp);
 	unsigned long flags;
-
-	phy_addr = ethernet_phy_get(mp);
+	int i;
 
 	/* the SMI register is a shared resource */
-	spin_lock_irqsave(&mv643xx_eth_phy_lock, flags);
+	spin_lock_irqsave(&mp->shared_smi->phy_lock, flags);
 
 	/* wait for the SMI register to become available */
-	for (i = 0; rdl(mp, SMI_REG) & ETH_SMI_BUSY; i++) {
+	for (i = 0; readl(smi_reg) & ETH_SMI_BUSY; i++) {
 		if (i == PHY_WAIT_ITERATIONS) {
 			printk("%s: PHY busy timeout\n", mp->dev->name);
 			goto out;
@@ -2980,10 +3066,10 @@ static void eth_port_write_smi_reg(struct mv643xx_private *mp,
 		udelay(PHY_WAIT_MICRO_SECONDS);
 	}
 
-	wrl(mp, SMI_REG, (phy_addr << 16) | (phy_reg << 21) |
-				ETH_SMI_OPCODE_WRITE | (value & 0xffff));
+	writel((phy_addr << 16) | (phy_reg << 21) |
+		ETH_SMI_OPCODE_WRITE | (value & 0xffff), smi_reg);
 out:
-	spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
+	spin_unlock_irqrestore(&mp->shared_smi->phy_lock, flags);
 }
 
 /*
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 4eb322e..a1c454d 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -22,12 +22,8 @@
  *************************************************************************/
 
 #define DRV_NAME	"pcnet32"
-#ifdef CONFIG_PCNET32_NAPI
-#define DRV_VERSION	"1.34-NAPI"
-#else
-#define DRV_VERSION	"1.34"
-#endif
-#define DRV_RELDATE	"14.Aug.2007"
+#define DRV_VERSION	"1.35"
+#define DRV_RELDATE	"21.Apr.2008"
 #define PFX		DRV_NAME ": "
 
 static const char *const version =
@@ -445,30 +441,24 @@ static struct pcnet32_access pcnet32_dwio = {
 
 static void pcnet32_netif_stop(struct net_device *dev)
 {
-#ifdef CONFIG_PCNET32_NAPI
 	struct pcnet32_private *lp = netdev_priv(dev);
-#endif
+
 	dev->trans_start = jiffies;
-#ifdef CONFIG_PCNET32_NAPI
 	napi_disable(&lp->napi);
-#endif
 	netif_tx_disable(dev);
 }
 
 static void pcnet32_netif_start(struct net_device *dev)
 {
-#ifdef CONFIG_PCNET32_NAPI
 	struct pcnet32_private *lp = netdev_priv(dev);
 	ulong ioaddr = dev->base_addr;
 	u16 val;
-#endif
+
 	netif_wake_queue(dev);
-#ifdef CONFIG_PCNET32_NAPI
 	val = lp->a.read_csr(ioaddr, CSR3);
 	val &= 0x00ff;
 	lp->a.write_csr(ioaddr, CSR3, val);
 	napi_enable(&lp->napi);
-#endif
 }
 
 /*
@@ -911,11 +901,7 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
 	rc = 1;			/* default to fail */
 
 	if (netif_running(dev))
-#ifdef CONFIG_PCNET32_NAPI
 		pcnet32_netif_stop(dev);
-#else
-		pcnet32_close(dev);
-#endif
 
 	spin_lock_irqsave(&lp->lock, flags);
 	lp->a.write_csr(ioaddr, CSR0, CSR0_STOP);	/* stop the chip */
@@ -1046,7 +1032,6 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
 	x = a->read_bcr(ioaddr, 32);	/* reset internal loopback */
 	a->write_bcr(ioaddr, 32, (x & ~0x0002));
 
-#ifdef CONFIG_PCNET32_NAPI
 	if (netif_running(dev)) {
 		pcnet32_netif_start(dev);
 		pcnet32_restart(dev, CSR0_NORMAL);
@@ -1055,16 +1040,6 @@ static int pcnet32_loopback_test(struct net_device *dev, uint64_t * data1)
 		lp->a.write_bcr(ioaddr, 20, 4);	/* return to 16bit mode */
 	}
 	spin_unlock_irqrestore(&lp->lock, flags);
-#else
-	if (netif_running(dev)) {
-		spin_unlock_irqrestore(&lp->lock, flags);
-		pcnet32_open(dev);
-	} else {
-		pcnet32_purge_rx_ring(dev);
-		lp->a.write_bcr(ioaddr, 20, 4);	/* return to 16bit mode */
-		spin_unlock_irqrestore(&lp->lock, flags);
-	}
-#endif
 
 	return (rc);
 }				/* end pcnet32_loopback_test  */
@@ -1270,11 +1245,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
 	}
 	dev->stats.rx_bytes += skb->len;
 	skb->protocol = eth_type_trans(skb, dev);
-#ifdef CONFIG_PCNET32_NAPI
 	netif_receive_skb(skb);
-#else
-	netif_rx(skb);
-#endif
 	dev->last_rx = jiffies;
 	dev->stats.rx_packets++;
 	return;
@@ -1403,7 +1374,6 @@ static int pcnet32_tx(struct net_device *dev)
 	return must_restart;
 }
 
-#ifdef CONFIG_PCNET32_NAPI
 static int pcnet32_poll(struct napi_struct *napi, int budget)
 {
 	struct pcnet32_private *lp = container_of(napi, struct pcnet32_private, napi);
@@ -1442,7 +1412,6 @@ static int pcnet32_poll(struct napi_struct *napi, int budget)
 	}
 	return work_done;
 }
-#endif
 
 #define PCNET32_REGS_PER_PHY	32
 #define PCNET32_MAX_PHYS	32
@@ -1864,9 +1833,7 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
 	/* napi.weight is used in both the napi and non-napi cases */
 	lp->napi.weight = lp->rx_ring_size / 2;
 
-#ifdef CONFIG_PCNET32_NAPI
 	netif_napi_add(dev, &lp->napi, pcnet32_poll, lp->rx_ring_size / 2);
-#endif
 
 	if (fdx && !(lp->options & PCNET32_PORT_ASEL) &&
 	    ((cards_found >= MAX_UNITS) || full_duplex[cards_found]))
@@ -2297,9 +2264,7 @@ static int pcnet32_open(struct net_device *dev)
 		goto err_free_ring;
 	}
 
-#ifdef CONFIG_PCNET32_NAPI
 	napi_enable(&lp->napi);
-#endif
 
 	/* Re-initialize the PCNET32, and start it when done. */
 	lp->a.write_csr(ioaddr, 1, (lp->init_dma_addr & 0xffff));
@@ -2623,7 +2588,6 @@ pcnet32_interrupt(int irq, void *dev_id)
 				       dev->name, csr0);
 			/* unlike for the lance, there is no restart needed */
 		}
-#ifdef CONFIG_PCNET32_NAPI
 		if (netif_rx_schedule_prep(dev, &lp->napi)) {
 			u16 val;
 			/* set interrupt masks */
@@ -2634,24 +2598,9 @@ pcnet32_interrupt(int irq, void *dev_id)
 			__netif_rx_schedule(dev, &lp->napi);
 			break;
 		}
-#else
-		pcnet32_rx(dev, lp->napi.weight);
-		if (pcnet32_tx(dev)) {
-			/* reset the chip to clear the error condition, then restart */
-			lp->a.reset(ioaddr);
-			lp->a.write_csr(ioaddr, CSR4, 0x0915); /* auto tx pad */
-			pcnet32_restart(dev, CSR0_START);
-			netif_wake_queue(dev);
-		}
-#endif
 		csr0 = lp->a.read_csr(ioaddr, CSR0);
 	}
 
-#ifndef CONFIG_PCNET32_NAPI
-	/* Set interrupt enable. */
-	lp->a.write_csr(ioaddr, CSR0, CSR0_INTEN);
-#endif
-
 	if (netif_msg_intr(lp))
 		printk(KERN_DEBUG "%s: exiting interrupt, csr0=%#4.4x.\n",
 		       dev->name, lp->a.read_csr(ioaddr, CSR0));
@@ -2670,9 +2619,7 @@ static int pcnet32_close(struct net_device *dev)
 	del_timer_sync(&lp->watchdog_timer);
 
 	netif_stop_queue(dev);
-#ifdef CONFIG_PCNET32_NAPI
 	napi_disable(&lp->napi);
-#endif
 
 	spin_lock_irqsave(&lp->lock, flags);
 
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 3c18bb5..45cc291 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -547,7 +547,7 @@ static void phy_force_reduction(struct phy_device *phydev)
  * Must not be called from interrupt context, or while the
  * phydev->lock is held.
  */
-void phy_error(struct phy_device *phydev)
+static void phy_error(struct phy_device *phydev)
 {
 	mutex_lock(&phydev->lock);
 	phydev->state = PHY_HALTED;
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index a59c1f2..2511ca7 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -434,10 +434,6 @@ static int uli526x_open(struct net_device *dev)
 
 	ULI526X_DBUG(0, "uli526x_open", 0);
 
-	ret = request_irq(dev->irq, &uli526x_interrupt, IRQF_SHARED, dev->name, dev);
-	if (ret)
-		return ret;
-
 	/* system variable init */
 	db->cr6_data = CR6_DEFAULT | uli526x_cr6_user_set;
 	db->tx_packet_cnt = 0;
@@ -456,6 +452,10 @@ static int uli526x_open(struct net_device *dev)
 	/* Initialize ULI526X board */
 	uli526x_init(dev);
 
+	ret = request_irq(dev->irq, &uli526x_interrupt, IRQF_SHARED, dev->name, dev);
+	if (ret)
+		return ret;
+
 	/* Active System Interface */
 	netif_wake_queue(dev);
 
@@ -1368,6 +1368,12 @@ static void update_cr6(u32 cr6_data, unsigned long ioaddr)
  *	This setup frame initialize ULI526X address filter mode
  */
 
+#ifdef __BIG_ENDIAN
+#define FLT_SHIFT 16
+#else
+#define FLT_SHIFT 0
+#endif
+
 static void send_filter_frame(struct net_device *dev, int mc_cnt)
 {
 	struct uli526x_board_info *db = netdev_priv(dev);
@@ -1384,27 +1390,27 @@ static void send_filter_frame(struct net_device *dev, int mc_cnt)
 
 	/* Node address */
 	addrptr = (u16 *) dev->dev_addr;
-	*suptr++ = addrptr[0];
-	*suptr++ = addrptr[1];
-	*suptr++ = addrptr[2];
+	*suptr++ = addrptr[0] << FLT_SHIFT;
+	*suptr++ = addrptr[1] << FLT_SHIFT;
+	*suptr++ = addrptr[2] << FLT_SHIFT;
 
 	/* broadcast address */
-	*suptr++ = 0xffff;
-	*suptr++ = 0xffff;
-	*suptr++ = 0xffff;
+	*suptr++ = 0xffff << FLT_SHIFT;
+	*suptr++ = 0xffff << FLT_SHIFT;
+	*suptr++ = 0xffff << FLT_SHIFT;
 
 	/* fit the multicast address */
 	for (mcptr = dev->mc_list, i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
 		addrptr = (u16 *) mcptr->dmi_addr;
-		*suptr++ = addrptr[0];
-		*suptr++ = addrptr[1];
-		*suptr++ = addrptr[2];
+		*suptr++ = addrptr[0] << FLT_SHIFT;
+		*suptr++ = addrptr[1] << FLT_SHIFT;
+		*suptr++ = addrptr[2] << FLT_SHIFT;
 	}
 
 	for (; i<14; i++) {
-		*suptr++ = 0xffff;
-		*suptr++ = 0xffff;
-		*suptr++ = 0xffff;
+		*suptr++ = 0xffff << FLT_SHIFT;
+		*suptr++ = 0xffff << FLT_SHIFT;
+		*suptr++ = 0xffff << FLT_SHIFT;
 	}
 
 	/* prepare the setup frame */
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 281ce3d..ca0bdac 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -62,7 +62,6 @@
 #endif				/* UGETH_VERBOSE_DEBUG */
 #define UGETH_MSG_DEFAULT	(NETIF_MSG_IFUP << 1 ) - 1
 
-void uec_set_ethtool_ops(struct net_device *netdev);
 
 static DEFINE_SPINLOCK(ugeth_lock);
 
@@ -216,7 +215,8 @@ static struct list_head *dequeue(struct list_head *lh)
 	}
 }
 
-static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd)
+static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth,
+		u8 __iomem *bd)
 {
 	struct sk_buff *skb = NULL;
 
@@ -236,21 +236,22 @@ static struct sk_buff *get_new_skb(struct ucc_geth_private *ugeth, u8 *bd)
 
 	skb->dev = ugeth->dev;
 
-	out_be32(&((struct qe_bd *)bd)->buf,
+	out_be32(&((struct qe_bd __iomem *)bd)->buf,
 		      dma_map_single(NULL,
 				     skb->data,
 				     ugeth->ug_info->uf_info.max_rx_buf_length +
 				     UCC_GETH_RX_DATA_BUF_ALIGNMENT,
 				     DMA_FROM_DEVICE));
 
-	out_be32((u32 *)bd, (R_E | R_I | (in_be32((u32 *)bd) & R_W)));
+	out_be32((u32 __iomem *)bd,
+			(R_E | R_I | (in_be32((u32 __iomem*)bd) & R_W)));
 
 	return skb;
 }
 
 static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ)
 {
-	u8 *bd;
+	u8 __iomem *bd;
 	u32 bd_status;
 	struct sk_buff *skb;
 	int i;
@@ -259,7 +260,7 @@ static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ)
 	i = 0;
 
 	do {
-		bd_status = in_be32((u32*)bd);
+		bd_status = in_be32((u32 __iomem *)bd);
 		skb = get_new_skb(ugeth, bd);
 
 		if (!skb)	/* If can not allocate data buffer,
@@ -277,7 +278,7 @@ static int rx_bd_buffer_set(struct ucc_geth_private *ugeth, u8 rxQ)
 }
 
 static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
-				  volatile u32 *p_start,
+				  u32 *p_start,
 				  u8 num_entries,
 				  u32 thread_size,
 				  u32 thread_alignment,
@@ -316,7 +317,7 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
 }
 
 static int return_init_enet_entries(struct ucc_geth_private *ugeth,
-				    volatile u32 *p_start,
+				    u32 *p_start,
 				    u8 num_entries,
 				    enum qe_risc_allocation risc,
 				    int skip_page_for_first_entry)
@@ -326,21 +327,22 @@ static int return_init_enet_entries(struct ucc_geth_private *ugeth,
 	int snum;
 
 	for (i = 0; i < num_entries; i++) {
+		u32 val = *p_start;
+
 		/* Check that this entry was actually valid --
 		needed in case failed in allocations */
-		if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) {
+		if ((val & ENET_INIT_PARAM_RISC_MASK) == risc) {
 			snum =
-			    (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >>
+			    (u32) (val & ENET_INIT_PARAM_SNUM_MASK) >>
 			    ENET_INIT_PARAM_SNUM_SHIFT;
 			qe_put_snum((u8) snum);
 			if (!((i == 0) && skip_page_for_first_entry)) {
 			/* First entry of Rx does not have page */
 				init_enet_offset =
-				    (in_be32(p_start) &
-				     ENET_INIT_PARAM_PTR_MASK);
+				    (val & ENET_INIT_PARAM_PTR_MASK);
 				qe_muram_free(init_enet_offset);
 			}
-			*(p_start++) = 0;	/* Just for cosmetics */
+			*p_start++ = 0;
 		}
 	}
 
@@ -349,7 +351,7 @@ static int return_init_enet_entries(struct ucc_geth_private *ugeth,
 
 #ifdef DEBUG
 static int dump_init_enet_entries(struct ucc_geth_private *ugeth,
-				  volatile u32 *p_start,
+				  u32 __iomem *p_start,
 				  u8 num_entries,
 				  u32 thread_size,
 				  enum qe_risc_allocation risc,
@@ -360,11 +362,13 @@ static int dump_init_enet_entries(struct ucc_geth_private *ugeth,
 	int snum;
 
 	for (i = 0; i < num_entries; i++) {
+		u32 val = in_be32(p_start);
+
 		/* Check that this entry was actually valid --
 		needed in case failed in allocations */
-		if ((*p_start & ENET_INIT_PARAM_RISC_MASK) == risc) {
+		if ((val & ENET_INIT_PARAM_RISC_MASK) == risc) {
 			snum =
-			    (u32) (*p_start & ENET_INIT_PARAM_SNUM_MASK) >>
+			    (u32) (val & ENET_INIT_PARAM_SNUM_MASK) >>
 			    ENET_INIT_PARAM_SNUM_SHIFT;
 			qe_put_snum((u8) snum);
 			if (!((i == 0) && skip_page_for_first_entry)) {
@@ -440,7 +444,7 @@ static int hw_add_addr_in_paddr(struct ucc_geth_private *ugeth,
 
 static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num)
 {
-	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
 
 	if (!(paddr_num < NUM_OF_PADDRS)) {
 		ugeth_warn("%s: Illagel paddr_num.", __FUNCTION__);
@@ -448,7 +452,7 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num)
 	}
 
 	p_82xx_addr_filt =
-	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
+	    (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->p_rx_glbl_pram->
 	    addressfiltering;
 
 	/* Writing address ff.ff.ff.ff.ff.ff disables address
@@ -463,11 +467,11 @@ static int hw_clear_addr_in_paddr(struct ucc_geth_private *ugeth, u8 paddr_num)
 static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth,
                                 u8 *p_enet_addr)
 {
-	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
 	u32 cecr_subblock;
 
 	p_82xx_addr_filt =
-	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
+	    (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->p_rx_glbl_pram->
 	    addressfiltering;
 
 	cecr_subblock =
@@ -487,7 +491,7 @@ static void hw_add_addr_in_hash(struct ucc_geth_private *ugeth,
 static void magic_packet_detection_enable(struct ucc_geth_private *ugeth)
 {
 	struct ucc_fast_private *uccf;
-	struct ucc_geth *ug_regs;
+	struct ucc_geth __iomem *ug_regs;
 	u32 maccfg2, uccm;
 
 	uccf = ugeth->uccf;
@@ -507,7 +511,7 @@ static void magic_packet_detection_enable(struct ucc_geth_private *ugeth)
 static void magic_packet_detection_disable(struct ucc_geth_private *ugeth)
 {
 	struct ucc_fast_private *uccf;
-	struct ucc_geth *ug_regs;
+	struct ucc_geth __iomem *ug_regs;
 	u32 maccfg2, uccm;
 
 	uccf = ugeth->uccf;
@@ -538,13 +542,13 @@ static void get_statistics(struct ucc_geth_private *ugeth,
 			   rx_firmware_statistics,
 			   struct ucc_geth_hardware_statistics *hardware_statistics)
 {
-	struct ucc_fast *uf_regs;
-	struct ucc_geth *ug_regs;
+	struct ucc_fast __iomem *uf_regs;
+	struct ucc_geth __iomem *ug_regs;
 	struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram;
 	struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram;
 
 	ug_regs = ugeth->ug_regs;
-	uf_regs = (struct ucc_fast *) ug_regs;
+	uf_regs = (struct ucc_fast __iomem *) ug_regs;
 	p_tx_fw_statistics_pram = ugeth->p_tx_fw_statistics_pram;
 	p_rx_fw_statistics_pram = ugeth->p_rx_fw_statistics_pram;
 
@@ -1132,9 +1136,9 @@ static void dump_regs(struct ucc_geth_private *ugeth)
 }
 #endif /* DEBUG */
 
-static void init_default_reg_vals(volatile u32 *upsmr_register,
-				  volatile u32 *maccfg1_register,
-				  volatile u32 *maccfg2_register)
+static void init_default_reg_vals(u32 __iomem *upsmr_register,
+				  u32 __iomem *maccfg1_register,
+				  u32 __iomem *maccfg2_register)
 {
 	out_be32(upsmr_register, UCC_GETH_UPSMR_INIT);
 	out_be32(maccfg1_register, UCC_GETH_MACCFG1_INIT);
@@ -1148,7 +1152,7 @@ static int init_half_duplex_params(int alt_beb,
 				   u8 alt_beb_truncation,
 				   u8 max_retransmissions,
 				   u8 collision_window,
-				   volatile u32 *hafdup_register)
+				   u32 __iomem *hafdup_register)
 {
 	u32 value = 0;
 
@@ -1180,7 +1184,7 @@ static int init_inter_frame_gap_params(u8 non_btb_cs_ipg,
 				       u8 non_btb_ipg,
 				       u8 min_ifg,
 				       u8 btb_ipg,
-				       volatile u32 *ipgifg_register)
+				       u32 __iomem *ipgifg_register)
 {
 	u32 value = 0;
 
@@ -1215,9 +1219,9 @@ int init_flow_control_params(u32 automatic_flow_control_mode,
 				    int tx_flow_control_enable,
 				    u16 pause_period,
 				    u16 extension_field,
-				    volatile u32 *upsmr_register,
-				    volatile u32 *uempr_register,
-				    volatile u32 *maccfg1_register)
+				    u32 __iomem *upsmr_register,
+				    u32 __iomem *uempr_register,
+				    u32 __iomem *maccfg1_register)
 {
 	u32 value = 0;
 
@@ -1243,8 +1247,8 @@ int init_flow_control_params(u32 automatic_flow_control_mode,
 
 static int init_hw_statistics_gathering_mode(int enable_hardware_statistics,
 					     int auto_zero_hardware_statistics,
-					     volatile u32 *upsmr_register,
-					     volatile u16 *uescr_register)
+					     u32 __iomem *upsmr_register,
+					     u16 __iomem *uescr_register)
 {
 	u32 upsmr_value = 0;
 	u16 uescr_value = 0;
@@ -1270,12 +1274,12 @@ static int init_hw_statistics_gathering_mode(int enable_hardware_statistics,
 static int init_firmware_statistics_gathering_mode(int
 		enable_tx_firmware_statistics,
 		int enable_rx_firmware_statistics,
-		volatile u32 *tx_rmon_base_ptr,
+		u32 __iomem *tx_rmon_base_ptr,
 		u32 tx_firmware_statistics_structure_address,
-		volatile u32 *rx_rmon_base_ptr,
+		u32 __iomem *rx_rmon_base_ptr,
 		u32 rx_firmware_statistics_structure_address,
-		volatile u16 *temoder_register,
-		volatile u32 *remoder_register)
+		u16 __iomem *temoder_register,
+		u32 __iomem *remoder_register)
 {
 	/* Note: this function does not check if */
 	/* the parameters it receives are NULL   */
@@ -1307,8 +1311,8 @@ static int init_mac_station_addr_regs(u8 address_byte_0,
 				      u8 address_byte_3,
 				      u8 address_byte_4,
 				      u8 address_byte_5,
-				      volatile u32 *macstnaddr1_register,
-				      volatile u32 *macstnaddr2_register)
+				      u32 __iomem *macstnaddr1_register,
+				      u32 __iomem *macstnaddr2_register)
 {
 	u32 value = 0;
 
@@ -1344,7 +1348,7 @@ static int init_mac_station_addr_regs(u8 address_byte_0,
 }
 
 static int init_check_frame_length_mode(int length_check,
-					volatile u32 *maccfg2_register)
+					u32 __iomem *maccfg2_register)
 {
 	u32 value = 0;
 
@@ -1360,7 +1364,7 @@ static int init_check_frame_length_mode(int length_check,
 }
 
 static int init_preamble_length(u8 preamble_length,
-				volatile u32 *maccfg2_register)
+				u32 __iomem *maccfg2_register)
 {
 	u32 value = 0;
 
@@ -1376,7 +1380,7 @@ static int init_preamble_length(u8 preamble_length,
 
 static int init_rx_parameters(int reject_broadcast,
 			      int receive_short_frames,
-			      int promiscuous, volatile u32 *upsmr_register)
+			      int promiscuous, u32 __iomem *upsmr_register)
 {
 	u32 value = 0;
 
@@ -1403,7 +1407,7 @@ static int init_rx_parameters(int reject_broadcast,
 }
 
 static int init_max_rx_buff_len(u16 max_rx_buf_len,
-				volatile u16 *mrblr_register)
+				u16 __iomem *mrblr_register)
 {
 	/* max_rx_buf_len value must be a multiple of 128 */
 	if ((max_rx_buf_len == 0)
@@ -1415,8 +1419,8 @@ static int init_max_rx_buff_len(u16 max_rx_buf_len,
 }
 
 static int init_min_frame_len(u16 min_frame_length,
-			      volatile u16 *minflr_register,
-			      volatile u16 *mrblr_register)
+			      u16 __iomem *minflr_register,
+			      u16 __iomem *mrblr_register)
 {
 	u16 mrblr_value = 0;
 
@@ -1431,8 +1435,8 @@ static int init_min_frame_len(u16 min_frame_length,
 static int adjust_enet_interface(struct ucc_geth_private *ugeth)
 {
 	struct ucc_geth_info *ug_info;
-	struct ucc_geth *ug_regs;
-	struct ucc_fast *uf_regs;
+	struct ucc_geth __iomem *ug_regs;
+	struct ucc_fast __iomem *uf_regs;
 	int ret_val;
 	u32 upsmr, maccfg2, tbiBaseAddress;
 	u16 value;
@@ -1517,8 +1521,8 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
 static void adjust_link(struct net_device *dev)
 {
 	struct ucc_geth_private *ugeth = netdev_priv(dev);
-	struct ucc_geth *ug_regs;
-	struct ucc_fast *uf_regs;
+	struct ucc_geth __iomem *ug_regs;
+	struct ucc_fast __iomem *uf_regs;
 	struct phy_device *phydev = ugeth->phydev;
 	unsigned long flags;
 	int new_state = 0;
@@ -1678,9 +1682,9 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth)
 	uccf = ugeth->uccf;
 
 	/* Clear acknowledge bit */
-	temp = ugeth->p_rx_glbl_pram->rxgstpack;
+	temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
 	temp &= ~GRACEFUL_STOP_ACKNOWLEDGE_RX;
-	ugeth->p_rx_glbl_pram->rxgstpack = temp;
+	out_8(&ugeth->p_rx_glbl_pram->rxgstpack, temp);
 
 	/* Keep issuing command and checking acknowledge bit until
 	it is asserted, according to spec */
@@ -1692,7 +1696,7 @@ static int ugeth_graceful_stop_rx(struct ucc_geth_private * ugeth)
 		qe_issue_cmd(QE_GRACEFUL_STOP_RX, cecr_subblock,
 			     QE_CR_PROTOCOL_ETHERNET, 0);
 
-		temp = ugeth->p_rx_glbl_pram->rxgstpack;
+		temp = in_8(&ugeth->p_rx_glbl_pram->rxgstpack);
 	} while (!(temp & GRACEFUL_STOP_ACKNOWLEDGE_RX));
 
 	uccf->stopped_rx = 1;
@@ -1991,19 +1995,20 @@ static int ugeth_82xx_filtering_clear_all_addr_in_hash(struct ucc_geth_private *
 						       enum enet_addr_type
 						       enet_addr_type)
 {
-	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
 	struct ucc_fast_private *uccf;
 	enum comm_dir comm_dir;
 	struct list_head *p_lh;
 	u16 i, num;
-	u32 *addr_h, *addr_l;
+	u32 __iomem *addr_h;
+	u32 __iomem *addr_l;
 	u8 *p_counter;
 
 	uccf = ugeth->uccf;
 
 	p_82xx_addr_filt =
-	    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->p_rx_glbl_pram->
-	    addressfiltering;
+	    (struct ucc_geth_82xx_address_filtering_pram __iomem *)
+	    ugeth->p_rx_glbl_pram->addressfiltering;
 
 	if (enet_addr_type == ENET_ADDR_TYPE_GROUP) {
 		addr_h = &(p_82xx_addr_filt->gaddr_h);
@@ -2079,7 +2084,7 @@ static int ugeth_82xx_filtering_clear_addr_in_paddr(struct ucc_geth_private *uge
 static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
 {
 	u16 i, j;
-	u8 *bd;
+	u8 __iomem *bd;
 
 	if (!ugeth)
 		return;
@@ -2154,8 +2159,8 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
 		for (j = 0; j < ugeth->ug_info->bdRingLenTx[i]; j++) {
 			if (ugeth->tx_skbuff[i][j]) {
 				dma_unmap_single(NULL,
-						 ((struct qe_bd *)bd)->buf,
-						 (in_be32((u32 *)bd) &
+						 in_be32(&((struct qe_bd __iomem *)bd)->buf),
+						 (in_be32((u32 __iomem *)bd) &
 						  BD_LENGTH_MASK),
 						 DMA_TO_DEVICE);
 				dev_kfree_skb_any(ugeth->tx_skbuff[i][j]);
@@ -2182,7 +2187,7 @@ static void ucc_geth_memclean(struct ucc_geth_private *ugeth)
 			for (j = 0; j < ugeth->ug_info->bdRingLenRx[i]; j++) {
 				if (ugeth->rx_skbuff[i][j]) {
 					dma_unmap_single(NULL,
-						((struct qe_bd *)bd)->buf,
+						in_be32(&((struct qe_bd __iomem *)bd)->buf),
 						ugeth->ug_info->
 						uf_info.max_rx_buf_length +
 						UCC_GETH_RX_DATA_BUF_ALIGNMENT,
@@ -2218,8 +2223,8 @@ static void ucc_geth_set_multi(struct net_device *dev)
 {
 	struct ucc_geth_private *ugeth;
 	struct dev_mc_list *dmi;
-	struct ucc_fast *uf_regs;
-	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
+	struct ucc_fast __iomem *uf_regs;
+	struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
 	int i;
 
 	ugeth = netdev_priv(dev);
@@ -2228,14 +2233,14 @@ static void ucc_geth_set_multi(struct net_device *dev)
 
 	if (dev->flags & IFF_PROMISC) {
 
-		uf_regs->upsmr |= UPSMR_PRO;
+		out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr) | UPSMR_PRO);
 
 	} else {
 
-		uf_regs->upsmr &= ~UPSMR_PRO;
+		out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr)&~UPSMR_PRO);
 
 		p_82xx_addr_filt =
-		    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->
+		    (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->
 		    p_rx_glbl_pram->addressfiltering;
 
 		if (dev->flags & IFF_ALLMULTI) {
@@ -2270,7 +2275,7 @@ static void ucc_geth_set_multi(struct net_device *dev)
 
 static void ucc_geth_stop(struct ucc_geth_private *ugeth)
 {
-	struct ucc_geth *ug_regs = ugeth->ug_regs;
+	struct ucc_geth __iomem *ug_regs = ugeth->ug_regs;
 	struct phy_device *phydev = ugeth->phydev;
 	u32 tempval;
 
@@ -2419,20 +2424,20 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
 		return -ENOMEM;
 	}
 
-	ugeth->ug_regs = (struct ucc_geth *) ioremap(uf_info->regs, sizeof(struct ucc_geth));
+	ugeth->ug_regs = (struct ucc_geth __iomem *) ioremap(uf_info->regs, sizeof(struct ucc_geth));
 
 	return 0;
 }
 
 static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 {
-	struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
-	struct ucc_geth_init_pram *p_init_enet_pram;
+	struct ucc_geth_82xx_address_filtering_pram __iomem *p_82xx_addr_filt;
+	struct ucc_geth_init_pram __iomem *p_init_enet_pram;
 	struct ucc_fast_private *uccf;
 	struct ucc_geth_info *ug_info;
 	struct ucc_fast_info *uf_info;
-	struct ucc_fast *uf_regs;
-	struct ucc_geth *ug_regs;
+	struct ucc_fast __iomem *uf_regs;
+	struct ucc_geth __iomem *ug_regs;
 	int ret_val = -EINVAL;
 	u32 remoder = UCC_GETH_REMODER_INIT;
 	u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
@@ -2440,7 +2445,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	u16 temoder = UCC_GETH_TEMODER_INIT;
 	u16 test;
 	u8 function_code = 0;
-	u8 *bd, *endOfRing;
+	u8 __iomem *bd;
+	u8 __iomem *endOfRing;
 	u8 numThreadsRxNumerical, numThreadsTxNumerical;
 
 	ugeth_vdbg("%s: IN", __FUNCTION__);
@@ -2602,11 +2608,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			if (UCC_GETH_TX_BD_RING_ALIGNMENT > 4)
 				align = UCC_GETH_TX_BD_RING_ALIGNMENT;
 			ugeth->tx_bd_ring_offset[j] =
-				kmalloc((u32) (length + align), GFP_KERNEL);
+				(u32) kmalloc((u32) (length + align), GFP_KERNEL);
 
 			if (ugeth->tx_bd_ring_offset[j] != 0)
 				ugeth->p_tx_bd_ring[j] =
-					(void*)((ugeth->tx_bd_ring_offset[j] +
+					(u8 __iomem *)((ugeth->tx_bd_ring_offset[j] +
 					align) & ~(align - 1));
 		} else if (uf_info->bd_mem_part == MEM_PART_MURAM) {
 			ugeth->tx_bd_ring_offset[j] =
@@ -2614,7 +2620,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 					   UCC_GETH_TX_BD_RING_ALIGNMENT);
 			if (!IS_ERR_VALUE(ugeth->tx_bd_ring_offset[j]))
 				ugeth->p_tx_bd_ring[j] =
-				    (u8 *) qe_muram_addr(ugeth->
+				    (u8 __iomem *) qe_muram_addr(ugeth->
 							 tx_bd_ring_offset[j]);
 		}
 		if (!ugeth->p_tx_bd_ring[j]) {
@@ -2626,8 +2632,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			return -ENOMEM;
 		}
 		/* Zero unused end of bd ring, according to spec */
-		memset(ugeth->p_tx_bd_ring[j] +
-		       ug_info->bdRingLenTx[j] * sizeof(struct qe_bd), 0,
+		memset_io((void __iomem *)(ugeth->p_tx_bd_ring[j] +
+		       ug_info->bdRingLenTx[j] * sizeof(struct qe_bd)), 0,
 		       length - ug_info->bdRingLenTx[j] * sizeof(struct qe_bd));
 	}
 
@@ -2639,10 +2645,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			if (UCC_GETH_RX_BD_RING_ALIGNMENT > 4)
 				align = UCC_GETH_RX_BD_RING_ALIGNMENT;
 			ugeth->rx_bd_ring_offset[j] =
-				kmalloc((u32) (length + align), GFP_KERNEL);
+				(u32) kmalloc((u32) (length + align), GFP_KERNEL);
 			if (ugeth->rx_bd_ring_offset[j] != 0)
 				ugeth->p_rx_bd_ring[j] =
-					(void*)((ugeth->rx_bd_ring_offset[j] +
+					(u8 __iomem *)((ugeth->rx_bd_ring_offset[j] +
 					align) & ~(align - 1));
 		} else if (uf_info->bd_mem_part == MEM_PART_MURAM) {
 			ugeth->rx_bd_ring_offset[j] =
@@ -2650,7 +2656,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 					   UCC_GETH_RX_BD_RING_ALIGNMENT);
 			if (!IS_ERR_VALUE(ugeth->rx_bd_ring_offset[j]))
 				ugeth->p_rx_bd_ring[j] =
-				    (u8 *) qe_muram_addr(ugeth->
+				    (u8 __iomem *) qe_muram_addr(ugeth->
 							 rx_bd_ring_offset[j]);
 		}
 		if (!ugeth->p_rx_bd_ring[j]) {
@@ -2685,14 +2691,14 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		bd = ugeth->confBd[j] = ugeth->txBd[j] = ugeth->p_tx_bd_ring[j];
 		for (i = 0; i < ug_info->bdRingLenTx[j]; i++) {
 			/* clear bd buffer */
-			out_be32(&((struct qe_bd *)bd)->buf, 0);
+			out_be32(&((struct qe_bd __iomem *)bd)->buf, 0);
 			/* set bd status and length */
-			out_be32((u32 *)bd, 0);
+			out_be32((u32 __iomem *)bd, 0);
 			bd += sizeof(struct qe_bd);
 		}
 		bd -= sizeof(struct qe_bd);
 		/* set bd status and length */
-		out_be32((u32 *)bd, T_W);	/* for last BD set Wrap bit */
+		out_be32((u32 __iomem *)bd, T_W); /* for last BD set Wrap bit */
 	}
 
 	/* Init Rx bds */
@@ -2717,14 +2723,14 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		bd = ugeth->rxBd[j] = ugeth->p_rx_bd_ring[j];
 		for (i = 0; i < ug_info->bdRingLenRx[j]; i++) {
 			/* set bd status and length */
-			out_be32((u32 *)bd, R_I);
+			out_be32((u32 __iomem *)bd, R_I);
 			/* clear bd buffer */
-			out_be32(&((struct qe_bd *)bd)->buf, 0);
+			out_be32(&((struct qe_bd __iomem *)bd)->buf, 0);
 			bd += sizeof(struct qe_bd);
 		}
 		bd -= sizeof(struct qe_bd);
 		/* set bd status and length */
-		out_be32((u32 *)bd, R_W); /* for last BD set Wrap bit */
+		out_be32((u32 __iomem *)bd, R_W); /* for last BD set Wrap bit */
 	}
 
 	/*
@@ -2744,10 +2750,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		return -ENOMEM;
 	}
 	ugeth->p_tx_glbl_pram =
-	    (struct ucc_geth_tx_global_pram *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_tx_global_pram __iomem *) qe_muram_addr(ugeth->
 							tx_glbl_pram_offset);
 	/* Zero out p_tx_glbl_pram */
-	memset(ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram));
+	memset_io((void __iomem *)ugeth->p_tx_glbl_pram, 0, sizeof(struct ucc_geth_tx_global_pram));
 
 	/* Fill global PRAM */
 
@@ -2768,7 +2774,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	}
 
 	ugeth->p_thread_data_tx =
-	    (struct ucc_geth_thread_data_tx *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_thread_data_tx __iomem *) qe_muram_addr(ugeth->
 							thread_dat_tx_offset);
 	out_be32(&ugeth->p_tx_glbl_pram->tqptr, ugeth->thread_dat_tx_offset);
 
@@ -2779,7 +2785,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 
 	/* iphoffset */
 	for (i = 0; i < TX_IP_OFFSET_ENTRY_MAX; i++)
-		ugeth->p_tx_glbl_pram->iphoffset[i] = ug_info->iphoffset[i];
+		out_8(&ugeth->p_tx_glbl_pram->iphoffset[i],
+				ug_info->iphoffset[i]);
 
 	/* SQPTR */
 	/* Size varies with number of Tx queues */
@@ -2797,7 +2804,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	}
 
 	ugeth->p_send_q_mem_reg =
-	    (struct ucc_geth_send_queue_mem_region *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_send_queue_mem_region __iomem *) qe_muram_addr(ugeth->
 			send_q_mem_reg_offset);
 	out_be32(&ugeth->p_tx_glbl_pram->sqptr, ugeth->send_q_mem_reg_offset);
 
@@ -2841,25 +2848,26 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		}
 
 		ugeth->p_scheduler =
-		    (struct ucc_geth_scheduler *) qe_muram_addr(ugeth->
+		    (struct ucc_geth_scheduler __iomem *) qe_muram_addr(ugeth->
 							   scheduler_offset);
 		out_be32(&ugeth->p_tx_glbl_pram->schedulerbasepointer,
 			 ugeth->scheduler_offset);
 		/* Zero out p_scheduler */
-		memset(ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler));
+		memset_io((void __iomem *)ugeth->p_scheduler, 0, sizeof(struct ucc_geth_scheduler));
 
 		/* Set values in scheduler */
 		out_be32(&ugeth->p_scheduler->mblinterval,
 			 ug_info->mblinterval);
 		out_be16(&ugeth->p_scheduler->nortsrbytetime,
 			 ug_info->nortsrbytetime);
-		ugeth->p_scheduler->fracsiz = ug_info->fracsiz;
-		ugeth->p_scheduler->strictpriorityq = ug_info->strictpriorityq;
-		ugeth->p_scheduler->txasap = ug_info->txasap;
-		ugeth->p_scheduler->extrabw = ug_info->extrabw;
+		out_8(&ugeth->p_scheduler->fracsiz, ug_info->fracsiz);
+		out_8(&ugeth->p_scheduler->strictpriorityq,
+				ug_info->strictpriorityq);
+		out_8(&ugeth->p_scheduler->txasap, ug_info->txasap);
+		out_8(&ugeth->p_scheduler->extrabw, ug_info->extrabw);
 		for (i = 0; i < NUM_TX_QUEUES; i++)
-			ugeth->p_scheduler->weightfactor[i] =
-			    ug_info->weightfactor[i];
+			out_8(&ugeth->p_scheduler->weightfactor[i],
+			    ug_info->weightfactor[i]);
 
 		/* Set pointers to cpucount registers in scheduler */
 		ugeth->p_cpucount[0] = &(ugeth->p_scheduler->cpucount0);
@@ -2890,10 +2898,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			return -ENOMEM;
 		}
 		ugeth->p_tx_fw_statistics_pram =
-		    (struct ucc_geth_tx_firmware_statistics_pram *)
+		    (struct ucc_geth_tx_firmware_statistics_pram __iomem *)
 		    qe_muram_addr(ugeth->tx_fw_statistics_pram_offset);
 		/* Zero out p_tx_fw_statistics_pram */
-		memset(ugeth->p_tx_fw_statistics_pram,
+		memset_io((void __iomem *)ugeth->p_tx_fw_statistics_pram,
 		       0, sizeof(struct ucc_geth_tx_firmware_statistics_pram));
 	}
 
@@ -2930,10 +2938,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		return -ENOMEM;
 	}
 	ugeth->p_rx_glbl_pram =
-	    (struct ucc_geth_rx_global_pram *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_rx_global_pram __iomem *) qe_muram_addr(ugeth->
 							rx_glbl_pram_offset);
 	/* Zero out p_rx_glbl_pram */
-	memset(ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram));
+	memset_io((void __iomem *)ugeth->p_rx_glbl_pram, 0, sizeof(struct ucc_geth_rx_global_pram));
 
 	/* Fill global PRAM */
 
@@ -2953,7 +2961,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	}
 
 	ugeth->p_thread_data_rx =
-	    (struct ucc_geth_thread_data_rx *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_thread_data_rx __iomem *) qe_muram_addr(ugeth->
 							thread_dat_rx_offset);
 	out_be32(&ugeth->p_rx_glbl_pram->rqptr, ugeth->thread_dat_rx_offset);
 
@@ -2976,10 +2984,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			return -ENOMEM;
 		}
 		ugeth->p_rx_fw_statistics_pram =
-		    (struct ucc_geth_rx_firmware_statistics_pram *)
+		    (struct ucc_geth_rx_firmware_statistics_pram __iomem *)
 		    qe_muram_addr(ugeth->rx_fw_statistics_pram_offset);
 		/* Zero out p_rx_fw_statistics_pram */
-		memset(ugeth->p_rx_fw_statistics_pram, 0,
+		memset_io((void __iomem *)ugeth->p_rx_fw_statistics_pram, 0,
 		       sizeof(struct ucc_geth_rx_firmware_statistics_pram));
 	}
 
@@ -3000,7 +3008,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	}
 
 	ugeth->p_rx_irq_coalescing_tbl =
-	    (struct ucc_geth_rx_interrupt_coalescing_table *)
+	    (struct ucc_geth_rx_interrupt_coalescing_table __iomem *)
 	    qe_muram_addr(ugeth->rx_irq_coalescing_tbl_offset);
 	out_be32(&ugeth->p_rx_glbl_pram->intcoalescingptr,
 		 ugeth->rx_irq_coalescing_tbl_offset);
@@ -3069,11 +3077,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	}
 
 	ugeth->p_rx_bd_qs_tbl =
-	    (struct ucc_geth_rx_bd_queues_entry *) qe_muram_addr(ugeth->
+	    (struct ucc_geth_rx_bd_queues_entry __iomem *) qe_muram_addr(ugeth->
 				    rx_bd_qs_tbl_offset);
 	out_be32(&ugeth->p_rx_glbl_pram->rbdqptr, ugeth->rx_bd_qs_tbl_offset);
 	/* Zero out p_rx_bd_qs_tbl */
-	memset(ugeth->p_rx_bd_qs_tbl,
+	memset_io((void __iomem *)ugeth->p_rx_bd_qs_tbl,
 	       0,
 	       ug_info->numQueuesRx * (sizeof(struct ucc_geth_rx_bd_queues_entry) +
 				       sizeof(struct ucc_geth_rx_prefetched_bds)));
@@ -3133,7 +3141,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		&ugeth->p_rx_glbl_pram->remoder);
 
 	/* function code register */
-	ugeth->p_rx_glbl_pram->rstate = function_code;
+	out_8(&ugeth->p_rx_glbl_pram->rstate, function_code);
 
 	/* initialize extended filtering */
 	if (ug_info->rxExtendedFiltering) {
@@ -3160,7 +3168,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		}
 
 		ugeth->p_exf_glbl_param =
-		    (struct ucc_geth_exf_global_pram *) qe_muram_addr(ugeth->
+		    (struct ucc_geth_exf_global_pram __iomem *) qe_muram_addr(ugeth->
 				 exf_glbl_param_offset);
 		out_be32(&ugeth->p_rx_glbl_pram->exfGlobalParam,
 			 ugeth->exf_glbl_param_offset);
@@ -3175,7 +3183,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			ugeth_82xx_filtering_clear_addr_in_paddr(ugeth, (u8) j);
 
 		p_82xx_addr_filt =
-		    (struct ucc_geth_82xx_address_filtering_pram *) ugeth->
+		    (struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->
 		    p_rx_glbl_pram->addressfiltering;
 
 		ugeth_82xx_filtering_clear_all_addr_in_hash(ugeth,
@@ -3307,17 +3315,21 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		return -ENOMEM;
 	}
 	p_init_enet_pram =
-	    (struct ucc_geth_init_pram *) qe_muram_addr(init_enet_pram_offset);
+	    (struct ucc_geth_init_pram __iomem *) qe_muram_addr(init_enet_pram_offset);
 
 	/* Copy shadow InitEnet command parameter structure into PRAM */
-	p_init_enet_pram->resinit1 = ugeth->p_init_enet_param_shadow->resinit1;
-	p_init_enet_pram->resinit2 = ugeth->p_init_enet_param_shadow->resinit2;
-	p_init_enet_pram->resinit3 = ugeth->p_init_enet_param_shadow->resinit3;
-	p_init_enet_pram->resinit4 = ugeth->p_init_enet_param_shadow->resinit4;
+	out_8(&p_init_enet_pram->resinit1,
+			ugeth->p_init_enet_param_shadow->resinit1);
+	out_8(&p_init_enet_pram->resinit2,
+			ugeth->p_init_enet_param_shadow->resinit2);
+	out_8(&p_init_enet_pram->resinit3,
+			ugeth->p_init_enet_param_shadow->resinit3);
+	out_8(&p_init_enet_pram->resinit4,
+			ugeth->p_init_enet_param_shadow->resinit4);
 	out_be16(&p_init_enet_pram->resinit5,
 		 ugeth->p_init_enet_param_shadow->resinit5);
-	p_init_enet_pram->largestexternallookupkeysize =
-	    ugeth->p_init_enet_param_shadow->largestexternallookupkeysize;
+	out_8(&p_init_enet_pram->largestexternallookupkeysize,
+	    ugeth->p_init_enet_param_shadow->largestexternallookupkeysize);
 	out_be32(&p_init_enet_pram->rgftgfrxglobal,
 		 ugeth->p_init_enet_param_shadow->rgftgfrxglobal);
 	for (i = 0; i < ENET_INIT_PARAM_MAX_ENTRIES_RX; i++)
@@ -3371,7 +3383,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 #ifdef CONFIG_UGETH_TX_ON_DEMAND
 	struct ucc_fast_private *uccf;
 #endif
-	u8 *bd;			/* BD pointer */
+	u8 __iomem *bd;			/* BD pointer */
 	u32 bd_status;
 	u8 txQ = 0;
 
@@ -3383,7 +3395,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	/* Start from the next BD that should be filled */
 	bd = ugeth->txBd[txQ];
-	bd_status = in_be32((u32 *)bd);
+	bd_status = in_be32((u32 __iomem *)bd);
 	/* Save the skb pointer so we can free it later */
 	ugeth->tx_skbuff[txQ][ugeth->skb_curtx[txQ]] = skb;
 
@@ -3393,7 +3405,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	     1) & TX_RING_MOD_MASK(ugeth->ug_info->bdRingLenTx[txQ]);
 
 	/* set up the buffer descriptor */
-	out_be32(&((struct qe_bd *)bd)->buf,
+	out_be32(&((struct qe_bd __iomem *)bd)->buf,
 		      dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE));
 
 	/* printk(KERN_DEBUG"skb->data is 0x%x\n",skb->data); */
@@ -3401,7 +3413,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	bd_status = (bd_status & T_W) | T_R | T_I | T_L | skb->len;
 
 	/* set bd status and length */
-	out_be32((u32 *)bd, bd_status);
+	out_be32((u32 __iomem *)bd, bd_status);
 
 	dev->trans_start = jiffies;
 
@@ -3441,7 +3453,7 @@ static int ucc_geth_start_xmit(struct sk_buff *skb, struct net_device *dev)
 static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit)
 {
 	struct sk_buff *skb;
-	u8 *bd;
+	u8 __iomem *bd;
 	u16 length, howmany = 0;
 	u32 bd_status;
 	u8 *bdBuffer;
@@ -3454,11 +3466,11 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
 	/* collect received buffers */
 	bd = ugeth->rxBd[rxQ];
 
-	bd_status = in_be32((u32 *)bd);
+	bd_status = in_be32((u32 __iomem *)bd);
 
 	/* while there are received buffers and BD is full (~R_E) */
 	while (!((bd_status & (R_E)) || (--rx_work_limit < 0))) {
-		bdBuffer = (u8 *) in_be32(&((struct qe_bd *)bd)->buf);
+		bdBuffer = (u8 *) in_be32(&((struct qe_bd __iomem *)bd)->buf);
 		length = (u16) ((bd_status & BD_LENGTH_MASK) - 4);
 		skb = ugeth->rx_skbuff[rxQ][ugeth->skb_currx[rxQ]];
 
@@ -3516,7 +3528,7 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
 		else
 			bd += sizeof(struct qe_bd);
 
-		bd_status = in_be32((u32 *)bd);
+		bd_status = in_be32((u32 __iomem *)bd);
 	}
 
 	ugeth->rxBd[rxQ] = bd;
@@ -3527,11 +3539,11 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 {
 	/* Start from the next BD that should be filled */
 	struct ucc_geth_private *ugeth = netdev_priv(dev);
-	u8 *bd;			/* BD pointer */
+	u8 __iomem *bd;		/* BD pointer */
 	u32 bd_status;
 
 	bd = ugeth->confBd[txQ];
-	bd_status = in_be32((u32 *)bd);
+	bd_status = in_be32((u32 __iomem *)bd);
 
 	/* Normal processing. */
 	while ((bd_status & T_R) == 0) {
@@ -3561,7 +3573,7 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
 			bd += sizeof(struct qe_bd);
 		else
 			bd = ugeth->p_tx_bd_ring[txQ];
-		bd_status = in_be32((u32 *)bd);
+		bd_status = in_be32((u32 __iomem *)bd);
 	}
 	ugeth->confBd[txQ] = bd;
 	return 0;
@@ -3910,7 +3922,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 			return -EINVAL;
 		}
 	} else {
-		prop = of_get_property(np, "rx-clock", NULL);
+		prop = of_get_property(np, "tx-clock", NULL);
 		if (!prop) {
 			printk(KERN_ERR
 				"ucc_geth: mising tx-clock-name property\n");
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index 9f8b758..abc0e22 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -700,8 +700,8 @@ struct ucc_geth_82xx_address_filtering_pram {
 	u32 iaddr_l;		/* individual address filter, low */
 	u32 gaddr_h;		/* group address filter, high */
 	u32 gaddr_l;		/* group address filter, low */
-	struct ucc_geth_82xx_enet_address taddr;
-	struct ucc_geth_82xx_enet_address paddr[NUM_OF_PADDRS];
+	struct ucc_geth_82xx_enet_address __iomem taddr;
+	struct ucc_geth_82xx_enet_address __iomem paddr[NUM_OF_PADDRS];
 	u8 res0[0x40 - 0x38];
 } __attribute__ ((packed));
 
@@ -1186,40 +1186,40 @@ struct ucc_geth_private {
 	struct ucc_fast_private *uccf;
 	struct net_device *dev;
 	struct napi_struct napi;
-	struct ucc_geth *ug_regs;
+	struct ucc_geth __iomem *ug_regs;
 	struct ucc_geth_init_pram *p_init_enet_param_shadow;
-	struct ucc_geth_exf_global_pram *p_exf_glbl_param;
+	struct ucc_geth_exf_global_pram __iomem *p_exf_glbl_param;
 	u32 exf_glbl_param_offset;
-	struct ucc_geth_rx_global_pram *p_rx_glbl_pram;
+	struct ucc_geth_rx_global_pram __iomem *p_rx_glbl_pram;
 	u32 rx_glbl_pram_offset;
-	struct ucc_geth_tx_global_pram *p_tx_glbl_pram;
+	struct ucc_geth_tx_global_pram __iomem *p_tx_glbl_pram;
 	u32 tx_glbl_pram_offset;
-	struct ucc_geth_send_queue_mem_region *p_send_q_mem_reg;
+	struct ucc_geth_send_queue_mem_region __iomem *p_send_q_mem_reg;
 	u32 send_q_mem_reg_offset;
-	struct ucc_geth_thread_data_tx *p_thread_data_tx;
+	struct ucc_geth_thread_data_tx __iomem *p_thread_data_tx;
 	u32 thread_dat_tx_offset;
-	struct ucc_geth_thread_data_rx *p_thread_data_rx;
+	struct ucc_geth_thread_data_rx __iomem *p_thread_data_rx;
 	u32 thread_dat_rx_offset;
-	struct ucc_geth_scheduler *p_scheduler;
+	struct ucc_geth_scheduler __iomem *p_scheduler;
 	u32 scheduler_offset;
-	struct ucc_geth_tx_firmware_statistics_pram *p_tx_fw_statistics_pram;
+	struct ucc_geth_tx_firmware_statistics_pram __iomem *p_tx_fw_statistics_pram;
 	u32 tx_fw_statistics_pram_offset;
-	struct ucc_geth_rx_firmware_statistics_pram *p_rx_fw_statistics_pram;
+	struct ucc_geth_rx_firmware_statistics_pram __iomem *p_rx_fw_statistics_pram;
 	u32 rx_fw_statistics_pram_offset;
-	struct ucc_geth_rx_interrupt_coalescing_table *p_rx_irq_coalescing_tbl;
+	struct ucc_geth_rx_interrupt_coalescing_table __iomem *p_rx_irq_coalescing_tbl;
 	u32 rx_irq_coalescing_tbl_offset;
-	struct ucc_geth_rx_bd_queues_entry *p_rx_bd_qs_tbl;
+	struct ucc_geth_rx_bd_queues_entry __iomem *p_rx_bd_qs_tbl;
 	u32 rx_bd_qs_tbl_offset;
-	u8 *p_tx_bd_ring[NUM_TX_QUEUES];
+	u8 __iomem *p_tx_bd_ring[NUM_TX_QUEUES];
 	u32 tx_bd_ring_offset[NUM_TX_QUEUES];
-	u8 *p_rx_bd_ring[NUM_RX_QUEUES];
+	u8 __iomem *p_rx_bd_ring[NUM_RX_QUEUES];
 	u32 rx_bd_ring_offset[NUM_RX_QUEUES];
-	u8 *confBd[NUM_TX_QUEUES];
-	u8 *txBd[NUM_TX_QUEUES];
-	u8 *rxBd[NUM_RX_QUEUES];
+	u8 __iomem *confBd[NUM_TX_QUEUES];
+	u8 __iomem *txBd[NUM_TX_QUEUES];
+	u8 __iomem *rxBd[NUM_RX_QUEUES];
 	int badFrame[NUM_RX_QUEUES];
 	u16 cpucount[NUM_TX_QUEUES];
-	volatile u16 *p_cpucount[NUM_TX_QUEUES];
+	u16 __iomem *p_cpucount[NUM_TX_QUEUES];
 	int indAddrRegUsed[NUM_OF_PADDRS];
 	u8 paddr[NUM_OF_PADDRS][ENET_NUM_OCTETS_PER_ADDRESS];	/* ethernet address */
 	u8 numGroupAddrInHash;
@@ -1251,4 +1251,12 @@ struct ucc_geth_private {
 	int oldlink;
 };
 
+void uec_set_ethtool_ops(struct net_device *netdev);
+int init_flow_control_params(u32 automatic_flow_control_mode,
+		int rx_flow_control_enable, int tx_flow_control_enable,
+		u16 pause_period, u16 extension_field,
+		u32 __iomem *upsmr_register, u32 __iomem *uempr_register,
+		u32 __iomem *maccfg1_register);
+
+
 #endif				/* __UCC_GETH_H__ */
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
index 9a9622c..299b7f1 100644
--- a/drivers/net/ucc_geth_ethtool.c
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -108,12 +108,6 @@ static char rx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
 #define UEC_TX_FW_STATS_LEN ARRAY_SIZE(tx_fw_stat_gstrings)
 #define UEC_RX_FW_STATS_LEN ARRAY_SIZE(rx_fw_stat_gstrings)
 
-extern int init_flow_control_params(u32 automatic_flow_control_mode,
-		int rx_flow_control_enable,
-		int tx_flow_control_enable, u16 pause_period,
-		u16 extension_field, volatile u32 *upsmr_register,
-		volatile u32 *uempr_register, volatile u32 *maccfg1_register);
-
 static int
 uec_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 {
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index 2af4907..9404747 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -104,7 +104,7 @@ int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 }
 
 /* Reset the MIIM registers, and wait for the bus to free */
-int uec_mdio_reset(struct mii_bus *bus)
+static int uec_mdio_reset(struct mii_bus *bus)
 {
 	struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
 	unsigned int timeout = PHY_INIT_TIMEOUT;
@@ -240,7 +240,7 @@ reg_map_fail:
 	return err;
 }
 
-int uec_mdio_remove(struct of_device *ofdev)
+static int uec_mdio_remove(struct of_device *ofdev)
 {
 	struct device *device = &ofdev->dev;
 	struct mii_bus *bus = dev_get_drvdata(device);
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h
index 30e11aa..a15cdd4 100644
--- a/include/linux/mv643xx_eth.h
+++ b/include/linux/mv643xx_eth.h
@@ -1,19 +1,31 @@
 /*
  * MV-643XX ethernet platform device data definition file.
  */
+
 #ifndef __LINUX_MV643XX_ETH_H
 #define __LINUX_MV643XX_ETH_H
 
-#define MV643XX_ETH_SHARED_NAME		"mv643xx_eth_shared"
-#define MV643XX_ETH_NAME		"mv643xx_eth"
+#include <linux/mbus.h>
+
+#define MV643XX_ETH_SHARED_NAME		"mv643xx_eth"
+#define MV643XX_ETH_NAME		"mv643xx_eth_port"
 #define MV643XX_ETH_SHARED_REGS		0x2000
 #define MV643XX_ETH_SHARED_REGS_SIZE	0x2000
 #define MV643XX_ETH_BAR_4		0x2220
 #define MV643XX_ETH_SIZE_REG_4		0x2224
 #define MV643XX_ETH_BASE_ADDR_ENABLE_REG	0x2290
 
+struct mv643xx_eth_shared_platform_data {
+	struct mbus_dram_target_info	*dram;
+	unsigned int	t_clk;
+};
+
 struct mv643xx_eth_platform_data {
+	struct platform_device	*shared;
 	int		port_number;
+
+	struct platform_device	*shared_smi;
+
 	u16		force_phy_addr;	/* force override if phy_addr == 0 */
 	u16		phy_addr;
 
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 02df20f..7224c40 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -412,6 +412,8 @@ int mdiobus_register(struct mii_bus *bus);
 void mdiobus_unregister(struct mii_bus *bus);
 void phy_sanitize_settings(struct phy_device *phydev);
 int phy_stop_interrupts(struct phy_device *phydev);
+int phy_enable_interrupts(struct phy_device *phydev);
+int phy_disable_interrupts(struct phy_device *phydev);
 
 static inline int phy_read_status(struct phy_device *phydev) {
 	return phydev->drv->read_status(phydev);
@@ -447,5 +449,8 @@ int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
 		int (*run)(struct phy_device *));
 int phy_scan_fixups(struct phy_device *phydev);
 
+int __init mdio_bus_init(void);
+void mdio_bus_exit(void);
+
 extern struct bus_type mdio_bus_type;
 #endif /* __PHY_H */

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-04-27  2:53     ` Jeff Garzik
@ 2008-04-27 11:34       ` Ben Hutchings
  0 siblings, 0 replies; 101+ messages in thread
From: Ben Hutchings @ 2008-04-27 11:34 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David Miller, netdev, linux-kernel

Jeff Garzik wrote:
> On Sat, Apr 26, 2008 at 05:43:19PM -0700, David Miller wrote:
> > From: Ben Hutchings <bhutchings@solarflare.com>
> > Date: Sat, 26 Apr 2008 23:07:26 +0100
> > 
> > > Still no sfc driver?  I thought you accepted it a couple of weeks ago.
> > 
> > Jeff, what happened here?
> > 
> > If Ben sent the full driver patch as Jeff asked for it, Jeff
> > should have added it by now. :-/
> 
> I have repeatedly requested the full patch, without receiving it.

You requested it once, and I sent it immediately.  I will re-send
it in a moment; please acknowledge receipt.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-04-27  0:43   ` David Miller
@ 2008-04-27  2:53     ` Jeff Garzik
  2008-04-27 11:34       ` Ben Hutchings
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2008-04-27  2:53 UTC (permalink / raw)
  To: David Miller; +Cc: bhutchings, netdev, linux-kernel

On Sat, Apr 26, 2008 at 05:43:19PM -0700, David Miller wrote:
> From: Ben Hutchings <bhutchings@solarflare.com>
> Date: Sat, 26 Apr 2008 23:07:26 +0100
> 
> > Still no sfc driver?  I thought you accepted it a couple of weeks ago.
> 
> Jeff, what happened here?
> 
> If Ben sent the full driver patch as Jeff asked for it, Jeff
> should have added it by now. :-/

I have repeatedly requested the full patch, without receiving it.  I
have requested the full patch via email, and not a URL to fetch and
reconstruct the patch description and sign-offs.

I searched my spam folder just now, just in case, but no sfc there
either.

We all agree the driver is OK for merging, I continue to wait for the
roll-up patch.

	Jeff




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-04-26 22:07 ` Ben Hutchings
@ 2008-04-27  0:43   ` David Miller
  2008-04-27  2:53     ` Jeff Garzik
  0 siblings, 1 reply; 101+ messages in thread
From: David Miller @ 2008-04-27  0:43 UTC (permalink / raw)
  To: bhutchings; +Cc: jeff, netdev, linux-kernel

From: Ben Hutchings <bhutchings@solarflare.com>
Date: Sat, 26 Apr 2008 23:07:26 +0100

> Still no sfc driver?  I thought you accepted it a couple of weeks ago.

Jeff, what happened here?

If Ben sent the full driver patch as Jeff asked for it, Jeff
should have added it by now. :-/

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-04-25  7:26 Jeff Garzik
  2008-04-25  7:32 ` David Miller
@ 2008-04-26 22:07 ` Ben Hutchings
  2008-04-27  0:43   ` David Miller
  1 sibling, 1 reply; 101+ messages in thread
From: Ben Hutchings @ 2008-04-26 22:07 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David Miller, netdev, LKML

Still no sfc driver?  I thought you accepted it a couple of weeks ago.

Ben.

-- 
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-04-25  7:26 Jeff Garzik
@ 2008-04-25  7:32 ` David Miller
  2008-04-26 22:07 ` Ben Hutchings
  1 sibling, 0 replies; 101+ messages in thread
From: David Miller @ 2008-04-25  7:32 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Fri, 25 Apr 2008 03:26:21 -0400

> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

Pulled, and thanks a lot for fixing the Tehuti ioctl bug.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2008-04-25  7:26 Jeff Garzik
  2008-04-25  7:32 ` David Miller
  2008-04-26 22:07 ` Ben Hutchings
  0 siblings, 2 replies; 101+ messages in thread
From: Jeff Garzik @ 2008-04-25  7:26 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


Please pull from 'upstream-davem' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

to receive the following updates:

 Documentation/networking/phy.txt   |   38 +++-
 drivers/net/arm/at91_ether.c       |    1 +
 drivers/net/arm/ep93xx_eth.c       |    2 +
 drivers/net/atlx/atl1.c            |  138 ++++++++++++
 drivers/net/atlx/atlx.c            |  177 ---------------
 drivers/net/ax88796.c              |    1 +
 drivers/net/bfin_mac.c             |    7 +-
 drivers/net/cpmac.c                |    2 +
 drivers/net/dm9000.c               |    1 +
 drivers/net/e1000e/82571.c         |    6 -
 drivers/net/e1000e/defines.h       |    3 +
 drivers/net/e1000e/e1000.h         |   34 +++-
 drivers/net/e1000e/es2lan.c        |  129 ++++++++---
 drivers/net/e1000e/ethtool.c       |   49 ++++-
 drivers/net/e1000e/hw.h            |   12 +-
 drivers/net/e1000e/netdev.c        |  159 ++++++++-----
 drivers/net/e1000e/phy.c           |   73 ++++---
 drivers/net/ehea/ehea_main.c       |    4 +-
 drivers/net/forcedeth.c            |  432 +++++++++++++++++++++++++++++-------
 drivers/net/gianfar.c              |  104 ++++++---
 drivers/net/ibm_newemac/core.c     |   83 ++++++-
 drivers/net/ibm_newemac/core.h     |   14 +-
 drivers/net/ibm_newemac/mal.c      |   20 ++-
 drivers/net/ibm_newemac/rgmii.c    |    2 +-
 drivers/net/ibm_newemac/tah.c      |    2 +-
 drivers/net/ibm_newemac/zmii.c     |    2 +-
 drivers/net/igb/igb_main.c         |    2 +
 drivers/net/irda/ali-ircc.c        |    2 +
 drivers/net/irda/pxaficp_ir.c      |    2 +
 drivers/net/irda/sa1100_ir.c       |    2 +
 drivers/net/ixgbe/ixgbe_main.c     |    2 +
 drivers/net/jazzsonic.c            |    2 +
 drivers/net/korina.c               |   39 ++--
 drivers/net/macb.c                 |    2 +
 drivers/net/meth.c                 |    2 +
 drivers/net/mv643xx_eth.c          |    5 +-
 drivers/net/netx-eth.c             |    2 +-
 drivers/net/netxen/netxen_nic_hw.c |   15 +-
 drivers/net/phy/mdio_bus.c         |    3 +
 drivers/net/phy/phy.c              |    4 +-
 drivers/net/phy/phy_device.c       |  129 ++++++++++-
 drivers/net/s2io.c                 |  128 +----------
 drivers/net/s2io.h                 |    9 -
 drivers/net/sgiseeq.c              |    4 +-
 drivers/net/smc911x.c              |    8 +-
 drivers/net/smc91x.c               |    2 +
 drivers/net/sni_82596.c            |    2 +
 drivers/net/tehuti.c               |   15 ++
 drivers/net/tsi108_eth.c           |    2 +
 drivers/net/typhoon.c              |    1 -
 drivers/net/ucc_geth.c             |    2 +-
 drivers/net/via-velocity.c         |   46 +++--
 drivers/net/wan/c101.c             |    6 +-
 drivers/net/wan/hdlc_fr.c          |    4 -
 include/linux/phy.h                |   24 ++-
 55 files changed, 1290 insertions(+), 671 deletions(-)

Andrew Morton (1):
      ehea: make things static

Andy Fleming (3):
      ucc_geth: Fix sneaky merge conflict regarding bus_id
      phylib: Add support for board-level PHY fixups
      gianfar: Fix skb allocation strategy

Auke Kok (3):
      e1000e: Add interrupt moderation run-time ethtool interface
      e1000e: lower ring minimum size to 64
      igb: save and restore pcie/msi state to support EEH recovery

Ayaz Abdulla (2):
      forcedeth: new backoff implementation
      forcedeth: realtek phy crossover detection

Benjamin Herrenschmidt (1):
      ibm_newemac: Increase MDIO timeouts

Bruce Allan (1):
      e1000e: cleanup several stats issues

Chris Snook (2):
      atlx: remove flash vendor parameter
      [netdrvr] atlx: code movement: move atl1 parameter parsing

Cédric Augonnet (1):
      Removing dead code in drivers/net/wan/hdlc_fr.c

David Graham (1):
      e1000e: Fix HW Error on es2lan, ARP capture issue by BMC

Francois Romieu (4):
      tehuti: check register size
      korina: fix misplaced return statement
      korina: misc cleanup
      via-velocity: fix vlan receipt

Grant Grundler (1):
      [netdrvr] typhoon: typhoon_resume - remove call to start_queue

Harvey Harrison (1):
      netxen: reduce stack usage of netxen_nic_flash_print

Jeff Garzik (1):
      [netdrvr] tehuti: move ioctl perm check closer to function start

Jesse Brandeburg (1):
      e1000e: Increment version to 0.2.1

Josh Boyer (2):
      ibm_newemac: Fix section mismatch warnings
      ibm_newemac Use status property for unused/unwired EMACs

Kay Sievers (1):
      net drivers: fix platform driver hotplug/coldplug

Krzysztof Halasa (1):
      WAN: Fix confusing insmod error code for C101 too.

Roel Kluin (1):
      smc911x: test after postfix decrement fails in smc911x_{reset,drop_pkt}

Sreenivasa Honnur (4):
      S2io: Fix memory leak during free_tx_buffers
      S2io: Version update for memory leak fix during free_tx_buffers
      S2io: Removed receive buffer replenishment tasklet
      S2io: Removed rx_lock and put_lock

Stefan Roese (2):
      ibm_newemac: Fix problem with jumbo frame support and EMAC V4.patch
      ibm_newemac: Add support for 460EX/GT-type MAL rx-channel handling

Valentine Barshak (2):
      ibm_newemac: PowerPC 440GX EMAC PHY clock workaround
      ibm_newemac: PowerPC 440EP/440GR EMAC PHY clock workaround

Wendy Xiong (2):
      ixgbe: save and restore pcie/msi state to support EEH recovery
      e1000e: save and restore pcie/msi state to support EEH recovery

diff --git a/Documentation/networking/phy.txt b/Documentation/networking/phy.txt
index 0bc95ea..8df6a7b 100644
--- a/Documentation/networking/phy.txt
+++ b/Documentation/networking/phy.txt
@@ -1,7 +1,7 @@
 
 -------
 PHY Abstraction Layer
-(Updated 2006-11-30)
+(Updated 2008-04-08)
 
 Purpose
 
@@ -291,3 +291,39 @@ Writing a PHY driver
  Feel free to look at the Marvell, Cicada, and Davicom drivers in
  drivers/net/phy/ for examples (the lxt and qsemi drivers have
  not been tested as of this writing)
+
+Board Fixups
+
+ Sometimes the specific interaction between the platform and the PHY requires
+ special handling.  For instance, to change where the PHY's clock input is,
+ or to add a delay to account for latency issues in the data path.  In order
+ to support such contingencies, the PHY Layer allows platform code to register
+ fixups to be run when the PHY is brought up (or subsequently reset).
+
+ When the PHY Layer brings up a PHY it checks to see if there are any fixups
+ registered for it, matching based on UID (contained in the PHY device's phy_id
+ field) and the bus identifier (contained in phydev->dev.bus_id).  Both must
+ match, however two constants, PHY_ANY_ID and PHY_ANY_UID, are provided as
+ wildcards for the bus ID and UID, respectively.
+
+ When a match is found, the PHY layer will invoke the run function associated
+ with the fixup.  This function is passed a pointer to the phy_device of
+ interest.  It should therefore only operate on that PHY.
+
+ The platform code can either register the fixup using phy_register_fixup():
+
+	int phy_register_fixup(const char *phy_id,
+		u32 phy_uid, u32 phy_uid_mask,
+		int (*run)(struct phy_device *));
+
+ Or using one of the two stubs, phy_register_fixup_for_uid() and
+ phy_register_fixup_for_id():
+
+ int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
+		int (*run)(struct phy_device *));
+ int phy_register_fixup_for_id(const char *phy_id,
+		int (*run)(struct phy_device *));
+
+ The stubs set one of the two matching criteria, and set the other one to
+ match anything.
+
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 0ae0d83..770226d 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -1246,3 +1246,4 @@ module_exit(at91ether_exit)
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver");
 MODULE_AUTHOR("Andrew Victor");
+MODULE_ALIAS("platform:" DRV_NAME);
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
index 91a6590..ecd8fc6 100644
--- a/drivers/net/arm/ep93xx_eth.c
+++ b/drivers/net/arm/ep93xx_eth.c
@@ -897,6 +897,7 @@ static struct platform_driver ep93xx_eth_driver = {
 	.remove		= ep93xx_eth_remove,
 	.driver		= {
 		.name	= "ep93xx-eth",
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -914,3 +915,4 @@ static void __exit ep93xx_eth_cleanup_module(void)
 module_init(ep93xx_eth_init_module);
 module_exit(ep93xx_eth_cleanup_module);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ep93xx-eth");
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
index 5586fc6..0afe522 100644
--- a/drivers/net/atlx/atl1.c
+++ b/drivers/net/atlx/atl1.c
@@ -91,6 +91,144 @@
 #include "atlx.c"
 
 /*
+ * This is the only thing that needs to be changed to adjust the
+ * maximum number of ports that the driver can manage.
+ */
+#define ATL1_MAX_NIC 4
+
+#define OPTION_UNSET    -1
+#define OPTION_DISABLED 0
+#define OPTION_ENABLED  1
+
+#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET }
+
+/*
+ * Interrupt Moderate Timer in units of 2 us
+ *
+ * Valid Range: 10-65535
+ *
+ * Default Value: 100 (200us)
+ */
+static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
+static int num_int_mod_timer;
+module_param_array_named(int_mod_timer, int_mod_timer, int,
+	&num_int_mod_timer, 0);
+MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
+
+#define DEFAULT_INT_MOD_CNT	100	/* 200us */
+#define MAX_INT_MOD_CNT		65000
+#define MIN_INT_MOD_CNT		50
+
+struct atl1_option {
+	enum { enable_option, range_option, list_option } type;
+	char *name;
+	char *err;
+	int def;
+	union {
+		struct {	/* range_option info */
+			int min;
+			int max;
+		} r;
+		struct {	/* list_option info */
+			int nr;
+			struct atl1_opt_list {
+				int i;
+				char *str;
+			} *p;
+		} l;
+	} arg;
+};
+
+static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
+	struct pci_dev *pdev)
+{
+	if (*value == OPTION_UNSET) {
+		*value = opt->def;
+		return 0;
+	}
+
+	switch (opt->type) {
+	case enable_option:
+		switch (*value) {
+		case OPTION_ENABLED:
+			dev_info(&pdev->dev, "%s enabled\n", opt->name);
+			return 0;
+		case OPTION_DISABLED:
+			dev_info(&pdev->dev, "%s disabled\n", opt->name);
+			return 0;
+		}
+		break;
+	case range_option:
+		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
+			dev_info(&pdev->dev, "%s set to %i\n", opt->name,
+				*value);
+			return 0;
+		}
+		break;
+	case list_option:{
+			int i;
+			struct atl1_opt_list *ent;
+
+			for (i = 0; i < opt->arg.l.nr; i++) {
+				ent = &opt->arg.l.p[i];
+				if (*value == ent->i) {
+					if (ent->str[0] != '\0')
+						dev_info(&pdev->dev, "%s\n",
+							ent->str);
+					return 0;
+				}
+			}
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
+		opt->name, *value, opt->err);
+	*value = opt->def;
+	return -1;
+}
+
+/*
+ * atl1_check_options - Range Checking for Command Line Parameters
+ * @adapter: board private structure
+ *
+ * This routine checks all command line parameters for valid user
+ * input.  If an invalid value is given, or if no user specified
+ * value exists, a default value is used.  The final value is stored
+ * in a variable in the adapter structure.
+ */
+void __devinit atl1_check_options(struct atl1_adapter *adapter)
+{
+	struct pci_dev *pdev = adapter->pdev;
+	int bd = adapter->bd_number;
+	if (bd >= ATL1_MAX_NIC) {
+		dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
+		dev_notice(&pdev->dev, "using defaults for all values\n");
+	}
+	{			/* Interrupt Moderate Timer */
+		struct atl1_option opt = {
+			.type = range_option,
+			.name = "Interrupt Moderator Timer",
+			.err = "using default of "
+				__MODULE_STRING(DEFAULT_INT_MOD_CNT),
+			.def = DEFAULT_INT_MOD_CNT,
+			.arg = {.r = {.min = MIN_INT_MOD_CNT,
+					.max = MAX_INT_MOD_CNT} }
+		};
+		int val;
+		if (num_int_mod_timer > bd) {
+			val = int_mod_timer[bd];
+			atl1_validate_option(&val, &opt, pdev);
+			adapter->imt = (u16) val;
+		} else
+			adapter->imt = (u16) (opt.def);
+	}
+}
+
+/*
  * atl1_pci_tbl - PCI Device ID Table
  */
 static const struct pci_device_id atl1_pci_tbl[] = {
diff --git a/drivers/net/atlx/atlx.c b/drivers/net/atlx/atlx.c
index 4186326..f06b854 100644
--- a/drivers/net/atlx/atlx.c
+++ b/drivers/net/atlx/atlx.c
@@ -253,181 +253,4 @@ static void atlx_restore_vlan(struct atlx_adapter *adapter)
 	atlx_vlan_rx_register(adapter->netdev, adapter->vlgrp);
 }
 
-/*
- * This is the only thing that needs to be changed to adjust the
- * maximum number of ports that the driver can manage.
- */
-#define ATL1_MAX_NIC 4
-
-#define OPTION_UNSET    -1
-#define OPTION_DISABLED 0
-#define OPTION_ENABLED  1
-
-#define ATL1_PARAM_INIT { [0 ... ATL1_MAX_NIC] = OPTION_UNSET }
-
-/*
- * Interrupt Moderate Timer in units of 2 us
- *
- * Valid Range: 10-65535
- *
- * Default Value: 100 (200us)
- */
-static int __devinitdata int_mod_timer[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
-static int num_int_mod_timer;
-module_param_array_named(int_mod_timer, int_mod_timer, int,
-	&num_int_mod_timer, 0);
-MODULE_PARM_DESC(int_mod_timer, "Interrupt moderator timer");
-
-/*
- * flash_vendor
- *
- * Valid Range: 0-2
- *
- * 0 - Atmel
- * 1 - SST
- * 2 - ST
- *
- * Default Value: 0
- */
-static int __devinitdata flash_vendor[ATL1_MAX_NIC+1] = ATL1_PARAM_INIT;
-static int num_flash_vendor;
-module_param_array_named(flash_vendor, flash_vendor, int, &num_flash_vendor, 0);
-MODULE_PARM_DESC(flash_vendor, "SPI flash vendor");
-
-#define DEFAULT_INT_MOD_CNT	100	/* 200us */
-#define MAX_INT_MOD_CNT		65000
-#define MIN_INT_MOD_CNT		50
-
-#define FLASH_VENDOR_DEFAULT	0
-#define FLASH_VENDOR_MIN	0
-#define FLASH_VENDOR_MAX	2
-
-struct atl1_option {
-	enum { enable_option, range_option, list_option } type;
-	char *name;
-	char *err;
-	int def;
-	union {
-		struct {	/* range_option info */
-			int min;
-			int max;
-		} r;
-		struct {	/* list_option info */
-			int nr;
-			struct atl1_opt_list {
-				int i;
-				char *str;
-			} *p;
-		} l;
-	} arg;
-};
-
-static int __devinit atl1_validate_option(int *value, struct atl1_option *opt,
-	struct pci_dev *pdev)
-{
-	if (*value == OPTION_UNSET) {
-		*value = opt->def;
-		return 0;
-	}
-
-	switch (opt->type) {
-	case enable_option:
-		switch (*value) {
-		case OPTION_ENABLED:
-			dev_info(&pdev->dev, "%s enabled\n", opt->name);
-			return 0;
-		case OPTION_DISABLED:
-			dev_info(&pdev->dev, "%s disabled\n", opt->name);
-			return 0;
-		}
-		break;
-	case range_option:
-		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
-			dev_info(&pdev->dev, "%s set to %i\n", opt->name,
-				*value);
-			return 0;
-		}
-		break;
-	case list_option:{
-			int i;
-			struct atl1_opt_list *ent;
-
-			for (i = 0; i < opt->arg.l.nr; i++) {
-				ent = &opt->arg.l.p[i];
-				if (*value == ent->i) {
-					if (ent->str[0] != '\0')
-						dev_info(&pdev->dev, "%s\n",
-							ent->str);
-					return 0;
-				}
-			}
-		}
-		break;
-
-	default:
-		break;
-	}
-
-	dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
-		opt->name, *value, opt->err);
-	*value = opt->def;
-	return -1;
-}
-
-/*
- * atl1_check_options - Range Checking for Command Line Parameters
- * @adapter: board private structure
- *
- * This routine checks all command line parameters for valid user
- * input.  If an invalid value is given, or if no user specified
- * value exists, a default value is used.  The final value is stored
- * in a variable in the adapter structure.
- */
-void __devinit atl1_check_options(struct atl1_adapter *adapter)
-{
-	struct pci_dev *pdev = adapter->pdev;
-	int bd = adapter->bd_number;
-	if (bd >= ATL1_MAX_NIC) {
-		dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
-		dev_notice(&pdev->dev, "using defaults for all values\n");
-	}
-	{			/* Interrupt Moderate Timer */
-		struct atl1_option opt = {
-			.type = range_option,
-			.name = "Interrupt Moderator Timer",
-			.err = "using default of "
-				__MODULE_STRING(DEFAULT_INT_MOD_CNT),
-			.def = DEFAULT_INT_MOD_CNT,
-			.arg = {.r = {.min = MIN_INT_MOD_CNT,
-					.max = MAX_INT_MOD_CNT} }
-		};
-		int val;
-		if (num_int_mod_timer > bd) {
-			val = int_mod_timer[bd];
-			atl1_validate_option(&val, &opt, pdev);
-			adapter->imt = (u16) val;
-		} else
-			adapter->imt = (u16) (opt.def);
-	}
-
-	{			/* Flash Vendor */
-		struct atl1_option opt = {
-			.type = range_option,
-			.name = "SPI Flash Vendor",
-			.err = "using default of "
-				__MODULE_STRING(FLASH_VENDOR_DEFAULT),
-			.def = DEFAULT_INT_MOD_CNT,
-			.arg = {.r = {.min = FLASH_VENDOR_MIN,
-					.max = FLASH_VENDOR_MAX} }
-		};
-		int val;
-		if (num_flash_vendor > bd) {
-			val = flash_vendor[bd];
-			atl1_validate_option(&val, &opt, pdev);
-			adapter->hw.flash_vendor = (u8) val;
-		} else
-			adapter->hw.flash_vendor = (u8) (opt.def);
-	}
-}
-
 #endif /* ATLX_C */
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 194949a..0b4adf4 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -1005,3 +1005,4 @@ module_exit(axdrv_exit);
 MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
 MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:ax88796");
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 717dcc1..4fec858 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -47,6 +47,7 @@
 MODULE_AUTHOR(DRV_AUTHOR);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION(DRV_DESC);
+MODULE_ALIAS("platform:bfin_mac");
 
 #if defined(CONFIG_BFIN_MAC_USE_L1)
 # define bfin_mac_alloc(dma_handle, size)  l1_data_sram_zalloc(size)
@@ -1089,8 +1090,9 @@ static struct platform_driver bfin_mac_driver = {
 	.resume = bfin_mac_resume,
 	.suspend = bfin_mac_suspend,
 	.driver = {
-		   .name = DRV_NAME,
-		   },
+		.name = DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
 };
 
 static int __init bfin_mac_init(void)
@@ -1106,3 +1108,4 @@ static void __exit bfin_mac_cleanup(void)
 }
 
 module_exit(bfin_mac_cleanup);
+
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 9da7ff4..2b5740b 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -42,6 +42,7 @@
 MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>");
 MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:cpmac");
 
 static int debug_level = 8;
 static int dumb_switch;
@@ -1103,6 +1104,7 @@ static int __devexit cpmac_remove(struct platform_device *pdev)
 
 static struct platform_driver cpmac_driver = {
 	.driver.name = "cpmac",
+	.driver.owner = THIS_MODULE,
 	.probe = cpmac_probe,
 	.remove = __devexit_p(cpmac_remove),
 };
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index d63cc93..e6fe261 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1418,3 +1418,4 @@ module_exit(dm9000_cleanup);
 MODULE_AUTHOR("Sascha Hauer, Ben Dooks");
 MODULE_DESCRIPTION("Davicom DM9000 network driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:dm9000");
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 01c8866..462351c 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -1326,12 +1326,10 @@ struct e1000_info e1000_82571_info = {
 	.mac			= e1000_82571,
 	.flags			= FLAG_HAS_HW_VLAN_FILTER
 				  | FLAG_HAS_JUMBO_FRAMES
-				  | FLAG_HAS_STATS_PTC_PRC
 				  | FLAG_HAS_WOL
 				  | FLAG_APME_IN_CTRL3
 				  | FLAG_RX_CSUM_ENABLED
 				  | FLAG_HAS_CTRLEXT_ON_LOAD
-				  | FLAG_HAS_STATS_ICR_ICT
 				  | FLAG_HAS_SMART_POWER_DOWN
 				  | FLAG_RESET_OVERWRITES_LAA /* errata */
 				  | FLAG_TARC_SPEED_MODE_BIT /* errata */
@@ -1347,12 +1345,10 @@ struct e1000_info e1000_82572_info = {
 	.mac			= e1000_82572,
 	.flags			= FLAG_HAS_HW_VLAN_FILTER
 				  | FLAG_HAS_JUMBO_FRAMES
-				  | FLAG_HAS_STATS_PTC_PRC
 				  | FLAG_HAS_WOL
 				  | FLAG_APME_IN_CTRL3
 				  | FLAG_RX_CSUM_ENABLED
 				  | FLAG_HAS_CTRLEXT_ON_LOAD
-				  | FLAG_HAS_STATS_ICR_ICT
 				  | FLAG_TARC_SPEED_MODE_BIT, /* errata */
 	.pba			= 38,
 	.get_variants		= e1000_get_variants_82571,
@@ -1365,11 +1361,9 @@ struct e1000_info e1000_82573_info = {
 	.mac			= e1000_82573,
 	.flags			= FLAG_HAS_HW_VLAN_FILTER
 				  | FLAG_HAS_JUMBO_FRAMES
-				  | FLAG_HAS_STATS_PTC_PRC
 				  | FLAG_HAS_WOL
 				  | FLAG_APME_IN_CTRL3
 				  | FLAG_RX_CSUM_ENABLED
-				  | FLAG_HAS_STATS_ICR_ICT
 				  | FLAG_HAS_SMART_POWER_DOWN
 				  | FLAG_HAS_AMT
 				  | FLAG_HAS_ERT
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index 572cfd4..2a53875 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -184,6 +184,7 @@
 #define E1000_SWFW_EEP_SM   0x1
 #define E1000_SWFW_PHY0_SM  0x2
 #define E1000_SWFW_PHY1_SM  0x4
+#define E1000_SWFW_CSR_SM   0x8
 
 /* Device Control */
 #define E1000_CTRL_FD       0x00000001  /* Full duplex.0=half; 1=full */
@@ -527,8 +528,10 @@
 #define PHY_ID2          0x03 /* Phy Id Reg (word 2) */
 #define PHY_AUTONEG_ADV  0x04 /* Autoneg Advertisement */
 #define PHY_LP_ABILITY   0x05 /* Link Partner Ability (Base Page) */
+#define PHY_AUTONEG_EXP  0x06 /* Autoneg Expansion Reg */
 #define PHY_1000T_CTRL   0x09 /* 1000Base-T Control Reg */
 #define PHY_1000T_STATUS 0x0A /* 1000Base-T Status Reg */
+#define PHY_EXT_STATUS   0x0F /* Extended Status Reg */
 
 /* NVM Control */
 #define E1000_EECD_SK        0x00000001 /* NVM Clock */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 5a89dff..38bfd0d 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -64,11 +64,14 @@ struct e1000_info;
 /* Tx/Rx descriptor defines */
 #define E1000_DEFAULT_TXD		256
 #define E1000_MAX_TXD			4096
-#define E1000_MIN_TXD			80
+#define E1000_MIN_TXD			64
 
 #define E1000_DEFAULT_RXD		256
 #define E1000_MAX_RXD			4096
-#define E1000_MIN_RXD			80
+#define E1000_MIN_RXD			64
+
+#define E1000_MIN_ITR_USECS		10 /* 100000 irq/sec */
+#define E1000_MAX_ITR_USECS		10000 /* 100    irq/sec */
 
 /* Early Receive defines */
 #define E1000_ERT_2048			0x100
@@ -147,6 +150,18 @@ struct e1000_ring {
 	struct e1000_queue_stats stats;
 };
 
+/* PHY register snapshot values */
+struct e1000_phy_regs {
+	u16 bmcr;		/* basic mode control register    */
+	u16 bmsr;		/* basic mode status register     */
+	u16 advertise;		/* auto-negotiation advertisement */
+	u16 lpa;		/* link partner ability register  */
+	u16 expansion;		/* auto-negotiation expansion reg */
+	u16 ctrl1000;		/* 1000BASE-T control register    */
+	u16 stat1000;		/* 1000BASE-T status register     */
+	u16 estatus;		/* extended status register       */
+};
+
 /* board specific private data structure */
 struct e1000_adapter {
 	struct timer_list watchdog_timer;
@@ -202,8 +217,8 @@ struct e1000_adapter {
 	/* Tx stats */
 	u64 tpt_old;
 	u64 colc_old;
-	u64 gotcl_old;
-	u32 gotcl;
+	u32 gotc;
+	u64 gotc_old;
 	u32 tx_timeout_count;
 	u32 tx_fifo_head;
 	u32 tx_head_addr;
@@ -227,8 +242,8 @@ struct e1000_adapter {
 	u64 hw_csum_err;
 	u64 hw_csum_good;
 	u64 rx_hdr_split;
-	u64 gorcl_old;
-	u32 gorcl;
+	u32 gorc;
+	u64 gorc_old;
 	u32 alloc_rx_buff_failed;
 	u32 rx_dma_failed;
 
@@ -250,6 +265,9 @@ struct e1000_adapter {
 	struct e1000_phy_info phy_info;
 	struct e1000_phy_stats phy_stats;
 
+	/* Snapshot of PHY registers */
+	struct e1000_phy_regs phy_regs;
+
 	struct e1000_ring test_tx_ring;
 	struct e1000_ring test_rx_ring;
 	u32 test_icr;
@@ -286,8 +304,6 @@ struct e1000_info {
 #define FLAG_HAS_CTRLEXT_ON_LOAD          (1 << 5)
 #define FLAG_HAS_SWSM_ON_LOAD             (1 << 6)
 #define FLAG_HAS_JUMBO_FRAMES             (1 << 7)
-#define FLAG_HAS_STATS_ICR_ICT            (1 << 9)
-#define FLAG_HAS_STATS_PTC_PRC            (1 << 10)
 #define FLAG_HAS_SMART_POWER_DOWN         (1 << 11)
 #define FLAG_IS_QUAD_PORT_A               (1 << 12)
 #define FLAG_IS_QUAD_PORT                 (1 << 13)
@@ -433,6 +449,8 @@ extern s32 e1000e_read_kmrn_reg(struct e1000_hw *hw, u32 offset, u16 *data);
 extern s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
 			       u32 usec_interval, bool *success);
 extern s32 e1000e_phy_reset_dsp(struct e1000_hw *hw);
+extern s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data);
+extern s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data);
 extern s32 e1000e_check_downshift(struct e1000_hw *hw);
 
 static inline s32 e1000_phy_hw_reset(struct e1000_hw *hw)
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index d59a99a..dc552d7 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -41,6 +41,7 @@
 #define E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL	 0x00
 #define E1000_KMRNCTRLSTA_OFFSET_INB_CTRL	 0x02
 #define E1000_KMRNCTRLSTA_OFFSET_HD_CTRL	 0x10
+#define E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE	 0x1F
 
 #define E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS	 0x0008
 #define E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS	 0x0800
@@ -48,6 +49,7 @@
 
 #define E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT 0x0004
 #define E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT	 0x0000
+#define E1000_KMRNCTRLSTA_OPMODE_E_IDLE		 0x2000
 
 #define E1000_TCTL_EXT_GCEX_MASK 0x000FFC00 /* Gigabit Carry Extend Padding */
 #define DEFAULT_TCTL_EXT_GCEX_80003ES2LAN	 0x00010000
@@ -85,6 +87,9 @@
 /* Kumeran Mode Control Register (Page 193, Register 16) */
 #define GG82563_KMCR_PASS_FALSE_CARRIER		 0x0800
 
+/* Max number of times Kumeran read/write should be validated */
+#define GG82563_MAX_KMRN_RETRY  0x5
+
 /* Power Management Control Register (Page 193, Register 20) */
 #define GG82563_PMCR_ENABLE_ELECTRICAL_IDLE	 0x0001
 					   /* 1=Enable SERDES Electrical Idle */
@@ -270,6 +275,7 @@ static s32 e1000_acquire_phy_80003es2lan(struct e1000_hw *hw)
 	u16 mask;
 
 	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
+	mask |= E1000_SWFW_CSR_SM;
 
 	return e1000_acquire_swfw_sync_80003es2lan(hw, mask);
 }
@@ -286,6 +292,8 @@ static void e1000_release_phy_80003es2lan(struct e1000_hw *hw)
 	u16 mask;
 
 	mask = hw->bus.func ? E1000_SWFW_PHY1_SM : E1000_SWFW_PHY0_SM;
+	mask |= E1000_SWFW_CSR_SM;
+
 	e1000_release_swfw_sync_80003es2lan(hw, mask);
 }
 
@@ -410,20 +418,27 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 	u32 page_select;
 	u16 temp;
 
+	ret_val = e1000_acquire_phy_80003es2lan(hw);
+	if (ret_val)
+		return ret_val;
+
 	/* Select Configuration Page */
-	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG)
+	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
 		page_select = GG82563_PHY_PAGE_SELECT;
-	else
+	} else {
 		/*
 		 * Use Alternative Page Select register to access
 		 * registers 30 and 31
 		 */
 		page_select = GG82563_PHY_PAGE_SELECT_ALT;
+	}
 
 	temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT);
-	ret_val = e1000e_write_phy_reg_m88(hw, page_select, temp);
-	if (ret_val)
+	ret_val = e1000e_write_phy_reg_mdic(hw, page_select, temp);
+	if (ret_val) {
+		e1000_release_phy_80003es2lan(hw);
 		return ret_val;
+	}
 
 	/*
 	 * The "ready" bit in the MDIC register may be incorrectly set
@@ -433,20 +448,21 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 	udelay(200);
 
 	/* ...and verify the command was successful. */
-	ret_val = e1000e_read_phy_reg_m88(hw, page_select, &temp);
+	ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
 
 	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
 		ret_val = -E1000_ERR_PHY;
+		e1000_release_phy_80003es2lan(hw);
 		return ret_val;
 	}
 
 	udelay(200);
 
-	ret_val = e1000e_read_phy_reg_m88(hw,
-					 MAX_PHY_REG_ADDRESS & offset,
-					 data);
+	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+					   data);
 
 	udelay(200);
+	e1000_release_phy_80003es2lan(hw);
 
 	return ret_val;
 }
@@ -467,20 +483,27 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 	u32 page_select;
 	u16 temp;
 
+	ret_val = e1000_acquire_phy_80003es2lan(hw);
+	if (ret_val)
+		return ret_val;
+
 	/* Select Configuration Page */
-	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG)
+	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG) {
 		page_select = GG82563_PHY_PAGE_SELECT;
-	else
+	} else {
 		/*
 		 * Use Alternative Page Select register to access
 		 * registers 30 and 31
 		 */
 		page_select = GG82563_PHY_PAGE_SELECT_ALT;
+	}
 
 	temp = (u16)((u16)offset >> GG82563_PAGE_SHIFT);
-	ret_val = e1000e_write_phy_reg_m88(hw, page_select, temp);
-	if (ret_val)
+	ret_val = e1000e_write_phy_reg_mdic(hw, page_select, temp);
+	if (ret_val) {
+		e1000_release_phy_80003es2lan(hw);
 		return ret_val;
+	}
 
 
 	/*
@@ -491,18 +514,20 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 	udelay(200);
 
 	/* ...and verify the command was successful. */
-	ret_val = e1000e_read_phy_reg_m88(hw, page_select, &temp);
+	ret_val = e1000e_read_phy_reg_mdic(hw, page_select, &temp);
 
-	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp)
+	if (((u16)offset >> GG82563_PAGE_SHIFT) != temp) {
+		e1000_release_phy_80003es2lan(hw);
 		return -E1000_ERR_PHY;
+	}
 
 	udelay(200);
 
-	ret_val = e1000e_write_phy_reg_m88(hw,
-					  MAX_PHY_REG_ADDRESS & offset,
-					  data);
+	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+					    data);
 
 	udelay(200);
+	e1000_release_phy_80003es2lan(hw);
 
 	return ret_val;
 }
@@ -882,10 +907,10 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
 	u32 ctrl_ext;
-	u16 data;
+	u32 i = 0;
+	u16 data, data2;
 
-	ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL,
-				     &data);
+	ret_val = e1e_rphy(hw, GG82563_PHY_MAC_SPEC_CTRL, &data);
 	if (ret_val)
 		return ret_val;
 
@@ -893,8 +918,7 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
 	/* Use 25MHz for both link down and 1000Base-T for Tx clock. */
 	data |= GG82563_MSCR_TX_CLK_1000MBPS_25;
 
-	ret_val = e1e_wphy(hw, GG82563_PHY_MAC_SPEC_CTRL,
-				      data);
+	ret_val = e1e_wphy(hw, GG82563_PHY_MAC_SPEC_CTRL, data);
 	if (ret_val)
 		return ret_val;
 
@@ -954,6 +978,18 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
+	ret_val = e1000e_read_kmrn_reg(hw,
+				       E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
+				       &data);
+	if (ret_val)
+		return ret_val;
+	data |= E1000_KMRNCTRLSTA_OPMODE_E_IDLE;
+	ret_val = e1000e_write_kmrn_reg(hw,
+					E1000_KMRNCTRLSTA_OFFSET_MAC2PHY_OPMODE,
+					data);
+	if (ret_val)
+		return ret_val;
+
 	ret_val = e1e_rphy(hw, GG82563_PHY_SPEC_CTRL_2, &data);
 	if (ret_val)
 		return ret_val;
@@ -983,9 +1019,18 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
 		if (ret_val)
 			return ret_val;
 
-		ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &data);
-		if (ret_val)
-			return ret_val;
+		do {
+			ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL,
+					   &data);
+			if (ret_val)
+				return ret_val;
+
+			ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL,
+					   &data2);
+			if (ret_val)
+				return ret_val;
+			i++;
+		} while ((data != data2) && (i < GG82563_MAX_KMRN_RETRY));
 
 		data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
 		ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, data);
@@ -1074,7 +1119,8 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex)
 {
 	s32 ret_val;
 	u32 tipg;
-	u16 reg_data;
+	u32 i = 0;
+	u16 reg_data, reg_data2;
 
 	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT;
 	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
@@ -1088,9 +1134,16 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex)
 	tipg |= DEFAULT_TIPG_IPGT_10_100_80003ES2LAN;
 	ew32(TIPG, tipg);
 
-	ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
-	if (ret_val)
-		return ret_val;
+	do {
+		ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
+		if (ret_val)
+			return ret_val;
+
+		ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data2);
+		if (ret_val)
+			return ret_val;
+		i++;
+	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));
 
 	if (duplex == HALF_DUPLEX)
 		reg_data |= GG82563_KMCR_PASS_FALSE_CARRIER;
@@ -1112,8 +1165,9 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex)
 static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
 {
 	s32 ret_val;
-	u16 reg_data;
+	u16 reg_data, reg_data2;
 	u32 tipg;
+	u32 i = 0;
 
 	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT;
 	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
@@ -1127,9 +1181,16 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
 	tipg |= DEFAULT_TIPG_IPGT_1000_80003ES2LAN;
 	ew32(TIPG, tipg);
 
-	ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
-	if (ret_val)
-		return ret_val;
+	do {
+		ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data);
+		if (ret_val)
+			return ret_val;
+
+		ret_val = e1e_rphy(hw, GG82563_PHY_KMRN_MODE_CTRL, &reg_data2);
+		if (ret_val)
+			return ret_val;
+		i++;
+	} while ((reg_data != reg_data2) && (i < GG82563_MAX_KMRN_RETRY));
 
 	reg_data &= ~GG82563_KMCR_PASS_FALSE_CARRIER;
 	ret_val = e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, reg_data);
@@ -1231,12 +1292,10 @@ struct e1000_info e1000_es2_info = {
 	.mac			= e1000_80003es2lan,
 	.flags			= FLAG_HAS_HW_VLAN_FILTER
 				  | FLAG_HAS_JUMBO_FRAMES
-				  | FLAG_HAS_STATS_PTC_PRC
 				  | FLAG_HAS_WOL
 				  | FLAG_APME_IN_CTRL3
 				  | FLAG_RX_CSUM_ENABLED
 				  | FLAG_HAS_CTRLEXT_ON_LOAD
-				  | FLAG_HAS_STATS_ICR_ICT
 				  | FLAG_RX_NEEDS_RESTART /* errata */
 				  | FLAG_TARC_SET_BIT_ZERO /* errata */
 				  | FLAG_APME_CHECK_PORT_B
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 6d1b257..ce045ac 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -46,8 +46,8 @@ struct e1000_stats {
 static const struct e1000_stats e1000_gstrings_stats[] = {
 	{ "rx_packets", E1000_STAT(stats.gprc) },
 	{ "tx_packets", E1000_STAT(stats.gptc) },
-	{ "rx_bytes", E1000_STAT(stats.gorcl) },
-	{ "tx_bytes", E1000_STAT(stats.gotcl) },
+	{ "rx_bytes", E1000_STAT(stats.gorc) },
+	{ "tx_bytes", E1000_STAT(stats.gotc) },
 	{ "rx_broadcast", E1000_STAT(stats.bprc) },
 	{ "tx_broadcast", E1000_STAT(stats.bptc) },
 	{ "rx_multicast", E1000_STAT(stats.mprc) },
@@ -83,7 +83,7 @@ static const struct e1000_stats e1000_gstrings_stats[] = {
 	{ "rx_flow_control_xoff", E1000_STAT(stats.xoffrxc) },
 	{ "tx_flow_control_xon", E1000_STAT(stats.xontxc) },
 	{ "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
-	{ "rx_long_byte_count", E1000_STAT(stats.gorcl) },
+	{ "rx_long_byte_count", E1000_STAT(stats.gorc) },
 	{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
 	{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
 	{ "rx_header_split", E1000_STAT(rx_hdr_split) },
@@ -1770,6 +1770,47 @@ static int e1000_phys_id(struct net_device *netdev, u32 data)
 	return 0;
 }
 
+static int e1000_get_coalesce(struct net_device *netdev,
+			      struct ethtool_coalesce *ec)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+
+	if (adapter->itr_setting <= 3)
+		ec->rx_coalesce_usecs = adapter->itr_setting;
+	else
+		ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
+
+	return 0;
+}
+
+static int e1000_set_coalesce(struct net_device *netdev,
+			      struct ethtool_coalesce *ec)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_hw *hw = &adapter->hw;
+
+	if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) ||
+	    ((ec->rx_coalesce_usecs > 3) &&
+	     (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) ||
+	    (ec->rx_coalesce_usecs == 2))
+		return -EINVAL;
+
+	if (ec->rx_coalesce_usecs <= 3) {
+		adapter->itr = 20000;
+		adapter->itr_setting = ec->rx_coalesce_usecs;
+	} else {
+		adapter->itr = (1000000 / ec->rx_coalesce_usecs);
+		adapter->itr_setting = adapter->itr & ~3;
+	}
+
+	if (adapter->itr_setting != 0)
+		ew32(ITR, 1000000000 / (adapter->itr * 256));
+	else
+		ew32(ITR, 0);
+
+	return 0;
+}
+
 static int e1000_nway_reset(struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
@@ -1845,6 +1886,8 @@ static const struct ethtool_ops e1000_ethtool_ops = {
 	.phys_id		= e1000_phys_id,
 	.get_ethtool_stats	= e1000_get_ethtool_stats,
 	.get_sset_count		= e1000e_get_sset_count,
+	.get_coalesce		= e1000_get_coalesce,
+	.set_coalesce		= e1000_set_coalesce,
 };
 
 void e1000e_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 53f1ac6..a930e6d 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -592,10 +592,8 @@ struct e1000_hw_stats {
 	u64 bprc;
 	u64 mprc;
 	u64 gptc;
-	u64 gorcl;
-	u64 gorch;
-	u64 gotcl;
-	u64 gotch;
+	u64 gorc;
+	u64 gotc;
 	u64 rnbc;
 	u64 ruc;
 	u64 rfc;
@@ -604,10 +602,8 @@ struct e1000_hw_stats {
 	u64 mgprc;
 	u64 mgpdc;
 	u64 mgptc;
-	u64 torl;
-	u64 torh;
-	u64 totl;
-	u64 toth;
+	u64 tor;
+	u64 tot;
 	u64 tpr;
 	u64 tpt;
 	u64 ptc64;
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index c8dc47f..8991ab8 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -46,7 +46,7 @@
 
 #include "e1000.h"
 
-#define DRV_VERSION "0.2.0"
+#define DRV_VERSION "0.2.1"
 char e1000e_driver_name[] = "e1000e";
 const char e1000e_driver_version[] = DRV_VERSION;
 
@@ -466,10 +466,10 @@ next_desc:
 	if (cleaned_count)
 		adapter->alloc_rx_buf(adapter, cleaned_count);
 
-	adapter->total_rx_packets += total_rx_packets;
 	adapter->total_rx_bytes += total_rx_bytes;
-	adapter->net_stats.rx_packets += total_rx_packets;
+	adapter->total_rx_packets += total_rx_packets;
 	adapter->net_stats.rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
 	return cleaned;
 }
 
@@ -606,8 +606,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 	}
 	adapter->total_tx_bytes += total_tx_bytes;
 	adapter->total_tx_packets += total_tx_packets;
-	adapter->net_stats.tx_packets += total_tx_packets;
 	adapter->net_stats.tx_bytes += total_tx_bytes;
+	adapter->net_stats.tx_packets += total_tx_packets;
 	return cleaned;
 }
 
@@ -775,10 +775,10 @@ next_desc:
 	if (cleaned_count)
 		adapter->alloc_rx_buf(adapter, cleaned_count);
 
-	adapter->total_rx_packets += total_rx_packets;
 	adapter->total_rx_bytes += total_rx_bytes;
-	adapter->net_stats.rx_packets += total_rx_packets;
+	adapter->total_rx_packets += total_rx_packets;
 	adapter->net_stats.rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
 	return cleaned;
 }
 
@@ -2506,56 +2506,27 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 
 	adapter->stats.crcerrs += er32(CRCERRS);
 	adapter->stats.gprc += er32(GPRC);
-	adapter->stats.gorcl += er32(GORCL);
-	adapter->stats.gorch += er32(GORCH);
+	adapter->stats.gorc += er32(GORCL);
+	er32(GORCH); /* Clear gorc */
 	adapter->stats.bprc += er32(BPRC);
 	adapter->stats.mprc += er32(MPRC);
 	adapter->stats.roc += er32(ROC);
 
-	if (adapter->flags & FLAG_HAS_STATS_PTC_PRC) {
-		adapter->stats.prc64 += er32(PRC64);
-		adapter->stats.prc127 += er32(PRC127);
-		adapter->stats.prc255 += er32(PRC255);
-		adapter->stats.prc511 += er32(PRC511);
-		adapter->stats.prc1023 += er32(PRC1023);
-		adapter->stats.prc1522 += er32(PRC1522);
-		adapter->stats.symerrs += er32(SYMERRS);
-		adapter->stats.sec += er32(SEC);
-	}
-
 	adapter->stats.mpc += er32(MPC);
 	adapter->stats.scc += er32(SCC);
 	adapter->stats.ecol += er32(ECOL);
 	adapter->stats.mcc += er32(MCC);
 	adapter->stats.latecol += er32(LATECOL);
 	adapter->stats.dc += er32(DC);
-	adapter->stats.rlec += er32(RLEC);
 	adapter->stats.xonrxc += er32(XONRXC);
 	adapter->stats.xontxc += er32(XONTXC);
 	adapter->stats.xoffrxc += er32(XOFFRXC);
 	adapter->stats.xofftxc += er32(XOFFTXC);
-	adapter->stats.fcruc += er32(FCRUC);
 	adapter->stats.gptc += er32(GPTC);
-	adapter->stats.gotcl += er32(GOTCL);
-	adapter->stats.gotch += er32(GOTCH);
+	adapter->stats.gotc += er32(GOTCL);
+	er32(GOTCH); /* Clear gotc */
 	adapter->stats.rnbc += er32(RNBC);
 	adapter->stats.ruc += er32(RUC);
-	adapter->stats.rfc += er32(RFC);
-	adapter->stats.rjc += er32(RJC);
-	adapter->stats.torl += er32(TORL);
-	adapter->stats.torh += er32(TORH);
-	adapter->stats.totl += er32(TOTL);
-	adapter->stats.toth += er32(TOTH);
-	adapter->stats.tpr += er32(TPR);
-
-	if (adapter->flags & FLAG_HAS_STATS_PTC_PRC) {
-		adapter->stats.ptc64 += er32(PTC64);
-		adapter->stats.ptc127 += er32(PTC127);
-		adapter->stats.ptc255 += er32(PTC255);
-		adapter->stats.ptc511 += er32(PTC511);
-		adapter->stats.ptc1023 += er32(PTC1023);
-		adapter->stats.ptc1522 += er32(PTC1522);
-	}
 
 	adapter->stats.mptc += er32(MPTC);
 	adapter->stats.bptc += er32(BPTC);
@@ -2574,19 +2545,6 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 	adapter->stats.tsctc += er32(TSCTC);
 	adapter->stats.tsctfc += er32(TSCTFC);
 
-	adapter->stats.iac += er32(IAC);
-
-	if (adapter->flags & FLAG_HAS_STATS_ICR_ICT) {
-		adapter->stats.icrxoc += er32(ICRXOC);
-		adapter->stats.icrxptc += er32(ICRXPTC);
-		adapter->stats.icrxatc += er32(ICRXATC);
-		adapter->stats.ictxptc += er32(ICTXPTC);
-		adapter->stats.ictxatc += er32(ICTXATC);
-		adapter->stats.ictxqec += er32(ICTXQEC);
-		adapter->stats.ictxqmtc += er32(ICTXQMTC);
-		adapter->stats.icrxdmtc += er32(ICRXDMTC);
-	}
-
 	/* Fill out the OS statistics structure */
 	adapter->net_stats.multicast = adapter->stats.mprc;
 	adapter->net_stats.collisions = adapter->stats.colc;
@@ -2633,6 +2591,54 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 	spin_unlock_irqrestore(&adapter->stats_lock, irq_flags);
 }
 
+/**
+ * e1000_phy_read_status - Update the PHY register status snapshot
+ * @adapter: board private structure
+ **/
+static void e1000_phy_read_status(struct e1000_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	struct e1000_phy_regs *phy = &adapter->phy_regs;
+	int ret_val;
+	unsigned long irq_flags;
+
+
+	spin_lock_irqsave(&adapter->stats_lock, irq_flags);
+
+	if ((er32(STATUS) & E1000_STATUS_LU) &&
+	    (adapter->hw.phy.media_type == e1000_media_type_copper)) {
+		ret_val  = e1e_rphy(hw, PHY_CONTROL, &phy->bmcr);
+		ret_val |= e1e_rphy(hw, PHY_STATUS, &phy->bmsr);
+		ret_val |= e1e_rphy(hw, PHY_AUTONEG_ADV, &phy->advertise);
+		ret_val |= e1e_rphy(hw, PHY_LP_ABILITY, &phy->lpa);
+		ret_val |= e1e_rphy(hw, PHY_AUTONEG_EXP, &phy->expansion);
+		ret_val |= e1e_rphy(hw, PHY_1000T_CTRL, &phy->ctrl1000);
+		ret_val |= e1e_rphy(hw, PHY_1000T_STATUS, &phy->stat1000);
+		ret_val |= e1e_rphy(hw, PHY_EXT_STATUS, &phy->estatus);
+		if (ret_val)
+			ndev_warn(adapter->netdev,
+				  "Error reading PHY register\n");
+	} else {
+		/*
+		 * Do not read PHY registers if link is not up
+		 * Set values to typical power-on defaults
+		 */
+		phy->bmcr = (BMCR_SPEED1000 | BMCR_ANENABLE | BMCR_FULLDPLX);
+		phy->bmsr = (BMSR_100FULL | BMSR_100HALF | BMSR_10FULL |
+			     BMSR_10HALF | BMSR_ESTATEN | BMSR_ANEGCAPABLE |
+			     BMSR_ERCAP);
+		phy->advertise = (ADVERTISE_PAUSE_ASYM | ADVERTISE_PAUSE_CAP |
+				  ADVERTISE_ALL | ADVERTISE_CSMA);
+		phy->lpa = 0;
+		phy->expansion = EXPANSION_ENABLENPAGE;
+		phy->ctrl1000 = ADVERTISE_1000FULL;
+		phy->stat1000 = 0;
+		phy->estatus = (ESTATUS_1000_TFULL | ESTATUS_1000_THALF);
+	}
+
+	spin_unlock_irqrestore(&adapter->stats_lock, irq_flags);
+}
+
 static void e1000_print_link_info(struct e1000_adapter *adapter)
 {
 	struct e1000_hw *hw = &adapter->hw;
@@ -2745,6 +2751,7 @@ static void e1000_watchdog_task(struct work_struct *work)
 		if (!netif_carrier_ok(netdev)) {
 			bool txb2b = 1;
 			/* update snapshot of PHY registers on LSC */
+			e1000_phy_read_status(adapter);
 			mac->ops.get_link_up_info(&adapter->hw,
 						   &adapter->link_speed,
 						   &adapter->link_duplex);
@@ -2842,10 +2849,10 @@ link_up:
 	mac->collision_delta = adapter->stats.colc - adapter->colc_old;
 	adapter->colc_old = adapter->stats.colc;
 
-	adapter->gorcl = adapter->stats.gorcl - adapter->gorcl_old;
-	adapter->gorcl_old = adapter->stats.gorcl;
-	adapter->gotcl = adapter->stats.gotcl - adapter->gotcl_old;
-	adapter->gotcl_old = adapter->stats.gotcl;
+	adapter->gorc = adapter->stats.gorc - adapter->gorc_old;
+	adapter->gorc_old = adapter->stats.gorc;
+	adapter->gotc = adapter->stats.gotc - adapter->gotc_old;
+	adapter->gotc_old = adapter->stats.gotc;
 
 	e1000e_update_adaptive(&adapter->hw);
 
@@ -3500,7 +3507,6 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct mii_ioctl_data *data = if_mii(ifr);
-	unsigned long irq_flags;
 
 	if (adapter->hw.phy.media_type != e1000_media_type_copper)
 		return -EOPNOTSUPP;
@@ -3512,13 +3518,40 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 	case SIOCGMIIREG:
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
-		spin_lock_irqsave(&adapter->stats_lock, irq_flags);
-		if (e1e_rphy(&adapter->hw, data->reg_num & 0x1F,
-				   &data->val_out)) {
-			spin_unlock_irqrestore(&adapter->stats_lock, irq_flags);
+		switch (data->reg_num & 0x1F) {
+		case MII_BMCR:
+			data->val_out = adapter->phy_regs.bmcr;
+			break;
+		case MII_BMSR:
+			data->val_out = adapter->phy_regs.bmsr;
+			break;
+		case MII_PHYSID1:
+			data->val_out = (adapter->hw.phy.id >> 16);
+			break;
+		case MII_PHYSID2:
+			data->val_out = (adapter->hw.phy.id & 0xFFFF);
+			break;
+		case MII_ADVERTISE:
+			data->val_out = adapter->phy_regs.advertise;
+			break;
+		case MII_LPA:
+			data->val_out = adapter->phy_regs.lpa;
+			break;
+		case MII_EXPANSION:
+			data->val_out = adapter->phy_regs.expansion;
+			break;
+		case MII_CTRL1000:
+			data->val_out = adapter->phy_regs.ctrl1000;
+			break;
+		case MII_STAT1000:
+			data->val_out = adapter->phy_regs.stat1000;
+			break;
+		case MII_ESTATUS:
+			data->val_out = adapter->phy_regs.estatus;
+			break;
+		default:
 			return -EIO;
 		}
-		spin_unlock_irqrestore(&adapter->stats_lock, irq_flags);
 		break;
 	case SIOCSMIIREG:
 	default:
@@ -3774,6 +3807,7 @@ static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev)
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 	pci_set_master(pdev);
+	pci_restore_state(pdev);
 
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 	pci_enable_wake(pdev, PCI_D3cold, 0);
@@ -3900,6 +3934,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 		goto err_pci_reg;
 
 	pci_set_master(pdev);
+	pci_save_state(pdev);
 
 	err = -ENOMEM;
 	netdev = alloc_etherdev(sizeof(struct e1000_adapter));
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index 3a4574c..e102332 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -116,7 +116,7 @@ s32 e1000e_phy_reset_dsp(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_read_phy_reg_mdic - Read MDI control register
+ *  e1000e_read_phy_reg_mdic - Read MDI control register
  *  @hw: pointer to the HW structure
  *  @offset: register offset to be read
  *  @data: pointer to the read data
@@ -124,7 +124,7 @@ s32 e1000e_phy_reset_dsp(struct e1000_hw *hw)
  *  Reads the MDI control register in the PHY at offset and stores the
  *  information read to data.
  **/
-static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
+s32 e1000e_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	u32 i, mdic = 0;
@@ -150,7 +150,7 @@ static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
 	 * Increasing the time out as testing showed failures with
 	 * the lower time out
 	 */
-	for (i = 0; i < 64; i++) {
+	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
 		udelay(50);
 		mdic = er32(MDIC);
 		if (mdic & E1000_MDIC_READY)
@@ -170,14 +170,14 @@ static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
 }
 
 /**
- *  e1000_write_phy_reg_mdic - Write MDI control register
+ *  e1000e_write_phy_reg_mdic - Write MDI control register
  *  @hw: pointer to the HW structure
  *  @offset: register offset to write to
  *  @data: data to write to register at offset
  *
  *  Writes data to MDI control register in the PHY at offset.
  **/
-static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
+s32 e1000e_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
 {
 	struct e1000_phy_info *phy = &hw->phy;
 	u32 i, mdic = 0;
@@ -199,9 +199,13 @@ static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
 
 	ew32(MDIC, mdic);
 
-	/* Poll the ready bit to see if the MDI read completed */
-	for (i = 0; i < E1000_GEN_POLL_TIMEOUT; i++) {
-		udelay(5);
+	/*
+	 * Poll the ready bit to see if the MDI read completed
+	 * Increasing the time out as testing showed failures with
+	 * the lower time out
+	 */
+	for (i = 0; i < (E1000_GEN_POLL_TIMEOUT * 3); i++) {
+		udelay(50);
 		mdic = er32(MDIC);
 		if (mdic & E1000_MDIC_READY)
 			break;
@@ -210,6 +214,10 @@ static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
 		hw_dbg(hw, "MDI Write did not complete\n");
 		return -E1000_ERR_PHY;
 	}
+	if (mdic & E1000_MDIC_ERROR) {
+		hw_dbg(hw, "MDI Error\n");
+		return -E1000_ERR_PHY;
+	}
 
 	return 0;
 }
@@ -232,9 +240,8 @@ s32 e1000e_read_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 *data)
 	if (ret_val)
 		return ret_val;
 
-	ret_val = e1000_read_phy_reg_mdic(hw,
-					  MAX_PHY_REG_ADDRESS & offset,
-					  data);
+	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+					   data);
 
 	hw->phy.ops.release_phy(hw);
 
@@ -258,9 +265,8 @@ s32 e1000e_write_phy_reg_m88(struct e1000_hw *hw, u32 offset, u16 data)
 	if (ret_val)
 		return ret_val;
 
-	ret_val = e1000_write_phy_reg_mdic(hw,
-					   MAX_PHY_REG_ADDRESS & offset,
-					   data);
+	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+					    data);
 
 	hw->phy.ops.release_phy(hw);
 
@@ -286,18 +292,17 @@ s32 e1000e_read_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 *data)
 		return ret_val;
 
 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
-		ret_val = e1000_write_phy_reg_mdic(hw,
-						   IGP01E1000_PHY_PAGE_SELECT,
-						   (u16)offset);
+		ret_val = e1000e_write_phy_reg_mdic(hw,
+						    IGP01E1000_PHY_PAGE_SELECT,
+						    (u16)offset);
 		if (ret_val) {
 			hw->phy.ops.release_phy(hw);
 			return ret_val;
 		}
 	}
 
-	ret_val = e1000_read_phy_reg_mdic(hw,
-					  MAX_PHY_REG_ADDRESS & offset,
-					  data);
+	ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+					   data);
 
 	hw->phy.ops.release_phy(hw);
 
@@ -322,18 +327,17 @@ s32 e1000e_write_phy_reg_igp(struct e1000_hw *hw, u32 offset, u16 data)
 		return ret_val;
 
 	if (offset > MAX_PHY_MULTI_PAGE_REG) {
-		ret_val = e1000_write_phy_reg_mdic(hw,
-						   IGP01E1000_PHY_PAGE_SELECT,
-						   (u16)offset);
+		ret_val = e1000e_write_phy_reg_mdic(hw,
+						    IGP01E1000_PHY_PAGE_SELECT,
+						    (u16)offset);
 		if (ret_val) {
 			hw->phy.ops.release_phy(hw);
 			return ret_val;
 		}
 	}
 
-	ret_val = e1000_write_phy_reg_mdic(hw,
-					   MAX_PHY_REG_ADDRESS & offset,
-					   data);
+	ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & offset,
+					    data);
 
 	hw->phy.ops.release_phy(hw);
 
@@ -420,7 +424,9 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
+	/* For newer PHYs this bit is downshift enable */
+	if (phy->type == e1000_phy_m88)
+		phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
 
 	/*
 	 * Options:
@@ -463,7 +469,7 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	if (phy->revision < 4) {
+	if ((phy->type == e1000_phy_m88) && (phy->revision < 4)) {
 		/*
 		 * Force TX_CLK in the Extended PHY Specific Control Register
 		 * to 25MHz clock.
@@ -518,8 +524,11 @@ s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw)
 		return ret_val;
 	}
 
-	/* Wait 15ms for MAC to configure PHY from NVM settings. */
-	msleep(15);
+	/*
+	 * Wait 100ms for MAC to configure PHY from NVM settings, to avoid
+	 * timeout issues when LFS is enabled.
+	 */
+	msleep(100);
 
 	/* disable lplu d0 during driver init */
 	ret_val = e1000_set_d0_lplu_state(hw, 0);
@@ -1152,9 +1161,7 @@ s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active)
 
 	if (!active) {
 		data &= ~IGP02E1000_PM_D3_LPLU;
-		ret_val = e1e_wphy(hw,
-					     IGP02E1000_PHY_POWER_MGMT,
-					     data);
+		ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
 		if (ret_val)
 			return ret_val;
 		/*
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 9ff7538..f9bc21c 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2611,7 +2611,7 @@ static int ehea_stop(struct net_device *dev)
 	return ret;
 }
 
-void ehea_purge_sq(struct ehea_qp *orig_qp)
+static void ehea_purge_sq(struct ehea_qp *orig_qp)
 {
 	struct ehea_qp qp = *orig_qp;
 	struct ehea_qp_init_attr *init_attr = &qp.init_attr;
@@ -2625,7 +2625,7 @@ void ehea_purge_sq(struct ehea_qp *orig_qp)
 	}
 }
 
-void ehea_flush_sq(struct ehea_port *port)
+static void ehea_flush_sq(struct ehea_port *port)
 {
 	int i;
 
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 8c4214b..35f66d4 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -96,6 +96,7 @@
 #define DEV_HAS_PAUSEFRAME_TX_V2   0x10000  /* device supports tx pause frames version 2 */
 #define DEV_HAS_PAUSEFRAME_TX_V3   0x20000  /* device supports tx pause frames version 3 */
 #define DEV_NEED_TX_LIMIT          0x40000  /* device needs to limit tx */
+#define DEV_HAS_GEAR_MODE          0x80000  /* device supports gear mode */
 
 enum {
 	NvRegIrqStatus = 0x000,
@@ -174,11 +175,13 @@ enum {
 	NvRegReceiverStatus = 0x98,
 #define NVREG_RCVSTAT_BUSY	0x01
 
-	NvRegRandomSeed = 0x9c,
-#define NVREG_RNDSEED_MASK	0x00ff
-#define NVREG_RNDSEED_FORCE	0x7f00
-#define NVREG_RNDSEED_FORCE2	0x2d00
-#define NVREG_RNDSEED_FORCE3	0x7400
+	NvRegSlotTime = 0x9c,
+#define NVREG_SLOTTIME_LEGBF_ENABLED	0x80000000
+#define NVREG_SLOTTIME_10_100_FULL	0x00007f00
+#define NVREG_SLOTTIME_1000_FULL 	0x0003ff00
+#define NVREG_SLOTTIME_HALF		0x0000ff00
+#define NVREG_SLOTTIME_DEFAULT	 	0x00007f00
+#define NVREG_SLOTTIME_MASK		0x000000ff
 
 	NvRegTxDeferral = 0xA0,
 #define NVREG_TX_DEFERRAL_DEFAULT		0x15050f
@@ -201,6 +204,11 @@ enum {
 
 	NvRegPhyInterface = 0xC0,
 #define PHY_RGMII		0x10000000
+	NvRegBackOffControl = 0xC4,
+#define NVREG_BKOFFCTRL_DEFAULT			0x70000000
+#define NVREG_BKOFFCTRL_SEED_MASK		0x000003ff
+#define NVREG_BKOFFCTRL_SELECT			24
+#define NVREG_BKOFFCTRL_GEAR			12
 
 	NvRegTxRingPhysAddr = 0x100,
 	NvRegRxRingPhysAddr = 0x104,
@@ -352,6 +360,7 @@ union ring_type {
 
 #define NV_TX_LASTPACKET	(1<<16)
 #define NV_TX_RETRYERROR	(1<<19)
+#define NV_TX_RETRYCOUNT_MASK	(0xF<<20)
 #define NV_TX_FORCED_INTERRUPT	(1<<24)
 #define NV_TX_DEFERRED		(1<<26)
 #define NV_TX_CARRIERLOST	(1<<27)
@@ -362,6 +371,7 @@ union ring_type {
 
 #define NV_TX2_LASTPACKET	(1<<29)
 #define NV_TX2_RETRYERROR	(1<<18)
+#define NV_TX2_RETRYCOUNT_MASK	(0xF<<19)
 #define NV_TX2_FORCED_INTERRUPT	(1<<30)
 #define NV_TX2_DEFERRED		(1<<25)
 #define NV_TX2_CARRIERLOST	(1<<26)
@@ -473,16 +483,22 @@ union ring_type {
 #define DESC_VER_3	3
 
 /* PHY defines */
-#define PHY_OUI_MARVELL	0x5043
-#define PHY_OUI_CICADA	0x03f1
-#define PHY_OUI_VITESSE	0x01c1
-#define PHY_OUI_REALTEK	0x0732
+#define PHY_OUI_MARVELL		0x5043
+#define PHY_OUI_CICADA		0x03f1
+#define PHY_OUI_VITESSE		0x01c1
+#define PHY_OUI_REALTEK		0x0732
+#define PHY_OUI_REALTEK2	0x0020
 #define PHYID1_OUI_MASK	0x03ff
 #define PHYID1_OUI_SHFT	6
 #define PHYID2_OUI_MASK	0xfc00
 #define PHYID2_OUI_SHFT	10
 #define PHYID2_MODEL_MASK		0x03f0
-#define PHY_MODEL_MARVELL_E3016		0x220
+#define PHY_MODEL_REALTEK_8211		0x0110
+#define PHY_REV_MASK			0x0001
+#define PHY_REV_REALTEK_8211B		0x0000
+#define PHY_REV_REALTEK_8211C		0x0001
+#define PHY_MODEL_REALTEK_8201		0x0200
+#define PHY_MODEL_MARVELL_E3016		0x0220
 #define PHY_MARVELL_E3016_INITMASK	0x0300
 #define PHY_CICADA_INIT1	0x0f000
 #define PHY_CICADA_INIT2	0x0e00
@@ -509,10 +525,18 @@ union ring_type {
 #define PHY_REALTEK_INIT_REG1	0x1f
 #define PHY_REALTEK_INIT_REG2	0x19
 #define PHY_REALTEK_INIT_REG3	0x13
+#define PHY_REALTEK_INIT_REG4	0x14
+#define PHY_REALTEK_INIT_REG5	0x18
+#define PHY_REALTEK_INIT_REG6	0x11
 #define PHY_REALTEK_INIT1	0x0000
 #define PHY_REALTEK_INIT2	0x8e00
 #define PHY_REALTEK_INIT3	0x0001
 #define PHY_REALTEK_INIT4	0xad17
+#define PHY_REALTEK_INIT5	0xfb54
+#define PHY_REALTEK_INIT6	0xf5c7
+#define PHY_REALTEK_INIT7	0x1000
+#define PHY_REALTEK_INIT8	0x0003
+#define PHY_REALTEK_INIT_MSK1	0x0003
 
 #define PHY_GIGABIT	0x0100
 
@@ -691,6 +715,7 @@ struct fe_priv {
 	int wolenabled;
 	unsigned int phy_oui;
 	unsigned int phy_model;
+	unsigned int phy_rev;
 	u16 gigabit;
 	int intr_test;
 	int recover_error;
@@ -704,6 +729,7 @@ struct fe_priv {
 	u32 txrxctl_bits;
 	u32 vlanctl_bits;
 	u32 driver_data;
+	u32 device_id;
 	u32 register_size;
 	int rx_csum;
 	u32 mac_in_use;
@@ -814,6 +840,16 @@ enum {
 };
 static int dma_64bit = NV_DMA_64BIT_ENABLED;
 
+/*
+ * Crossover Detection
+ * Realtek 8201 phy + some OEM boards do not work properly.
+ */
+enum {
+	NV_CROSSOVER_DETECTION_DISABLED,
+	NV_CROSSOVER_DETECTION_ENABLED
+};
+static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED;
+
 static inline struct fe_priv *get_nvpriv(struct net_device *dev)
 {
 	return netdev_priv(dev);
@@ -1078,25 +1114,53 @@ static int phy_init(struct net_device *dev)
 		}
 	}
 	if (np->phy_oui == PHY_OUI_REALTEK) {
-		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
-			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
-			return PHY_ERROR;
-		}
-		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
-			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
-			return PHY_ERROR;
-		}
-		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
-			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
-			return PHY_ERROR;
-		}
-		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
-			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
-			return PHY_ERROR;
+		if (np->phy_model == PHY_MODEL_REALTEK_8211 &&
+		    np->phy_rev == PHY_REV_REALTEK_8211B) {
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
 		}
-		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
-			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
-			return PHY_ERROR;
+		if (np->phy_model == PHY_MODEL_REALTEK_8201) {
+			if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) {
+				phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
+				phy_reserved |= PHY_REALTEK_INIT7;
+				if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) {
+					printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+					return PHY_ERROR;
+				}
+			}
 		}
 	}
 
@@ -1236,26 +1300,71 @@ static int phy_init(struct net_device *dev)
 		}
 	}
 	if (np->phy_oui == PHY_OUI_REALTEK) {
-		/* reset could have cleared these out, set them back */
-		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
-			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
-			return PHY_ERROR;
-		}
-		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
-			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
-			return PHY_ERROR;
-		}
-		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
-			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
-			return PHY_ERROR;
-		}
-		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
-			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
-			return PHY_ERROR;
+		if (np->phy_model == PHY_MODEL_REALTEK_8211 &&
+		    np->phy_rev == PHY_REV_REALTEK_8211B) {
+			/* reset could have cleared these out, set them back */
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG4, PHY_REALTEK_INIT5)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG5, PHY_REALTEK_INIT6)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
+			if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+				printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+				return PHY_ERROR;
+			}
 		}
-		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
-			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
-			return PHY_ERROR;
+		if (np->phy_model == PHY_MODEL_REALTEK_8201) {
+			if (np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_32 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_33 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_34 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_35 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_36 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_37 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_38 ||
+			    np->device_id == PCI_DEVICE_ID_NVIDIA_NVENET_39) {
+				phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, MII_READ);
+				phy_reserved |= PHY_REALTEK_INIT7;
+				if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG6, phy_reserved)) {
+					printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+					return PHY_ERROR;
+				}
+			}
+			if (phy_cross == NV_CROSSOVER_DETECTION_DISABLED) {
+				if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
+					printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+					return PHY_ERROR;
+				}
+				phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, MII_READ);
+				phy_reserved &= ~PHY_REALTEK_INIT_MSK1;
+				phy_reserved |= PHY_REALTEK_INIT3;
+				if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, phy_reserved)) {
+					printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+					return PHY_ERROR;
+				}
+				if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+					printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+					return PHY_ERROR;
+				}
+			}
 		}
 	}
 
@@ -1769,6 +1878,115 @@ static inline u32 nv_get_empty_tx_slots(struct fe_priv *np)
 	return (u32)(np->tx_ring_size - ((np->tx_ring_size + (np->put_tx_ctx - np->get_tx_ctx)) % np->tx_ring_size));
 }
 
+static void nv_legacybackoff_reseed(struct net_device *dev)
+{
+	u8 __iomem *base = get_hwbase(dev);
+	u32 reg;
+	u32 low;
+	int tx_status = 0;
+
+	reg = readl(base + NvRegSlotTime) & ~NVREG_SLOTTIME_MASK;
+	get_random_bytes(&low, sizeof(low));
+	reg |= low & NVREG_SLOTTIME_MASK;
+
+	/* Need to stop tx before change takes effect.
+	 * Caller has already gained np->lock.
+	 */
+	tx_status = readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_START;
+	if (tx_status)
+		nv_stop_tx(dev);
+	nv_stop_rx(dev);
+	writel(reg, base + NvRegSlotTime);
+	if (tx_status)
+		nv_start_tx(dev);
+	nv_start_rx(dev);
+}
+
+/* Gear Backoff Seeds */
+#define BACKOFF_SEEDSET_ROWS	8
+#define BACKOFF_SEEDSET_LFSRS	15
+
+/* Known Good seed sets */
+static const u32 main_seedset[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS] = {
+    {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874},
+    {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 385, 761, 790, 974},
+    {145, 155, 165, 175, 185, 196, 235, 245, 255, 265, 275, 285, 660, 690, 874},
+    {245, 255, 265, 575, 385, 298, 335, 345, 355, 366, 375, 386, 761, 790, 974},
+    {266, 265, 276, 585, 397, 208, 345, 355, 365, 376, 385, 396, 771, 700, 984},
+    {266, 265, 276, 586, 397, 208, 346, 355, 365, 376, 285, 396, 771, 700, 984},
+    {366, 365, 376, 686, 497, 308, 447, 455, 466, 476, 485, 496, 871, 800,  84},
+    {466, 465, 476, 786, 597, 408, 547, 555, 566, 576, 585, 597, 971, 900, 184}};
+
+static const u32 gear_seedset[BACKOFF_SEEDSET_ROWS][BACKOFF_SEEDSET_LFSRS] = {
+    {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375,  30, 295},
+    {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
+    {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 397},
+    {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375,  30, 295},
+    {251, 262, 273, 324, 319, 508, 375, 364, 341, 371, 398, 193, 375,  30, 295},
+    {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
+    {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395},
+    {351, 375, 373, 469, 551, 639, 477, 464, 441, 472, 498, 293, 476, 130, 395}};
+
+static void nv_gear_backoff_reseed(struct net_device *dev)
+{
+	u8 __iomem *base = get_hwbase(dev);
+	u32 miniseed1, miniseed2, miniseed2_reversed, miniseed3, miniseed3_reversed;
+	u32 temp, seedset, combinedSeed;
+	int i;
+
+	/* Setup seed for free running LFSR */
+	/* We are going to read the time stamp counter 3 times
+	   and swizzle bits around to increase randomness */
+	get_random_bytes(&miniseed1, sizeof(miniseed1));
+	miniseed1 &= 0x0fff;
+	if (miniseed1 == 0)
+		miniseed1 = 0xabc;
+
+	get_random_bytes(&miniseed2, sizeof(miniseed2));
+	miniseed2 &= 0x0fff;
+	if (miniseed2 == 0)
+		miniseed2 = 0xabc;
+	miniseed2_reversed =
+		((miniseed2 & 0xF00) >> 8) |
+		 (miniseed2 & 0x0F0) |
+		 ((miniseed2 & 0x00F) << 8);
+
+	get_random_bytes(&miniseed3, sizeof(miniseed3));
+	miniseed3 &= 0x0fff;
+	if (miniseed3 == 0)
+		miniseed3 = 0xabc;
+	miniseed3_reversed =
+		((miniseed3 & 0xF00) >> 8) |
+		 (miniseed3 & 0x0F0) |
+		 ((miniseed3 & 0x00F) << 8);
+
+	combinedSeed = ((miniseed1 ^ miniseed2_reversed) << 12) |
+		       (miniseed2 ^ miniseed3_reversed);
+
+	/* Seeds can not be zero */
+	if ((combinedSeed & NVREG_BKOFFCTRL_SEED_MASK) == 0)
+		combinedSeed |= 0x08;
+	if ((combinedSeed & (NVREG_BKOFFCTRL_SEED_MASK << NVREG_BKOFFCTRL_GEAR)) == 0)
+		combinedSeed |= 0x8000;
+
+	/* No need to disable tx here */
+	temp = NVREG_BKOFFCTRL_DEFAULT | (0 << NVREG_BKOFFCTRL_SELECT);
+	temp |= combinedSeed & NVREG_BKOFFCTRL_SEED_MASK;
+	temp |= combinedSeed >> NVREG_BKOFFCTRL_GEAR;
+	writel(temp,base + NvRegBackOffControl);
+
+    	/* Setup seeds for all gear LFSRs. */
+	get_random_bytes(&seedset, sizeof(seedset));
+	seedset = seedset % BACKOFF_SEEDSET_ROWS;
+	for (i = 1; i <= BACKOFF_SEEDSET_LFSRS; i++)
+	{
+		temp = NVREG_BKOFFCTRL_DEFAULT | (i << NVREG_BKOFFCTRL_SELECT);
+		temp |= main_seedset[seedset][i-1] & 0x3ff;
+		temp |= ((gear_seedset[seedset][i-1] & 0x3ff) << NVREG_BKOFFCTRL_GEAR);
+		writel(temp, base + NvRegBackOffControl);
+	}
+}
+
 /*
  * nv_start_xmit: dev->hard_start_xmit function
  * Called with netif_tx_lock held.
@@ -2088,6 +2306,8 @@ static void nv_tx_done(struct net_device *dev)
 						dev->stats.tx_fifo_errors++;
 					if (flags & NV_TX_CARRIERLOST)
 						dev->stats.tx_carrier_errors++;
+					if ((flags & NV_TX_RETRYERROR) && !(flags & NV_TX_RETRYCOUNT_MASK))
+						nv_legacybackoff_reseed(dev);
 					dev->stats.tx_errors++;
 				} else {
 					dev->stats.tx_packets++;
@@ -2103,6 +2323,8 @@ static void nv_tx_done(struct net_device *dev)
 						dev->stats.tx_fifo_errors++;
 					if (flags & NV_TX2_CARRIERLOST)
 						dev->stats.tx_carrier_errors++;
+					if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK))
+						nv_legacybackoff_reseed(dev);
 					dev->stats.tx_errors++;
 				} else {
 					dev->stats.tx_packets++;
@@ -2144,6 +2366,15 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit)
 		if (flags & NV_TX2_LASTPACKET) {
 			if (!(flags & NV_TX2_ERROR))
 				dev->stats.tx_packets++;
+			else {
+				if ((flags & NV_TX2_RETRYERROR) && !(flags & NV_TX2_RETRYCOUNT_MASK)) {
+					if (np->driver_data & DEV_HAS_GEAR_MODE)
+						nv_gear_backoff_reseed(dev);
+					else
+						nv_legacybackoff_reseed(dev);
+				}
+			}
+
 			dev_kfree_skb_any(np->get_tx_ctx->skb);
 			np->get_tx_ctx->skb = NULL;
 
@@ -2905,15 +3136,14 @@ set_speed:
 	}
 
 	if (np->gigabit == PHY_GIGABIT) {
-		phyreg = readl(base + NvRegRandomSeed);
+		phyreg = readl(base + NvRegSlotTime);
 		phyreg &= ~(0x3FF00);
-		if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10)
-			phyreg |= NVREG_RNDSEED_FORCE3;
-		else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100)
-			phyreg |= NVREG_RNDSEED_FORCE2;
+		if (((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_10) ||
+		    ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_100))
+			phyreg |= NVREG_SLOTTIME_10_100_FULL;
 		else if ((np->linkspeed & 0xFFF) == NVREG_LINKSPEED_1000)
-			phyreg |= NVREG_RNDSEED_FORCE;
-		writel(phyreg, base + NvRegRandomSeed);
+			phyreg |= NVREG_SLOTTIME_1000_FULL;
+		writel(phyreg, base + NvRegSlotTime);
 	}
 
 	phyreg = readl(base + NvRegPhyInterface);
@@ -4843,6 +5073,7 @@ static int nv_open(struct net_device *dev)
 	u8 __iomem *base = get_hwbase(dev);
 	int ret = 1;
 	int oom, i;
+	u32 low;
 
 	dprintk(KERN_DEBUG "nv_open: begin\n");
 
@@ -4902,8 +5133,20 @@ static int nv_open(struct net_device *dev)
 	writel(np->rx_buf_sz, base + NvRegOffloadConfig);
 
 	writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus);
-	get_random_bytes(&i, sizeof(i));
-	writel(NVREG_RNDSEED_FORCE | (i&NVREG_RNDSEED_MASK), base + NvRegRandomSeed);
+
+	get_random_bytes(&low, sizeof(low));
+	low &= NVREG_SLOTTIME_MASK;
+	if (np->desc_ver == DESC_VER_1) {
+		writel(low|NVREG_SLOTTIME_DEFAULT, base + NvRegSlotTime);
+	} else {
+		if (!(np->driver_data & DEV_HAS_GEAR_MODE)) {
+			/* setup legacy backoff */
+			writel(NVREG_SLOTTIME_LEGBF_ENABLED|NVREG_SLOTTIME_10_100_FULL|low, base + NvRegSlotTime);
+		} else {
+			writel(NVREG_SLOTTIME_10_100_FULL, base + NvRegSlotTime);
+			nv_gear_backoff_reseed(dev);
+		}
+	}
 	writel(NVREG_TX_DEFERRAL_DEFAULT, base + NvRegTxDeferral);
 	writel(NVREG_RX_DEFERRAL_DEFAULT, base + NvRegRxDeferral);
 	if (poll_interval == -1) {
@@ -5110,6 +5353,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 
 	/* copy of driver data */
 	np->driver_data = id->driver_data;
+	/* copy of device id */
+	np->device_id = id->device;
 
 	/* handle different descriptor versions */
 	if (id->driver_data & DEV_HAS_HIGH_DMA) {
@@ -5399,6 +5644,14 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 			pci_name(pci_dev), id1, id2, phyaddr);
 		np->phyaddr = phyaddr;
 		np->phy_oui = id1 | id2;
+
+		/* Realtek hardcoded phy id1 to all zero's on certain phys */
+		if (np->phy_oui == PHY_OUI_REALTEK2)
+			np->phy_oui = PHY_OUI_REALTEK;
+		/* Setup phy revision for Realtek */
+		if (np->phy_oui == PHY_OUI_REALTEK && np->phy_model == PHY_MODEL_REALTEK_8211)
+			np->phy_rev = mii_rw(dev, phyaddr, MII_RESV1, MII_READ) & PHY_REV_MASK;
+
 		break;
 	}
 	if (i == 33) {
@@ -5477,6 +5730,28 @@ out:
 	return err;
 }
 
+static void nv_restore_phy(struct net_device *dev)
+{
+	struct fe_priv *np = netdev_priv(dev);
+	u16 phy_reserved, mii_control;
+
+	if (np->phy_oui == PHY_OUI_REALTEK &&
+	    np->phy_model == PHY_MODEL_REALTEK_8201 &&
+	    phy_cross == NV_CROSSOVER_DETECTION_DISABLED) {
+		mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3);
+		phy_reserved = mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, MII_READ);
+		phy_reserved &= ~PHY_REALTEK_INIT_MSK1;
+		phy_reserved |= PHY_REALTEK_INIT8;
+		mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, phy_reserved);
+		mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1);
+
+		/* restart auto negotiation */
+		mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
+		mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE);
+		mii_rw(dev, np->phyaddr, MII_BMCR, mii_control);
+	}
+}
+
 static void __devexit nv_remove(struct pci_dev *pci_dev)
 {
 	struct net_device *dev = pci_get_drvdata(pci_dev);
@@ -5493,6 +5768,9 @@ static void __devexit nv_remove(struct pci_dev *pci_dev)
 	writel(readl(base + NvRegTransmitPoll) & ~NVREG_TRANSMITPOLL_MAC_ADDR_REV,
 	       base + NvRegTransmitPoll);
 
+	/* restore any phy related changes */
+	nv_restore_phy(dev);
+
 	/* free all structures */
 	free_rings(dev);
 	iounmap(get_hwbase(dev));
@@ -5632,83 +5910,83 @@ static struct pci_device_id pci_tbl[] = {
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
 	},
 	{0,},
 };
@@ -5744,6 +6022,8 @@ module_param(msix, int, 0);
 MODULE_PARM_DESC(msix, "MSIX interrupts are enabled by setting to 1 and disabled by setting to 0.");
 module_param(dma_64bit, int, 0);
 MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0.");
+module_param(phy_cross, int, 0);
+MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0.");
 
 MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
 MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index c8c3df7..99a4b99 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -98,7 +98,6 @@
 #include "gianfar_mii.h"
 
 #define TX_TIMEOUT      (1*HZ)
-#define SKB_ALLOC_TIMEOUT 1000000
 #undef BRIEF_GFAR_ERRORS
 #undef VERBOSE_GFAR_ERRORS
 
@@ -115,7 +114,9 @@ static int gfar_enet_open(struct net_device *dev);
 static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void gfar_timeout(struct net_device *dev);
 static int gfar_close(struct net_device *dev);
-struct sk_buff *gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp);
+struct sk_buff *gfar_new_skb(struct net_device *dev);
+static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
+		struct sk_buff *skb);
 static int gfar_set_mac_address(struct net_device *dev);
 static int gfar_change_mtu(struct net_device *dev, int new_mtu);
 static irqreturn_t gfar_error(int irq, void *dev_id);
@@ -783,14 +784,21 @@ int startup_gfar(struct net_device *dev)
 
 	rxbdp = priv->rx_bd_base;
 	for (i = 0; i < priv->rx_ring_size; i++) {
-		struct sk_buff *skb = NULL;
+		struct sk_buff *skb;
 
-		rxbdp->status = 0;
+		skb = gfar_new_skb(dev);
 
-		skb = gfar_new_skb(dev, rxbdp);
+		if (!skb) {
+			printk(KERN_ERR "%s: Can't allocate RX buffers\n",
+					dev->name);
+
+			goto err_rxalloc_fail;
+		}
 
 		priv->rx_skbuff[i] = skb;
 
+		gfar_new_rxbdp(dev, rxbdp, skb);
+
 		rxbdp++;
 	}
 
@@ -916,6 +924,7 @@ rx_irq_fail:
 tx_irq_fail:
 	free_irq(priv->interruptError, dev);
 err_irq_fail:
+err_rxalloc_fail:	
 rx_skb_fail:
 	free_skb_resources(priv);
 tx_skb_fail:
@@ -1328,18 +1337,37 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
+static void gfar_new_rxbdp(struct net_device *dev, struct rxbd8 *bdp,
+		struct sk_buff *skb)
+{
+	struct gfar_private *priv = netdev_priv(dev);
+	u32 * status_len = (u32 *)bdp;
+	u16 flags;
+
+	bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
+			priv->rx_buffer_size, DMA_FROM_DEVICE);
+
+	flags = RXBD_EMPTY | RXBD_INTERRUPT;
+
+	if (bdp == priv->rx_bd_base + priv->rx_ring_size - 1)
+		flags |= RXBD_WRAP;
+
+	eieio();
+
+	*status_len = (u32)flags << 16;
+}
+
+
+struct sk_buff * gfar_new_skb(struct net_device *dev)
 {
 	unsigned int alignamount;
 	struct gfar_private *priv = netdev_priv(dev);
 	struct sk_buff *skb = NULL;
-	unsigned int timeout = SKB_ALLOC_TIMEOUT;
 
 	/* We have to allocate the skb, so keep trying till we succeed */
-	while ((!skb) && timeout--)
-		skb = dev_alloc_skb(priv->rx_buffer_size + RXBUF_ALIGNMENT);
+	skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT);
 
-	if (NULL == skb)
+	if (!skb)
 		return NULL;
 
 	alignamount = RXBUF_ALIGNMENT -
@@ -1350,15 +1378,6 @@ struct sk_buff * gfar_new_skb(struct net_device *dev, struct rxbd8 *bdp)
 	 */
 	skb_reserve(skb, alignamount);
 
-	bdp->bufPtr = dma_map_single(&dev->dev, skb->data,
-			priv->rx_buffer_size, DMA_FROM_DEVICE);
-
-	bdp->length = 0;
-
-	/* Mark the buffer empty */
-	eieio();
-	bdp->status |= (RXBD_EMPTY | RXBD_INTERRUPT);
-
 	return skb;
 }
 
@@ -1544,10 +1563,31 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
 	bdp = priv->cur_rx;
 
 	while (!((bdp->status & RXBD_EMPTY) || (--rx_work_limit < 0))) {
+		struct sk_buff *newskb;
 		rmb();
+
+		/* Add another skb for the future */
+		newskb = gfar_new_skb(dev);
+
 		skb = priv->rx_skbuff[priv->skb_currx];
 
-		if ((bdp->status & RXBD_LAST) && !(bdp->status & RXBD_ERR)) {
+		/* We drop the frame if we failed to allocate a new buffer */
+		if (unlikely(!newskb || !(bdp->status & RXBD_LAST) ||
+				 bdp->status & RXBD_ERR)) {
+			count_errors(bdp->status, dev);
+
+			if (unlikely(!newskb))
+				newskb = skb;
+
+			if (skb) {
+				dma_unmap_single(&priv->dev->dev,
+						bdp->bufPtr,
+						priv->rx_buffer_size,
+						DMA_FROM_DEVICE);
+
+				dev_kfree_skb_any(skb);
+			}
+		} else {
 			/* Increment the number of packets */
 			dev->stats.rx_packets++;
 			howmany++;
@@ -1558,23 +1598,14 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
 			gfar_process_frame(dev, skb, pkt_len);
 
 			dev->stats.rx_bytes += pkt_len;
-		} else {
-			count_errors(bdp->status, dev);
-
-			if (skb)
-				dev_kfree_skb_any(skb);
-
-			priv->rx_skbuff[priv->skb_currx] = NULL;
 		}
 
 		dev->last_rx = jiffies;
 
-		/* Clear the status flags for this buffer */
-		bdp->status &= ~RXBD_STATS;
+		priv->rx_skbuff[priv->skb_currx] = newskb;
 
-		/* Add another skb for the future */
-		skb = gfar_new_skb(dev, bdp);
-		priv->rx_skbuff[priv->skb_currx] = skb;
+		/* Setup the new bdp */
+		gfar_new_rxbdp(dev, bdp, newskb);
 
 		/* Update to the next pointer */
 		if (bdp->status & RXBD_WRAP)
@@ -1584,9 +1615,8 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
 
 		/* update to point at the next skb */
 		priv->skb_currx =
-		    (priv->skb_currx +
-		     1) & RX_RING_MOD_MASK(priv->rx_ring_size);
-
+		    (priv->skb_currx + 1) &
+		    RX_RING_MOD_MASK(priv->rx_ring_size);
 	}
 
 	/* Update the current rxbd pointer to be the next one */
@@ -2001,12 +2031,16 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:fsl-gianfar");
+
 /* Structure for a device driver */
 static struct platform_driver gfar_driver = {
 	.probe = gfar_probe,
 	.remove = gfar_remove,
 	.driver	= {
 		.name = "fsl-gianfar",
+		.owner = THIS_MODULE,
 	},
 };
 
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 378a239..5d2108c 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -43,6 +43,8 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/uaccess.h>
+#include <asm/dcr.h>
+#include <asm/dcr-regs.h>
 
 #include "core.h"
 
@@ -127,10 +129,35 @@ static struct device_node *emac_boot_list[EMAC_BOOT_LIST_SIZE];
 static inline void emac_report_timeout_error(struct emac_instance *dev,
 					     const char *error)
 {
-	if (net_ratelimit())
+	if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX |
+				  EMAC_FTR_440EP_PHY_CLK_FIX))
+		DBG(dev, "%s" NL, error);
+	else if (net_ratelimit())
 		printk(KERN_ERR "%s: %s\n", dev->ndev->name, error);
 }
 
+/* EMAC PHY clock workaround:
+ * 440EP/440GR has more sane SDR0_MFR register implementation than 440GX,
+ * which allows controlling each EMAC clock
+ */
+static inline void emac_rx_clk_tx(struct emac_instance *dev)
+{
+#ifdef CONFIG_PPC_DCR_NATIVE
+	if (emac_has_feature(dev, EMAC_FTR_440EP_PHY_CLK_FIX))
+		dcri_clrset(SDR0, SDR0_MFR,
+			    0, SDR0_MFR_ECS >> dev->cell_index);
+#endif
+}
+
+static inline void emac_rx_clk_default(struct emac_instance *dev)
+{
+#ifdef CONFIG_PPC_DCR_NATIVE
+	if (emac_has_feature(dev, EMAC_FTR_440EP_PHY_CLK_FIX))
+		dcri_clrset(SDR0, SDR0_MFR,
+			    SDR0_MFR_ECS >> dev->cell_index, 0);
+#endif
+}
+
 /* PHY polling intervals */
 #define PHY_POLL_LINK_ON	HZ
 #define PHY_POLL_LINK_OFF	(HZ / 5)
@@ -524,7 +551,10 @@ static int emac_configure(struct emac_instance *dev)
 		rx_size = dev->rx_fifo_size_gige;
 
 		if (dev->ndev->mtu > ETH_DATA_LEN) {
-			mr1 |= EMAC_MR1_JPSM;
+			if (emac_has_feature(dev, EMAC_FTR_EMAC4))
+				mr1 |= EMAC4_MR1_JPSM;
+			else
+				mr1 |= EMAC_MR1_JPSM;
 			dev->stop_timeout = STOP_TIMEOUT_1000_JUMBO;
 		} else
 			dev->stop_timeout = STOP_TIMEOUT_1000;
@@ -708,7 +738,7 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg)
 		rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port);
 
 	/* Wait for management interface to become idle */
-	n = 10;
+	n = 20;
 	while (!emac_phy_done(dev, in_be32(&p->stacr))) {
 		udelay(1);
 		if (!--n) {
@@ -733,7 +763,7 @@ static int __emac_mdio_read(struct emac_instance *dev, u8 id, u8 reg)
 	out_be32(&p->stacr, r);
 
 	/* Wait for read to complete */
-	n = 100;
+	n = 200;
 	while (!emac_phy_done(dev, (r = in_be32(&p->stacr)))) {
 		udelay(1);
 		if (!--n) {
@@ -780,7 +810,7 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg,
 		rgmii_get_mdio(dev->rgmii_dev, dev->rgmii_port);
 
 	/* Wait for management interface to be idle */
-	n = 10;
+	n = 20;
 	while (!emac_phy_done(dev, in_be32(&p->stacr))) {
 		udelay(1);
 		if (!--n) {
@@ -806,7 +836,7 @@ static void __emac_mdio_write(struct emac_instance *dev, u8 id, u8 reg,
 	out_be32(&p->stacr, r);
 
 	/* Wait for write to complete */
-	n = 100;
+	n = 200;
 	while (!emac_phy_done(dev, in_be32(&p->stacr))) {
 		udelay(1);
 		if (!--n) {
@@ -1094,9 +1124,11 @@ static int emac_open(struct net_device *ndev)
 		int link_poll_interval;
 		if (dev->phy.def->ops->poll_link(&dev->phy)) {
 			dev->phy.def->ops->read_link(&dev->phy);
+			emac_rx_clk_default(dev);
 			netif_carrier_on(dev->ndev);
 			link_poll_interval = PHY_POLL_LINK_ON;
 		} else {
+			emac_rx_clk_tx(dev);
 			netif_carrier_off(dev->ndev);
 			link_poll_interval = PHY_POLL_LINK_OFF;
 		}
@@ -1174,6 +1206,7 @@ static void emac_link_timer(struct work_struct *work)
 
 	if (dev->phy.def->ops->poll_link(&dev->phy)) {
 		if (!netif_carrier_ok(dev->ndev)) {
+			emac_rx_clk_default(dev);
 			/* Get new link parameters */
 			dev->phy.def->ops->read_link(&dev->phy);
 
@@ -1186,6 +1219,7 @@ static void emac_link_timer(struct work_struct *work)
 		link_poll_interval = PHY_POLL_LINK_ON;
 	} else {
 		if (netif_carrier_ok(dev->ndev)) {
+			emac_rx_clk_tx(dev);
 			netif_carrier_off(dev->ndev);
 			netif_tx_disable(dev->ndev);
 			emac_reinitialize(dev);
@@ -2237,7 +2271,7 @@ static int __devinit emac_of_bus_notify(struct notifier_block *nb,
 	return 0;
 }
 
-static struct notifier_block emac_of_bus_notifier = {
+static struct notifier_block emac_of_bus_notifier __devinitdata = {
 	.notifier_call = emac_of_bus_notify
 };
 
@@ -2330,6 +2364,19 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
 	dev->phy.mdio_read = emac_mdio_read;
 	dev->phy.mdio_write = emac_mdio_write;
 
+	/* Enable internal clock source */
+#ifdef CONFIG_PPC_DCR_NATIVE
+	if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX))
+		dcri_clrset(SDR0, SDR0_MFR, 0, SDR0_MFR_ECS);
+#endif
+	/* PHY clock workaround */
+	emac_rx_clk_tx(dev);
+
+	/* Enable internal clock source on 440GX*/
+#ifdef CONFIG_PPC_DCR_NATIVE
+	if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX))
+		dcri_clrset(SDR0, SDR0_MFR, 0, SDR0_MFR_ECS);
+#endif
 	/* Configure EMAC with defaults so we can at least use MDIO
 	 * This is needed mostly for 440GX
 	 */
@@ -2362,6 +2409,12 @@ static int __devinit emac_init_phy(struct emac_instance *dev)
 			if (!emac_mii_phy_probe(&dev->phy, i))
 				break;
 		}
+
+	/* Enable external clock source */
+#ifdef CONFIG_PPC_DCR_NATIVE
+	if (emac_has_feature(dev, EMAC_FTR_440GX_PHY_CLK_FIX))
+		dcri_clrset(SDR0, SDR0_MFR, SDR0_MFR_ECS, 0);
+#endif
 	mutex_unlock(&emac_phy_map_lock);
 	if (i == 0x20) {
 		printk(KERN_WARNING "%s: can't find PHY!\n", np->full_name);
@@ -2487,8 +2540,15 @@ static int __devinit emac_init_config(struct emac_instance *dev)
 	}
 
 	/* Check EMAC version */
-	if (of_device_is_compatible(np, "ibm,emac4"))
+	if (of_device_is_compatible(np, "ibm,emac4")) {
 		dev->features |= EMAC_FTR_EMAC4;
+		if (of_device_is_compatible(np, "ibm,emac-440gx"))
+			dev->features |= EMAC_FTR_440GX_PHY_CLK_FIX;
+	} else {
+		if (of_device_is_compatible(np, "ibm,emac-440ep") ||
+		    of_device_is_compatible(np, "ibm,emac-440gr"))
+			dev->features |= EMAC_FTR_440EP_PHY_CLK_FIX;
+	}
 
 	/* Fixup some feature bits based on the device tree */
 	if (of_get_property(np, "has-inverted-stacr-oc", NULL))
@@ -2559,8 +2619,11 @@ static int __devinit emac_probe(struct of_device *ofdev,
 	struct device_node **blist = NULL;
 	int err, i;
 
-	/* Skip unused/unwired EMACS */
-	if (of_get_property(np, "unused", NULL))
+	/* Skip unused/unwired EMACS.  We leave the check for an unused
+	 * property here for now, but new flat device trees should set a
+	 * status property to "disabled" instead.
+	 */
+	if (of_get_property(np, "unused", NULL) || !of_device_is_available(np))
 		return -ENODEV;
 
 	/* Find ourselves in the bootlist if we are there */
diff --git a/drivers/net/ibm_newemac/core.h b/drivers/net/ibm_newemac/core.h
index 4e74d82..1683db9 100644
--- a/drivers/net/ibm_newemac/core.h
+++ b/drivers/net/ibm_newemac/core.h
@@ -301,6 +301,14 @@ struct emac_instance {
  * Set if we have new type STACR with STAOPC
  */
 #define EMAC_FTR_HAS_NEW_STACR		0x00000040
+/*
+ * Set if we need phy clock workaround for 440gx
+ */
+#define EMAC_FTR_440GX_PHY_CLK_FIX	0x00000080
+/*
+ * Set if we need phy clock workaround for 440ep or 440gr
+ */
+#define EMAC_FTR_440EP_PHY_CLK_FIX	0x00000100
 
 
 /* Right now, we don't quite handle the always/possible masks on the
@@ -312,8 +320,8 @@ enum {
 
 	EMAC_FTRS_POSSIBLE	=
 #ifdef CONFIG_IBM_NEW_EMAC_EMAC4
-	    EMAC_FTR_EMAC4	| EMAC_FTR_HAS_NEW_STACR	|
-	    EMAC_FTR_STACR_OC_INVERT	|
+	    EMAC_FTR_EMAC4 | EMAC_FTR_HAS_NEW_STACR |
+	    EMAC_FTR_STACR_OC_INVERT | EMAC_FTR_440GX_PHY_CLK_FIX |
 #endif
 #ifdef CONFIG_IBM_NEW_EMAC_TAH
 	    EMAC_FTR_HAS_TAH	|
@@ -324,7 +332,7 @@ enum {
 #ifdef CONFIG_IBM_NEW_EMAC_RGMII
 	    EMAC_FTR_HAS_RGMII	|
 #endif
-	    0,
+	EMAC_FTR_440EP_PHY_CLK_FIX,
 };
 
 static inline int emac_has_feature(struct emac_instance *dev,
diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c
index 6869f08..10c267b 100644
--- a/drivers/net/ibm_newemac/mal.c
+++ b/drivers/net/ibm_newemac/mal.c
@@ -61,8 +61,8 @@ int __devinit mal_register_commac(struct mal_instance	*mal,
 	return 0;
 }
 
-void __devexit mal_unregister_commac(struct mal_instance	*mal,
-				     struct mal_commac		*commac)
+void mal_unregister_commac(struct mal_instance	*mal,
+		struct mal_commac *commac)
 {
 	unsigned long flags;
 
@@ -136,6 +136,14 @@ void mal_enable_rx_channel(struct mal_instance *mal, int channel)
 {
 	unsigned long flags;
 
+	/*
+	 * On some 4xx PPC's (e.g. 460EX/GT), the rx channel is a multiple
+	 * of 8, but enabling in MAL_RXCASR needs the divided by 8 value
+	 * for the bitmask
+	 */
+	if (!(channel % 8))
+		channel >>= 3;
+
 	spin_lock_irqsave(&mal->lock, flags);
 
 	MAL_DBG(mal, "enable_rx(%d)" NL, channel);
@@ -148,6 +156,14 @@ void mal_enable_rx_channel(struct mal_instance *mal, int channel)
 
 void mal_disable_rx_channel(struct mal_instance *mal, int channel)
 {
+	/*
+	 * On some 4xx PPC's (e.g. 460EX/GT), the rx channel is a multiple
+	 * of 8, but enabling in MAL_RXCASR needs the divided by 8 value
+	 * for the bitmask
+	 */
+	if (!(channel % 8))
+		channel >>= 3;
+
 	set_mal_dcrn(mal, MAL_RXCARR, MAL_CHAN_MASK(channel));
 
 	MAL_DBG(mal, "disable_rx(%d)" NL, channel);
diff --git a/drivers/net/ibm_newemac/rgmii.c b/drivers/net/ibm_newemac/rgmii.c
index 5757788..e32da3d 100644
--- a/drivers/net/ibm_newemac/rgmii.c
+++ b/drivers/net/ibm_newemac/rgmii.c
@@ -179,7 +179,7 @@ void rgmii_put_mdio(struct of_device *ofdev, int input)
 	mutex_unlock(&dev->lock);
 }
 
-void __devexit rgmii_detach(struct of_device *ofdev, int input)
+void rgmii_detach(struct of_device *ofdev, int input)
 {
 	struct rgmii_instance *dev = dev_get_drvdata(&ofdev->dev);
 	struct rgmii_regs __iomem *p = dev->base;
diff --git a/drivers/net/ibm_newemac/tah.c b/drivers/net/ibm_newemac/tah.c
index b023d10..30173a9 100644
--- a/drivers/net/ibm_newemac/tah.c
+++ b/drivers/net/ibm_newemac/tah.c
@@ -35,7 +35,7 @@ int __devinit tah_attach(struct of_device *ofdev, int channel)
 	return 0;
 }
 
-void __devexit tah_detach(struct of_device *ofdev, int channel)
+void tah_detach(struct of_device *ofdev, int channel)
 {
 	struct tah_instance *dev = dev_get_drvdata(&ofdev->dev);
 
diff --git a/drivers/net/ibm_newemac/zmii.c b/drivers/net/ibm_newemac/zmii.c
index 2ea472a..17b1541 100644
--- a/drivers/net/ibm_newemac/zmii.c
+++ b/drivers/net/ibm_newemac/zmii.c
@@ -189,7 +189,7 @@ void zmii_set_speed(struct of_device *ofdev, int input, int speed)
 	mutex_unlock(&dev->lock);
 }
 
-void __devexit zmii_detach(struct of_device *ofdev, int input)
+void zmii_detach(struct of_device *ofdev, int input)
 {
 	struct zmii_instance *dev = dev_get_drvdata(&ofdev->dev);
 
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index aaee02e..ae398f0 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -871,6 +871,7 @@ static int __devinit igb_probe(struct pci_dev *pdev,
 		goto err_pci_reg;
 
 	pci_set_master(pdev);
+	pci_save_state(pdev);
 
 	err = -ENOMEM;
 	netdev = alloc_etherdev(sizeof(struct igb_adapter));
@@ -4079,6 +4080,7 @@ static pci_ers_result_t igb_io_slot_reset(struct pci_dev *pdev)
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 	pci_set_master(pdev);
+	pci_restore_state(pdev);
 
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 	pci_enable_wake(pdev, PCI_D3cold, 0);
diff --git a/drivers/net/irda/ali-ircc.c b/drivers/net/irda/ali-ircc.c
index 9f58452..083b0dd 100644
--- a/drivers/net/irda/ali-ircc.c
+++ b/drivers/net/irda/ali-ircc.c
@@ -60,6 +60,7 @@ static struct platform_driver ali_ircc_driver = {
 	.resume		= ali_ircc_resume,
 	.driver		= {
 		.name	= ALI_IRCC_DRIVER_NAME,
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -2256,6 +2257,7 @@ static void FIR2SIR(int iobase)
 MODULE_AUTHOR("Benjamin Kong <benjamin_kong@ali.com.tw>");
 MODULE_DESCRIPTION("ALi FIR Controller Driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" ALI_IRCC_DRIVER_NAME);
 
 
 module_param_array(io, int, NULL, 0);
diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c
index 8c09344..60b94bb 100644
--- a/drivers/net/irda/pxaficp_ir.c
+++ b/drivers/net/irda/pxaficp_ir.c
@@ -897,6 +897,7 @@ static int pxa_irda_remove(struct platform_device *_dev)
 static struct platform_driver pxa_ir_driver = {
 	.driver         = {
 		.name   = "pxa2xx-ir",
+		.owner	= THIS_MODULE,
 	},
 	.probe		= pxa_irda_probe,
 	.remove		= pxa_irda_remove,
@@ -918,3 +919,4 @@ module_init(pxa_irda_init);
 module_exit(pxa_irda_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa2xx-ir");
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 056639f..1bc8518 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -1008,6 +1008,7 @@ static struct platform_driver sa1100ir_driver = {
 	.resume		= sa1100_irda_resume,
 	.driver		= {
 		.name	= "sa11x0-ir",
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -1041,3 +1042,4 @@ MODULE_LICENSE("GPL");
 MODULE_PARM_DESC(power_level, "IrDA power level, 1 (low) to 3 (high)");
 MODULE_PARM_DESC(tx_lpm, "Enable transmitter low power (1.6us) mode");
 MODULE_PARM_DESC(max_rate, "Maximum baud rate (4000000, 115200, 57600, 38400, 19200, 9600)");
+MODULE_ALIAS("platform:sa11x0-ir");
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index cb371a8..7b85922 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -3431,6 +3431,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 	}
 
 	pci_set_master(pdev);
+	pci_save_state(pdev);
 
 #ifdef CONFIG_NETDEVICES_MULTIQUEUE
 	netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), MAX_TX_QUEUES);
@@ -3721,6 +3722,7 @@ static pci_ers_result_t ixgbe_io_slot_reset(struct pci_dev *pdev)
 		return PCI_ERS_RESULT_DISCONNECT;
 	}
 	pci_set_master(pdev);
+	pci_restore_state(pdev);
 
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 	pci_enable_wake(pdev, PCI_D3cold, 0);
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index 5c154fe..0794482 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -249,6 +249,7 @@ out:
 MODULE_DESCRIPTION("Jazz SONIC ethernet driver");
 module_param(sonic_debug, int, 0);
 MODULE_PARM_DESC(sonic_debug, "jazzsonic debug level (1-4)");
+MODULE_ALIAS("platform:jazzsonic");
 
 #include "sonic.c"
 
@@ -271,6 +272,7 @@ static struct platform_driver jazz_sonic_driver = {
 	.remove	= __devexit_p(jazz_sonic_device_remove),
 	.driver	= {
 		.name	= jazz_sonic_string,
+		.owner	= THIS_MODULE,
 	},
 };
 
diff --git a/drivers/net/korina.c b/drivers/net/korina.c
index 1d24a73..e185763 100644
--- a/drivers/net/korina.c
+++ b/drivers/net/korina.c
@@ -883,7 +883,7 @@ static int korina_init(struct net_device *dev)
 static int korina_restart(struct net_device *dev)
 {
 	struct korina_private *lp = netdev_priv(dev);
-	int ret = 0;
+	int ret;
 
 	/*
 	 * Disable interrupts
@@ -987,7 +987,7 @@ static void korina_poll_controller(struct net_device *dev)
 static int korina_open(struct net_device *dev)
 {
 	struct korina_private *lp = netdev_priv(dev);
-	int ret = 0;
+	int ret;
 
 	/* Initialize */
 	ret = korina_init(dev);
@@ -1031,6 +1031,8 @@ static int korina_open(struct net_device *dev)
 		    dev->name, lp->und_irq);
 		goto err_free_ovr_irq;
 	}
+out:
+	return ret;
 
 err_free_ovr_irq:
 	free_irq(lp->ovr_irq, dev);
@@ -1041,8 +1043,6 @@ err_free_rx_irq:
 err_release:
 	korina_free_ring(dev);
 	goto out;
-out:
-	return ret;
 }
 
 static int korina_close(struct net_device *dev)
@@ -1082,7 +1082,7 @@ static int korina_probe(struct platform_device *pdev)
 	struct korina_private *lp;
 	struct net_device *dev;
 	struct resource *r;
-	int retval, err;
+	int rc;
 
 	dev = alloc_etherdev(sizeof(struct korina_private));
 	if (!dev) {
@@ -1106,7 +1106,7 @@ static int korina_probe(struct platform_device *pdev)
 	lp->eth_regs = ioremap_nocache(r->start, r->end - r->start);
 	if (!lp->eth_regs) {
 		printk(KERN_ERR DRV_NAME "cannot remap registers\n");
-		retval = -ENXIO;
+		rc = -ENXIO;
 		goto probe_err_out;
 	}
 
@@ -1114,7 +1114,7 @@ static int korina_probe(struct platform_device *pdev)
 	lp->rx_dma_regs = ioremap_nocache(r->start, r->end - r->start);
 	if (!lp->rx_dma_regs) {
 		printk(KERN_ERR DRV_NAME "cannot remap Rx DMA registers\n");
-		retval = -ENXIO;
+		rc = -ENXIO;
 		goto probe_err_dma_rx;
 	}
 
@@ -1122,14 +1122,14 @@ static int korina_probe(struct platform_device *pdev)
 	lp->tx_dma_regs = ioremap_nocache(r->start, r->end - r->start);
 	if (!lp->tx_dma_regs) {
 		printk(KERN_ERR DRV_NAME "cannot remap Tx DMA registers\n");
-		retval = -ENXIO;
+		rc = -ENXIO;
 		goto probe_err_dma_tx;
 	}
 
 	lp->td_ring = kmalloc(TD_RING_SIZE + RD_RING_SIZE, GFP_KERNEL);
 	if (!lp->td_ring) {
 		printk(KERN_ERR DRV_NAME "cannot allocate descriptors\n");
-		retval = -ENOMEM;
+		rc = -ENXIO;
 		goto probe_err_td_ring;
 	}
 
@@ -1166,14 +1166,14 @@ static int korina_probe(struct platform_device *pdev)
 	lp->mii_if.phy_id_mask = 0x1f;
 	lp->mii_if.reg_num_mask = 0x1f;
 
-	err = register_netdev(dev);
-	if (err) {
+	rc = register_netdev(dev);
+	if (rc < 0) {
 		printk(KERN_ERR DRV_NAME
-			": cannot register net device %d\n", err);
-		retval = -EINVAL;
+			": cannot register net device %d\n", rc);
 		goto probe_err_register;
 	}
-	return 0;
+out:
+	return rc;
 
 probe_err_register:
 	kfree(lp->td_ring);
@@ -1185,7 +1185,7 @@ probe_err_dma_rx:
 	iounmap(lp->eth_regs);
 probe_err_out:
 	free_netdev(dev);
-	return retval;
+	goto out;
 }
 
 static int korina_remove(struct platform_device *pdev)
@@ -1193,12 +1193,9 @@ static int korina_remove(struct platform_device *pdev)
 	struct korina_device *bif = platform_get_drvdata(pdev);
 	struct korina_private *lp = netdev_priv(bif->dev);
 
-	if (lp->eth_regs)
-		iounmap(lp->eth_regs);
-	if (lp->rx_dma_regs)
-		iounmap(lp->rx_dma_regs);
-	if (lp->tx_dma_regs)
-		iounmap(lp->tx_dma_regs);
+	iounmap(lp->eth_regs);
+	iounmap(lp->rx_dma_regs);
+	iounmap(lp->tx_dma_regs);
 
 	platform_set_drvdata(pdev, NULL);
 	unregister_netdev(bif->dev);
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index d513bb8..92dccd4 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -1281,6 +1281,7 @@ static struct platform_driver macb_driver = {
 	.remove		= __exit_p(macb_remove),
 	.driver		= {
 		.name		= "macb",
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -1300,3 +1301,4 @@ module_exit(macb_exit);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Atmel MACB Ethernet driver");
 MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
+MODULE_ALIAS("platform:macb");
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index cdaa8fc..0b32648 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -830,6 +830,7 @@ static struct platform_driver meth_driver = {
 	.remove	= __devexit_p(meth_remove),
 	.driver = {
 		.name	= "meth",
+		.owner	= THIS_MODULE,
 	}
 };
 
@@ -855,3 +856,4 @@ module_exit(meth_exit_module);
 MODULE_AUTHOR("Ilya Volynets <ilya@theIlya.com>");
 MODULE_DESCRIPTION("SGI O2 Builtin Fast Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:meth");
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 601ffd6..381b36e 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -2030,6 +2030,7 @@ static struct platform_driver mv643xx_eth_driver = {
 	.shutdown = mv643xx_eth_shutdown,
 	.driver = {
 		.name = MV643XX_ETH_NAME,
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -2038,6 +2039,7 @@ static struct platform_driver mv643xx_eth_shared_driver = {
 	.remove = mv643xx_eth_shared_remove,
 	.driver = {
 		.name = MV643XX_ETH_SHARED_NAME,
+		.owner	= THIS_MODULE,
 	},
 };
 
@@ -2085,7 +2087,8 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR(	"Rabeeh Khoury, Assaf Hoffman, Matthew Dharm, Manish Lachwani"
 		" and Dale Farnsworth");
 MODULE_DESCRIPTION("Ethernet driver for Marvell MV643XX");
-MODULE_ALIAS("platform:mv643xx_eth");
+MODULE_ALIAS("platform:" MV643XX_ETH_NAME);
+MODULE_ALIAS("platform:" MV643XX_ETH_SHARED_NAME);
 
 /*
  * The second part is the low level driver of the gigE ethernet ports.
diff --git a/drivers/net/netx-eth.c b/drivers/net/netx-eth.c
index 78d34af..dc442e3 100644
--- a/drivers/net/netx-eth.c
+++ b/drivers/net/netx-eth.c
@@ -502,4 +502,4 @@ module_exit(netx_eth_cleanup);
 
 MODULE_AUTHOR("Sascha Hauer, Pengutronix");
 MODULE_LICENSE("GPL");
-
+MODULE_ALIAS("platform:" CARDNAME);
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 05748ca..af73564 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -1132,8 +1132,8 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
 	u32 fw_minor = 0;
 	u32 fw_build = 0;
 	char brd_name[NETXEN_MAX_SHORT_NAME];
-	struct netxen_new_user_info user_info;
-	int i, addr = NETXEN_USER_START;
+	char serial_num[32];
+	int i, addr;
 	__le32 *ptr32;
 
 	struct netxen_board_info *board_info = &(adapter->ahw.boardcfg);
@@ -1150,10 +1150,10 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
 		valid = 0;
 	}
 	if (valid) {
-		ptr32 = (u32 *) & user_info;
-		for (i = 0;
-		     i < sizeof(struct netxen_new_user_info) / sizeof(u32);
-		     i++) {
+		ptr32 = (u32 *)&serial_num;
+		addr = NETXEN_USER_START +
+		       offsetof(struct netxen_new_user_info, serial_num);
+		for (i = 0; i < 8; i++) {
 			if (netxen_rom_fast_read(adapter, addr, ptr32) == -1) {
 				printk("%s: ERROR reading %s board userarea.\n",
 				       netxen_nic_driver_name,
@@ -1163,10 +1163,11 @@ void netxen_nic_flash_print(struct netxen_adapter *adapter)
 			ptr32++;
 			addr += sizeof(u32);
 		}
+
 		get_brd_name_by_type(board_info->board_type, brd_name);
 
 		printk("NetXen %s Board S/N %s  Chip id 0x%x\n",
-		       brd_name, user_info.serial_num, board_info->chip_id);
+		       brd_name, serial_num, board_info->chip_id);
 
 		printk("NetXen %s Board #%d, Chip id 0x%x\n",
 		       board_info->board_type == 0x0b ? "XGB" : "GBE",
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index 963630c..94e0b7e 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -89,6 +89,9 @@ int mdiobus_register(struct mii_bus *bus)
 
 			phydev->bus = bus;
 
+			/* Run all of the fixups for this PHY */
+			phy_scan_fixups(phydev);
+
 			err = device_register(&phydev->dev);
 
 			if (err) {
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 12fccb1..3c18bb5 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -406,8 +406,10 @@ int phy_mii_ioctl(struct phy_device *phydev,
 		
 		if (mii_data->reg_num == MII_BMCR 
 				&& val & BMCR_RESET
-				&& phydev->drv->config_init)
+				&& phydev->drv->config_init) {
+			phy_scan_fixups(phydev);
 			phydev->drv->config_init(phydev);
+		}
 		break;
 
 	default:
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 8b1121b..ddf8d51 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -53,6 +53,96 @@ static void phy_device_release(struct device *dev)
 	phy_device_free(to_phy_device(dev));
 }
 
+static LIST_HEAD(phy_fixup_list);
+static DEFINE_MUTEX(phy_fixup_lock);
+
+/*
+ * Creates a new phy_fixup and adds it to the list
+ * @bus_id: A string which matches phydev->dev.bus_id (or PHY_ANY_ID)
+ * @phy_uid: Used to match against phydev->phy_id (the UID of the PHY)
+ * 	It can also be PHY_ANY_UID
+ * @phy_uid_mask: Applied to phydev->phy_id and fixup->phy_uid before
+ * 	comparison
+ * @run: The actual code to be run when a matching PHY is found
+ */
+int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
+		int (*run)(struct phy_device *))
+{
+	struct phy_fixup *fixup;
+
+	fixup = kzalloc(sizeof(struct phy_fixup), GFP_KERNEL);
+	if (!fixup)
+		return -ENOMEM;
+
+	strncpy(fixup->bus_id, bus_id, BUS_ID_SIZE);
+	fixup->phy_uid = phy_uid;
+	fixup->phy_uid_mask = phy_uid_mask;
+	fixup->run = run;
+
+	mutex_lock(&phy_fixup_lock);
+	list_add_tail(&fixup->list, &phy_fixup_list);
+	mutex_unlock(&phy_fixup_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(phy_register_fixup);
+
+/* Registers a fixup to be run on any PHY with the UID in phy_uid */
+int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
+		int (*run)(struct phy_device *))
+{
+	return phy_register_fixup(PHY_ANY_ID, phy_uid, phy_uid_mask, run);
+}
+EXPORT_SYMBOL(phy_register_fixup_for_uid);
+
+/* Registers a fixup to be run on the PHY with id string bus_id */
+int phy_register_fixup_for_id(const char *bus_id,
+		int (*run)(struct phy_device *))
+{
+	return phy_register_fixup(bus_id, PHY_ANY_UID, 0xffffffff, run);
+}
+EXPORT_SYMBOL(phy_register_fixup_for_id);
+
+/*
+ * Returns 1 if fixup matches phydev in bus_id and phy_uid.
+ * Fixups can be set to match any in one or more fields.
+ */
+static int phy_needs_fixup(struct phy_device *phydev, struct phy_fixup *fixup)
+{
+	if (strcmp(fixup->bus_id, phydev->dev.bus_id) != 0)
+		if (strcmp(fixup->bus_id, PHY_ANY_ID) != 0)
+			return 0;
+
+	if ((fixup->phy_uid & fixup->phy_uid_mask) !=
+			(phydev->phy_id & fixup->phy_uid_mask))
+		if (fixup->phy_uid != PHY_ANY_UID)
+			return 0;
+
+	return 1;
+}
+
+/* Runs any matching fixups for this phydev */
+int phy_scan_fixups(struct phy_device *phydev)
+{
+	struct phy_fixup *fixup;
+
+	mutex_lock(&phy_fixup_lock);
+	list_for_each_entry(fixup, &phy_fixup_list, list) {
+		if (phy_needs_fixup(phydev, fixup)) {
+			int err;
+
+			err = fixup->run(phydev);
+
+			if (err < 0)
+				return err;
+		}
+	}
+	mutex_unlock(&phy_fixup_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL(phy_scan_fixups);
+
 struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id)
 {
 	struct phy_device *dev;
@@ -179,13 +269,13 @@ void phy_prepare_link(struct phy_device *phydev,
  *   choose to call only the subset of functions which provide
  *   the desired functionality.
  */
-struct phy_device * phy_connect(struct net_device *dev, const char *phy_id,
+struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
 		void (*handler)(struct net_device *), u32 flags,
 		phy_interface_t interface)
 {
 	struct phy_device *phydev;
 
-	phydev = phy_attach(dev, phy_id, flags, interface);
+	phydev = phy_attach(dev, bus_id, flags, interface);
 
 	if (IS_ERR(phydev))
 		return phydev;
@@ -226,7 +316,7 @@ static int phy_compare_id(struct device *dev, void *data)
 /**
  * phy_attach - attach a network device to a particular PHY device
  * @dev: network device to attach
- * @phy_id: PHY device to attach
+ * @bus_id: PHY device to attach
  * @flags: PHY device's dev_flags
  * @interface: PHY device's interface
  *
@@ -238,7 +328,7 @@ static int phy_compare_id(struct device *dev, void *data)
  *     change.  The phy_device is returned to the attaching driver.
  */
 struct phy_device *phy_attach(struct net_device *dev,
-		const char *phy_id, u32 flags, phy_interface_t interface)
+		const char *bus_id, u32 flags, phy_interface_t interface)
 {
 	struct bus_type *bus = &mdio_bus_type;
 	struct phy_device *phydev;
@@ -246,12 +336,12 @@ struct phy_device *phy_attach(struct net_device *dev,
 
 	/* Search the list of PHY devices on the mdio bus for the
 	 * PHY with the requested name */
-	d = bus_find_device(bus, NULL, (void *)phy_id, phy_compare_id);
+	d = bus_find_device(bus, NULL, (void *)bus_id, phy_compare_id);
 
 	if (d) {
 		phydev = to_phy_device(d);
 	} else {
-		printk(KERN_ERR "%s not found\n", phy_id);
+		printk(KERN_ERR "%s not found\n", bus_id);
 		return ERR_PTR(-ENODEV);
 	}
 
@@ -271,7 +361,7 @@ struct phy_device *phy_attach(struct net_device *dev,
 
 	if (phydev->attached_dev) {
 		printk(KERN_ERR "%s: %s already attached\n",
-				dev->name, phy_id);
+				dev->name, bus_id);
 		return ERR_PTR(-EBUSY);
 	}
 
@@ -287,6 +377,11 @@ struct phy_device *phy_attach(struct net_device *dev,
 	if (phydev->drv->config_init) {
 		int err;
 
+		err = phy_scan_fixups(phydev);
+
+		if (err < 0)
+			return ERR_PTR(err);
+
 		err = phydev->drv->config_init(phydev);
 
 		if (err < 0)
@@ -395,6 +490,7 @@ EXPORT_SYMBOL(genphy_config_advert);
  */
 int genphy_setup_forced(struct phy_device *phydev)
 {
+	int err;
 	int ctl = 0;
 
 	phydev->pause = phydev->asym_pause = 0;
@@ -407,17 +503,26 @@ int genphy_setup_forced(struct phy_device *phydev)
 	if (DUPLEX_FULL == phydev->duplex)
 		ctl |= BMCR_FULLDPLX;
 	
-	ctl = phy_write(phydev, MII_BMCR, ctl);
+	err = phy_write(phydev, MII_BMCR, ctl);
 
-	if (ctl < 0)
-		return ctl;
+	if (err < 0)
+		return err;
+
+	/*
+	 * Run the fixups on this PHY, just in case the
+	 * board code needs to change something after a reset
+	 */
+	err = phy_scan_fixups(phydev);
+
+	if (err < 0)
+		return err;
 
 	/* We just reset the device, so we'd better configure any
 	 * settings the PHY requires to operate */
 	if (phydev->drv->config_init)
-		ctl = phydev->drv->config_init(phydev);
+		err = phydev->drv->config_init(phydev);
 
-	return ctl;
+	return err;
 }
 
 
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index dcbe01b..157fd93 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -86,7 +86,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.26.20"
+#define DRV_VERSION "2.0.26.22"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -117,20 +117,6 @@ static inline int RXD_IS_UP2DT(struct RxD_t *rxdp)
 
 #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \
 				      ADAPTER_STATUS_RMAC_LOCAL_FAULT)))
-#define TASKLET_IN_USE test_and_set_bit(0, (&sp->tasklet_status))
-#define PANIC	1
-#define LOW	2
-static inline int rx_buffer_level(struct s2io_nic * sp, int rxb_size, int ring)
-{
-	struct mac_info *mac_control;
-
-	mac_control = &sp->mac_control;
-	if (rxb_size <= rxd_count[sp->rxd_mode])
-		return PANIC;
-	else if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16)
-		return  LOW;
-	return 0;
-}
 
 static inline int is_s2io_card_up(const struct s2io_nic * sp)
 {
@@ -2458,7 +2444,7 @@ static void free_tx_buffers(struct s2io_nic *nic)
 	for (i = 0; i < config->tx_fifo_num; i++) {
 		unsigned long flags;
 		spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags);
-		for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) {
+		for (j = 0; j < config->tx_cfg[i].fifo_len; j++) {
 			txdp = (struct TxD *) \
 			mac_control->fifos[i].list_info[j].list_virt_addr;
 			skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
@@ -2544,7 +2530,6 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
 	struct config_param *config;
 	u64 tmp;
 	struct buffAdd *ba;
-	unsigned long flags;
 	struct RxD_t *first_rxdp = NULL;
 	u64 Buffer0_ptr = 0, Buffer1_ptr = 0;
 	struct RxD1 *rxdp1;
@@ -2592,15 +2577,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
 			DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n",
 				  dev->name, rxdp);
 		}
-		if(!napi) {
-			spin_lock_irqsave(&nic->put_lock, flags);
-			mac_control->rings[ring_no].put_pos =
-			(block_no * (rxd_count[nic->rxd_mode] + 1)) + off;
-			spin_unlock_irqrestore(&nic->put_lock, flags);
-		} else {
-			mac_control->rings[ring_no].put_pos =
-			(block_no * (rxd_count[nic->rxd_mode] + 1)) + off;
-		}
+
 		if ((rxdp->Control_1 & RXD_OWN_XENA) &&
 			((nic->rxd_mode == RXD_MODE_3B) &&
 				(rxdp->Control_2 & s2BIT(0)))) {
@@ -2978,7 +2955,7 @@ static void rx_intr_handler(struct ring_info *ring_data)
 {
 	struct s2io_nic *nic = ring_data->nic;
 	struct net_device *dev = (struct net_device *) nic->dev;
-	int get_block, put_block, put_offset;
+	int get_block, put_block;
 	struct rx_curr_get_info get_info, put_info;
 	struct RxD_t *rxdp;
 	struct sk_buff *skb;
@@ -2987,19 +2964,11 @@ static void rx_intr_handler(struct ring_info *ring_data)
 	struct RxD1* rxdp1;
 	struct RxD3* rxdp3;
 
-	spin_lock(&nic->rx_lock);
-
 	get_info = ring_data->rx_curr_get_info;
 	get_block = get_info.block_index;
 	memcpy(&put_info, &ring_data->rx_curr_put_info, sizeof(put_info));
 	put_block = put_info.block_index;
 	rxdp = ring_data->rx_blocks[get_block].rxds[get_info.offset].virt_addr;
-	if (!napi) {
-		spin_lock(&nic->put_lock);
-		put_offset = ring_data->put_pos;
-		spin_unlock(&nic->put_lock);
-	} else
-		put_offset = ring_data->put_pos;
 
 	while (RXD_IS_UP2DT(rxdp)) {
 		/*
@@ -3016,7 +2985,6 @@ static void rx_intr_handler(struct ring_info *ring_data)
 			DBG_PRINT(ERR_DBG, "%s: The skb is ",
 				  dev->name);
 			DBG_PRINT(ERR_DBG, "Null in Rx Intr\n");
-			spin_unlock(&nic->rx_lock);
 			return;
 		}
 		if (nic->rxd_mode == RXD_MODE_1) {
@@ -3072,8 +3040,6 @@ static void rx_intr_handler(struct ring_info *ring_data)
 			}
 		}
 	}
-
-	spin_unlock(&nic->rx_lock);
 }
 
 /**
@@ -4105,7 +4071,6 @@ static int s2io_close(struct net_device *dev)
 			do_s2io_delete_unicast_mc(sp, tmp64);
 	}
 
-	/* Reset card, kill tasklet and free Tx and Rx buffers. */
 	s2io_card_down(sp);
 
 	return 0;
@@ -4370,29 +4335,9 @@ s2io_alarm_handle(unsigned long data)
 
 static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n)
 {
-	int rxb_size, level;
-
-	if (!sp->lro) {
-		rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]);
-		level = rx_buffer_level(sp, rxb_size, rng_n);
-
-		if ((level == PANIC) && (!TASKLET_IN_USE)) {
-			int ret;
-			DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__);
-			DBG_PRINT(INTR_DBG, "PANIC levels\n");
-			if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) {
-				DBG_PRINT(INFO_DBG, "Out of memory in %s",
-					  __FUNCTION__);
-				clear_bit(0, (&sp->tasklet_status));
-				return -1;
-			}
-			clear_bit(0, (&sp->tasklet_status));
-		} else if (level == LOW)
-			tasklet_schedule(&sp->task);
-
-	} else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) {
-			DBG_PRINT(INFO_DBG, "%s:Out of memory", sp->dev->name);
-			DBG_PRINT(INFO_DBG, " in Rx Intr!!\n");
+	if (fill_rx_buffers(sp, rng_n) == -ENOMEM) {
+		DBG_PRINT(INFO_DBG, "%s:Out of memory", sp->dev->name);
+		DBG_PRINT(INFO_DBG, " in Rx Intr!!\n");
 	}
 	return 0;
 }
@@ -6770,49 +6715,6 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu)
 }
 
 /**
- *  s2io_tasklet - Bottom half of the ISR.
- *  @dev_adr : address of the device structure in dma_addr_t format.
- *  Description:
- *  This is the tasklet or the bottom half of the ISR. This is
- *  an extension of the ISR which is scheduled by the scheduler to be run
- *  when the load on the CPU is low. All low priority tasks of the ISR can
- *  be pushed into the tasklet. For now the tasklet is used only to
- *  replenish the Rx buffers in the Rx buffer descriptors.
- *  Return value:
- *  void.
- */
-
-static void s2io_tasklet(unsigned long dev_addr)
-{
-	struct net_device *dev = (struct net_device *) dev_addr;
-	struct s2io_nic *sp = dev->priv;
-	int i, ret;
-	struct mac_info *mac_control;
-	struct config_param *config;
-
-	mac_control = &sp->mac_control;
-	config = &sp->config;
-
-	if (!TASKLET_IN_USE) {
-		for (i = 0; i < config->rx_ring_num; i++) {
-			ret = fill_rx_buffers(sp, i);
-			if (ret == -ENOMEM) {
-				DBG_PRINT(INFO_DBG, "%s: Out of ",
-					  dev->name);
-				DBG_PRINT(INFO_DBG, "memory in tasklet\n");
-				break;
-			} else if (ret == -EFILL) {
-				DBG_PRINT(INFO_DBG,
-					  "%s: Rx Ring %d is full\n",
-					  dev->name, i);
-				break;
-			}
-		}
-		clear_bit(0, (&sp->tasklet_status));
-	}
-}
-
-/**
  * s2io_set_link - Set the LInk status
  * @data: long pointer to device private structue
  * Description: Sets the link status for the adapter
@@ -7161,7 +7063,6 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 {
 	int cnt = 0;
 	struct XENA_dev_config __iomem *bar0 = sp->bar0;
-	unsigned long flags;
 	register u64 val64 = 0;
 	struct config_param *config;
 	config = &sp->config;
@@ -7186,9 +7087,6 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 
 	s2io_rem_isr(sp);
 
-	/* Kill tasklet. */
-	tasklet_kill(&sp->task);
-
 	/* Check if the device is Quiescent and then Reset the NIC */
 	while(do_io) {
 		/* As per the HW requirement we need to replenish the
@@ -7223,9 +7121,7 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
 	free_tx_buffers(sp);
 
 	/* Free all Rx buffers */
-	spin_lock_irqsave(&sp->rx_lock, flags);
 	free_rx_buffers(sp);
-	spin_unlock_irqrestore(&sp->rx_lock, flags);
 
 	clear_bit(__S2IO_STATE_LINK_TASK, &(sp->state));
 }
@@ -7314,9 +7210,6 @@ static int s2io_card_up(struct s2io_nic * sp)
 
 	S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2));
 
-	/* Enable tasklet for the device */
-	tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev);
-
 	/*  Enable select interrupts */
 	en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS);
 	if (sp->config.intr_type != INTA)
@@ -8119,20 +8012,15 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	s2io_reset(sp);
 
 	/*
-	 * Initialize the tasklet status and link state flags
+	 * Initialize link state flags
 	 * and the card state parameter
 	 */
-	sp->tasklet_status = 0;
 	sp->state = 0;
 
 	/* Initialize spinlocks */
 	for (i = 0; i < sp->config.tx_fifo_num; i++)
 		spin_lock_init(&mac_control->fifos[i].tx_lock);
 
-	if (!napi)
-		spin_lock_init(&sp->put_lock);
-	spin_lock_init(&sp->rx_lock);
-
 	/*
 	 * SXE-002: Configure link and activity LED to init state
 	 * on driver load.
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index e68fdf7..ce53a02 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -703,9 +703,6 @@ struct ring_info {
 	 */
 	struct rx_curr_get_info rx_curr_get_info;
 
-	/* Index to the absolute position of the put pointer of Rx ring */
-	int put_pos;
-
 	/* Buffer Address store. */
 	struct buffAdd **ba;
 	struct s2io_nic *nic;
@@ -868,8 +865,6 @@ struct s2io_nic {
 	int device_enabled_once;
 
 	char name[60];
-	struct tasklet_struct task;
-	volatile unsigned long tasklet_status;
 
 	/* Timer that handles I/O errors/exceptions */
 	struct timer_list alarm_timer;
@@ -879,8 +874,6 @@ struct s2io_nic {
 
 	atomic_t rx_bufs_left[MAX_RX_RINGS];
 
-	spinlock_t put_lock;
-
 #define PROMISC     1
 #define ALL_MULTI   2
 
@@ -964,7 +957,6 @@ struct s2io_nic {
 	u8		lro;
 	u16		lro_max_aggr_per_sess;
 	volatile unsigned long state;
-	spinlock_t	rx_lock;
 	u64		general_int_mask;
 #define VPD_STRING_LEN 80
 	u8  product_name[VPD_STRING_LEN];
@@ -1094,7 +1086,6 @@ static void s2io_handle_errors(void * dev_id);
 static int s2io_starter(void);
 static void s2io_closer(void);
 static void s2io_tx_watchdog(struct net_device *dev);
-static void s2io_tasklet(unsigned long dev_addr);
 static void s2io_set_multicast(struct net_device *dev);
 static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp);
 static void s2io_link(struct s2io_nic * sp, int link);
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 78994ed..6261201 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -825,7 +825,8 @@ static struct platform_driver sgiseeq_driver = {
 	.probe	= sgiseeq_probe,
 	.remove	= __devexit_p(sgiseeq_remove),
 	.driver = {
-		.name	= "sgiseeq"
+		.name	= "sgiseeq",
+		.owner	= THIS_MODULE,
 	}
 };
 
@@ -850,3 +851,4 @@ module_exit(sgiseeq_module_exit);
 MODULE_DESCRIPTION("SGI Seeq 8003 driver");
 MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sgiseeq");
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 76cc1d3..4e28002 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -92,6 +92,7 @@ module_param(tx_fifo_kb, int, 0400);
 MODULE_PARM_DESC(tx_fifo_kb,"transmit FIFO size in KB (1<x<15)(default=8)");
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:smc911x");
 
 /*
  * The internal workings of the driver.  If you are changing anything
@@ -243,7 +244,7 @@ static void smc911x_reset(struct net_device *dev)
 		do {
 			udelay(10);
 			reg = SMC_GET_PMT_CTRL() & PMT_CTRL_READY_;
-		} while ( timeout-- && !reg);
+		} while (--timeout && !reg);
 		if (timeout == 0) {
 			PRINTK("%s: smc911x_reset timeout waiting for PM restore\n", dev->name);
 			return;
@@ -267,7 +268,7 @@ static void smc911x_reset(struct net_device *dev)
 				resets++;
 				break;
 			}
-		} while ( timeout-- && (reg & HW_CFG_SRST_));
+		} while (--timeout && (reg & HW_CFG_SRST_));
 	}
 	if (timeout == 0) {
 		PRINTK("%s: smc911x_reset timeout waiting for reset\n", dev->name);
@@ -413,7 +414,7 @@ static inline void smc911x_drop_pkt(struct net_device *dev)
 		do {
 			udelay(10);
 			reg = SMC_GET_RX_DP_CTRL() & RX_DP_CTRL_FFWD_BUSY_;
-		} while ( timeout-- && reg);
+		} while (--timeout && reg);
 		if (timeout == 0) {
 			PRINTK("%s: timeout waiting for RX fast forward\n", dev->name);
 		}
@@ -2262,6 +2263,7 @@ static struct platform_driver smc911x_driver = {
 	.resume	 = smc911x_drv_resume,
 	.driver	 = {
 		.name	 = CARDNAME,
+		.owner	= THIS_MODULE,
 	},
 };
 
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 600b92a..a188e33 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -132,6 +132,7 @@ module_param(watchdog, int, 0400);
 MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:smc91x");
 
 /*
  * The internal workings of the driver.  If you are changing anything
@@ -2308,6 +2309,7 @@ static struct platform_driver smc_driver = {
 	.resume		= smc_drv_resume,
 	.driver		= {
 		.name	= CARDNAME,
+		.owner	= THIS_MODULE,
 	},
 };
 
diff --git a/drivers/net/sni_82596.c b/drivers/net/sni_82596.c
index 2cf6794..854ccf2 100644
--- a/drivers/net/sni_82596.c
+++ b/drivers/net/sni_82596.c
@@ -44,6 +44,7 @@ static const char sni_82596_string[] = "snirm_82596";
 MODULE_AUTHOR("Thomas Bogendoerfer");
 MODULE_DESCRIPTION("i82596 driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:snirm_82596");
 module_param(i596_debug, int, 0);
 MODULE_PARM_DESC(i596_debug, "82596 debug mask");
 
@@ -166,6 +167,7 @@ static struct platform_driver sni_82596_driver = {
 	.remove	= __devexit_p(sni_82596_driver_remove),
 	.driver	= {
 		.name	= sni_82596_string,
+		.owner	= THIS_MODULE,
 	},
 };
 
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 17585e5..e83b166 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -625,6 +625,12 @@ static void __init bdx_firmware_endianess(void)
 		s_firmLoad[i] = CPU_CHIP_SWAP32(s_firmLoad[i]);
 }
 
+static int bdx_range_check(struct bdx_priv *priv, u32 offset)
+{
+	return (offset > (u32) (BDX_REGS_SIZE / priv->nic->port_num)) ?
+		-EINVAL : 0;
+}
+
 static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
 {
 	struct bdx_priv *priv = ndev->priv;
@@ -643,9 +649,15 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
 		DBG("%d 0x%x 0x%x\n", data[0], data[1], data[2]);
 	}
 
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
 	switch (data[0]) {
 
 	case BDX_OP_READ:
+		error = bdx_range_check(priv, data[1]);
+		if (error < 0)
+			return error;
 		data[2] = READ_REG(priv, data[1]);
 		DBG("read_reg(0x%x)=0x%x (dec %d)\n", data[1], data[2],
 		    data[2]);
@@ -655,6 +667,9 @@ static int bdx_ioctl_priv(struct net_device *ndev, struct ifreq *ifr, int cmd)
 		break;
 
 	case BDX_OP_WRITE:
+		error = bdx_range_check(priv, data[1]);
+		if (error < 0)
+			return error;
 		WRITE_REG(priv, data[1], data[2]);
 		DBG("write_reg(0x%x, 0x%x)\n", data[1], data[2]);
 		break;
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 6f33f84..6017d52 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -162,6 +162,7 @@ static struct platform_driver tsi_eth_driver = {
 	.remove = tsi108_ether_remove,
 	.driver	= {
 		.name = "tsi-ethernet",
+		.owner = THIS_MODULE,
 	},
 };
 
@@ -1729,3 +1730,4 @@ module_exit(tsi108_ether_exit);
 MODULE_AUTHOR("Tundra Semiconductor Corporation");
 MODULE_DESCRIPTION("Tsi108 Gigabit Ethernet driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:tsi-ethernet");
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 333961b..c0dd25b 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -2183,7 +2183,6 @@ typhoon_resume(struct pci_dev *pdev)
 	}
 
 	netif_device_attach(dev);
-	netif_start_queue(dev);
 	return 0;
 
 reset:
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 29a4d65..0aac91c 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -3926,7 +3926,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 	ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
 	fixed_link = of_get_property(np, "fixed-link", NULL);
 	if (fixed_link) {
-		ug_info->mdio_bus = 0;
+		snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "0");
 		ug_info->phy_address = fixed_link[0];
 		phy = NULL;
 	} else {
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index ed1afaf..6b8d882 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -605,7 +605,6 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index,
 static void velocity_init_cam_filter(struct velocity_info *vptr)
 {
 	struct mac_regs __iomem * regs = vptr->mac_regs;
-	unsigned short vid;
 
 	/* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
 	WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
@@ -617,29 +616,33 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)
 	mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
 	mac_set_cam_mask(regs, vptr->mCAMmask);
 
-	/* Enable first VCAM */
+	/* Enable VCAMs */
 	if (vptr->vlgrp) {
-		for (vid = 0; vid < VLAN_VID_MASK; vid++) {
-			if (vlan_group_get_device(vptr->vlgrp, vid)) {
-				/* If Tagging option is enabled and
-				   VLAN ID is not zero, then
-				   turn on MCFG_RTGOPT also */
-				if (vid != 0)
-					WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
+		unsigned int vid, i = 0;
+
+		if (!vlan_group_get_device(vptr->vlgrp, 0))
+			WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
 
-				mac_set_vlan_cam(regs, 0, (u8 *) &vid);
+		for (vid = 1; (vid < VLAN_VID_MASK); vid++) {
+			if (vlan_group_get_device(vptr->vlgrp, vid)) {
+				mac_set_vlan_cam(regs, i, (u8 *) &vid);
+				vptr->vCAMmask[i / 8] |= 0x1 << (i % 8);
+				if (++i >= VCAM_SIZE)
+					break;
 			}
 		}
-		vptr->vCAMmask[0] |= 1;
 		mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
-	} else {
-		u16 temp = 0;
-		mac_set_vlan_cam(regs, 0, (u8 *) &temp);
-		temp = 1;
-		mac_set_vlan_cam_mask(regs, (u8 *) &temp);
 	}
 }
 
+static void velocity_vlan_rx_register(struct net_device *dev,
+				      struct vlan_group *grp)
+{
+	struct velocity_info *vptr = netdev_priv(dev);
+
+	vptr->vlgrp = grp;
+}
+
 static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
 {
 	struct velocity_info *vptr = netdev_priv(dev);
@@ -959,11 +962,13 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
 
 	dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid;
 	dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid;
+	dev->vlan_rx_register = velocity_vlan_rx_register;
 
 #ifdef  VELOCITY_ZERO_COPY_SUPPORT
 	dev->features |= NETIF_F_SG;
 #endif
-	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER;
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER |
+		NETIF_F_HW_VLAN_RX;
 
 	if (vptr->flags & VELOCITY_FLAGS_TX_CSUM)
 		dev->features |= NETIF_F_IP_CSUM;
@@ -1597,8 +1602,13 @@ static int velocity_receive_frame(struct velocity_info *vptr, int idx)
 	skb_put(skb, pkt_len - 4);
 	skb->protocol = eth_type_trans(skb, vptr->dev);
 
+	if (vptr->vlgrp && (rd->rdesc0.RSR & RSR_DETAG)) {
+		vlan_hwaccel_rx(skb, vptr->vlgrp,
+				swab16(le16_to_cpu(rd->rdesc1.PQTAG)));
+	} else
+		netif_rx(skb);
+
 	stats->rx_bytes += pkt_len;
-	netif_rx(skb);
 
 	return 0;
 }
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index c4c8eab..c2cc42f 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -402,7 +402,7 @@ static int __init c101_init(void)
 #ifdef MODULE
 		printk(KERN_INFO "c101: no card initialized\n");
 #endif
-		return -ENOSYS;	/* no parameters specified, abort */
+		return -EINVAL;	/* no parameters specified, abort */
 	}
 
 	printk(KERN_INFO "%s\n", version);
@@ -420,11 +420,11 @@ static int __init c101_init(void)
 			c101_run(irq, ram);
 
 		if (*hw == '\x0')
-			return first_card ? 0 : -ENOSYS;
+			return first_card ? 0 : -EINVAL;
 	}while(*hw++ == ':');
 
 	printk(KERN_ERR "c101: invalid hardware parameters\n");
-	return first_card ? 0 : -ENOSYS;
+	return first_card ? 0 : -EINVAL;
 }
 
 
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index c4ab032..520bb0b 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1090,10 +1090,6 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
 	pvc_device *pvc = NULL;
 	struct net_device *dev;
 	int result, used;
-	char * prefix = "pvc%d";
-
-	if (type == ARPHRD_ETHER)
-		prefix = "pvceth%d";
 
 	if ((pvc = add_pvc(frad, dlci)) == NULL) {
 		printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n",
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 779cbcd..02df20f 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -379,6 +379,18 @@ struct phy_driver {
 };
 #define to_phy_driver(d) container_of(d, struct phy_driver, driver)
 
+#define PHY_ANY_ID "MATCH ANY PHY"
+#define PHY_ANY_UID 0xffffffff
+
+/* A Structure for boards to register fixups with the PHY Lib */
+struct phy_fixup {
+	struct list_head list;
+	char bus_id[BUS_ID_SIZE];
+	u32 phy_uid;
+	u32 phy_uid_mask;
+	int (*run)(struct phy_device *phydev);
+};
+
 int phy_read(struct phy_device *phydev, u16 regnum);
 int phy_write(struct phy_device *phydev, u16 regnum, u16 val);
 int get_phy_id(struct mii_bus *bus, int addr, u32 *phy_id);
@@ -386,8 +398,8 @@ struct phy_device* get_phy_device(struct mii_bus *bus, int addr);
 int phy_clear_interrupt(struct phy_device *phydev);
 int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
 struct phy_device * phy_attach(struct net_device *dev,
-		const char *phy_id, u32 flags, phy_interface_t interface);
-struct phy_device * phy_connect(struct net_device *dev, const char *phy_id,
+		const char *bus_id, u32 flags, phy_interface_t interface);
+struct phy_device * phy_connect(struct net_device *dev, const char *bus_id,
 		void (*handler)(struct net_device *), u32 flags,
 		phy_interface_t interface);
 void phy_disconnect(struct phy_device *phydev);
@@ -427,5 +439,13 @@ void phy_print_status(struct phy_device *phydev);
 struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id);
 void phy_device_free(struct phy_device *phydev);
 
+int phy_register_fixup(const char *bus_id, u32 phy_uid, u32 phy_uid_mask,
+		int (*run)(struct phy_device *));
+int phy_register_fixup_for_id(const char *bus_id,
+		int (*run)(struct phy_device *));
+int phy_register_fixup_for_uid(u32 phy_uid, u32 phy_uid_mask,
+		int (*run)(struct phy_device *));
+int phy_scan_fixups(struct phy_device *phydev);
+
 extern struct bus_type mdio_bus_type;
 #endif /* __PHY_H */

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-03-29  2:24 Jeff Garzik
@ 2008-03-29  3:02 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2008-03-29  3:02 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel, akpm

From: Jeff Garzik <jeff@garzik.org>
Date: Fri, 28 Mar 2008 22:24:21 -0400

> 
> Updates for net-2.6.26.
> 
> 
> Please pull from 'upstream-net26' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-net26
> 
> to receive the following updates:

Pulled and pushed out to net-2.6.26, thanks Jeff.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2008-03-29  2:24 Jeff Garzik
  2008-03-29  3:02 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2008-03-29  2:24 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML, Andrew Morton


Updates for net-2.6.26.


Please pull from 'upstream-net26' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-net26

to receive the following updates:

 drivers/net/3c509.c            |  729 ++++++++++++++++++++--------------------
 drivers/net/arcnet/arcnet.c    |    5 +-
 drivers/net/e1000e/82571.c     |  127 +++++---
 drivers/net/e1000e/Makefile    |    2 +-
 drivers/net/e1000e/defines.h   |  109 ++++---
 drivers/net/e1000e/e1000.h     |   29 +-
 drivers/net/e1000e/es2lan.c    |  105 ++++---
 drivers/net/e1000e/ethtool.c   |  161 ++++++----
 drivers/net/e1000e/hw.h        |  171 +++++-----
 drivers/net/e1000e/ich8lan.c   |  279 +++++++++-------
 drivers/net/e1000e/lib.c       |  286 ++++++++++-------
 drivers/net/e1000e/netdev.c    |  592 +++++++++++++++++++++------------
 drivers/net/e1000e/param.c     |   33 ++-
 drivers/net/e1000e/phy.c       |  164 ++++++----
 drivers/net/ehea/ehea.h        |    6 +-
 drivers/net/ehea/ehea_main.c   |   90 +++---
 drivers/net/ixgbe/ixgbe_main.c |    6 +-
 drivers/net/tokenring/3c359.c  |   21 +-
 drivers/net/yellowfin.c        |    4 +-
 include/linux/arcdevice.h      |    4 +-
 20 files changed, 1678 insertions(+), 1245 deletions(-)

Bruce Allan (1):
      e1000e: reformat comment blocks, cosmetic changes only

Daniel Walker (5):
      netdev: ehea: semaphore to mutex
      netdev: ehea: ehea_fw_handles semaphore to mutex
      netdev: ehea: locking order correction
      netdev: ehea: bcmc_regs semaphore to mutex
      netdev: ehea: port_lock semaphore to mutex

Denis V. Lunev (1):
      Compilation fix for ixgbe_main.c.

Jeff Kirsher (2):
      e1000e: rename mc_addr_list_update
      e1000e: reorganize PHY and flow control interface

Mariusz Kozlowski (1):
      net: yellowfin parenthesis fix

Ondrej Zary (1):
      3c509: convert to isa_driver and pnp_driver

S.Caglar Onur (2):
      drivers/net/arcnet/arcnet.c: use time_* macros
      drivers/net/tokenring/3c359.c: use time_* macros

diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index 8fafac9..54dac06 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -54,25 +54,24 @@
 		v1.19a 28Oct2002 Davud Ruggiero <jdr@farfalle.com>
 			- Increase *read_eeprom udelay to workaround oops with 2 cards.
 		v1.19b 08Nov2002 Marc Zyngier <maz@wild-wind.fr.eu.org>
-		    - Introduce driver model for EISA cards.
+			- Introduce driver model for EISA cards.
+		v1.20  04Feb2008 Ondrej Zary <linux@rainbow-software.org>
+			- convert to isa_driver and pnp_driver and some cleanups
 */
 
 #define DRV_NAME	"3c509"
-#define DRV_VERSION	"1.19b"
-#define DRV_RELDATE	"08Nov2002"
+#define DRV_VERSION	"1.20"
+#define DRV_RELDATE	"04Feb2008"
 
 /* A few values that may be tweaked. */
 
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (400*HZ/1000)
-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 10;
 
 #include <linux/module.h>
-#ifdef CONFIG_MCA
 #include <linux/mca.h>
-#endif
-#include <linux/isapnp.h>
+#include <linux/isa.h>
+#include <linux/pnp.h>
 #include <linux/string.h>
 #include <linux/interrupt.h>
 #include <linux/errno.h>
@@ -97,10 +96,6 @@ static int max_interrupt_work = 10;
 
 static char version[] __initdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n";
 
-#if defined(CONFIG_PM) && (defined(CONFIG_MCA) || defined(CONFIG_EISA))
-#define EL3_SUSPEND
-#endif
-
 #ifdef EL3_DEBUG
 static int el3_debug = EL3_DEBUG;
 #else
@@ -111,6 +106,7 @@ static int el3_debug = 2;
  * a global variable so that the mca/eisa probe routines can increment
  * it */
 static int el3_cards = 0;
+#define EL3_MAX_CARDS 8
 
 /* To minimize the size of the driver source I only define operating
    constants if they are used several times.  You'll need the manual
@@ -119,7 +115,7 @@ static int el3_cards = 0;
 #define EL3_DATA 0x00
 #define EL3_CMD 0x0e
 #define EL3_STATUS 0x0e
-#define	 EEPROM_READ 0x80
+#define	EEPROM_READ 0x80
 
 #define EL3_IO_EXTENT	16
 
@@ -168,23 +164,31 @@ enum RxFilter {
  */
 #define SKB_QUEUE_SIZE	64
 
+enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_MCA, EL3_EISA };
+
 struct el3_private {
 	struct net_device_stats stats;
-	struct net_device *next_dev;
 	spinlock_t lock;
 	/* skb send-queue */
 	int head, size;
 	struct sk_buff *queue[SKB_QUEUE_SIZE];
-	enum {
-		EL3_MCA,
-		EL3_PNP,
-		EL3_EISA,
-	} type;						/* type of device */
-	struct device *dev;
+	enum el3_cardtype type;
 };
-static int id_port __initdata = 0x110;	/* Start with 0x110 to avoid new sound cards.*/
-static struct net_device *el3_root_dev;
+static int id_port;
+static int current_tag;
+static struct net_device *el3_devs[EL3_MAX_CARDS];
+
+/* Parameters that may be passed into the module. */
+static int debug = -1;
+static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+static int max_interrupt_work = 10;
+#ifdef CONFIG_PNP
+static int nopnp;
+#endif
 
+static int __init el3_common_init(struct net_device *dev);
+static void el3_common_remove(struct net_device *dev);
 static ushort id_read_eeprom(int index);
 static ushort read_eeprom(int ioaddr, int index);
 static int el3_open(struct net_device *dev);
@@ -199,7 +203,7 @@ static void el3_tx_timeout (struct net_device *dev);
 static void el3_down(struct net_device *dev);
 static void el3_up(struct net_device *dev);
 static const struct ethtool_ops ethtool_ops;
-#ifdef EL3_SUSPEND
+#ifdef CONFIG_PM
 static int el3_suspend(struct device *, pm_message_t);
 static int el3_resume(struct device *);
 #else
@@ -209,13 +213,272 @@ static int el3_resume(struct device *);
 
 
 /* generic device remove for all device types */
-#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
 static int el3_device_remove (struct device *device);
-#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void el3_poll_controller(struct net_device *dev);
 #endif
 
+/* Return 0 on success, 1 on error, 2 when found already detected PnP card */
+static int el3_isa_id_sequence(__be16 *phys_addr)
+{
+	short lrs_state = 0xff;
+	int i;
+
+	/* ISA boards are detected by sending the ID sequence to the
+	   ID_PORT.  We find cards past the first by setting the 'current_tag'
+	   on cards as they are found.  Cards with their tag set will not
+	   respond to subsequent ID sequences. */
+
+	outb(0x00, id_port);
+	outb(0x00, id_port);
+	for (i = 0; i < 255; i++) {
+		outb(lrs_state, id_port);
+		lrs_state <<= 1;
+		lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
+	}
+	/* For the first probe, clear all board's tag registers. */
+	if (current_tag == 0)
+		outb(0xd0, id_port);
+	else			/* Otherwise kill off already-found boards. */
+		outb(0xd8, id_port);
+	if (id_read_eeprom(7) != 0x6d50)
+		return 1;
+	/* Read in EEPROM data, which does contention-select.
+	   Only the lowest address board will stay "on-line".
+	   3Com got the byte order backwards. */
+	for (i = 0; i < 3; i++)
+		phys_addr[i] = htons(id_read_eeprom(i));
+#ifdef CONFIG_PNP
+	if (!nopnp) {
+		/* The ISA PnP 3c509 cards respond to the ID sequence too.
+		   This check is needed in order not to register them twice. */
+		for (i = 0; i < el3_cards; i++) {
+			struct el3_private *lp = netdev_priv(el3_devs[i]);
+			if (lp->type == EL3_PNP
+			    && !memcmp(phys_addr, el3_devs[i]->dev_addr,
+				       ETH_ALEN)) {
+				if (el3_debug > 3)
+					printk(KERN_DEBUG "3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
+						phys_addr[0] & 0xff, phys_addr[0] >> 8,
+						phys_addr[1] & 0xff, phys_addr[1] >> 8,
+						phys_addr[2] & 0xff, phys_addr[2] >> 8);
+				/* Set the adaptor tag so that the next card can be found. */
+				outb(0xd0 + ++current_tag, id_port);
+				return 2;
+			}
+		}
+	}
+#endif /* CONFIG_PNP */
+	return 0;
+
+}
+
+static void __devinit el3_dev_fill(struct net_device *dev, __be16 *phys_addr,
+				   int ioaddr, int irq, int if_port,
+				   enum el3_cardtype type)
+{
+	struct el3_private *lp = netdev_priv(dev);
+
+	memcpy(dev->dev_addr, phys_addr, ETH_ALEN);
+	dev->base_addr = ioaddr;
+	dev->irq = irq;
+	dev->if_port = if_port;
+	lp->type = type;
+}
+
+static int __devinit el3_isa_match(struct device *pdev,
+				   unsigned int ndev)
+{
+	struct net_device *dev;
+	int ioaddr, isa_irq, if_port, err;
+	unsigned int iobase;
+	__be16 phys_addr[3];
+
+	while ((err = el3_isa_id_sequence(phys_addr)) == 2)
+		;	/* Skip to next card when PnP card found */
+	if (err == 1)
+		return 0;
+
+	iobase = id_read_eeprom(8);
+	if_port = iobase >> 14;
+	ioaddr = 0x200 + ((iobase & 0x1f) << 4);
+	if (irq[el3_cards] > 1 && irq[el3_cards] < 16)
+		isa_irq = irq[el3_cards];
+	else
+		isa_irq = id_read_eeprom(9) >> 12;
+
+	dev = alloc_etherdev(sizeof(struct el3_private));
+	if (!dev)
+		return -ENOMEM;
+
+	netdev_boot_setup_check(dev);
+
+	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-isa")) {
+		free_netdev(dev);
+		return 0;
+	}
+
+	/* Set the adaptor tag so that the next card can be found. */
+	outb(0xd0 + ++current_tag, id_port);
+
+	/* Activate the adaptor at the EEPROM location. */
+	outb((ioaddr >> 4) | 0xe0, id_port);
+
+	EL3WINDOW(0);
+	if (inw(ioaddr) != 0x6d50) {
+		free_netdev(dev);
+		return 0;
+	}
+
+	/* Free the interrupt so that some other card can use it. */
+	outw(0x0f00, ioaddr + WN0_IRQ);
+
+	el3_dev_fill(dev, phys_addr, ioaddr, isa_irq, if_port, EL3_ISA);
+	dev_set_drvdata(pdev, dev);
+	if (el3_common_init(dev)) {
+		free_netdev(dev);
+		return 0;
+	}
+
+	el3_devs[el3_cards++] = dev;
+	return 1;
+}
+
+static int __devexit el3_isa_remove(struct device *pdev,
+				    unsigned int ndev)
+{
+	el3_device_remove(pdev);
+	dev_set_drvdata(pdev, NULL);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int el3_isa_suspend(struct device *dev, unsigned int n,
+			   pm_message_t state)
+{
+	current_tag = 0;
+	return el3_suspend(dev, state);
+}
+
+static int el3_isa_resume(struct device *dev, unsigned int n)
+{
+	struct net_device *ndev = dev_get_drvdata(dev);
+	int ioaddr = ndev->base_addr, err;
+	__be16 phys_addr[3];
+
+	while ((err = el3_isa_id_sequence(phys_addr)) == 2)
+		;	/* Skip to next card when PnP card found */
+	if (err == 1)
+		return 0;
+	/* Set the adaptor tag so that the next card can be found. */
+	outb(0xd0 + ++current_tag, id_port);
+	/* Enable the card */
+	outb((ioaddr >> 4) | 0xe0, id_port);
+	EL3WINDOW(0);
+	if (inw(ioaddr) != 0x6d50)
+		return 1;
+	/* Free the interrupt so that some other card can use it. */
+	outw(0x0f00, ioaddr + WN0_IRQ);
+	return el3_resume(dev);
+}
+#endif
+
+static struct isa_driver el3_isa_driver = {
+	.match		= el3_isa_match,
+	.remove		= __devexit_p(el3_isa_remove),
+#ifdef CONFIG_PM
+	.suspend	= el3_isa_suspend,
+	.resume		= el3_isa_resume,
+#endif
+	.driver		= {
+		.name	= "3c509"
+	},
+};
+static int isa_registered;
+
+#ifdef CONFIG_PNP
+static struct pnp_device_id el3_pnp_ids[] = {
+	{ .id = "TCM5090" }, /* 3Com Etherlink III (TP) */
+	{ .id = "TCM5091" }, /* 3Com Etherlink III */
+	{ .id = "TCM5094" }, /* 3Com Etherlink III (combo) */
+	{ .id = "TCM5095" }, /* 3Com Etherlink III (TPO) */
+	{ .id = "TCM5098" }, /* 3Com Etherlink III (TPC) */
+	{ .id = "PNP80f7" }, /* 3Com Etherlink III compatible */
+	{ .id = "PNP80f8" }, /* 3Com Etherlink III compatible */
+	{ .id = "" }
+};
+MODULE_DEVICE_TABLE(pnp, el3_pnp_ids);
+
+static int __devinit el3_pnp_probe(struct pnp_dev *pdev,
+				    const struct pnp_device_id *id)
+{
+	short i;
+	int ioaddr, irq, if_port;
+	u16 phys_addr[3];
+	struct net_device *dev = NULL;
+	int err;
+
+	ioaddr = pnp_port_start(pdev, 0);
+	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509-pnp"))
+		return -EBUSY;
+	irq = pnp_irq(pdev, 0);
+	EL3WINDOW(0);
+	for (i = 0; i < 3; i++)
+		phys_addr[i] = htons(read_eeprom(ioaddr, i));
+	if_port = read_eeprom(ioaddr, 8) >> 14;
+	dev = alloc_etherdev(sizeof(struct el3_private));
+	if (!dev) {
+		release_region(ioaddr, EL3_IO_EXTENT);
+		return -ENOMEM;
+	}
+	SET_NETDEV_DEV(dev, &pdev->dev);
+	netdev_boot_setup_check(dev);
+
+	el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_PNP);
+	pnp_set_drvdata(pdev, dev);
+	err = el3_common_init(dev);
+
+	if (err) {
+		pnp_set_drvdata(pdev, NULL);
+		free_netdev(dev);
+		return err;
+	}
+
+	el3_devs[el3_cards++] = dev;
+	return 0;
+}
+
+static void __devexit el3_pnp_remove(struct pnp_dev *pdev)
+{
+	el3_common_remove(pnp_get_drvdata(pdev));
+	pnp_set_drvdata(pdev, NULL);
+}
+
+#ifdef CONFIG_PM
+static int el3_pnp_suspend(struct pnp_dev *pdev, pm_message_t state)
+{
+	return el3_suspend(&pdev->dev, state);
+}
+
+static int el3_pnp_resume(struct pnp_dev *pdev)
+{
+	return el3_resume(&pdev->dev);
+}
+#endif
+
+static struct pnp_driver el3_pnp_driver = {
+	.name		= "3c509",
+	.id_table	= el3_pnp_ids,
+	.probe		= el3_pnp_probe,
+	.remove		= __devexit_p(el3_pnp_remove),
+#ifdef CONFIG_PM
+	.suspend	= el3_pnp_suspend,
+	.resume		= el3_pnp_resume,
+#endif
+};
+static int pnp_registered;
+#endif /* CONFIG_PNP */
+
 #ifdef CONFIG_EISA
 static struct eisa_device_id el3_eisa_ids[] = {
 		{ "TCM5092" },
@@ -230,13 +493,14 @@ static int el3_eisa_probe (struct device *device);
 static struct eisa_driver el3_eisa_driver = {
 		.id_table = el3_eisa_ids,
 		.driver   = {
-				.name    = "3c509",
+				.name    = "3c579",
 				.probe   = el3_eisa_probe,
 				.remove  = __devexit_p (el3_device_remove),
 				.suspend = el3_suspend,
 				.resume  = el3_resume,
 		}
 };
+static int eisa_registered;
 #endif
 
 #ifdef CONFIG_MCA
@@ -271,45 +535,9 @@ static struct mca_driver el3_mca_driver = {
 				.resume  = el3_resume,
 		},
 };
+static int mca_registered;
 #endif /* CONFIG_MCA */
 
-#if defined(__ISAPNP__)
-static struct isapnp_device_id el3_isapnp_adapters[] __initdata = {
-	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5090),
-		(long) "3Com Etherlink III (TP)" },
-	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5091),
-		(long) "3Com Etherlink III" },
-	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5094),
-		(long) "3Com Etherlink III (combo)" },
-	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5095),
-		(long) "3Com Etherlink III (TPO)" },
-	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5098),
-		(long) "3Com Etherlink III (TPC)" },
-	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_FUNCTION(0x80f7),
-		(long) "3Com Etherlink III compatible" },
-	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('P', 'N', 'P'), ISAPNP_FUNCTION(0x80f8),
-		(long) "3Com Etherlink III compatible" },
-	{ }	/* terminate list */
-};
-
-static __be16 el3_isapnp_phys_addr[8][3];
-static int nopnp;
-#endif /* __ISAPNP__ */
-
-/* With the driver model introduction for EISA devices, both init
- * and cleanup have been split :
- * - EISA devices probe/remove starts in el3_eisa_probe/el3_device_remove
- * - MCA/ISA still use el3_probe
- *
- * Both call el3_common_init/el3_common_remove. */
-
 static int __init el3_common_init(struct net_device *dev)
 {
 	struct el3_private *lp = netdev_priv(dev);
@@ -360,231 +588,11 @@ static int __init el3_common_init(struct net_device *dev)
 
 static void el3_common_remove (struct net_device *dev)
 {
-	struct el3_private *lp = netdev_priv(dev);
-
-	(void) lp;				/* Keep gcc quiet... */
-#if defined(__ISAPNP__)
-	if (lp->type == EL3_PNP)
-		pnp_device_detach(to_pnp_dev(lp->dev));
-#endif
-
 	unregister_netdev (dev);
 	release_region(dev->base_addr, EL3_IO_EXTENT);
 	free_netdev (dev);
 }
 
-static int __init el3_probe(int card_idx)
-{
-	struct net_device *dev;
-	struct el3_private *lp;
-	short lrs_state = 0xff, i;
-	int ioaddr, irq, if_port;
-	__be16 phys_addr[3];
-	static int current_tag;
-	int err = -ENODEV;
-#if defined(__ISAPNP__)
-	static int pnp_cards;
-	struct pnp_dev *idev = NULL;
-	int pnp_found = 0;
-
-	if (nopnp == 1)
-		goto no_pnp;
-
-	for (i=0; el3_isapnp_adapters[i].vendor != 0; i++) {
-		int j;
-		while ((idev = pnp_find_dev(NULL,
-					    el3_isapnp_adapters[i].vendor,
-					    el3_isapnp_adapters[i].function,
-					    idev))) {
-			if (pnp_device_attach(idev) < 0)
-				continue;
-			if (pnp_activate_dev(idev) < 0) {
-__again:
-				pnp_device_detach(idev);
-				continue;
-			}
-			if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0))
-				goto __again;
-			ioaddr = pnp_port_start(idev, 0);
-			if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509 PnP")) {
-				pnp_device_detach(idev);
-				return -EBUSY;
-			}
-			irq = pnp_irq(idev, 0);
-			if (el3_debug > 3)
-				printk ("ISAPnP reports %s at i/o 0x%x, irq %d\n",
-					(char*) el3_isapnp_adapters[i].driver_data, ioaddr, irq);
-			EL3WINDOW(0);
-			for (j = 0; j < 3; j++)
-				el3_isapnp_phys_addr[pnp_cards][j] =
-					phys_addr[j] =
-						htons(read_eeprom(ioaddr, j));
-			if_port = read_eeprom(ioaddr, 8) >> 14;
-			dev = alloc_etherdev(sizeof (struct el3_private));
-			if (!dev) {
-					release_region(ioaddr, EL3_IO_EXTENT);
-					pnp_device_detach(idev);
-					return -ENOMEM;
-			}
-
-			SET_NETDEV_DEV(dev, &idev->dev);
-			pnp_cards++;
-
-			netdev_boot_setup_check(dev);
-			pnp_found = 1;
-			goto found;
-		}
-	}
-no_pnp:
-#endif /* __ISAPNP__ */
-
-	/* Select an open I/O location at 0x1*0 to do contention select. */
-	for ( ; id_port < 0x200; id_port += 0x10) {
-		if (!request_region(id_port, 1, "3c509"))
-			continue;
-		outb(0x00, id_port);
-		outb(0xff, id_port);
-		if (inb(id_port) & 0x01){
-			release_region(id_port, 1);
-			break;
-		} else
-			release_region(id_port, 1);
-	}
-	if (id_port >= 0x200) {
-		/* Rare -- do we really need a warning? */
-		printk(" WARNING: No I/O port available for 3c509 activation.\n");
-		return -ENODEV;
-	}
-
-	/* Next check for all ISA bus boards by sending the ID sequence to the
-	   ID_PORT.  We find cards past the first by setting the 'current_tag'
-	   on cards as they are found.  Cards with their tag set will not
-	   respond to subsequent ID sequences. */
-
-	outb(0x00, id_port);
-	outb(0x00, id_port);
-	for(i = 0; i < 255; i++) {
-		outb(lrs_state, id_port);
-		lrs_state <<= 1;
-		lrs_state = lrs_state & 0x100 ? lrs_state ^ 0xcf : lrs_state;
-	}
-
-	/* For the first probe, clear all board's tag registers. */
-	if (current_tag == 0)
-		outb(0xd0, id_port);
-	else				/* Otherwise kill off already-found boards. */
-		outb(0xd8, id_port);
-
-	if (id_read_eeprom(7) != 0x6d50) {
-		return -ENODEV;
-	}
-
-	/* Read in EEPROM data, which does contention-select.
-	   Only the lowest address board will stay "on-line".
-	   3Com got the byte order backwards. */
-	for (i = 0; i < 3; i++) {
-		phys_addr[i] = htons(id_read_eeprom(i));
-	}
-
-#if defined(__ISAPNP__)
-	if (nopnp == 0) {
-		/* The ISA PnP 3c509 cards respond to the ID sequence.
-		   This check is needed in order not to register them twice. */
-		for (i = 0; i < pnp_cards; i++) {
-			if (phys_addr[0] == el3_isapnp_phys_addr[i][0] &&
-			    phys_addr[1] == el3_isapnp_phys_addr[i][1] &&
-			    phys_addr[2] == el3_isapnp_phys_addr[i][2])
-			{
-				if (el3_debug > 3)
-					printk("3c509 with address %02x %02x %02x %02x %02x %02x was found by ISAPnP\n",
-						phys_addr[0] & 0xff, phys_addr[0] >> 8,
-						phys_addr[1] & 0xff, phys_addr[1] >> 8,
-						phys_addr[2] & 0xff, phys_addr[2] >> 8);
-				/* Set the adaptor tag so that the next card can be found. */
-				outb(0xd0 + ++current_tag, id_port);
-				goto no_pnp;
-			}
-		}
-	}
-#endif /* __ISAPNP__ */
-
-	{
-		unsigned int iobase = id_read_eeprom(8);
-		if_port = iobase >> 14;
-		ioaddr = 0x200 + ((iobase & 0x1f) << 4);
-	}
-	irq = id_read_eeprom(9) >> 12;
-
-	dev = alloc_etherdev(sizeof (struct el3_private));
-	if (!dev)
-		return -ENOMEM;
-
-	netdev_boot_setup_check(dev);
-
-	/* Set passed-in IRQ or I/O Addr. */
-	if (dev->irq > 1  &&  dev->irq < 16)
-			irq = dev->irq;
-
-	if (dev->base_addr) {
-		if (dev->mem_end == 0x3c509 	/* Magic key */
-		    && dev->base_addr >= 0x200  &&  dev->base_addr <= 0x3e0)
-			ioaddr = dev->base_addr & 0x3f0;
-		else if (dev->base_addr != ioaddr)
-			goto out;
-	}
-
-	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509")) {
-		err = -EBUSY;
-		goto out;
-	}
-
-	/* Set the adaptor tag so that the next card can be found. */
-	outb(0xd0 + ++current_tag, id_port);
-
-	/* Activate the adaptor at the EEPROM location. */
-	outb((ioaddr >> 4) | 0xe0, id_port);
-
-	EL3WINDOW(0);
-	if (inw(ioaddr) != 0x6d50)
-		goto out1;
-
-	/* Free the interrupt so that some other card can use it. */
-	outw(0x0f00, ioaddr + WN0_IRQ);
-
-#if defined(__ISAPNP__)
- found:							/* PNP jumps here... */
-#endif /* __ISAPNP__ */
-
-	memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
-	dev->base_addr = ioaddr;
-	dev->irq = irq;
-	dev->if_port = if_port;
-	lp = netdev_priv(dev);
-#if defined(__ISAPNP__)
-	lp->dev = &idev->dev;
-	if (pnp_found)
-		lp->type = EL3_PNP;
-#endif
-	err = el3_common_init(dev);
-
-	if (err)
-		goto out1;
-
-	el3_cards++;
-	lp->next_dev = el3_root_dev;
-	el3_root_dev = dev;
-	return 0;
-
-out1:
-#if defined(__ISAPNP__)
-	if (idev)
-		pnp_device_detach(idev);
-#endif
-out:
-	free_netdev(dev);
-	return err;
-}
-
 #ifdef CONFIG_MCA
 static int __init el3_mca_probe(struct device *device)
 {
@@ -596,7 +604,6 @@ static int __init el3_mca_probe(struct device *device)
 	 * redone for multi-card detection by ZP Gu (zpg@castle.net)
 	 * now works as a module */
 
-	struct el3_private *lp;
 	short i;
 	int ioaddr, irq, if_port;
 	u16 phys_addr[3];
@@ -613,7 +620,7 @@ static int __init el3_mca_probe(struct device *device)
 	irq = pos5 & 0x0f;
 
 
-	printk("3c529: found %s at slot %d\n",
+	printk(KERN_INFO "3c529: found %s at slot %d\n",
 		   el3_mca_adapter_names[mdev->index], slot + 1);
 
 	/* claim the slot */
@@ -626,7 +633,7 @@ static int __init el3_mca_probe(struct device *device)
 	irq = mca_device_transform_irq(mdev, irq);
 	ioaddr = mca_device_transform_ioport(mdev, ioaddr);
 	if (el3_debug > 2) {
-			printk("3c529: irq %d  ioaddr 0x%x  ifport %d\n", irq, ioaddr, if_port);
+			printk(KERN_DEBUG "3c529: irq %d  ioaddr 0x%x  ifport %d\n", irq, ioaddr, if_port);
 	}
 	EL3WINDOW(0);
 	for (i = 0; i < 3; i++) {
@@ -641,13 +648,7 @@ static int __init el3_mca_probe(struct device *device)
 
 	netdev_boot_setup_check(dev);
 
-	memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
-	dev->base_addr = ioaddr;
-	dev->irq = irq;
-	dev->if_port = if_port;
-	lp = netdev_priv(dev);
-	lp->dev = device;
-	lp->type = EL3_MCA;
+	el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
 	device->driver_data = dev;
 	err = el3_common_init(dev);
 
@@ -657,7 +658,7 @@ static int __init el3_mca_probe(struct device *device)
 		return -ENOMEM;
 	}
 
-	el3_cards++;
+	el3_devs[el3_cards++] = dev;
 	return 0;
 }
 
@@ -666,7 +667,6 @@ static int __init el3_mca_probe(struct device *device)
 #ifdef CONFIG_EISA
 static int __init el3_eisa_probe (struct device *device)
 {
-	struct el3_private *lp;
 	short i;
 	int ioaddr, irq, if_port;
 	u16 phys_addr[3];
@@ -678,7 +678,7 @@ static int __init el3_eisa_probe (struct device *device)
 	edev = to_eisa_device (device);
 	ioaddr = edev->base_addr;
 
-	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c509"))
+	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c579-eisa"))
 		return -EBUSY;
 
 	/* Change the register set to the configuration window 0. */
@@ -700,13 +700,7 @@ static int __init el3_eisa_probe (struct device *device)
 
 	netdev_boot_setup_check(dev);
 
-	memcpy(dev->dev_addr, phys_addr, sizeof(phys_addr));
-	dev->base_addr = ioaddr;
-	dev->irq = irq;
-	dev->if_port = if_port;
-	lp = netdev_priv(dev);
-	lp->dev = device;
-	lp->type = EL3_EISA;
+	el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA);
 	eisa_set_drvdata (edev, dev);
 	err = el3_common_init(dev);
 
@@ -716,12 +710,11 @@ static int __init el3_eisa_probe (struct device *device)
 		return err;
 	}
 
-	el3_cards++;
+	el3_devs[el3_cards++] = dev;
 	return 0;
 }
 #endif
 
-#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
 /* This remove works for all device types.
  *
  * The net dev must be stored in the driver_data field */
@@ -734,7 +727,6 @@ static int __devexit el3_device_remove (struct device *device)
 	el3_common_remove (dev);
 	return 0;
 }
-#endif
 
 /* Read a word from the EEPROM using the regular EEPROM access register.
    Assume that we are in register window zero.
@@ -749,7 +741,7 @@ static ushort read_eeprom(int ioaddr, int index)
 }
 
 /* Read a word from the EEPROM when in the ISA ID probe state. */
-static ushort __init id_read_eeprom(int index)
+static ushort id_read_eeprom(int index)
 {
 	int bit, word = 0;
 
@@ -765,7 +757,7 @@ static ushort __init id_read_eeprom(int index)
 		word = (word << 1) + (inb(id_port) & 0x01);
 
 	if (el3_debug > 3)
-		printk("  3c509 EEPROM word %d %#4.4x.\n", index, word);
+		printk(KERN_DEBUG "  3c509 EEPROM word %d %#4.4x.\n", index, word);
 
 	return word;
 }
@@ -787,13 +779,13 @@ el3_open(struct net_device *dev)
 
 	EL3WINDOW(0);
 	if (el3_debug > 3)
-		printk("%s: Opening, IRQ %d	 status@%x %4.4x.\n", dev->name,
+		printk(KERN_DEBUG "%s: Opening, IRQ %d	 status@%x %4.4x.\n", dev->name,
 			   dev->irq, ioaddr + EL3_STATUS, inw(ioaddr + EL3_STATUS));
 
 	el3_up(dev);
 
 	if (el3_debug > 3)
-		printk("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
+		printk(KERN_DEBUG "%s: Opened 3c509  IRQ %d  status %4.4x.\n",
 			   dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
 
 	return 0;
@@ -806,7 +798,7 @@ el3_tx_timeout (struct net_device *dev)
 	int ioaddr = dev->base_addr;
 
 	/* Transmitter timeout, serious problems. */
-	printk("%s: transmit timed out, Tx_status %2.2x status %4.4x "
+	printk(KERN_WARNING "%s: transmit timed out, Tx_status %2.2x status %4.4x "
 		   "Tx FIFO room %d.\n",
 		   dev->name, inb(ioaddr + TX_STATUS), inw(ioaddr + EL3_STATUS),
 		   inw(ioaddr + TX_FREE));
@@ -831,7 +823,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	lp->stats.tx_bytes += skb->len;
 
 	if (el3_debug > 4) {
-		printk("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
+		printk(KERN_DEBUG "%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
 			   dev->name, skb->len, inw(ioaddr + EL3_STATUS));
 	}
 #if 0
@@ -840,7 +832,7 @@ el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		ushort status = inw(ioaddr + EL3_STATUS);
 		if (status & 0x0001 		/* IRQ line active, missed one. */
 			&& inw(ioaddr + EL3_STATUS) & 1) { 			/* Make sure. */
-			printk("%s: Missed interrupt, status then %04x now %04x"
+			printk(KERN_DEBUG "%s: Missed interrupt, status then %04x now %04x"
 				   "  Tx %2.2x Rx %4.4x.\n", dev->name, status,
 				   inw(ioaddr + EL3_STATUS), inb(ioaddr + TX_STATUS),
 				   inw(ioaddr + RX_STATUS));
@@ -914,7 +906,7 @@ el3_interrupt(int irq, void *dev_id)
 
 	if (el3_debug > 4) {
 		status = inw(ioaddr + EL3_STATUS);
-		printk("%s: interrupt, status %4.4x.\n", dev->name, status);
+		printk(KERN_DEBUG "%s: interrupt, status %4.4x.\n", dev->name, status);
 	}
 
 	while ((status = inw(ioaddr + EL3_STATUS)) &
@@ -925,7 +917,7 @@ el3_interrupt(int irq, void *dev_id)
 
 		if (status & TxAvailable) {
 			if (el3_debug > 5)
-				printk("	TX room bit was handled.\n");
+				printk(KERN_DEBUG "	TX room bit was handled.\n");
 			/* There's room in the FIFO for a full-sized packet. */
 			outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
 			netif_wake_queue (dev);
@@ -964,7 +956,7 @@ el3_interrupt(int irq, void *dev_id)
 		}
 
 		if (--i < 0) {
-			printk("%s: Infinite loop in interrupt, status %4.4x.\n",
+			printk(KERN_ERR "%s: Infinite loop in interrupt, status %4.4x.\n",
 				   dev->name, status);
 			/* Clear all interrupts. */
 			outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
@@ -975,7 +967,7 @@ el3_interrupt(int irq, void *dev_id)
 	}
 
 	if (el3_debug > 4) {
-		printk("%s: exiting interrupt, status %4.4x.\n", dev->name,
+		printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n", dev->name,
 			   inw(ioaddr + EL3_STATUS));
 	}
 	spin_unlock(&lp->lock);
@@ -1450,7 +1442,7 @@ el3_up(struct net_device *dev)
 }
 
 /* Power Management support functions */
-#ifdef EL3_SUSPEND
+#ifdef CONFIG_PM
 
 static int
 el3_suspend(struct device *pdev, pm_message_t state)
@@ -1500,79 +1492,102 @@ el3_resume(struct device *pdev)
 	return 0;
 }
 
-#endif /* EL3_SUSPEND */
-
-/* Parameters that may be passed into the module. */
-static int debug = -1;
-static int irq[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int xcvr[] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1};
+#endif /* CONFIG_PM */
 
 module_param(debug,int, 0);
 module_param_array(irq, int, NULL, 0);
-module_param_array(xcvr, int, NULL, 0);
 module_param(max_interrupt_work, int, 0);
 MODULE_PARM_DESC(debug, "debug level (0-6)");
 MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
-MODULE_PARM_DESC(xcvr,"transceiver(s) (0=internal, 1=external)");
 MODULE_PARM_DESC(max_interrupt_work, "maximum events handled per interrupt");
-#if defined(__ISAPNP__)
+#ifdef CONFIG_PNP
 module_param(nopnp, int, 0);
 MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)");
-MODULE_DEVICE_TABLE(isapnp, el3_isapnp_adapters);
-#endif	/* __ISAPNP__ */
-MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B) ISA/PnP ethernet driver");
+#endif	/* CONFIG_PNP */
+MODULE_DESCRIPTION("3Com Etherlink III (3c509, 3c509B, 3c529, 3c579) ethernet driver");
 MODULE_LICENSE("GPL");
 
 static int __init el3_init_module(void)
 {
 	int ret = 0;
-	el3_cards = 0;
 
 	if (debug >= 0)
 		el3_debug = debug;
 
-	el3_root_dev = NULL;
-	while (el3_probe(el3_cards) == 0) {
-		if (irq[el3_cards] > 1)
-			el3_root_dev->irq = irq[el3_cards];
-		if (xcvr[el3_cards] >= 0)
-			el3_root_dev->if_port = xcvr[el3_cards];
-		el3_cards++;
+#ifdef CONFIG_PNP
+	if (!nopnp) {
+		ret = pnp_register_driver(&el3_pnp_driver);
+		if (!ret)
+			pnp_registered = 1;
+	}
+#endif
+	/* Select an open I/O location at 0x1*0 to do ISA contention select. */
+	/* Start with 0x110 to avoid some sound cards.*/
+	for (id_port = 0x110 ; id_port < 0x200; id_port += 0x10) {
+		if (!request_region(id_port, 1, "3c509-control"))
+			continue;
+		outb(0x00, id_port);
+		outb(0xff, id_port);
+		if (inb(id_port) & 0x01)
+			break;
+		else
+			release_region(id_port, 1);
+	}
+	if (id_port >= 0x200) {
+		id_port = 0;
+		printk(KERN_ERR "No I/O port available for 3c509 activation.\n");
+	} else {
+		ret = isa_register_driver(&el3_isa_driver, EL3_MAX_CARDS);
+		if (!ret)
+			isa_registered = 1;
 	}
-
 #ifdef CONFIG_EISA
 	ret = eisa_driver_register(&el3_eisa_driver);
+	if (!ret)
+		eisa_registered = 1;
 #endif
 #ifdef CONFIG_MCA
-	{
-		int err = mca_register_driver(&el3_mca_driver);
-		if (ret == 0)
-			ret = err;
-	}
+	ret = mca_register_driver(&el3_mca_driver);
+	if (!ret)
+		mca_registered = 1;
+#endif
+
+#ifdef CONFIG_PNP
+	if (pnp_registered)
+		ret = 0;
+#endif
+	if (isa_registered)
+		ret = 0;
+#ifdef CONFIG_EISA
+	if (eisa_registered)
+		ret = 0;
+#endif
+#ifdef CONFIG_MCA
+	if (mca_registered)
+		ret = 0;
 #endif
 	return ret;
 }
 
 static void __exit el3_cleanup_module(void)
 {
-	struct net_device *next_dev;
-
-	while (el3_root_dev) {
-		struct el3_private *lp = netdev_priv(el3_root_dev);
-
-		next_dev = lp->next_dev;
-		el3_common_remove (el3_root_dev);
-		el3_root_dev = next_dev;
-	}
-
+#ifdef CONFIG_PNP
+	if (pnp_registered)
+		pnp_unregister_driver(&el3_pnp_driver);
+#endif
+	if (isa_registered)
+		isa_unregister_driver(&el3_isa_driver);
+	if (id_port)
+		release_region(id_port, 1);
 #ifdef CONFIG_EISA
-	eisa_driver_unregister (&el3_eisa_driver);
+	if (eisa_registered)
+		eisa_driver_unregister(&el3_eisa_driver);
 #endif
 #ifdef CONFIG_MCA
-	mca_unregister_driver(&el3_mca_driver);
+	if (mca_registered)
+		mca_unregister_driver(&el3_mca_driver);
 #endif
 }
 
 module_init (el3_init_module);
 module_exit (el3_cleanup_module);
-
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index c59c806..bdc4c0b 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -940,7 +940,7 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
 
 			/* is the RECON info empty or old? */
 			if (!lp->first_recon || !lp->last_recon ||
-			    jiffies - lp->last_recon > HZ * 10) {
+			    time_after(jiffies, lp->last_recon + HZ * 10)) {
 				if (lp->network_down)
 					BUGMSG(D_NORMAL, "reconfiguration detected: cabling restored?\n");
 				lp->first_recon = lp->last_recon = jiffies;
@@ -974,7 +974,8 @@ irqreturn_t arcnet_interrupt(int irq, void *dev_id)
 					lp->num_recons = 1;
 				}
 			}
-		} else if (lp->network_down && jiffies - lp->last_recon > HZ * 10) {
+		} else if (lp->network_down &&
+				time_after(jiffies, lp->last_recon + HZ * 10)) {
 			if (lp->network_down)
 				BUGMSG(D_NORMAL, "cabling restored?\n");
 			lp->first_recon = lp->last_recon = 0;
diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c
index 7fe2031..f7e1619 100644
--- a/drivers/net/e1000e/82571.c
+++ b/drivers/net/e1000e/82571.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -29,6 +29,9 @@
 /*
  * 82571EB Gigabit Ethernet Controller
  * 82571EB Gigabit Ethernet Controller (Fiber)
+ * 82571EB Dual Port Gigabit Mezzanine Adapter
+ * 82571EB Quad Port Gigabit Mezzanine Adapter
+ * 82571PT Gigabit PT Quad Port Server ExpressModule
  * 82572EI Gigabit Ethernet Controller (Copper)
  * 82572EI Gigabit Ethernet Controller (Fiber)
  * 82572EI Gigabit Ethernet Controller
@@ -72,7 +75,7 @@ static s32 e1000_init_phy_params_82571(struct e1000_hw *hw)
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
 
-	if (hw->media_type != e1000_media_type_copper) {
+	if (hw->phy.media_type != e1000_media_type_copper) {
 		phy->type = e1000_phy_none;
 		return 0;
 	}
@@ -150,7 +153,8 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
 		if (((eecd >> 15) & 0x3) == 0x3) {
 			nvm->type = e1000_nvm_flash_hw;
 			nvm->word_size = 2048;
-			/* Autonomous Flash update bit must be cleared due
+			/*
+			 * Autonomous Flash update bit must be cleared due
 			 * to Flash update issue.
 			 */
 			eecd &= ~E1000_EECD_AUPDEN;
@@ -159,10 +163,11 @@ static s32 e1000_init_nvm_params_82571(struct e1000_hw *hw)
 		}
 		/* Fall Through */
 	default:
-		nvm->type	= e1000_nvm_eeprom_spi;
+		nvm->type = e1000_nvm_eeprom_spi;
 		size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
 				  E1000_EECD_SIZE_EX_SHIFT);
-		/* Added to a constant, "size" becomes the left-shift value
+		/*
+		 * Added to a constant, "size" becomes the left-shift value
 		 * for setting word_size.
 		 */
 		size += NVM_WORD_SIZE_BASE_SHIFT;
@@ -190,16 +195,16 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
 	case E1000_DEV_ID_82571EB_FIBER:
 	case E1000_DEV_ID_82572EI_FIBER:
 	case E1000_DEV_ID_82571EB_QUAD_FIBER:
-		hw->media_type = e1000_media_type_fiber;
+		hw->phy.media_type = e1000_media_type_fiber;
 		break;
 	case E1000_DEV_ID_82571EB_SERDES:
 	case E1000_DEV_ID_82572EI_SERDES:
 	case E1000_DEV_ID_82571EB_SERDES_DUAL:
 	case E1000_DEV_ID_82571EB_SERDES_QUAD:
-		hw->media_type = e1000_media_type_internal_serdes;
+		hw->phy.media_type = e1000_media_type_internal_serdes;
 		break;
 	default:
-		hw->media_type = e1000_media_type_copper;
+		hw->phy.media_type = e1000_media_type_copper;
 		break;
 	}
 
@@ -208,25 +213,28 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter)
 	/* Set rar entry count */
 	mac->rar_entry_count = E1000_RAR_ENTRIES;
 	/* Set if manageability features are enabled. */
-	mac->arc_subsystem_valid =
-		(er32(FWSM) & E1000_FWSM_MODE_MASK) ? 1 : 0;
+	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? 1 : 0;
 
 	/* check for link */
-	switch (hw->media_type) {
+	switch (hw->phy.media_type) {
 	case e1000_media_type_copper:
 		func->setup_physical_interface = e1000_setup_copper_link_82571;
 		func->check_for_link = e1000e_check_for_copper_link;
 		func->get_link_up_info = e1000e_get_speed_and_duplex_copper;
 		break;
 	case e1000_media_type_fiber:
-		func->setup_physical_interface = e1000_setup_fiber_serdes_link_82571;
+		func->setup_physical_interface =
+			e1000_setup_fiber_serdes_link_82571;
 		func->check_for_link = e1000e_check_for_fiber_link;
-		func->get_link_up_info = e1000e_get_speed_and_duplex_fiber_serdes;
+		func->get_link_up_info =
+			e1000e_get_speed_and_duplex_fiber_serdes;
 		break;
 	case e1000_media_type_internal_serdes:
-		func->setup_physical_interface = e1000_setup_fiber_serdes_link_82571;
+		func->setup_physical_interface =
+			e1000_setup_fiber_serdes_link_82571;
 		func->check_for_link = e1000e_check_for_serdes_link;
-		func->get_link_up_info = e1000e_get_speed_and_duplex_fiber_serdes;
+		func->get_link_up_info =
+			e1000e_get_speed_and_duplex_fiber_serdes;
 		break;
 	default:
 		return -E1000_ERR_CONFIG;
@@ -322,10 +330,12 @@ static s32 e1000_get_phy_id_82571(struct e1000_hw *hw)
 	switch (hw->mac.type) {
 	case e1000_82571:
 	case e1000_82572:
-		/* The 82571 firmware may still be configuring the PHY.
+		/*
+		 * The 82571 firmware may still be configuring the PHY.
 		 * In this case, we cannot access the PHY until the
 		 * configuration is done.  So we explicitly set the
-		 * PHY ID. */
+		 * PHY ID.
+		 */
 		phy->id = IGP01E1000_I_PHY_ID;
 		break;
 	case e1000_82573:
@@ -479,8 +489,10 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	/* If our nvm is an EEPROM, then we're done
-	 * otherwise, commit the checksum to the flash NVM. */
+	/*
+	 * If our nvm is an EEPROM, then we're done
+	 * otherwise, commit the checksum to the flash NVM.
+	 */
 	if (hw->nvm.type != e1000_nvm_flash_hw)
 		return ret_val;
 
@@ -496,7 +508,8 @@ static s32 e1000_update_nvm_checksum_82571(struct e1000_hw *hw)
 
 	/* Reset the firmware if using STM opcode. */
 	if ((er32(FLOP) & 0xFF00) == E1000_STM_OPCODE) {
-		/* The enabling of and the actual reset must be done
+		/*
+		 * The enabling of and the actual reset must be done
 		 * in two write cycles.
 		 */
 		ew32(HICR, E1000_HICR_FW_RESET_ENABLE);
@@ -557,8 +570,10 @@ static s32 e1000_write_nvm_eewr_82571(struct e1000_hw *hw, u16 offset,
 	u32 eewr = 0;
 	s32 ret_val = 0;
 
-	/* A check for invalid values:  offset too large, too many words,
-	 * and not enough words. */
+	/*
+	 * A check for invalid values:  offset too large, too many words,
+	 * and not enough words.
+	 */
 	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
 	    (words == 0)) {
 		hw_dbg(hw, "nvm parameter(s) out of bounds\n");
@@ -645,30 +660,32 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active)
 	} else {
 		data &= ~IGP02E1000_PM_D0_LPLU;
 		ret_val = e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, data);
-		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used
+		/*
+		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
 		 * during Dx states where the power conservation is most
 		 * important.  During driver activity we should enable
-		 * SmartSpeed, so performance is maintained. */
+		 * SmartSpeed, so performance is maintained.
+		 */
 		if (phy->smart_speed == e1000_smart_speed_on) {
 			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     &data);
+					   &data);
 			if (ret_val)
 				return ret_val;
 
 			data |= IGP01E1000_PSCFR_SMART_SPEED;
 			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     data);
+					   data);
 			if (ret_val)
 				return ret_val;
 		} else if (phy->smart_speed == e1000_smart_speed_off) {
 			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     &data);
+					   &data);
 			if (ret_val)
 				return ret_val;
 
 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
 			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     data);
+					   data);
 			if (ret_val)
 				return ret_val;
 		}
@@ -693,7 +710,8 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
 	s32 ret_val;
 	u16 i = 0;
 
-	/* Prevent the PCI-E bus from sticking if there is no TLP connection
+	/*
+	 * Prevent the PCI-E bus from sticking if there is no TLP connection
 	 * on the last TLP read/write transaction when MAC is reset.
 	 */
 	ret_val = e1000e_disable_pcie_master(hw);
@@ -709,8 +727,10 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
 
 	msleep(10);
 
-	/* Must acquire the MDIO ownership before MAC reset.
-	 * Ownership defaults to firmware after a reset. */
+	/*
+	 * Must acquire the MDIO ownership before MAC reset.
+	 * Ownership defaults to firmware after a reset.
+	 */
 	if (hw->mac.type == e1000_82573) {
 		extcnf_ctrl = er32(EXTCNF_CTRL);
 		extcnf_ctrl |= E1000_EXTCNF_CTRL_MDIO_SW_OWNERSHIP;
@@ -747,7 +767,8 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw)
 		/* We don't want to continue accessing MAC registers. */
 		return ret_val;
 
-	/* Phy configuration from NVM just starts after EECD_AUTO_RD is set.
+	/*
+	 * Phy configuration from NVM just starts after EECD_AUTO_RD is set.
 	 * Need to wait for Phy configuration completion before accessing
 	 * NVM and Phy.
 	 */
@@ -793,7 +814,8 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
 	e1000e_clear_vfta(hw);
 
 	/* Setup the receive address. */
-	/* If, however, a locally administered address was assigned to the
+	/*
+	 * If, however, a locally administered address was assigned to the
 	 * 82571, we must reserve a RAR for it to work around an issue where
 	 * resetting one port will reload the MAC on the other port.
 	 */
@@ -830,7 +852,8 @@ static s32 e1000_init_hw_82571(struct e1000_hw *hw)
 		ew32(GCR, reg_data);
 	}
 
-	/* Clear all of the statistics registers (clear on read).  It is
+	/*
+	 * Clear all of the statistics registers (clear on read).  It is
 	 * important that we do this after we have tried to establish link
 	 * because the symbol error count will increment wildly if there
 	 * is no link.
@@ -922,7 +945,8 @@ void e1000e_clear_vfta(struct e1000_hw *hw)
 
 	if (hw->mac.type == e1000_82573) {
 		if (hw->mng_cookie.vlan_id != 0) {
-			/* The VFTA is a 4096b bit-field, each identifying
+			/*
+			 * The VFTA is a 4096b bit-field, each identifying
 			 * a single VLAN ID.  The following operations
 			 * determine which 32b entry (i.e. offset) into the
 			 * array we want to set the VLAN ID (i.e. bit) of
@@ -936,7 +960,8 @@ void e1000e_clear_vfta(struct e1000_hw *hw)
 		}
 	}
 	for (offset = 0; offset < E1000_VLAN_FILTER_TBL_SIZE; offset++) {
-		/* If the offset we want to clear is the same offset of the
+		/*
+		 * If the offset we want to clear is the same offset of the
 		 * manageability VLAN ID, then clear all bits except that of
 		 * the manageability unit.
 		 */
@@ -947,7 +972,7 @@ void e1000e_clear_vfta(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_mc_addr_list_update_82571 - Update Multicast addresses
+ *  e1000_update_mc_addr_list_82571 - Update Multicast addresses
  *  @hw: pointer to the HW structure
  *  @mc_addr_list: array of multicast addresses to program
  *  @mc_addr_count: number of multicast addresses to program
@@ -959,7 +984,7 @@ void e1000e_clear_vfta(struct e1000_hw *hw)
  *  The parameter rar_count will usually be hw->mac.rar_entry_count
  *  unless there are workarounds that change this.
  **/
-static void e1000_mc_addr_list_update_82571(struct e1000_hw *hw,
+static void e1000_update_mc_addr_list_82571(struct e1000_hw *hw,
 					    u8 *mc_addr_list,
 					    u32 mc_addr_count,
 					    u32 rar_used_count,
@@ -968,8 +993,8 @@ static void e1000_mc_addr_list_update_82571(struct e1000_hw *hw,
 	if (e1000e_get_laa_state_82571(hw))
 		rar_count--;
 
-	e1000e_mc_addr_list_update_generic(hw, mc_addr_list, mc_addr_count,
-					  rar_used_count, rar_count);
+	e1000e_update_mc_addr_list_generic(hw, mc_addr_list, mc_addr_count,
+					   rar_used_count, rar_count);
 }
 
 /**
@@ -984,12 +1009,13 @@ static void e1000_mc_addr_list_update_82571(struct e1000_hw *hw,
  **/
 static s32 e1000_setup_link_82571(struct e1000_hw *hw)
 {
-	/* 82573 does not have a word in the NVM to determine
+	/*
+	 * 82573 does not have a word in the NVM to determine
 	 * the default flow control setting, so we explicitly
 	 * set it to full.
 	 */
 	if (hw->mac.type == e1000_82573)
-		hw->mac.fc = e1000_fc_full;
+		hw->fc.type = e1000_fc_full;
 
 	return e1000e_setup_link(hw);
 }
@@ -1050,14 +1076,14 @@ static s32 e1000_setup_fiber_serdes_link_82571(struct e1000_hw *hw)
 	switch (hw->mac.type) {
 	case e1000_82571:
 	case e1000_82572:
-		/* If SerDes loopback mode is entered, there is no form
+		/*
+		 * If SerDes loopback mode is entered, there is no form
 		 * of reset to take the adapter out of that mode.  So we
 		 * have to explicitly take the adapter out of loopback
 		 * mode.  This prevents drivers from twiddling their thumbs
 		 * if another tool failed to take it out of loopback mode.
 		 */
-		ew32(SCTL,
-				E1000_SCTL_DISABLE_SERDES_LOOPBACK);
+		ew32(SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
 		break;
 	default:
 		break;
@@ -1124,7 +1150,8 @@ void e1000e_set_laa_state_82571(struct e1000_hw *hw, bool state)
 
 	/* If workaround is activated... */
 	if (state)
-		/* Hold a copy of the LAA in RAR[14] This is done so that
+		/*
+		 * Hold a copy of the LAA in RAR[14] This is done so that
 		 * between the time RAR[0] gets clobbered and the time it
 		 * gets fixed, the actual LAA is in one of the RARs and no
 		 * incoming packets directed to this port are dropped.
@@ -1152,7 +1179,8 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw)
 	if (nvm->type != e1000_nvm_flash_hw)
 		return 0;
 
-	/* Check bit 4 of word 10h.  If it is 0, firmware is done updating
+	/*
+	 * Check bit 4 of word 10h.  If it is 0, firmware is done updating
 	 * 10h-12h.  Checksum may need to be fixed.
 	 */
 	ret_val = e1000_read_nvm(hw, 0x10, 1, &data);
@@ -1160,7 +1188,8 @@ static s32 e1000_fix_nvm_checksum_82571(struct e1000_hw *hw)
 		return ret_val;
 
 	if (!(data & 0x10)) {
-		/* Read 0x23 and check bit 15.  This bit is a 1
+		/*
+		 * Read 0x23 and check bit 15.  This bit is a 1
 		 * when the checksum has already been fixed.  If
 		 * the checksum is still wrong and this bit is a
 		 * 1, we need to return bad checksum.  Otherwise,
@@ -1240,7 +1269,7 @@ static struct e1000_mac_operations e82571_mac_ops = {
 	/* .get_link_up_info: media type dependent */
 	.led_on			= e1000e_led_on_generic,
 	.led_off		= e1000e_led_off_generic,
-	.mc_addr_list_update	= e1000_mc_addr_list_update_82571,
+	.update_mc_addr_list	= e1000_update_mc_addr_list_82571,
 	.reset_hw		= e1000_reset_hw_82571,
 	.init_hw		= e1000_init_hw_82571,
 	.setup_link		= e1000_setup_link_82571,
diff --git a/drivers/net/e1000e/Makefile b/drivers/net/e1000e/Makefile
index 650f866..360c913 100644
--- a/drivers/net/e1000e/Makefile
+++ b/drivers/net/e1000e/Makefile
@@ -1,7 +1,7 @@
 ################################################################################
 #
 # Intel PRO/1000 Linux driver
-# Copyright(c) 1999 - 2007 Intel Corporation.
+# Copyright(c) 1999 - 2008 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,
diff --git a/drivers/net/e1000e/defines.h b/drivers/net/e1000e/defines.h
index a4f511f..572cfd4 100644
--- a/drivers/net/e1000e/defines.h
+++ b/drivers/net/e1000e/defines.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -120,10 +120,10 @@
 #define E1000_MANC_ARP_EN        0x00002000 /* Enable ARP Request Filtering */
 #define E1000_MANC_RCV_TCO_EN    0x00020000 /* Receive TCO Packets Enabled */
 #define E1000_MANC_BLK_PHY_RST_ON_IDE   0x00040000 /* Block phy resets */
-#define E1000_MANC_EN_MAC_ADDR_FILTER   0x00100000 /* Enable MAC address
-						    * filtering */
-#define E1000_MANC_EN_MNG2HOST   0x00200000 /* Enable MNG packets to host
-					     * memory */
+/* Enable MAC address filtering */
+#define E1000_MANC_EN_MAC_ADDR_FILTER   0x00100000
+/* Enable MNG packets to host memory */
+#define E1000_MANC_EN_MNG2HOST   0x00200000
 
 /* Receive Control */
 #define E1000_RCTL_EN             0x00000002    /* enable */
@@ -135,25 +135,26 @@
 #define E1000_RCTL_LBM_MAC        0x00000040    /* MAC loopback mode */
 #define E1000_RCTL_LBM_TCVR       0x000000C0    /* tcvr loopback mode */
 #define E1000_RCTL_DTYP_PS        0x00000400    /* Packet Split descriptor */
-#define E1000_RCTL_RDMTS_HALF     0x00000000    /* rx desc min threshold size */
+#define E1000_RCTL_RDMTS_HALF     0x00000000    /* Rx desc min threshold size */
 #define E1000_RCTL_MO_SHIFT       12            /* multicast offset shift */
 #define E1000_RCTL_BAM            0x00008000    /* broadcast enable */
 /* these buffer sizes are valid if E1000_RCTL_BSEX is 0 */
-#define E1000_RCTL_SZ_2048        0x00000000    /* rx buffer size 2048 */
-#define E1000_RCTL_SZ_1024        0x00010000    /* rx buffer size 1024 */
-#define E1000_RCTL_SZ_512         0x00020000    /* rx buffer size 512 */
-#define E1000_RCTL_SZ_256         0x00030000    /* rx buffer size 256 */
+#define E1000_RCTL_SZ_2048        0x00000000    /* Rx buffer size 2048 */
+#define E1000_RCTL_SZ_1024        0x00010000    /* Rx buffer size 1024 */
+#define E1000_RCTL_SZ_512         0x00020000    /* Rx buffer size 512 */
+#define E1000_RCTL_SZ_256         0x00030000    /* Rx buffer size 256 */
 /* these buffer sizes are valid if E1000_RCTL_BSEX is 1 */
-#define E1000_RCTL_SZ_16384       0x00010000    /* rx buffer size 16384 */
-#define E1000_RCTL_SZ_8192        0x00020000    /* rx buffer size 8192 */
-#define E1000_RCTL_SZ_4096        0x00030000    /* rx buffer size 4096 */
+#define E1000_RCTL_SZ_16384       0x00010000    /* Rx buffer size 16384 */
+#define E1000_RCTL_SZ_8192        0x00020000    /* Rx buffer size 8192 */
+#define E1000_RCTL_SZ_4096        0x00030000    /* Rx buffer size 4096 */
 #define E1000_RCTL_VFE            0x00040000    /* vlan filter enable */
 #define E1000_RCTL_CFIEN          0x00080000    /* canonical form enable */
 #define E1000_RCTL_CFI            0x00100000    /* canonical form indicator */
 #define E1000_RCTL_BSEX           0x02000000    /* Buffer size extension */
 #define E1000_RCTL_SECRC          0x04000000    /* Strip Ethernet CRC */
 
-/* Use byte values for the following shift parameters
+/*
+ * Use byte values for the following shift parameters
  * Usage:
  *     psrctl |= (((ROUNDUP(value0, 128) >> E1000_PSRCTL_BSIZE0_SHIFT) &
  *                  E1000_PSRCTL_BSIZE0_MASK) |
@@ -206,7 +207,8 @@
 #define E1000_CTRL_VME      0x40000000  /* IEEE VLAN mode enable */
 #define E1000_CTRL_PHY_RST  0x80000000  /* PHY Reset */
 
-/* Bit definitions for the Management Data IO (MDIO) and Management Data
+/*
+ * Bit definitions for the Management Data IO (MDIO) and Management Data
  * Clock (MDC) pins in the Device Control Register.
  */
 
@@ -279,7 +281,7 @@
 #define E1000_TXD_STAT_TC    0x00000004 /* Tx Underrun */
 
 /* Transmit Control */
-#define E1000_TCTL_EN     0x00000002    /* enable tx */
+#define E1000_TCTL_EN     0x00000002    /* enable Tx */
 #define E1000_TCTL_PSP    0x00000008    /* pad short packets */
 #define E1000_TCTL_CT     0x00000ff0    /* collision threshold */
 #define E1000_TCTL_COLD   0x003ff000    /* collision distance */
@@ -337,8 +339,8 @@
 #define E1000_KABGTXD_BGSQLBIAS           0x00050000
 
 /* PBA constants */
-#define E1000_PBA_8K  0x0008    /* 8KB, default Rx allocation */
-#define E1000_PBA_16K 0x0010    /* 16KB, default TX allocation */
+#define E1000_PBA_8K  0x0008    /* 8KB */
+#define E1000_PBA_16K 0x0010    /* 16KB */
 
 #define E1000_PBS_16K E1000_PBA_16K
 
@@ -356,12 +358,13 @@
 /* Interrupt Cause Read */
 #define E1000_ICR_TXDW          0x00000001 /* Transmit desc written back */
 #define E1000_ICR_LSC           0x00000004 /* Link Status Change */
-#define E1000_ICR_RXSEQ         0x00000008 /* rx sequence error */
-#define E1000_ICR_RXDMT0        0x00000010 /* rx desc min. threshold (0) */
-#define E1000_ICR_RXT0          0x00000080 /* rx timer intr (ring 0) */
+#define E1000_ICR_RXSEQ         0x00000008 /* Rx sequence error */
+#define E1000_ICR_RXDMT0        0x00000010 /* Rx desc min. threshold (0) */
+#define E1000_ICR_RXT0          0x00000080 /* Rx timer intr (ring 0) */
 #define E1000_ICR_INT_ASSERTED  0x80000000 /* If this bit asserted, the driver should claim the interrupt */
 
-/* This defines the bits that are set in the Interrupt Mask
+/*
+ * This defines the bits that are set in the Interrupt Mask
  * Set/Read Register.  Each bit is documented below:
  *   o RXT0   = Receiver Timer Interrupt (ring 0)
  *   o TXDW   = Transmit Descriptor Written Back
@@ -379,21 +382,22 @@
 /* Interrupt Mask Set */
 #define E1000_IMS_TXDW      E1000_ICR_TXDW      /* Transmit desc written back */
 #define E1000_IMS_LSC       E1000_ICR_LSC       /* Link Status Change */
-#define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* rx sequence error */
-#define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
-#define E1000_IMS_RXT0      E1000_ICR_RXT0      /* rx timer intr */
+#define E1000_IMS_RXSEQ     E1000_ICR_RXSEQ     /* Rx sequence error */
+#define E1000_IMS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */
+#define E1000_IMS_RXT0      E1000_ICR_RXT0      /* Rx timer intr */
 
 /* Interrupt Cause Set */
 #define E1000_ICS_LSC       E1000_ICR_LSC       /* Link Status Change */
 #define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* rx desc min. threshold */
+#define E1000_ICS_RXDMT0    E1000_ICR_RXDMT0    /* Rx desc min. threshold */
 
 /* Transmit Descriptor Control */
 #define E1000_TXDCTL_PTHRESH 0x0000003F /* TXDCTL Prefetch Threshold */
 #define E1000_TXDCTL_WTHRESH 0x003F0000 /* TXDCTL Writeback Threshold */
 #define E1000_TXDCTL_FULL_TX_DESC_WB 0x01010000 /* GRAN=1, WTHRESH=1 */
 #define E1000_TXDCTL_MAX_TX_DESC_PREFETCH 0x0100001F /* GRAN=1, PTHRESH=31 */
-#define E1000_TXDCTL_COUNT_DESC 0x00400000 /* Enable the counting of desc.
-					      still to be processed. */
+/* Enable the counting of desc. still to be processed. */
+#define E1000_TXDCTL_COUNT_DESC 0x00400000
 
 /* Flow Control Constants */
 #define FLOW_CONTROL_ADDRESS_LOW  0x00C28001
@@ -404,7 +408,8 @@
 #define E1000_VLAN_FILTER_TBL_SIZE 128  /* VLAN Filter Table (4096 bits) */
 
 /* Receive Address */
-/* Number of high/low register pairs in the RAR. The RAR (Receive Address
+/*
+ * Number of high/low register pairs in the RAR. The RAR (Receive Address
  * Registers) holds the directed and multicast addresses that we monitor.
  * Technically, we have 16 spots.  However, we reserve one of these spots
  * (RAR[15]) for our directed address used by controllers with
@@ -533,8 +538,8 @@
 #define E1000_EECD_REQ       0x00000040 /* NVM Access Request */
 #define E1000_EECD_GNT       0x00000080 /* NVM Access Grant */
 #define E1000_EECD_SIZE      0x00000200 /* NVM Size (0=64 word 1=256 word) */
-#define E1000_EECD_ADDR_BITS 0x00000400 /* NVM Addressing bits based on type
-					 * (0-small, 1-large) */
+/* NVM Addressing bits based on type (0-small, 1-large) */
+#define E1000_EECD_ADDR_BITS 0x00000400
 #define E1000_NVM_GRANT_ATTEMPTS   1000 /* NVM # attempts to gain grant */
 #define E1000_EECD_AUTO_RD          0x00000200  /* NVM Auto Read done */
 #define E1000_EECD_SIZE_EX_MASK     0x00007800  /* NVM Size */
@@ -626,7 +631,8 @@
 #define MAX_PHY_MULTI_PAGE_REG 0xF
 
 /* Bit definitions for valid PHY IDs. */
-/* I = Integrated
+/*
+ * I = Integrated
  * E = External
  */
 #define M88E1000_E_PHY_ID    0x01410C50
@@ -653,37 +659,37 @@
 #define M88E1000_PSCR_MDI_MANUAL_MODE  0x0000  /* MDI Crossover Mode bits 6:5 */
 					       /* Manual MDI configuration */
 #define M88E1000_PSCR_MDIX_MANUAL_MODE 0x0020  /* Manual MDIX configuration */
-#define M88E1000_PSCR_AUTO_X_1000T     0x0040  /* 1000BASE-T: Auto crossover,
-						*  100BASE-TX/10BASE-T:
-						*  MDI Mode
-						*/
-#define M88E1000_PSCR_AUTO_X_MODE      0x0060  /* Auto crossover enabled
-						* all speeds.
-						*/
-					/* 1=Enable Extended 10BASE-T distance
-					 * (Lower 10BASE-T RX Threshold)
-					 * 0=Normal 10BASE-T RX Threshold */
-					/* 1=5-Bit interface in 100BASE-TX
-					 * 0=MII interface in 100BASE-TX */
-#define M88E1000_PSCR_ASSERT_CRS_ON_TX     0x0800 /* 1=Assert CRS on Transmit */
+/* 1000BASE-T: Auto crossover, 100BASE-TX/10BASE-T: MDI Mode */
+#define M88E1000_PSCR_AUTO_X_1000T     0x0040
+/* Auto crossover enabled all speeds */
+#define M88E1000_PSCR_AUTO_X_MODE      0x0060
+/*
+ * 1=Enable Extended 10BASE-T distance (Lower 10BASE-T Rx Threshold)
+ * 0=Normal 10BASE-T Rx Threshold
+ */
+#define M88E1000_PSCR_ASSERT_CRS_ON_TX 0x0800 /* 1=Assert CRS on Transmit */
 
 /* M88E1000 PHY Specific Status Register */
 #define M88E1000_PSSR_REV_POLARITY       0x0002 /* 1=Polarity reversed */
 #define M88E1000_PSSR_DOWNSHIFT          0x0020 /* 1=Downshifted */
 #define M88E1000_PSSR_MDIX               0x0040 /* 1=MDIX; 0=MDI */
-#define M88E1000_PSSR_CABLE_LENGTH       0x0380 /* 0=<50M;1=50-80M;2=80-110M;
-					    * 3=110-140M;4=>140M */
+/* 0=<50M; 1=50-80M; 2=80-110M; 3=110-140M; 4=>140M */
+#define M88E1000_PSSR_CABLE_LENGTH       0x0380
 #define M88E1000_PSSR_SPEED              0xC000 /* Speed, bits 14:15 */
 #define M88E1000_PSSR_1000MBS            0x8000 /* 10=1000Mbs */
 
 #define M88E1000_PSSR_CABLE_LENGTH_SHIFT 7
 
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the master */
+/*
+ * Number of times we will attempt to autonegotiate before downshifting if we
+ * are the master
+ */
 #define M88E1000_EPSCR_MASTER_DOWNSHIFT_MASK 0x0C00
 #define M88E1000_EPSCR_MASTER_DOWNSHIFT_1X   0x0000
-/* Number of times we will attempt to autonegotiate before downshifting if we
- * are the slave */
+/*
+ * Number of times we will attempt to autonegotiate before downshifting if we
+ * are the slave
+ */
 #define M88E1000_EPSCR_SLAVE_DOWNSHIFT_MASK  0x0300
 #define M88E1000_EPSCR_SLAVE_DOWNSHIFT_1X    0x0100
 #define M88E1000_EPSCR_TX_CLK_25      0x0070 /* 25  MHz TX_CLK */
@@ -692,7 +698,8 @@
 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_MASK  0x0E00
 #define M88EC018_EPSCR_DOWNSHIFT_COUNTER_5X    0x0800
 
-/* Bits...
+/*
+ * Bits...
  * 15-5: page
  * 4-0: register offset
  */
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h
index 4bf0c6c..b941a6b 100644
--- a/drivers/net/e1000e/e1000.h
+++ b/drivers/net/e1000e/e1000.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -61,7 +61,7 @@ struct e1000_info;
 	ndev_printk(KERN_NOTICE , netdev, format, ## arg)
 
 
-/* TX/RX descriptor defines */
+/* Tx/Rx descriptor defines */
 #define E1000_DEFAULT_TXD		256
 #define E1000_MAX_TXD			4096
 #define E1000_MIN_TXD			80
@@ -114,13 +114,13 @@ struct e1000_buffer {
 	dma_addr_t dma;
 	struct sk_buff *skb;
 	union {
-		/* TX */
+		/* Tx */
 		struct {
 			unsigned long time_stamp;
 			u16 length;
 			u16 next_to_watch;
 		};
-		/* RX */
+		/* Rx */
 		/* arrays of page information for packet split */
 		struct e1000_ps_page *ps_pages;
 	};
@@ -177,7 +177,7 @@ struct e1000_adapter {
 	u16 rx_itr;
 
 	/*
-	 * TX
+	 * Tx
 	 */
 	struct e1000_ring *tx_ring /* One per active queue */
 						____cacheline_aligned_in_smp;
@@ -199,7 +199,7 @@ struct e1000_adapter {
 	unsigned int total_rx_bytes;
 	unsigned int total_rx_packets;
 
-	/* TX stats */
+	/* Tx stats */
 	u64 tpt_old;
 	u64 colc_old;
 	u64 gotcl_old;
@@ -211,7 +211,7 @@ struct e1000_adapter {
 	u32 tx_dma_failed;
 
 	/*
-	 * RX
+	 * Rx
 	 */
 	bool (*clean_rx) (struct e1000_adapter *adapter,
 			  int *work_done, int work_to_do)
@@ -223,7 +223,7 @@ struct e1000_adapter {
 	u32 rx_int_delay;
 	u32 rx_abs_int_delay;
 
-	/* RX stats */
+	/* Rx stats */
 	u64 hw_csum_err;
 	u64 hw_csum_good;
 	u64 rx_hdr_split;
@@ -234,6 +234,8 @@ struct e1000_adapter {
 
 	unsigned int rx_ps_pages;
 	u16 rx_ps_bsize0;
+	u32 max_frame_size;
+	u32 min_frame_size;
 
 	/* OS defined structs */
 	struct net_device *netdev;
@@ -258,7 +260,7 @@ struct e1000_adapter {
 	u32 wol;
 	u32 pba;
 
-	u8 fc_autoneg;
+	bool fc_autoneg;
 
 	unsigned long led_status;
 
@@ -305,6 +307,7 @@ struct e1000_info {
 #define FLAG_MSI_ENABLED                  (1 << 27)
 #define FLAG_RX_CSUM_ENABLED              (1 << 28)
 #define FLAG_TSO_FORCE                    (1 << 29)
+#define FLAG_RX_RESTART_NOW               (1 << 30)
 
 #define E1000_RX_DESC_PS(R, i)	    \
 	(&(((union e1000_rx_desc_packet_split *)((R).desc))[i]))
@@ -387,9 +390,11 @@ extern s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw);
 extern s32 e1000e_setup_link(struct e1000_hw *hw);
 extern void e1000e_clear_vfta(struct e1000_hw *hw);
 extern void e1000e_init_rx_addrs(struct e1000_hw *hw, u16 rar_count);
-extern void e1000e_mc_addr_list_update_generic(struct e1000_hw *hw,
-				       u8 *mc_addr_list, u32 mc_addr_count,
-				       u32 rar_used_count, u32 rar_count);
+extern void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
+					       u8 *mc_addr_list,
+					       u32 mc_addr_count,
+					       u32 rar_used_count,
+					       u32 rar_count);
 extern void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index);
 extern s32 e1000e_set_fc_watermarks(struct e1000_hw *hw);
 extern void e1000e_set_pcie_no_snoop(struct e1000_hw *hw, u32 no_snoop);
diff --git a/drivers/net/e1000e/es2lan.c b/drivers/net/e1000e/es2lan.c
index 88657ad..e3f4aee 100644
--- a/drivers/net/e1000e/es2lan.c
+++ b/drivers/net/e1000e/es2lan.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -92,7 +92,8 @@
 /* In-Band Control Register (Page 194, Register 18) */
 #define GG82563_ICR_DIS_PADDING			 0x0010 /* Disable Padding */
 
-/* A table for the GG82563 cable length where the range is defined
+/*
+ * A table for the GG82563 cable length where the range is defined
  * with a lower bound at "index" and the upper bound at
  * "index + 5".
  */
@@ -118,7 +119,7 @@ static s32 e1000_init_phy_params_80003es2lan(struct e1000_hw *hw)
 	struct e1000_phy_info *phy = &hw->phy;
 	s32 ret_val;
 
-	if (hw->media_type != e1000_media_type_copper) {
+	if (hw->phy.media_type != e1000_media_type_copper) {
 		phy->type	= e1000_phy_none;
 		return 0;
 	}
@@ -167,12 +168,13 @@ static s32 e1000_init_nvm_params_80003es2lan(struct e1000_hw *hw)
 		break;
 	}
 
-	nvm->type	       = e1000_nvm_eeprom_spi;
+	nvm->type = e1000_nvm_eeprom_spi;
 
 	size = (u16)((eecd & E1000_EECD_SIZE_EX_MASK) >>
 			  E1000_EECD_SIZE_EX_SHIFT);
 
-	/* Added to a constant, "size" becomes the left-shift value
+	/*
+	 * Added to a constant, "size" becomes the left-shift value
 	 * for setting word_size.
 	 */
 	size += NVM_WORD_SIZE_BASE_SHIFT;
@@ -196,10 +198,10 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter)
 	/* Set media type */
 	switch (adapter->pdev->device) {
 	case E1000_DEV_ID_80003ES2LAN_SERDES_DPT:
-		hw->media_type = e1000_media_type_internal_serdes;
+		hw->phy.media_type = e1000_media_type_internal_serdes;
 		break;
 	default:
-		hw->media_type = e1000_media_type_copper;
+		hw->phy.media_type = e1000_media_type_copper;
 		break;
 	}
 
@@ -208,11 +210,10 @@ static s32 e1000_init_mac_params_80003es2lan(struct e1000_adapter *adapter)
 	/* Set rar entry count */
 	mac->rar_entry_count = E1000_RAR_ENTRIES;
 	/* Set if manageability features are enabled. */
-	mac->arc_subsystem_valid =
-		(er32(FWSM) & E1000_FWSM_MODE_MASK) ? 1 : 0;
+	mac->arc_subsystem_valid = (er32(FWSM) & E1000_FWSM_MODE_MASK) ? 1 : 0;
 
 	/* check for link */
-	switch (hw->media_type) {
+	switch (hw->phy.media_type) {
 	case e1000_media_type_copper:
 		func->setup_physical_interface = e1000_setup_copper_link_80003es2lan;
 		func->check_for_link = e1000e_check_for_copper_link;
@@ -344,8 +345,10 @@ static s32 e1000_acquire_swfw_sync_80003es2lan(struct e1000_hw *hw, u16 mask)
 		if (!(swfw_sync & (fwmask | swmask)))
 			break;
 
-		/* Firmware currently using resource (fwmask)
-		 * or other software thread using resource (swmask) */
+		/*
+		 * Firmware currently using resource (fwmask)
+		 * or other software thread using resource (swmask)
+		 */
 		e1000e_put_hw_semaphore(hw);
 		mdelay(5);
 		i++;
@@ -407,7 +410,8 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG)
 		page_select = GG82563_PHY_PAGE_SELECT;
 	else
-		/* Use Alternative Page Select register to access
+		/*
+		 * Use Alternative Page Select register to access
 		 * registers 30 and 31
 		 */
 		page_select = GG82563_PHY_PAGE_SELECT_ALT;
@@ -417,7 +421,8 @@ static s32 e1000_read_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 	if (ret_val)
 		return ret_val;
 
-	/* The "ready" bit in the MDIC register may be incorrectly set
+	/*
+	 * The "ready" bit in the MDIC register may be incorrectly set
 	 * before the device has completed the "Page Select" MDI
 	 * transaction.  So we wait 200us after each MDI command...
 	 */
@@ -462,7 +467,8 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 	if ((offset & MAX_PHY_REG_ADDRESS) < GG82563_MIN_ALT_REG)
 		page_select = GG82563_PHY_PAGE_SELECT;
 	else
-		/* Use Alternative Page Select register to access
+		/*
+		 * Use Alternative Page Select register to access
 		 * registers 30 and 31
 		 */
 		page_select = GG82563_PHY_PAGE_SELECT_ALT;
@@ -473,7 +479,8 @@ static s32 e1000_write_phy_reg_gg82563_80003es2lan(struct e1000_hw *hw,
 		return ret_val;
 
 
-	/* The "ready" bit in the MDIC register may be incorrectly set
+	/*
+	 * The "ready" bit in the MDIC register may be incorrectly set
 	 * before the device has completed the "Page Select" MDI
 	 * transaction.  So we wait 200us after each MDI command...
 	 */
@@ -554,7 +561,8 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
 	u16 phy_data;
 	bool link;
 
-	/* Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
+	/*
+	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
 	 * forced whenever speed and duplex are forced.
 	 */
 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
@@ -583,7 +591,7 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
 
 	udelay(1);
 
-	if (hw->phy.wait_for_link) {
+	if (hw->phy.autoneg_wait_to_complete) {
 		hw_dbg(hw, "Waiting for forced speed/duplex link "
 			 "on GG82563 phy.\n");
 
@@ -593,7 +601,8 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
 			return ret_val;
 
 		if (!link) {
-			/* We didn't get link.
+			/*
+			 * We didn't get link.
 			 * Reset the DSP and cross our fingers.
 			 */
 			ret_val = e1000e_phy_reset_dsp(hw);
@@ -612,7 +621,8 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	/* Resetting the phy means we need to verify the TX_CLK corresponds
+	/*
+	 * Resetting the phy means we need to verify the TX_CLK corresponds
 	 * to the link speed.  10Mbps -> 2.5MHz, else 25MHz.
 	 */
 	phy_data &= ~GG82563_MSCR_TX_CLK_MASK;
@@ -621,7 +631,8 @@ static s32 e1000_phy_force_speed_duplex_80003es2lan(struct e1000_hw *hw)
 	else
 		phy_data |= GG82563_MSCR_TX_CLK_100MBPS_25;
 
-	/* In addition, we must re-enable CRS on Tx for both half and full
+	/*
+	 * In addition, we must re-enable CRS on Tx for both half and full
 	 * duplex.
 	 */
 	phy_data |= GG82563_MSCR_ASSERT_CRS_ON_TX;
@@ -671,7 +682,7 @@ static s32 e1000_get_link_up_info_80003es2lan(struct e1000_hw *hw, u16 *speed,
 {
 	s32 ret_val;
 
-	if (hw->media_type == e1000_media_type_copper) {
+	if (hw->phy.media_type == e1000_media_type_copper) {
 		ret_val = e1000e_get_speed_and_duplex_copper(hw,
 								    speed,
 								    duplex);
@@ -704,7 +715,8 @@ static s32 e1000_reset_hw_80003es2lan(struct e1000_hw *hw)
 	u32 icr;
 	s32 ret_val;
 
-	/* Prevent the PCI-E bus from sticking if there is no TLP connection
+	/*
+	 * Prevent the PCI-E bus from sticking if there is no TLP connection
 	 * on the last TLP read/write transaction when MAC is reset.
 	 */
 	ret_val = e1000e_disable_pcie_master(hw);
@@ -808,7 +820,8 @@ static s32 e1000_init_hw_80003es2lan(struct e1000_hw *hw)
 	reg_data &= ~0x00100000;
 	E1000_WRITE_REG_ARRAY(hw, E1000_FFLT, 0x0001, reg_data);
 
-	/* Clear all of the statistics registers (clear on read).  It is
+	/*
+	 * Clear all of the statistics registers (clear on read).  It is
 	 * important that we do this after we have tried to establish link
 	 * because the symbol error count will increment wildly if there
 	 * is no link.
@@ -841,7 +854,7 @@ static void e1000_initialize_hw_bits_80003es2lan(struct e1000_hw *hw)
 	/* Transmit Arbitration Control 0 */
 	reg = er32(TARC0);
 	reg &= ~(0xF << 27); /* 30:27 */
-	if (hw->media_type != e1000_media_type_copper)
+	if (hw->phy.media_type != e1000_media_type_copper)
 		reg &= ~(1 << 20);
 	ew32(TARC0, reg);
 
@@ -881,7 +894,8 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	/* Options:
+	/*
+	 * Options:
 	 *   MDI/MDI-X = 0 (default)
 	 *   0 - Auto for all speeds
 	 *   1 - MDI mode
@@ -907,7 +921,8 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
 		break;
 	}
 
-	/* Options:
+	/*
+	 * Options:
 	 *   disable_polarity_correction = 0 (default)
 	 *       Automatic Correction for Reversed Cable Polarity
 	 *   0 - Disabled
@@ -928,10 +943,9 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
 		return ret_val;
 	}
 
-	/* Bypass RX and TX FIFO's */
-	ret_val = e1000e_write_kmrn_reg(hw,
-				E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,
-				E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS |
+	/* Bypass Rx and Tx FIFO's */
+	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_FIFO_CTRL,
+					E1000_KMRNCTRLSTA_FIFO_CTRL_RX_BYPASS |
 					E1000_KMRNCTRLSTA_FIFO_CTRL_TX_BYPASS);
 	if (ret_val)
 		return ret_val;
@@ -953,7 +967,8 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	/* Do not init these registers when the HW is in IAMT mode, since the
+	/*
+	 * Do not init these registers when the HW is in IAMT mode, since the
 	 * firmware will have already initialized them.  We only initialize
 	 * them if the HW is not in IAMT mode.
 	 */
@@ -974,7 +989,8 @@ static s32 e1000_copper_link_setup_gg82563_80003es2lan(struct e1000_hw *hw)
 			return ret_val;
 	}
 
-	/* Workaround: Disable padding in Kumeran interface in the MAC
+	/*
+	 * Workaround: Disable padding in Kumeran interface in the MAC
 	 * and in the PHY to avoid CRC errors.
 	 */
 	ret_val = e1e_rphy(hw, GG82563_PHY_INBAND_CTRL, &data);
@@ -1007,9 +1023,11 @@ static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
 	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
 	ew32(CTRL, ctrl);
 
-	/* Set the mac to wait the maximum time between each
+	/*
+	 * Set the mac to wait the maximum time between each
 	 * iteration and increase the max iterations when
-	 * polling the phy; this fixes erroneous timeouts at 10Mbps. */
+	 * polling the phy; this fixes erroneous timeouts at 10Mbps.
+	 */
 	ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF);
 	if (ret_val)
 		return ret_val;
@@ -1026,9 +1044,8 @@ static s32 e1000_setup_copper_link_80003es2lan(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 	reg_data |= E1000_KMRNCTRLSTA_INB_CTRL_DIS_PADDING;
-	ret_val = e1000e_write_kmrn_reg(hw,
-				       E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
-				       reg_data);
+	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_INB_CTRL,
+					reg_data);
 	if (ret_val)
 		return ret_val;
 
@@ -1056,9 +1073,8 @@ static s32 e1000_cfg_kmrn_10_100_80003es2lan(struct e1000_hw *hw, u16 duplex)
 	u16 reg_data;
 
 	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_10_100_DEFAULT;
-	ret_val = e1000e_write_kmrn_reg(hw,
-				       E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
-				       reg_data);
+	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
+					reg_data);
 	if (ret_val)
 		return ret_val;
 
@@ -1096,9 +1112,8 @@ static s32 e1000_cfg_kmrn_1000_80003es2lan(struct e1000_hw *hw)
 	u32 tipg;
 
 	reg_data = E1000_KMRNCTRLSTA_HD_CTRL_1000_DEFAULT;
-	ret_val = e1000e_write_kmrn_reg(hw,
-				       E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
-				       reg_data);
+	ret_val = e1000e_write_kmrn_reg(hw, E1000_KMRNCTRLSTA_OFFSET_HD_CTRL,
+					reg_data);
 	if (ret_val)
 		return ret_val;
 
@@ -1175,7 +1190,7 @@ static struct e1000_mac_operations es2_mac_ops = {
 	.get_link_up_info	= e1000_get_link_up_info_80003es2lan,
 	.led_on			= e1000e_led_on_generic,
 	.led_off		= e1000e_led_off_generic,
-	.mc_addr_list_update	= e1000e_mc_addr_list_update_generic,
+	.update_mc_addr_list	= e1000e_update_mc_addr_list_generic,
 	.reset_hw		= e1000_reset_hw_80003es2lan,
 	.init_hw		= e1000_init_hw_80003es2lan,
 	.setup_link		= e1000e_setup_link,
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index f77a742..4ae0056 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -102,7 +102,7 @@ static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
 	"Interrupt test (offline)", "Loopback test  (offline)",
 	"Link test   (on/offline)"
 };
-#define E1000_TEST_LEN	ARRAY_SIZE(e1000_gstrings_test)
+#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
 
 static int e1000_get_settings(struct net_device *netdev,
 			      struct ethtool_cmd *ecmd)
@@ -111,7 +111,7 @@ static int e1000_get_settings(struct net_device *netdev,
 	struct e1000_hw *hw = &adapter->hw;
 	u32 status;
 
-	if (hw->media_type == e1000_media_type_copper) {
+	if (hw->phy.media_type == e1000_media_type_copper) {
 
 		ecmd->supported = (SUPPORTED_10baseT_Half |
 				   SUPPORTED_10baseT_Full |
@@ -165,7 +165,7 @@ static int e1000_get_settings(struct net_device *netdev,
 		ecmd->duplex = -1;
 	}
 
-	ecmd->autoneg = ((hw->media_type == e1000_media_type_fiber) ||
+	ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
 			 hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
 	return 0;
 }
@@ -187,7 +187,7 @@ static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u16 spddplx)
 	mac->autoneg = 0;
 
 	/* Fiber NICs only allow 1000 gbps Full duplex */
-	if ((adapter->hw.media_type == e1000_media_type_fiber) &&
+	if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
 		spddplx != (SPEED_1000 + DUPLEX_FULL)) {
 		ndev_err(adapter->netdev, "Unsupported Speed/Duplex "
 			 "configuration\n");
@@ -226,8 +226,10 @@ static int e1000_set_settings(struct net_device *netdev,
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 
-	/* When SoL/IDER sessions are active, autoneg/speed/duplex
-	 * cannot be changed */
+	/*
+	 * When SoL/IDER sessions are active, autoneg/speed/duplex
+	 * cannot be changed
+	 */
 	if (e1000_check_reset_block(hw)) {
 		ndev_err(netdev, "Cannot change link "
 			 "characteristics when SoL/IDER is active.\n");
@@ -239,7 +241,7 @@ static int e1000_set_settings(struct net_device *netdev,
 
 	if (ecmd->autoneg == AUTONEG_ENABLE) {
 		hw->mac.autoneg = 1;
-		if (hw->media_type == e1000_media_type_fiber)
+		if (hw->phy.media_type == e1000_media_type_fiber)
 			hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full |
 						     ADVERTISED_FIBRE |
 						     ADVERTISED_Autoneg;
@@ -248,6 +250,8 @@ static int e1000_set_settings(struct net_device *netdev,
 						     ADVERTISED_TP |
 						     ADVERTISED_Autoneg;
 		ecmd->advertising = hw->phy.autoneg_advertised;
+		if (adapter->fc_autoneg)
+			hw->fc.original_type = e1000_fc_default;
 	} else {
 		if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) {
 			clear_bit(__E1000_RESETTING, &adapter->state);
@@ -277,11 +281,11 @@ static void e1000_get_pauseparam(struct net_device *netdev,
 	pause->autoneg =
 		(adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
 
-	if (hw->mac.fc == e1000_fc_rx_pause) {
+	if (hw->fc.type == e1000_fc_rx_pause) {
 		pause->rx_pause = 1;
-	} else if (hw->mac.fc == e1000_fc_tx_pause) {
+	} else if (hw->fc.type == e1000_fc_tx_pause) {
 		pause->tx_pause = 1;
-	} else if (hw->mac.fc == e1000_fc_full) {
+	} else if (hw->fc.type == e1000_fc_full) {
 		pause->rx_pause = 1;
 		pause->tx_pause = 1;
 	}
@@ -300,18 +304,18 @@ static int e1000_set_pauseparam(struct net_device *netdev,
 		msleep(1);
 
 	if (pause->rx_pause && pause->tx_pause)
-		hw->mac.fc = e1000_fc_full;
+		hw->fc.type = e1000_fc_full;
 	else if (pause->rx_pause && !pause->tx_pause)
-		hw->mac.fc = e1000_fc_rx_pause;
+		hw->fc.type = e1000_fc_rx_pause;
 	else if (!pause->rx_pause && pause->tx_pause)
-		hw->mac.fc = e1000_fc_tx_pause;
+		hw->fc.type = e1000_fc_tx_pause;
 	else if (!pause->rx_pause && !pause->tx_pause)
-		hw->mac.fc = e1000_fc_none;
+		hw->fc.type = e1000_fc_none;
 
-	hw->mac.original_fc = hw->mac.fc;
+	hw->fc.original_type = hw->fc.type;
 
 	if (adapter->fc_autoneg == AUTONEG_ENABLE) {
-		hw->mac.fc = e1000_fc_default;
+		hw->fc.type = e1000_fc_default;
 		if (netif_running(adapter->netdev)) {
 			e1000e_down(adapter);
 			e1000e_up(adapter);
@@ -319,7 +323,7 @@ static int e1000_set_pauseparam(struct net_device *netdev,
 			e1000e_reset(adapter);
 		}
 	} else {
-		retval = ((hw->media_type == e1000_media_type_fiber) ?
+		retval = ((hw->phy.media_type == e1000_media_type_fiber) ?
 			  hw->mac.ops.setup_link(hw) : e1000e_force_mac_fc(hw));
 	}
 
@@ -558,8 +562,10 @@ static int e1000_set_eeprom(struct net_device *netdev,
 	ret_val = e1000_write_nvm(hw, first_word,
 				  last_word - first_word + 1, eeprom_buff);
 
-	/* Update the checksum over the first part of the EEPROM if needed
-	 * and flush shadow RAM for 82573 controllers */
+	/*
+	 * Update the checksum over the first part of the EEPROM if needed
+	 * and flush shadow RAM for 82573 controllers
+	 */
 	if ((ret_val == 0) && ((first_word <= NVM_CHECKSUM_REG) ||
 			       (hw->mac.type == e1000_82573)))
 		e1000e_update_nvm_checksum(hw);
@@ -578,8 +584,10 @@ static void e1000_get_drvinfo(struct net_device *netdev,
 	strncpy(drvinfo->driver,  e1000e_driver_name, 32);
 	strncpy(drvinfo->version, e1000e_driver_version, 32);
 
-	/* EEPROM image version # is reported as firmware version # for
-	 * PCI-E controllers */
+	/*
+	 * EEPROM image version # is reported as firmware version # for
+	 * PCI-E controllers
+	 */
 	e1000_read_nvm(&adapter->hw, 5, 1, &eeprom_data);
 	sprintf(firmware_version, "%d.%d-%d",
 		(eeprom_data & 0xF000) >> 12,
@@ -658,8 +666,10 @@ static int e1000_set_ringparam(struct net_device *netdev,
 		if (err)
 			goto err_setup_tx;
 
-		/* save the new, restore the old in order to free it,
-		 * then restore the new back again */
+		/*
+		 * restore the old in order to free it,
+		 * then add in the new
+		 */
 		adapter->rx_ring = rx_old;
 		adapter->tx_ring = tx_old;
 		e1000e_free_rx_resources(adapter);
@@ -758,7 +768,8 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 	u32 i;
 	u32 toggle;
 
-	/* The status register is Read Only, so a write should fail.
+	/*
+	 * The status register is Read Only, so a write should fail.
 	 * Some bits that get toggled are ignored.
 	 */
 	switch (mac->type) {
@@ -908,7 +919,8 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
 		mask = 1 << i;
 
 		if (!shared_int) {
-			/* Disable the interrupt to be reported in
+			/*
+			 * Disable the interrupt to be reported in
 			 * the cause register and then force the same
 			 * interrupt and see if one gets posted.  If
 			 * an interrupt was posted to the bus, the
@@ -925,7 +937,8 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
 			}
 		}
 
-		/* Enable the interrupt to be reported in
+		/*
+		 * Enable the interrupt to be reported in
 		 * the cause register and then force the same
 		 * interrupt and see if one gets posted.  If
 		 * an interrupt was not posted to the bus, the
@@ -942,7 +955,8 @@ static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
 		}
 
 		if (!shared_int) {
-			/* Disable the other interrupts to be reported in
+			/*
+			 * Disable the other interrupts to be reported in
 			 * the cause register and then force the other
 			 * interrupts and see if any get posted.  If
 			 * an interrupt was posted to the bus, the
@@ -1175,21 +1189,21 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
 	u32 ctrl_reg = 0;
 	u32 stat_reg = 0;
 
-	adapter->hw.mac.autoneg = 0;
+	hw->mac.autoneg = 0;
 
-	if (adapter->hw.phy.type == e1000_phy_m88) {
+	if (hw->phy.type == e1000_phy_m88) {
 		/* Auto-MDI/MDIX Off */
 		e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808);
 		/* reset to update Auto-MDI/MDIX */
 		e1e_wphy(hw, PHY_CONTROL, 0x9140);
 		/* autoneg off */
 		e1e_wphy(hw, PHY_CONTROL, 0x8140);
-	} else if (adapter->hw.phy.type == e1000_phy_gg82563)
+	} else if (hw->phy.type == e1000_phy_gg82563)
 		e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x1CC);
 
 	ctrl_reg = er32(CTRL);
 
-	if (adapter->hw.phy.type == e1000_phy_ife) {
+	if (hw->phy.type == e1000_phy_ife) {
 		/* force 100, set loopback */
 		e1e_wphy(hw, PHY_CONTROL, 0x6100);
 
@@ -1212,12 +1226,14 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
 			     E1000_CTRL_FD);	 /* Force Duplex to FULL */
 	}
 
-	if (adapter->hw.media_type == e1000_media_type_copper &&
-	   adapter->hw.phy.type == e1000_phy_m88) {
+	if (hw->phy.media_type == e1000_media_type_copper &&
+	    hw->phy.type == e1000_phy_m88) {
 		ctrl_reg |= E1000_CTRL_ILOS; /* Invert Loss of Signal */
 	} else {
-		/* Set the ILOS bit on the fiber Nic if half duplex link is
-		 * detected. */
+		/*
+		 * Set the ILOS bit on the fiber Nic if half duplex link is
+		 * detected.
+		 */
 		stat_reg = er32(STATUS);
 		if ((stat_reg & E1000_STATUS_FD) == 0)
 			ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);
@@ -1225,10 +1241,11 @@ static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
 
 	ew32(CTRL, ctrl_reg);
 
-	/* Disable the receiver on the PHY so when a cable is plugged in, the
+	/*
+	 * Disable the receiver on the PHY so when a cable is plugged in, the
 	 * PHY does not begin to autoneg when a cable is reconnected to the NIC.
 	 */
-	if (adapter->hw.phy.type == e1000_phy_m88)
+	if (hw->phy.type == e1000_phy_m88)
 		e1000_phy_disable_receiver(adapter);
 
 	udelay(500);
@@ -1244,8 +1261,10 @@ static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter)
 
 	/* special requirements for 82571/82572 fiber adapters */
 
-	/* jump through hoops to make sure link is up because serdes
-	 * link is hardwired up */
+	/*
+	 * jump through hoops to make sure link is up because serdes
+	 * link is hardwired up
+	 */
 	ctrl |= E1000_CTRL_SLU;
 	ew32(CTRL, ctrl);
 
@@ -1263,8 +1282,10 @@ static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter)
 		ew32(CTRL, ctrl);
 	}
 
-	/* special write to serdes control register to enable SerDes analog
-	 * loopback */
+	/*
+	 * special write to serdes control register to enable SerDes analog
+	 * loopback
+	 */
 #define E1000_SERDES_LB_ON 0x410
 	ew32(SCTL, E1000_SERDES_LB_ON);
 	msleep(10);
@@ -1279,8 +1300,10 @@ static int e1000_set_es2lan_mac_loopback(struct e1000_adapter *adapter)
 	u32 ctrlext = er32(CTRL_EXT);
 	u32 ctrl = er32(CTRL);
 
-	/* save CTRL_EXT to restore later, reuse an empty variable (unused
-	   on mac_type 80003es2lan) */
+	/*
+	 * save CTRL_EXT to restore later, reuse an empty variable (unused
+	 * on mac_type 80003es2lan)
+	 */
 	adapter->tx_fifo_head = ctrlext;
 
 	/* clear the serdes mode bits, putting the device into mac loopback */
@@ -1312,8 +1335,8 @@ static int e1000_setup_loopback_test(struct e1000_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 	u32 rctl;
 
-	if (hw->media_type == e1000_media_type_fiber ||
-	    hw->media_type == e1000_media_type_internal_serdes) {
+	if (hw->phy.media_type == e1000_media_type_fiber ||
+	    hw->phy.media_type == e1000_media_type_internal_serdes) {
 		switch (hw->mac.type) {
 		case e1000_80003es2lan:
 			return e1000_set_es2lan_mac_loopback(adapter);
@@ -1328,7 +1351,7 @@ static int e1000_setup_loopback_test(struct e1000_adapter *adapter)
 			ew32(RCTL, rctl);
 			return 0;
 		}
-	} else if (hw->media_type == e1000_media_type_copper) {
+	} else if (hw->phy.media_type == e1000_media_type_copper) {
 		return e1000_integrated_phy_loopback(adapter);
 	}
 
@@ -1347,18 +1370,17 @@ static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
 
 	switch (hw->mac.type) {
 	case e1000_80003es2lan:
-		if (hw->media_type == e1000_media_type_fiber ||
-		    hw->media_type == e1000_media_type_internal_serdes) {
+		if (hw->phy.media_type == e1000_media_type_fiber ||
+		    hw->phy.media_type == e1000_media_type_internal_serdes) {
 			/* restore CTRL_EXT, stealing space from tx_fifo_head */
-			ew32(CTRL_EXT,
-					adapter->tx_fifo_head);
+			ew32(CTRL_EXT, adapter->tx_fifo_head);
 			adapter->tx_fifo_head = 0;
 		}
 		/* fall through */
 	case e1000_82571:
 	case e1000_82572:
-		if (hw->media_type == e1000_media_type_fiber ||
-		    hw->media_type == e1000_media_type_internal_serdes) {
+		if (hw->phy.media_type == e1000_media_type_fiber ||
+		    hw->phy.media_type == e1000_media_type_internal_serdes) {
 #define E1000_SERDES_LB_OFF 0x400
 			ew32(SCTL, E1000_SERDES_LB_OFF);
 			msleep(10);
@@ -1414,7 +1436,8 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)
 
 	ew32(RDT, rx_ring->count - 1);
 
-	/* Calculate the loop count based on the largest descriptor ring
+	/*
+	 * Calculate the loop count based on the largest descriptor ring
 	 * The idea is to wrap the largest ring a number of times using 64
 	 * send/receive pairs during each loop
 	 */
@@ -1454,7 +1477,8 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)
 			l++;
 			if (l == rx_ring->count)
 				l = 0;
-			/* time + 20 msecs (200 msecs on 2.4) is more than
+			/*
+			 * time + 20 msecs (200 msecs on 2.4) is more than
 			 * enough time to complete the receives, if it's
 			 * exceeded, break and error off
 			 */
@@ -1473,8 +1497,10 @@ static int e1000_run_loopback_test(struct e1000_adapter *adapter)
 
 static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data)
 {
-	/* PHY loopback cannot be performed if SoL/IDER
-	 * sessions are active */
+	/*
+	 * PHY loopback cannot be performed if SoL/IDER
+	 * sessions are active
+	 */
 	if (e1000_check_reset_block(&adapter->hw)) {
 		ndev_err(adapter->netdev, "Cannot do PHY loopback test "
 			 "when SoL/IDER is active.\n");
@@ -1504,12 +1530,14 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
 	struct e1000_hw *hw = &adapter->hw;
 
 	*data = 0;
-	if (hw->media_type == e1000_media_type_internal_serdes) {
+	if (hw->phy.media_type == e1000_media_type_internal_serdes) {
 		int i = 0;
 		hw->mac.serdes_has_link = 0;
 
-		/* On some blade server designs, link establishment
-		 * could take as long as 2-3 minutes */
+		/*
+		 * On some blade server designs, link establishment
+		 * could take as long as 2-3 minutes
+		 */
 		do {
 			hw->mac.ops.check_for_link(hw);
 			if (hw->mac.serdes_has_link)
@@ -1562,8 +1590,10 @@ static void e1000_diag_test(struct net_device *netdev,
 
 		ndev_info(netdev, "offline testing starting\n");
 
-		/* Link test performed before hardware reset so autoneg doesn't
-		 * interfere with test result */
+		/*
+		 * Link test performed before hardware reset so autoneg doesn't
+		 * interfere with test result
+		 */
 		if (e1000_link_test(adapter, &data[4]))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
@@ -1596,9 +1626,9 @@ static void e1000_diag_test(struct net_device *netdev,
 		adapter->hw.mac.autoneg = autoneg;
 
 		/* force this routine to wait until autoneg complete/timeout */
-		adapter->hw.phy.wait_for_link = 1;
+		adapter->hw.phy.autoneg_wait_to_complete = 1;
 		e1000e_reset(adapter);
-		adapter->hw.phy.wait_for_link = 0;
+		adapter->hw.phy.autoneg_wait_to_complete = 0;
 
 		clear_bit(__E1000_TESTING, &adapter->state);
 		if (if_running)
@@ -1768,8 +1798,7 @@ static void e1000_get_strings(struct net_device *netdev, u32 stringset,
 
 	switch (stringset) {
 	case ETH_SS_TEST:
-		memcpy(data, *e1000_gstrings_test,
-			sizeof(e1000_gstrings_test));
+		memcpy(data, *e1000_gstrings_test, sizeof(e1000_gstrings_test));
 		break;
 	case ETH_SS_STATS:
 		for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 916025b..0b4145a 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -66,14 +66,14 @@ enum e1e_registers {
 	E1000_IMS      = 0x000D0, /* Interrupt Mask Set - RW */
 	E1000_IMC      = 0x000D8, /* Interrupt Mask Clear - WO */
 	E1000_IAM      = 0x000E0, /* Interrupt Acknowledge Auto Mask */
-	E1000_RCTL     = 0x00100, /* RX Control - RW */
+	E1000_RCTL     = 0x00100, /* Rx Control - RW */
 	E1000_FCTTV    = 0x00170, /* Flow Control Transmit Timer Value - RW */
-	E1000_TXCW     = 0x00178, /* TX Configuration Word - RW */
-	E1000_RXCW     = 0x00180, /* RX Configuration Word - RO */
-	E1000_TCTL     = 0x00400, /* TX Control - RW */
-	E1000_TCTL_EXT = 0x00404, /* Extended TX Control - RW */
-	E1000_TIPG     = 0x00410, /* TX Inter-packet gap -RW */
-	E1000_AIT      = 0x00458, /* Adaptive Interframe Spacing Throttle - RW */
+	E1000_TXCW     = 0x00178, /* Tx Configuration Word - RW */
+	E1000_RXCW     = 0x00180, /* Rx Configuration Word - RO */
+	E1000_TCTL     = 0x00400, /* Tx Control - RW */
+	E1000_TCTL_EXT = 0x00404, /* Extended Tx Control - RW */
+	E1000_TIPG     = 0x00410, /* Tx Inter-packet gap -RW */
+	E1000_AIT      = 0x00458, /* Adaptive Interframe Spacing Throttle -RW */
 	E1000_LEDCTL   = 0x00E00, /* LED Control - RW */
 	E1000_EXTCNF_CTRL  = 0x00F00, /* Extended Configuration Control */
 	E1000_EXTCNF_SIZE  = 0x00F08, /* Extended Configuration Size */
@@ -87,12 +87,12 @@ enum e1e_registers {
 	E1000_FCRTL    = 0x02160, /* Flow Control Receive Threshold Low - RW */
 	E1000_FCRTH    = 0x02168, /* Flow Control Receive Threshold High - RW */
 	E1000_PSRCTL   = 0x02170, /* Packet Split Receive Control - RW */
-	E1000_RDBAL    = 0x02800, /* RX Descriptor Base Address Low - RW */
-	E1000_RDBAH    = 0x02804, /* RX Descriptor Base Address High - RW */
-	E1000_RDLEN    = 0x02808, /* RX Descriptor Length - RW */
-	E1000_RDH      = 0x02810, /* RX Descriptor Head - RW */
-	E1000_RDT      = 0x02818, /* RX Descriptor Tail - RW */
-	E1000_RDTR     = 0x02820, /* RX Delay Timer - RW */
+	E1000_RDBAL    = 0x02800, /* Rx Descriptor Base Address Low - RW */
+	E1000_RDBAH    = 0x02804, /* Rx Descriptor Base Address High - RW */
+	E1000_RDLEN    = 0x02808, /* Rx Descriptor Length - RW */
+	E1000_RDH      = 0x02810, /* Rx Descriptor Head - RW */
+	E1000_RDT      = 0x02818, /* Rx Descriptor Tail - RW */
+	E1000_RDTR     = 0x02820, /* Rx Delay Timer - RW */
 	E1000_RADV     = 0x0282C, /* RX Interrupt Absolute Delay Timer - RW */
 
 /* Convenience macros
@@ -105,17 +105,17 @@ enum e1e_registers {
  */
 #define E1000_RDBAL_REG(_n)   (E1000_RDBAL + (_n << 8))
 	E1000_KABGTXD  = 0x03004, /* AFE Band Gap Transmit Ref Data */
-	E1000_TDBAL    = 0x03800, /* TX Descriptor Base Address Low - RW */
-	E1000_TDBAH    = 0x03804, /* TX Descriptor Base Address High - RW */
-	E1000_TDLEN    = 0x03808, /* TX Descriptor Length - RW */
-	E1000_TDH      = 0x03810, /* TX Descriptor Head - RW */
-	E1000_TDT      = 0x03818, /* TX Descriptor Tail - RW */
-	E1000_TIDV     = 0x03820, /* TX Interrupt Delay Value - RW */
-	E1000_TXDCTL   = 0x03828, /* TX Descriptor Control - RW */
-	E1000_TADV     = 0x0382C, /* TX Interrupt Absolute Delay Val - RW */
-	E1000_TARC0    = 0x03840, /* TX Arbitration Count (0) */
-	E1000_TXDCTL1  = 0x03928, /* TX Descriptor Control (1) - RW */
-	E1000_TARC1    = 0x03940, /* TX Arbitration Count (1) */
+	E1000_TDBAL    = 0x03800, /* Tx Descriptor Base Address Low - RW */
+	E1000_TDBAH    = 0x03804, /* Tx Descriptor Base Address High - RW */
+	E1000_TDLEN    = 0x03808, /* Tx Descriptor Length - RW */
+	E1000_TDH      = 0x03810, /* Tx Descriptor Head - RW */
+	E1000_TDT      = 0x03818, /* Tx Descriptor Tail - RW */
+	E1000_TIDV     = 0x03820, /* Tx Interrupt Delay Value - RW */
+	E1000_TXDCTL   = 0x03828, /* Tx Descriptor Control - RW */
+	E1000_TADV     = 0x0382C, /* Tx Interrupt Absolute Delay Val - RW */
+	E1000_TARC0    = 0x03840, /* Tx Arbitration Count (0) */
+	E1000_TXDCTL1  = 0x03928, /* Tx Descriptor Control (1) - RW */
+	E1000_TARC1    = 0x03940, /* Tx Arbitration Count (1) */
 	E1000_CRCERRS  = 0x04000, /* CRC Error Count - R/clr */
 	E1000_ALGNERRC = 0x04004, /* Alignment Error Count - R/clr */
 	E1000_SYMERRS  = 0x04008, /* Symbol Error Count - R/clr */
@@ -127,53 +127,53 @@ enum e1e_registers {
 	E1000_LATECOL  = 0x04020, /* Late Collision Count - R/clr */
 	E1000_COLC     = 0x04028, /* Collision Count - R/clr */
 	E1000_DC       = 0x04030, /* Defer Count - R/clr */
-	E1000_TNCRS    = 0x04034, /* TX-No CRS - R/clr */
+	E1000_TNCRS    = 0x04034, /* Tx-No CRS - R/clr */
 	E1000_SEC      = 0x04038, /* Sequence Error Count - R/clr */
 	E1000_CEXTERR  = 0x0403C, /* Carrier Extension Error Count - R/clr */
 	E1000_RLEC     = 0x04040, /* Receive Length Error Count - R/clr */
-	E1000_XONRXC   = 0x04048, /* XON RX Count - R/clr */
-	E1000_XONTXC   = 0x0404C, /* XON TX Count - R/clr */
-	E1000_XOFFRXC  = 0x04050, /* XOFF RX Count - R/clr */
-	E1000_XOFFTXC  = 0x04054, /* XOFF TX Count - R/clr */
-	E1000_FCRUC    = 0x04058, /* Flow Control RX Unsupported Count- R/clr */
-	E1000_PRC64    = 0x0405C, /* Packets RX (64 bytes) - R/clr */
-	E1000_PRC127   = 0x04060, /* Packets RX (65-127 bytes) - R/clr */
-	E1000_PRC255   = 0x04064, /* Packets RX (128-255 bytes) - R/clr */
-	E1000_PRC511   = 0x04068, /* Packets RX (255-511 bytes) - R/clr */
-	E1000_PRC1023  = 0x0406C, /* Packets RX (512-1023 bytes) - R/clr */
-	E1000_PRC1522  = 0x04070, /* Packets RX (1024-1522 bytes) - R/clr */
-	E1000_GPRC     = 0x04074, /* Good Packets RX Count - R/clr */
-	E1000_BPRC     = 0x04078, /* Broadcast Packets RX Count - R/clr */
-	E1000_MPRC     = 0x0407C, /* Multicast Packets RX Count - R/clr */
-	E1000_GPTC     = 0x04080, /* Good Packets TX Count - R/clr */
-	E1000_GORCL    = 0x04088, /* Good Octets RX Count Low - R/clr */
-	E1000_GORCH    = 0x0408C, /* Good Octets RX Count High - R/clr */
-	E1000_GOTCL    = 0x04090, /* Good Octets TX Count Low - R/clr */
-	E1000_GOTCH    = 0x04094, /* Good Octets TX Count High - R/clr */
-	E1000_RNBC     = 0x040A0, /* RX No Buffers Count - R/clr */
-	E1000_RUC      = 0x040A4, /* RX Undersize Count - R/clr */
-	E1000_RFC      = 0x040A8, /* RX Fragment Count - R/clr */
-	E1000_ROC      = 0x040AC, /* RX Oversize Count - R/clr */
-	E1000_RJC      = 0x040B0, /* RX Jabber Count - R/clr */
-	E1000_MGTPRC   = 0x040B4, /* Management Packets RX Count - R/clr */
+	E1000_XONRXC   = 0x04048, /* XON Rx Count - R/clr */
+	E1000_XONTXC   = 0x0404C, /* XON Tx Count - R/clr */
+	E1000_XOFFRXC  = 0x04050, /* XOFF Rx Count - R/clr */
+	E1000_XOFFTXC  = 0x04054, /* XOFF Tx Count - R/clr */
+	E1000_FCRUC    = 0x04058, /* Flow Control Rx Unsupported Count- R/clr */
+	E1000_PRC64    = 0x0405C, /* Packets Rx (64 bytes) - R/clr */
+	E1000_PRC127   = 0x04060, /* Packets Rx (65-127 bytes) - R/clr */
+	E1000_PRC255   = 0x04064, /* Packets Rx (128-255 bytes) - R/clr */
+	E1000_PRC511   = 0x04068, /* Packets Rx (255-511 bytes) - R/clr */
+	E1000_PRC1023  = 0x0406C, /* Packets Rx (512-1023 bytes) - R/clr */
+	E1000_PRC1522  = 0x04070, /* Packets Rx (1024-1522 bytes) - R/clr */
+	E1000_GPRC     = 0x04074, /* Good Packets Rx Count - R/clr */
+	E1000_BPRC     = 0x04078, /* Broadcast Packets Rx Count - R/clr */
+	E1000_MPRC     = 0x0407C, /* Multicast Packets Rx Count - R/clr */
+	E1000_GPTC     = 0x04080, /* Good Packets Tx Count - R/clr */
+	E1000_GORCL    = 0x04088, /* Good Octets Rx Count Low - R/clr */
+	E1000_GORCH    = 0x0408C, /* Good Octets Rx Count High - R/clr */
+	E1000_GOTCL    = 0x04090, /* Good Octets Tx Count Low - R/clr */
+	E1000_GOTCH    = 0x04094, /* Good Octets Tx Count High - R/clr */
+	E1000_RNBC     = 0x040A0, /* Rx No Buffers Count - R/clr */
+	E1000_RUC      = 0x040A4, /* Rx Undersize Count - R/clr */
+	E1000_RFC      = 0x040A8, /* Rx Fragment Count - R/clr */
+	E1000_ROC      = 0x040AC, /* Rx Oversize Count - R/clr */
+	E1000_RJC      = 0x040B0, /* Rx Jabber Count - R/clr */
+	E1000_MGTPRC   = 0x040B4, /* Management Packets Rx Count - R/clr */
 	E1000_MGTPDC   = 0x040B8, /* Management Packets Dropped Count - R/clr */
-	E1000_MGTPTC   = 0x040BC, /* Management Packets TX Count - R/clr */
-	E1000_TORL     = 0x040C0, /* Total Octets RX Low - R/clr */
-	E1000_TORH     = 0x040C4, /* Total Octets RX High - R/clr */
-	E1000_TOTL     = 0x040C8, /* Total Octets TX Low - R/clr */
-	E1000_TOTH     = 0x040CC, /* Total Octets TX High - R/clr */
-	E1000_TPR      = 0x040D0, /* Total Packets RX - R/clr */
-	E1000_TPT      = 0x040D4, /* Total Packets TX - R/clr */
-	E1000_PTC64    = 0x040D8, /* Packets TX (64 bytes) - R/clr */
-	E1000_PTC127   = 0x040DC, /* Packets TX (65-127 bytes) - R/clr */
-	E1000_PTC255   = 0x040E0, /* Packets TX (128-255 bytes) - R/clr */
-	E1000_PTC511   = 0x040E4, /* Packets TX (256-511 bytes) - R/clr */
-	E1000_PTC1023  = 0x040E8, /* Packets TX (512-1023 bytes) - R/clr */
-	E1000_PTC1522  = 0x040EC, /* Packets TX (1024-1522 Bytes) - R/clr */
-	E1000_MPTC     = 0x040F0, /* Multicast Packets TX Count - R/clr */
-	E1000_BPTC     = 0x040F4, /* Broadcast Packets TX Count - R/clr */
-	E1000_TSCTC    = 0x040F8, /* TCP Segmentation Context TX - R/clr */
-	E1000_TSCTFC   = 0x040FC, /* TCP Segmentation Context TX Fail - R/clr */
+	E1000_MGTPTC   = 0x040BC, /* Management Packets Tx Count - R/clr */
+	E1000_TORL     = 0x040C0, /* Total Octets Rx Low - R/clr */
+	E1000_TORH     = 0x040C4, /* Total Octets Rx High - R/clr */
+	E1000_TOTL     = 0x040C8, /* Total Octets Tx Low - R/clr */
+	E1000_TOTH     = 0x040CC, /* Total Octets Tx High - R/clr */
+	E1000_TPR      = 0x040D0, /* Total Packets Rx - R/clr */
+	E1000_TPT      = 0x040D4, /* Total Packets Tx - R/clr */
+	E1000_PTC64    = 0x040D8, /* Packets Tx (64 bytes) - R/clr */
+	E1000_PTC127   = 0x040DC, /* Packets Tx (65-127 bytes) - R/clr */
+	E1000_PTC255   = 0x040E0, /* Packets Tx (128-255 bytes) - R/clr */
+	E1000_PTC511   = 0x040E4, /* Packets Tx (256-511 bytes) - R/clr */
+	E1000_PTC1023  = 0x040E8, /* Packets Tx (512-1023 bytes) - R/clr */
+	E1000_PTC1522  = 0x040EC, /* Packets Tx (1024-1522 Bytes) - R/clr */
+	E1000_MPTC     = 0x040F0, /* Multicast Packets Tx Count - R/clr */
+	E1000_BPTC     = 0x040F4, /* Broadcast Packets Tx Count - R/clr */
+	E1000_TSCTC    = 0x040F8, /* TCP Segmentation Context Tx - R/clr */
+	E1000_TSCTFC   = 0x040FC, /* TCP Segmentation Context Tx Fail - R/clr */
 	E1000_IAC      = 0x04100, /* Interrupt Assertion Count */
 	E1000_ICRXPTC  = 0x04104, /* Irq Cause Rx Packet Timer Expire Count */
 	E1000_ICRXATC  = 0x04108, /* Irq Cause Rx Abs Timer Expire Count */
@@ -183,7 +183,7 @@ enum e1e_registers {
 	E1000_ICTXQMTC = 0x0411C, /* Irq Cause Tx Queue MinThreshold Count */
 	E1000_ICRXDMTC = 0x04120, /* Irq Cause Rx Desc MinThreshold Count */
 	E1000_ICRXOC   = 0x04124, /* Irq Cause Receiver Overrun Count */
-	E1000_RXCSUM   = 0x05000, /* RX Checksum Control - RW */
+	E1000_RXCSUM   = 0x05000, /* Rx Checksum Control - RW */
 	E1000_RFCTL    = 0x05008, /* Receive Filter Control */
 	E1000_MTA      = 0x05200, /* Multicast Table Array - RW Array */
 	E1000_RA       = 0x05400, /* Receive Address - RW Array */
@@ -250,8 +250,8 @@ enum e1e_registers {
 #define E1000_VFTA_ENTRY_BIT_SHIFT_MASK	0x1F
 
 #define E1000_HICR_EN			0x01  /* Enable bit - RO */
-#define E1000_HICR_C			0x02  /* Driver sets this bit when done
-					       * to put command in RAM */
+/* Driver sets this bit when done to put command in RAM */
+#define E1000_HICR_C			0x02
 #define E1000_HICR_FW_RESET_ENABLE	0x40
 #define E1000_HICR_FW_RESET		0x80
 
@@ -400,7 +400,7 @@ enum e1000_rev_polarity{
 	e1000_rev_polarity_undefined = 0xFF
 };
 
-enum e1000_fc_mode {
+enum e1000_fc_type {
 	e1000_fc_none = 0,
 	e1000_fc_rx_pause,
 	e1000_fc_tx_pause,
@@ -685,8 +685,7 @@ struct e1000_mac_operations {
 	s32  (*get_link_up_info)(struct e1000_hw *, u16 *, u16 *);
 	s32  (*led_on)(struct e1000_hw *);
 	s32  (*led_off)(struct e1000_hw *);
-	void (*mc_addr_list_update)(struct e1000_hw *, u8 *, u32, u32,
-					 u32);
+	void (*update_mc_addr_list)(struct e1000_hw *, u8 *, u32, u32, u32);
 	s32  (*reset_hw)(struct e1000_hw *);
 	s32  (*init_hw)(struct e1000_hw *);
 	s32  (*setup_link)(struct e1000_hw *);
@@ -728,16 +727,12 @@ struct e1000_mac_info {
 	u8 perm_addr[6];
 
 	enum e1000_mac_type type;
-	enum e1000_fc_mode  fc;
-	enum e1000_fc_mode  original_fc;
 
 	u32 collision_delta;
 	u32 ledctl_default;
 	u32 ledctl_mode1;
 	u32 ledctl_mode2;
-	u32 max_frame_size;
 	u32 mc_filter_type;
-	u32 min_frame_size;
 	u32 tx_packet_delta;
 	u32 txcw;
 
@@ -748,9 +743,6 @@ struct e1000_mac_info {
 	u16 ifs_step_size;
 	u16 mta_reg_count;
 	u16 rar_entry_count;
-	u16 fc_high_water;
-	u16 fc_low_water;
-	u16 fc_pause_time;
 
 	u8  forced_speed_duplex;
 
@@ -780,6 +772,8 @@ struct e1000_phy_info {
 	u32 reset_delay_us; /* in usec */
 	u32 revision;
 
+	enum e1000_media_type media_type;
+
 	u16 autoneg_advertised;
 	u16 autoneg_mask;
 	u16 cable_length;
@@ -792,7 +786,7 @@ struct e1000_phy_info {
 	bool is_mdix;
 	bool polarity_correction;
 	bool speed_downgraded;
-	bool wait_for_link;
+	bool autoneg_wait_to_complete;
 };
 
 struct e1000_nvm_info {
@@ -817,6 +811,16 @@ struct e1000_bus_info {
 	u16 func;
 };
 
+struct e1000_fc_info {
+	u32 high_water;          /* Flow control high-water mark */
+	u32 low_water;           /* Flow control low-water mark */
+	u16 pause_time;          /* Flow control pause timer */
+	bool send_xon;           /* Flow control send XON */
+	bool strict_ieee;        /* Strict IEEE mode */
+	enum e1000_fc_type type; /* Type of flow control */
+	enum e1000_fc_type original_type;
+};
+
 struct e1000_dev_spec_82571 {
 	bool laa_is_present;
 	bool alt_mac_addr_is_present;
@@ -841,6 +845,7 @@ struct e1000_hw {
 	u8 __iomem *flash_address;
 
 	struct e1000_mac_info  mac;
+	struct e1000_fc_info   fc;
 	struct e1000_phy_info  phy;
 	struct e1000_nvm_info  nvm;
 	struct e1000_bus_info  bus;
@@ -850,8 +855,6 @@ struct e1000_hw {
 		struct e1000_dev_spec_82571	e82571;
 		struct e1000_dev_spec_ich8lan	ich8lan;
 	} dev_spec;
-
-	enum e1000_media_type media_type;
 };
 
 #ifdef DEBUG
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index 0ae3955..e358a77 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -243,8 +243,7 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
 	u32 sector_end_addr;
 	u16 i;
 
-	/* Can't read flash registers if the register set isn't mapped.
-	 */
+	/* Can't read flash registers if the register set isn't mapped. */
 	if (!hw->flash_address) {
 		hw_dbg(hw, "ERROR: Flash registers not mapped\n");
 		return -E1000_ERR_CONFIG;
@@ -254,17 +253,21 @@ static s32 e1000_init_nvm_params_ich8lan(struct e1000_hw *hw)
 
 	gfpreg = er32flash(ICH_FLASH_GFPREG);
 
-	/* sector_X_addr is a "sector"-aligned address (4096 bytes)
+	/*
+	 * sector_X_addr is a "sector"-aligned address (4096 bytes)
 	 * Add 1 to sector_end_addr since this sector is included in
-	 * the overall size. */
+	 * the overall size.
+	 */
 	sector_base_addr = gfpreg & FLASH_GFPREG_BASE_MASK;
 	sector_end_addr = ((gfpreg >> 16) & FLASH_GFPREG_BASE_MASK) + 1;
 
 	/* flash_base_addr is byte-aligned */
 	nvm->flash_base_addr = sector_base_addr << FLASH_SECTOR_ADDR_SHIFT;
 
-	/* find total size of the NVM, then cut in half since the total
-	 * size represents two separate NVM banks. */
+	/*
+	 * find total size of the NVM, then cut in half since the total
+	 * size represents two separate NVM banks.
+	 */
 	nvm->flash_bank_size = (sector_end_addr - sector_base_addr)
 				<< FLASH_SECTOR_ADDR_SHIFT;
 	nvm->flash_bank_size /= 2;
@@ -295,7 +298,7 @@ static s32 e1000_init_mac_params_ich8lan(struct e1000_adapter *adapter)
 	struct e1000_mac_info *mac = &hw->mac;
 
 	/* Set media type function pointer */
-	hw->media_type = e1000_media_type_copper;
+	hw->phy.media_type = e1000_media_type_copper;
 
 	/* Set mta register count */
 	mac->mta_reg_count = 32;
@@ -450,7 +453,7 @@ static s32 e1000_phy_force_speed_duplex_ich8lan(struct e1000_hw *hw)
 
 	udelay(1);
 
-	if (phy->wait_for_link) {
+	if (phy->autoneg_wait_to_complete) {
 		hw_dbg(hw, "Waiting for forced speed/duplex link on IFE phy.\n");
 
 		ret_val = e1000e_phy_has_link_generic(hw,
@@ -496,7 +499,8 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	/* Initialize the PHY from the NVM on ICH platforms.  This
+	/*
+	 * Initialize the PHY from the NVM on ICH platforms.  This
 	 * is needed due to an issue where the NVM configuration is
 	 * not properly autoloaded after power transitions.
 	 * Therefore, after each PHY reset, we will load the
@@ -523,7 +527,8 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
 			udelay(100);
 		} while ((!data) && --loop);
 
-		/* If basic configuration is incomplete before the above loop
+		/*
+		 * If basic configuration is incomplete before the above loop
 		 * count reaches 0, loading the configuration from NVM will
 		 * leave the PHY in a bad state possibly resulting in no link.
 		 */
@@ -536,8 +541,10 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
 		data &= ~E1000_STATUS_LAN_INIT_DONE;
 		ew32(STATUS, data);
 
-		/* Make sure HW does not configure LCD from PHY
-		 * extended configuration before SW configuration */
+		/*
+		 * Make sure HW does not configure LCD from PHY
+		 * extended configuration before SW configuration
+		 */
 		data = er32(EXTCNF_CTRL);
 		if (data & E1000_EXTCNF_CTRL_LCD_WRITE_ENABLE)
 			return 0;
@@ -551,8 +558,7 @@ static s32 e1000_phy_hw_reset_ich8lan(struct e1000_hw *hw)
 		cnf_base_addr = data & E1000_EXTCNF_CTRL_EXT_CNF_POINTER_MASK;
 		cnf_base_addr >>= E1000_EXTCNF_CTRL_EXT_CNF_POINTER_SHIFT;
 
-		/* Configure LCD from extended configuration
-		 * region. */
+		/* Configure LCD from extended configuration region. */
 
 		/* cnf_base_addr is in DWORD */
 		word_addr = (u16)(cnf_base_addr << 1);
@@ -681,8 +687,8 @@ static s32 e1000_check_polarity_ife_ich8lan(struct e1000_hw *hw)
 	s32 ret_val;
 	u16 phy_data, offset, mask;
 
-	/* Polarity is determined based on the reversal feature
-	 * being enabled.
+	/*
+	 * Polarity is determined based on the reversal feature being enabled.
 	 */
 	if (phy->polarity_correction) {
 		offset	= IFE_PHY_EXTENDED_STATUS_CONTROL;
@@ -731,8 +737,10 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
 		phy_ctrl |= E1000_PHY_CTRL_D0A_LPLU;
 		ew32(PHY_CTRL, phy_ctrl);
 
-		/* Call gig speed drop workaround on LPLU before accessing
-		 * any PHY registers */
+		/*
+		 * Call gig speed drop workaround on LPLU before accessing
+		 * any PHY registers
+		 */
 		if ((hw->mac.type == e1000_ich8lan) &&
 		    (hw->phy.type == e1000_phy_igp_3))
 			e1000e_gig_downshift_workaround_ich8lan(hw);
@@ -747,30 +755,32 @@ static s32 e1000_set_d0_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
 		phy_ctrl &= ~E1000_PHY_CTRL_D0A_LPLU;
 		ew32(PHY_CTRL, phy_ctrl);
 
-		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used
+		/*
+		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
 		 * during Dx states where the power conservation is most
 		 * important.  During driver activity we should enable
-		 * SmartSpeed, so performance is maintained. */
+		 * SmartSpeed, so performance is maintained.
+		 */
 		if (phy->smart_speed == e1000_smart_speed_on) {
 			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						    &data);
+					   &data);
 			if (ret_val)
 				return ret_val;
 
 			data |= IGP01E1000_PSCFR_SMART_SPEED;
 			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     data);
+					   data);
 			if (ret_val)
 				return ret_val;
 		} else if (phy->smart_speed == e1000_smart_speed_off) {
 			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						    &data);
+					   &data);
 			if (ret_val)
 				return ret_val;
 
 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
 			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     data);
+					   data);
 			if (ret_val)
 				return ret_val;
 		}
@@ -804,34 +814,32 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
 	if (!active) {
 		phy_ctrl &= ~E1000_PHY_CTRL_NOND0A_LPLU;
 		ew32(PHY_CTRL, phy_ctrl);
-		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used
+		/*
+		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
 		 * during Dx states where the power conservation is most
 		 * important.  During driver activity we should enable
-		 * SmartSpeed, so performance is maintained. */
+		 * SmartSpeed, so performance is maintained.
+		 */
 		if (phy->smart_speed == e1000_smart_speed_on) {
-			ret_val = e1e_rphy(hw,
-						    IGP01E1000_PHY_PORT_CONFIG,
-						    &data);
+			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
+					   &data);
 			if (ret_val)
 				return ret_val;
 
 			data |= IGP01E1000_PSCFR_SMART_SPEED;
-			ret_val = e1e_wphy(hw,
-						     IGP01E1000_PHY_PORT_CONFIG,
-						     data);
+			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
+					   data);
 			if (ret_val)
 				return ret_val;
 		} else if (phy->smart_speed == e1000_smart_speed_off) {
-			ret_val = e1e_rphy(hw,
-						    IGP01E1000_PHY_PORT_CONFIG,
-						    &data);
+			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
+					   &data);
 			if (ret_val)
 				return ret_val;
 
 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-			ret_val = e1e_wphy(hw,
-						     IGP01E1000_PHY_PORT_CONFIG,
-						     data);
+			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
+					   data);
 			if (ret_val)
 				return ret_val;
 		}
@@ -841,23 +849,21 @@ static s32 e1000_set_d3_lplu_state_ich8lan(struct e1000_hw *hw, bool active)
 		phy_ctrl |= E1000_PHY_CTRL_NOND0A_LPLU;
 		ew32(PHY_CTRL, phy_ctrl);
 
-		/* Call gig speed drop workaround on LPLU before accessing
-		 * any PHY registers */
+		/*
+		 * Call gig speed drop workaround on LPLU before accessing
+		 * any PHY registers
+		 */
 		if ((hw->mac.type == e1000_ich8lan) &&
 		    (hw->phy.type == e1000_phy_igp_3))
 			e1000e_gig_downshift_workaround_ich8lan(hw);
 
 		/* When LPLU is enabled, we should disable SmartSpeed */
-		ret_val = e1e_rphy(hw,
-					    IGP01E1000_PHY_PORT_CONFIG,
-					    &data);
+		ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG, &data);
 		if (ret_val)
 			return ret_val;
 
 		data &= ~IGP01E1000_PSCFR_SMART_SPEED;
-		ret_val = e1e_wphy(hw,
-					     IGP01E1000_PHY_PORT_CONFIG,
-					     data);
+		ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG, data);
 	}
 
 	return 0;
@@ -944,7 +950,8 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
 
 	ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
 
-	/* Either we should have a hardware SPI cycle in progress
+	/*
+	 * Either we should have a hardware SPI cycle in progress
 	 * bit to check against, in order to start a new cycle or
 	 * FDONE bit should be changed in the hardware so that it
 	 * is 1 after hardware reset, which can then be used as an
@@ -953,15 +960,19 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
 	 */
 
 	if (hsfsts.hsf_status.flcinprog == 0) {
-		/* There is no cycle running at present,
-		 * so we can start a cycle */
-		/* Begin by setting Flash Cycle Done. */
+		/*
+		 * There is no cycle running at present,
+		 * so we can start a cycle
+		 * Begin by setting Flash Cycle Done.
+		 */
 		hsfsts.hsf_status.flcdone = 1;
 		ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
 		ret_val = 0;
 	} else {
-		/* otherwise poll for sometime so the current
-		 * cycle has a chance to end before giving up. */
+		/*
+		 * otherwise poll for sometime so the current
+		 * cycle has a chance to end before giving up.
+		 */
 		for (i = 0; i < ICH_FLASH_READ_COMMAND_TIMEOUT; i++) {
 			hsfsts.regval = __er16flash(hw, ICH_FLASH_HSFSTS);
 			if (hsfsts.hsf_status.flcinprog == 0) {
@@ -971,8 +982,10 @@ static s32 e1000_flash_cycle_init_ich8lan(struct e1000_hw *hw)
 			udelay(1);
 		}
 		if (ret_val == 0) {
-			/* Successful in waiting for previous cycle to timeout,
-			 * now set the Flash Cycle Done. */
+			/*
+			 * Successful in waiting for previous cycle to timeout,
+			 * now set the Flash Cycle Done.
+			 */
 			hsfsts.hsf_status.flcdone = 1;
 			ew16flash(ICH_FLASH_HSFSTS, hsfsts.regval);
 		} else {
@@ -1077,10 +1090,12 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 		ret_val = e1000_flash_cycle_ich8lan(hw,
 						ICH_FLASH_READ_COMMAND_TIMEOUT);
 
-		/* Check if FCERR is set to 1, if set to 1, clear it
+		/*
+		 * Check if FCERR is set to 1, if set to 1, clear it
 		 * and try the whole sequence a few more times, else
 		 * read in (shift in) the Flash Data0, the order is
-		 * least significant byte first msb to lsb */
+		 * least significant byte first msb to lsb
+		 */
 		if (ret_val == 0) {
 			flash_data = er32flash(ICH_FLASH_FDATA0);
 			if (size == 1) {
@@ -1090,7 +1105,8 @@ static s32 e1000_read_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 			}
 			break;
 		} else {
-			/* If we've gotten here, then things are probably
+			/*
+			 * If we've gotten here, then things are probably
 			 * completely hosed, but if the error condition is
 			 * detected, it won't hurt to give it another try...
 			 * ICH_FLASH_CYCLE_REPEAT_COUNT times.
@@ -1168,18 +1184,20 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
 
 	ret_val = e1000e_update_nvm_checksum_generic(hw);
 	if (ret_val)
-		return ret_val;;
+		return ret_val;
 
 	if (nvm->type != e1000_nvm_flash_sw)
-		return ret_val;;
+		return ret_val;
 
 	ret_val = e1000_acquire_swflag_ich8lan(hw);
 	if (ret_val)
-		return ret_val;;
+		return ret_val;
 
-	/* We're writing to the opposite bank so if we're on bank 1,
+	/*
+	 * We're writing to the opposite bank so if we're on bank 1,
 	 * write to bank 0 etc.  We also need to erase the segment that
-	 * is going to be written */
+	 * is going to be written
+	 */
 	if (!(er32(EECD) & E1000_EECD_SEC1VAL)) {
 		new_bank_offset = nvm->flash_bank_size;
 		old_bank_offset = 0;
@@ -1191,9 +1209,11 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
 	}
 
 	for (i = 0; i < E1000_ICH8_SHADOW_RAM_WORDS; i++) {
-		/* Determine whether to write the value stored
+		/*
+		 * Determine whether to write the value stored
 		 * in the other NVM bank or a modified value stored
-		 * in the shadow RAM */
+		 * in the shadow RAM
+		 */
 		if (dev_spec->shadow_ram[i].modified) {
 			data = dev_spec->shadow_ram[i].value;
 		} else {
@@ -1202,12 +1222,14 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
 						      &data);
 		}
 
-		/* If the word is 0x13, then make sure the signature bits
+		/*
+		 * If the word is 0x13, then make sure the signature bits
 		 * (15:14) are 11b until the commit has completed.
 		 * This will allow us to write 10b which indicates the
 		 * signature is valid.  We want to do this after the write
 		 * has completed so that we don't mark the segment valid
-		 * while the write is still in progress */
+		 * while the write is still in progress
+		 */
 		if (i == E1000_ICH_NVM_SIG_WORD)
 			data |= E1000_ICH_NVM_SIG_MASK;
 
@@ -1230,18 +1252,22 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
 			break;
 	}
 
-	/* Don't bother writing the segment valid bits if sector
-	 * programming failed. */
+	/*
+	 * Don't bother writing the segment valid bits if sector
+	 * programming failed.
+	 */
 	if (ret_val) {
 		hw_dbg(hw, "Flash commit failed.\n");
 		e1000_release_swflag_ich8lan(hw);
 		return ret_val;
 	}
 
-	/* Finally validate the new segment by setting bit 15:14
+	/*
+	 * Finally validate the new segment by setting bit 15:14
 	 * to 10b in word 0x13 , this can be done without an
 	 * erase as well since these bits are 11 to start with
-	 * and we need to change bit 14 to 0b */
+	 * and we need to change bit 14 to 0b
+	 */
 	act_offset = new_bank_offset + E1000_ICH_NVM_SIG_WORD;
 	e1000_read_flash_word_ich8lan(hw, act_offset, &data);
 	data &= 0xBFFF;
@@ -1253,10 +1279,12 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
 		return ret_val;
 	}
 
-	/* And invalidate the previously valid segment by setting
+	/*
+	 * And invalidate the previously valid segment by setting
 	 * its signature word (0x13) high_byte to 0b. This can be
 	 * done without an erase because flash erase sets all bits
-	 * to 1's. We can write 1's to 0's without an erase */
+	 * to 1's. We can write 1's to 0's without an erase
+	 */
 	act_offset = (old_bank_offset + E1000_ICH_NVM_SIG_WORD) * 2 + 1;
 	ret_val = e1000_retry_write_flash_byte_ich8lan(hw, act_offset, 0);
 	if (ret_val) {
@@ -1272,7 +1300,8 @@ static s32 e1000_update_nvm_checksum_ich8lan(struct e1000_hw *hw)
 
 	e1000_release_swflag_ich8lan(hw);
 
-	/* Reload the EEPROM, or else modifications will not appear
+	/*
+	 * Reload the EEPROM, or else modifications will not appear
 	 * until after the next adapter reset.
 	 */
 	e1000e_reload_nvm(hw);
@@ -1294,7 +1323,8 @@ static s32 e1000_validate_nvm_checksum_ich8lan(struct e1000_hw *hw)
 	s32 ret_val;
 	u16 data;
 
-	/* Read 0x19 and check bit 6.  If this bit is 0, the checksum
+	/*
+	 * Read 0x19 and check bit 6.  If this bit is 0, the checksum
 	 * needs to be fixed.  This bit is an indication that the NVM
 	 * was prepared by OEM software and did not calculate the
 	 * checksum...a likely scenario.
@@ -1364,14 +1394,17 @@ static s32 e1000_write_flash_data_ich8lan(struct e1000_hw *hw, u32 offset,
 
 		ew32flash(ICH_FLASH_FDATA0, flash_data);
 
-		/* check if FCERR is set to 1 , if set to 1, clear it
-		 * and try the whole sequence a few more times else done */
+		/*
+		 * check if FCERR is set to 1 , if set to 1, clear it
+		 * and try the whole sequence a few more times else done
+		 */
 		ret_val = e1000_flash_cycle_ich8lan(hw,
 					       ICH_FLASH_WRITE_COMMAND_TIMEOUT);
 		if (!ret_val)
 			break;
 
-		/* If we're here, then things are most likely
+		/*
+		 * If we're here, then things are most likely
 		 * completely hosed, but if the error condition
 		 * is detected, it won't hurt to give it another
 		 * try...ICH_FLASH_CYCLE_REPEAT_COUNT times.
@@ -1462,9 +1495,10 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
 
 	hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
 
-	/* Determine HW Sector size: Read BERASE bits of hw flash status
-	 * register */
-	/* 00: The Hw sector is 256 bytes, hence we need to erase 16
+	/*
+	 * Determine HW Sector size: Read BERASE bits of hw flash status
+	 * register
+	 * 00: The Hw sector is 256 bytes, hence we need to erase 16
 	 *     consecutive sectors.  The start index for the nth Hw sector
 	 *     can be calculated as = bank * 4096 + n * 256
 	 * 01: The Hw sector is 4K bytes, hence we need to erase 1 sector.
@@ -1511,13 +1545,16 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
 			if (ret_val)
 				return ret_val;
 
-			/* Write a value 11 (block Erase) in Flash
-			 * Cycle field in hw flash control */
+			/*
+			 * Write a value 11 (block Erase) in Flash
+			 * Cycle field in hw flash control
+			 */
 			hsflctl.regval = er16flash(ICH_FLASH_HSFCTL);
 			hsflctl.hsf_ctrl.flcycle = ICH_CYCLE_ERASE;
 			ew16flash(ICH_FLASH_HSFCTL, hsflctl.regval);
 
-			/* Write the last 24 bits of an index within the
+			/*
+			 * Write the last 24 bits of an index within the
 			 * block into Flash Linear address field in Flash
 			 * Address.
 			 */
@@ -1529,13 +1566,14 @@ static s32 e1000_erase_flash_bank_ich8lan(struct e1000_hw *hw, u32 bank)
 			if (ret_val == 0)
 				break;
 
-			/* Check if FCERR is set to 1.  If 1,
+			/*
+			 * Check if FCERR is set to 1.  If 1,
 			 * clear it and try the whole sequence
-			 * a few more times else Done */
+			 * a few more times else Done
+			 */
 			hsfsts.regval = er16flash(ICH_FLASH_HSFSTS);
 			if (hsfsts.hsf_status.flcerr == 1)
-				/* repeat for some time before
-				 * giving up */
+				/* repeat for some time before giving up */
 				continue;
 			else if (hsfsts.hsf_status.flcdone == 0)
 				return ret_val;
@@ -1585,7 +1623,8 @@ static s32 e1000_get_bus_info_ich8lan(struct e1000_hw *hw)
 
 	ret_val = e1000e_get_bus_info_pcie(hw);
 
-	/* ICH devices are "PCI Express"-ish.  They have
+	/*
+	 * ICH devices are "PCI Express"-ish.  They have
 	 * a configuration space, but do not contain
 	 * PCI Express Capability registers, so bus width
 	 * must be hardcoded.
@@ -1608,7 +1647,8 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
 	u32 ctrl, icr, kab;
 	s32 ret_val;
 
-	/* Prevent the PCI-E bus from sticking if there is no TLP connection
+	/*
+	 * Prevent the PCI-E bus from sticking if there is no TLP connection
 	 * on the last TLP read/write transaction when MAC is reset.
 	 */
 	ret_val = e1000e_disable_pcie_master(hw);
@@ -1619,7 +1659,8 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
 	hw_dbg(hw, "Masking off all interrupts\n");
 	ew32(IMC, 0xffffffff);
 
-	/* Disable the Transmit and Receive units.  Then delay to allow
+	/*
+	 * Disable the Transmit and Receive units.  Then delay to allow
 	 * any pending transactions to complete before we hit the MAC
 	 * with the global reset.
 	 */
@@ -1640,7 +1681,8 @@ static s32 e1000_reset_hw_ich8lan(struct e1000_hw *hw)
 	ctrl = er32(CTRL);
 
 	if (!e1000_check_reset_block(hw)) {
-		/* PHY HW reset requires MAC CORE reset at the same
+		/*
+		 * PHY HW reset requires MAC CORE reset at the same
 		 * time to make sure the interface between MAC and the
 		 * external PHY is reset.
 		 */
@@ -1724,8 +1766,10 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
 		 E1000_TXDCTL_MAX_TX_DESC_PREFETCH;
 	ew32(TXDCTL1, txdctl);
 
-	/* ICH8 has opposite polarity of no_snoop bits.
-	 * By default, we should use snoop behavior. */
+	/*
+	 * ICH8 has opposite polarity of no_snoop bits.
+	 * By default, we should use snoop behavior.
+	 */
 	if (mac->type == e1000_ich8lan)
 		snoop = PCIE_ICH8_SNOOP_ALL;
 	else
@@ -1736,7 +1780,8 @@ static s32 e1000_init_hw_ich8lan(struct e1000_hw *hw)
 	ctrl_ext |= E1000_CTRL_EXT_RO_DIS;
 	ew32(CTRL_EXT, ctrl_ext);
 
-	/* Clear all of the statistics registers (clear on read).  It is
+	/*
+	 * Clear all of the statistics registers (clear on read).  It is
 	 * important that we do this after we have tried to establish link
 	 * because the symbol error count will increment wildly if there
 	 * is no link.
@@ -1807,29 +1852,29 @@ static void e1000_initialize_hw_bits_ich8lan(struct e1000_hw *hw)
  **/
 static s32 e1000_setup_link_ich8lan(struct e1000_hw *hw)
 {
-	struct e1000_mac_info *mac = &hw->mac;
 	s32 ret_val;
 
 	if (e1000_check_reset_block(hw))
 		return 0;
 
-	/* ICH parts do not have a word in the NVM to determine
+	/*
+	 * ICH parts do not have a word in the NVM to determine
 	 * the default flow control setting, so we explicitly
 	 * set it to full.
 	 */
-	if (mac->fc == e1000_fc_default)
-		mac->fc = e1000_fc_full;
+	if (hw->fc.type == e1000_fc_default)
+		hw->fc.type = e1000_fc_full;
 
-	mac->original_fc = mac->fc;
+	hw->fc.original_type = hw->fc.type;
 
-	hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", mac->fc);
+	hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);
 
 	/* Continue to configure the copper link. */
 	ret_val = e1000_setup_copper_link_ich8lan(hw);
 	if (ret_val)
 		return ret_val;
 
-	ew32(FCTTV, mac->fc_pause_time);
+	ew32(FCTTV, hw->fc.pause_time);
 
 	return e1000e_set_fc_watermarks(hw);
 }
@@ -1853,9 +1898,11 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
 	ctrl &= ~(E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX);
 	ew32(CTRL, ctrl);
 
-	/* Set the mac to wait the maximum time between each iteration
+	/*
+	 * Set the mac to wait the maximum time between each iteration
 	 * and increase the max iterations when polling the phy;
-	 * this fixes erroneous timeouts at 10Mbps. */
+	 * this fixes erroneous timeouts at 10Mbps.
+	 */
 	ret_val = e1000e_write_kmrn_reg(hw, GG82563_REG(0x34, 4), 0xFFFF);
 	if (ret_val)
 		return ret_val;
@@ -1882,7 +1929,7 @@ static s32 e1000_setup_copper_link_ich8lan(struct e1000_hw *hw)
  *  @speed: pointer to store current link speed
  *  @duplex: pointer to store the current link duplex
  *
- *  Calls the generic get_speed_and_duplex to retreive the current link
+ *  Calls the generic get_speed_and_duplex to retrieve the current link
  *  information and then calls the Kumeran lock loss workaround for links at
  *  gigabit speeds.
  **/
@@ -1930,9 +1977,11 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
 	if (!dev_spec->kmrn_lock_loss_workaround_enabled)
 		return 0;
 
-	/* Make sure link is up before proceeding.  If not just return.
+	/*
+	 * Make sure link is up before proceeding.  If not just return.
 	 * Attempting this while link is negotiating fouled up link
-	 * stability */
+	 * stability
+	 */
 	ret_val = e1000e_phy_has_link_generic(hw, 1, 0, &link);
 	if (!link)
 		return 0;
@@ -1961,8 +2010,10 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
 		     E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
 	ew32(PHY_CTRL, phy_ctrl);
 
-	/* Call gig speed drop workaround on Gig disable before accessing
-	 * any PHY registers */
+	/*
+	 * Call gig speed drop workaround on Gig disable before accessing
+	 * any PHY registers
+	 */
 	e1000e_gig_downshift_workaround_ich8lan(hw);
 
 	/* unable to acquire PCS lock */
@@ -1970,7 +2021,7 @@ static s32 e1000_kmrn_lock_loss_workaround_ich8lan(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_set_kmrn_lock_loss_workaound_ich8lan - Set Kumeran workaround state
+ *  e1000_set_kmrn_lock_loss_workaround_ich8lan - Set Kumeran workaround state
  *  @hw: pointer to the HW structure
  *  @state: boolean value used to set the current Kumeran workaround state
  *
@@ -2017,8 +2068,10 @@ void e1000e_igp3_phy_powerdown_workaround_ich8lan(struct e1000_hw *hw)
 			E1000_PHY_CTRL_NOND0A_GBE_DISABLE);
 		ew32(PHY_CTRL, reg);
 
-		/* Call gig speed drop workaround on Gig disable before
-		 * accessing any PHY registers */
+		/*
+		 * Call gig speed drop workaround on Gig disable before
+		 * accessing any PHY registers
+		 */
 		if (hw->mac.type == e1000_ich8lan)
 			e1000e_gig_downshift_workaround_ich8lan(hw);
 
@@ -2158,7 +2211,7 @@ static struct e1000_mac_operations ich8_mac_ops = {
 	.get_link_up_info	= e1000_get_link_up_info_ich8lan,
 	.led_on			= e1000_led_on_ich8lan,
 	.led_off		= e1000_led_off_ich8lan,
-	.mc_addr_list_update	= e1000e_mc_addr_list_update_generic,
+	.update_mc_addr_list	= e1000e_update_mc_addr_list_generic,
 	.reset_hw		= e1000_reset_hw_ich8lan,
 	.init_hw		= e1000_init_hw_ich8lan,
 	.setup_link		= e1000_setup_link_ich8lan,
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 073934c..ea3ff63 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -43,8 +43,8 @@ enum e1000_mng_mode {
 
 #define E1000_FACTPS_MNGCG		0x20000000
 
-#define E1000_IAMT_SIGNATURE		0x544D4149 /* Intel(R) Active Management
-						    * Technology signature */
+/* Intel(R) Active Management Technology signature */
+#define E1000_IAMT_SIGNATURE		0x544D4149
 
 /**
  *  e1000e_get_bus_info_pcie - Get PCIe bus information
@@ -142,7 +142,8 @@ void e1000e_rar_set(struct e1000_hw *hw, u8 *addr, u32 index)
 {
 	u32 rar_low, rar_high;
 
-	/* HW expects these in little endian so we reverse the byte order
+	/*
+	 * HW expects these in little endian so we reverse the byte order
 	 * from network order (big endian) to little endian
 	 */
 	rar_low = ((u32) addr[0] |
@@ -171,7 +172,8 @@ static void e1000_mta_set(struct e1000_hw *hw, u32 hash_value)
 {
 	u32 hash_bit, hash_reg, mta;
 
-	/* The MTA is a register array of 32-bit registers. It is
+	/*
+	 * The MTA is a register array of 32-bit registers. It is
 	 * treated like an array of (32*mta_reg_count) bits.  We want to
 	 * set bit BitArray[hash_value]. So we figure out what register
 	 * the bit is in, read it, OR in the new bit, then write
@@ -208,12 +210,15 @@ static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
 	/* Register count multiplied by bits per register */
 	hash_mask = (hw->mac.mta_reg_count * 32) - 1;
 
-	/* For a mc_filter_type of 0, bit_shift is the number of left-shifts
-	 * where 0xFF would still fall within the hash mask. */
+	/*
+	 * For a mc_filter_type of 0, bit_shift is the number of left-shifts
+	 * where 0xFF would still fall within the hash mask.
+	 */
 	while (hash_mask >> bit_shift != 0xFF)
 		bit_shift++;
 
-	/* The portion of the address that is used for the hash table
+	/*
+	 * The portion of the address that is used for the hash table
 	 * is determined by the mc_filter_type setting.
 	 * The algorithm is such that there is a total of 8 bits of shifting.
 	 * The bit_shift for a mc_filter_type of 0 represents the number of
@@ -224,8 +229,8 @@ static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
 	 * cases are a variation of this algorithm...essentially raising the
 	 * number of bits to shift mc_addr[5] left, while still keeping the
 	 * 8-bit shifting total.
-	 */
-	/* For example, given the following Destination MAC Address and an
+	 *
+	 * For example, given the following Destination MAC Address and an
 	 * mta register count of 128 (thus a 4096-bit vector and 0xFFF mask),
 	 * we can see that the bit_shift for case 0 is 4.  These are the hash
 	 * values resulting from each mc_filter_type...
@@ -260,7 +265,7 @@ static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
 }
 
 /**
- *  e1000e_mc_addr_list_update_generic - Update Multicast addresses
+ *  e1000e_update_mc_addr_list_generic - Update Multicast addresses
  *  @hw: pointer to the HW structure
  *  @mc_addr_list: array of multicast addresses to program
  *  @mc_addr_count: number of multicast addresses to program
@@ -272,14 +277,15 @@ static u32 e1000_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
  *  The parameter rar_count will usually be hw->mac.rar_entry_count
  *  unless there are workarounds that change this.
  **/
-void e1000e_mc_addr_list_update_generic(struct e1000_hw *hw,
-				       u8 *mc_addr_list, u32 mc_addr_count,
-				       u32 rar_used_count, u32 rar_count)
+void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
+					u8 *mc_addr_list, u32 mc_addr_count,
+					u32 rar_used_count, u32 rar_count)
 {
 	u32 hash_value;
 	u32 i;
 
-	/* Load the first set of multicast addresses into the exact
+	/*
+	 * Load the first set of multicast addresses into the exact
 	 * filters (RAR).  If there are not enough to fill the RAR
 	 * array, clear the filters.
 	 */
@@ -375,7 +381,8 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
 	s32 ret_val;
 	bool link;
 
-	/* We only want to go out to the PHY registers to see if Auto-Neg
+	/*
+	 * We only want to go out to the PHY registers to see if Auto-Neg
 	 * has completed and/or if our link status has changed.  The
 	 * get_link_status flag is set upon receiving a Link Status
 	 * Change or Rx Sequence Error interrupt.
@@ -383,7 +390,8 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
 	if (!mac->get_link_status)
 		return 0;
 
-	/* First we want to see if the MII Status Register reports
+	/*
+	 * First we want to see if the MII Status Register reports
 	 * link.  If so, then we want to get the current speed/duplex
 	 * of the PHY.
 	 */
@@ -396,11 +404,14 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
 
 	mac->get_link_status = 0;
 
-	/* Check if there was DownShift, must be checked
-	 * immediately after link-up */
+	/*
+	 * Check if there was DownShift, must be checked
+	 * immediately after link-up
+	 */
 	e1000e_check_downshift(hw);
 
-	/* If we are forcing speed/duplex, then we simply return since
+	/*
+	 * If we are forcing speed/duplex, then we simply return since
 	 * we have already determined whether we have link or not.
 	 */
 	if (!mac->autoneg) {
@@ -408,13 +419,15 @@ s32 e1000e_check_for_copper_link(struct e1000_hw *hw)
 		return ret_val;
 	}
 
-	/* Auto-Neg is enabled.  Auto Speed Detection takes care
+	/*
+	 * Auto-Neg is enabled.  Auto Speed Detection takes care
 	 * of MAC speed/duplex configuration.  So we only need to
 	 * configure Collision Distance in the MAC.
 	 */
 	e1000e_config_collision_dist(hw);
 
-	/* Configure Flow Control now that Auto-Neg has completed.
+	/*
+	 * Configure Flow Control now that Auto-Neg has completed.
 	 * First, we need to restore the desired flow control
 	 * settings because we may have had to re-autoneg with a
 	 * different link partner.
@@ -446,7 +459,8 @@ s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
 	status = er32(STATUS);
 	rxcw = er32(RXCW);
 
-	/* If we don't have link (auto-negotiation failed or link partner
+	/*
+	 * If we don't have link (auto-negotiation failed or link partner
 	 * cannot auto-negotiate), the cable is plugged in (we have signal),
 	 * and our link partner is not trying to auto-negotiate with us (we
 	 * are receiving idles or data), we need to force link up. We also
@@ -477,7 +491,8 @@ s32 e1000e_check_for_fiber_link(struct e1000_hw *hw)
 			return ret_val;
 		}
 	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
-		/* If we are forcing link and we are receiving /C/ ordered
+		/*
+		 * If we are forcing link and we are receiving /C/ ordered
 		 * sets, re-enable auto-negotiation in the TXCW register
 		 * and disable forced link in the Device Control register
 		 * in an attempt to auto-negotiate with our link partner.
@@ -511,7 +526,8 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
 	status = er32(STATUS);
 	rxcw = er32(RXCW);
 
-	/* If we don't have link (auto-negotiation failed or link partner
+	/*
+	 * If we don't have link (auto-negotiation failed or link partner
 	 * cannot auto-negotiate), and our link partner is not trying to
 	 * auto-negotiate with us (we are receiving idles or data),
 	 * we need to force link up. We also need to give auto-negotiation
@@ -540,7 +556,8 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
 			return ret_val;
 		}
 	} else if ((ctrl & E1000_CTRL_SLU) && (rxcw & E1000_RXCW_C)) {
-		/* If we are forcing link and we are receiving /C/ ordered
+		/*
+		 * If we are forcing link and we are receiving /C/ ordered
 		 * sets, re-enable auto-negotiation in the TXCW register
 		 * and disable forced link in the Device Control register
 		 * in an attempt to auto-negotiate with our link partner.
@@ -551,7 +568,8 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
 
 		mac->serdes_has_link = 1;
 	} else if (!(E1000_TXCW_ANE & er32(TXCW))) {
-		/* If we force link for non-auto-negotiation switch, check
+		/*
+		 * If we force link for non-auto-negotiation switch, check
 		 * link status based on MAC synchronization for internal
 		 * serdes media type.
 		 */
@@ -585,11 +603,11 @@ s32 e1000e_check_for_serdes_link(struct e1000_hw *hw)
  **/
 static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
 {
-	struct e1000_mac_info *mac = &hw->mac;
 	s32 ret_val;
 	u16 nvm_data;
 
-	/* Read and store word 0x0F of the EEPROM. This word contains bits
+	/*
+	 * Read and store word 0x0F of the EEPROM. This word contains bits
 	 * that determine the hardware's default PAUSE (flow control) mode,
 	 * a bit that determines whether the HW defaults to enabling or
 	 * disabling auto-negotiation, and the direction of the
@@ -605,12 +623,12 @@ static s32 e1000_set_default_fc_generic(struct e1000_hw *hw)
 	}
 
 	if ((nvm_data & NVM_WORD0F_PAUSE_MASK) == 0)
-		mac->fc = e1000_fc_none;
+		hw->fc.type = e1000_fc_none;
 	else if ((nvm_data & NVM_WORD0F_PAUSE_MASK) ==
 		 NVM_WORD0F_ASM_DIR)
-		mac->fc = e1000_fc_tx_pause;
+		hw->fc.type = e1000_fc_tx_pause;
 	else
-		mac->fc = e1000_fc_full;
+		hw->fc.type = e1000_fc_full;
 
 	return 0;
 }
@@ -630,7 +648,8 @@ s32 e1000e_setup_link(struct e1000_hw *hw)
 	struct e1000_mac_info *mac = &hw->mac;
 	s32 ret_val;
 
-	/* In the case of the phy reset being blocked, we already have a link.
+	/*
+	 * In the case of the phy reset being blocked, we already have a link.
 	 * We do not need to set it up again.
 	 */
 	if (e1000_check_reset_block(hw))
@@ -640,26 +659,28 @@ s32 e1000e_setup_link(struct e1000_hw *hw)
 	 * If flow control is set to default, set flow control based on
 	 * the EEPROM flow control settings.
 	 */
-	if (mac->fc == e1000_fc_default) {
+	if (hw->fc.type == e1000_fc_default) {
 		ret_val = e1000_set_default_fc_generic(hw);
 		if (ret_val)
 			return ret_val;
 	}
 
-	/* We want to save off the original Flow Control configuration just
+	/*
+	 * We want to save off the original Flow Control configuration just
 	 * in case we get disconnected and then reconnected into a different
 	 * hub or switch with different Flow Control capabilities.
 	 */
-	mac->original_fc = mac->fc;
+	hw->fc.original_type = hw->fc.type;
 
-	hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", mac->fc);
+	hw_dbg(hw, "After fix-ups FlowControl is now = %x\n", hw->fc.type);
 
 	/* Call the necessary media_type subroutine to configure the link. */
 	ret_val = mac->ops.setup_physical_interface(hw);
 	if (ret_val)
 		return ret_val;
 
-	/* Initialize the flow control address, type, and PAUSE timer
+	/*
+	 * Initialize the flow control address, type, and PAUSE timer
 	 * registers to their default values.  This is done even if flow
 	 * control is disabled, because it does not hurt anything to
 	 * initialize these registers.
@@ -669,7 +690,7 @@ s32 e1000e_setup_link(struct e1000_hw *hw)
 	ew32(FCAH, FLOW_CONTROL_ADDRESS_HIGH);
 	ew32(FCAL, FLOW_CONTROL_ADDRESS_LOW);
 
-	ew32(FCTTV, mac->fc_pause_time);
+	ew32(FCTTV, hw->fc.pause_time);
 
 	return e1000e_set_fc_watermarks(hw);
 }
@@ -686,7 +707,8 @@ static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
 	struct e1000_mac_info *mac = &hw->mac;
 	u32 txcw;
 
-	/* Check for a software override of the flow control settings, and
+	/*
+	 * Check for a software override of the flow control settings, and
 	 * setup the device accordingly.  If auto-negotiation is enabled, then
 	 * software will have to set the "PAUSE" bits to the correct value in
 	 * the Transmit Config Word Register (TXCW) and re-start auto-
@@ -700,31 +722,34 @@ static s32 e1000_commit_fc_settings_generic(struct e1000_hw *hw)
 	 *	  but not send pause frames).
 	 *      2:  Tx flow control is enabled (we can send pause frames but we
 	 *	  do not support receiving pause frames).
-	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
+	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
 	 */
-	switch (mac->fc) {
+	switch (hw->fc.type) {
 	case e1000_fc_none:
 		/* Flow control completely disabled by a software over-ride. */
 		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD);
 		break;
 	case e1000_fc_rx_pause:
-		/* RX Flow control is enabled and TX Flow control is disabled
+		/*
+		 * Rx Flow control is enabled and Tx Flow control is disabled
 		 * by a software over-ride. Since there really isn't a way to
-		 * advertise that we are capable of RX Pause ONLY, we will
-		 * advertise that we support both symmetric and asymmetric RX
+		 * advertise that we are capable of Rx Pause ONLY, we will
+		 * advertise that we support both symmetric and asymmetric Rx
 		 * PAUSE.  Later, we will disable the adapter's ability to send
 		 * PAUSE frames.
 		 */
 		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
 		break;
 	case e1000_fc_tx_pause:
-		/* TX Flow control is enabled, and RX Flow control is disabled,
+		/*
+		 * Tx Flow control is enabled, and Rx Flow control is disabled,
 		 * by a software over-ride.
 		 */
 		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_ASM_DIR);
 		break;
 	case e1000_fc_full:
-		/* Flow control (both RX and TX) is enabled by a software
+		/*
+		 * Flow control (both Rx and Tx) is enabled by a software
 		 * over-ride.
 		 */
 		txcw = (E1000_TXCW_ANE | E1000_TXCW_FD | E1000_TXCW_PAUSE_MASK);
@@ -754,7 +779,8 @@ static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
 	u32 i, status;
 	s32 ret_val;
 
-	/* If we have a signal (the cable is plugged in, or assumed true for
+	/*
+	 * If we have a signal (the cable is plugged in, or assumed true for
 	 * serdes media) then poll for a "Link-Up" indication in the Device
 	 * Status Register.  Time-out if a link isn't seen in 500 milliseconds
 	 * seconds (Auto-negotiation should complete in less than 500
@@ -769,7 +795,8 @@ static s32 e1000_poll_fiber_serdes_link_generic(struct e1000_hw *hw)
 	if (i == FIBER_LINK_UP_LIMIT) {
 		hw_dbg(hw, "Never got a valid link from auto-neg!!!\n");
 		mac->autoneg_failed = 1;
-		/* AutoNeg failed to achieve a link, so we'll call
+		/*
+		 * AutoNeg failed to achieve a link, so we'll call
 		 * mac->check_for_link. This routine will force the
 		 * link up if we detect a signal. This will allow us to
 		 * communicate with non-autonegotiating link partners.
@@ -811,7 +838,8 @@ s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	/* Since auto-negotiation is enabled, take the link out of reset (the
+	/*
+	 * Since auto-negotiation is enabled, take the link out of reset (the
 	 * link will be in reset, because we previously reset the chip). This
 	 * will restart auto-negotiation.  If auto-negotiation is successful
 	 * then the link-up status bit will be set and the flow control enable
@@ -823,11 +851,12 @@ s32 e1000e_setup_fiber_serdes_link(struct e1000_hw *hw)
 	e1e_flush();
 	msleep(1);
 
-	/* For these adapters, the SW defineable pin 1 is set when the optics
+	/*
+	 * For these adapters, the SW definable pin 1 is set when the optics
 	 * detect a signal.  If we have a signal, then poll for a "Link-Up"
 	 * indication.
 	 */
-	if (hw->media_type == e1000_media_type_internal_serdes ||
+	if (hw->phy.media_type == e1000_media_type_internal_serdes ||
 	    (er32(CTRL) & E1000_CTRL_SWDPIN1)) {
 		ret_val = e1000_poll_fiber_serdes_link_generic(hw);
 	} else {
@@ -864,27 +893,28 @@ void e1000e_config_collision_dist(struct e1000_hw *hw)
  *
  *  Sets the flow control high/low threshold (watermark) registers.  If
  *  flow control XON frame transmission is enabled, then set XON frame
- *  tansmission as well.
+ *  transmission as well.
  **/
 s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
 {
-	struct e1000_mac_info *mac = &hw->mac;
 	u32 fcrtl = 0, fcrth = 0;
 
-	/* Set the flow control receive threshold registers.  Normally,
+	/*
+	 * Set the flow control receive threshold registers.  Normally,
 	 * these registers will be set to a default threshold that may be
 	 * adjusted later by the driver's runtime code.  However, if the
 	 * ability to transmit pause frames is not enabled, then these
 	 * registers will be set to 0.
 	 */
-	if (mac->fc & e1000_fc_tx_pause) {
-		/* We need to set up the Receive Threshold high and low water
+	if (hw->fc.type & e1000_fc_tx_pause) {
+		/*
+		 * We need to set up the Receive Threshold high and low water
 		 * marks as well as (optionally) enabling the transmission of
 		 * XON frames.
 		 */
-		fcrtl = mac->fc_low_water;
+		fcrtl = hw->fc.low_water;
 		fcrtl |= E1000_FCRTL_XONE;
-		fcrth = mac->fc_high_water;
+		fcrth = hw->fc.high_water;
 	}
 	ew32(FCRTL, fcrtl);
 	ew32(FCRTH, fcrth);
@@ -904,18 +934,18 @@ s32 e1000e_set_fc_watermarks(struct e1000_hw *hw)
  **/
 s32 e1000e_force_mac_fc(struct e1000_hw *hw)
 {
-	struct e1000_mac_info *mac = &hw->mac;
 	u32 ctrl;
 
 	ctrl = er32(CTRL);
 
-	/* Because we didn't get link via the internal auto-negotiation
+	/*
+	 * Because we didn't get link via the internal auto-negotiation
 	 * mechanism (we either forced link or we got link via PHY
 	 * auto-neg), we have to manually enable/disable transmit an
 	 * receive flow control.
 	 *
 	 * The "Case" statement below enables/disable flow control
-	 * according to the "mac->fc" parameter.
+	 * according to the "hw->fc.type" parameter.
 	 *
 	 * The possible values of the "fc" parameter are:
 	 *      0:  Flow control is completely disabled
@@ -923,12 +953,12 @@ s32 e1000e_force_mac_fc(struct e1000_hw *hw)
 	 *	  frames but not send pause frames).
 	 *      2:  Tx flow control is enabled (we can send pause frames
 	 *	  frames but we do not receive pause frames).
-	 *      3:  Both Rx and TX flow control (symmetric) is enabled.
+	 *      3:  Both Rx and Tx flow control (symmetric) is enabled.
 	 *  other:  No other values should be possible at this point.
 	 */
-	hw_dbg(hw, "mac->fc = %u\n", mac->fc);
+	hw_dbg(hw, "hw->fc.type = %u\n", hw->fc.type);
 
-	switch (mac->fc) {
+	switch (hw->fc.type) {
 	case e1000_fc_none:
 		ctrl &= (~(E1000_CTRL_TFCE | E1000_CTRL_RFCE));
 		break;
@@ -970,16 +1000,17 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 	u16 mii_status_reg, mii_nway_adv_reg, mii_nway_lp_ability_reg;
 	u16 speed, duplex;
 
-	/* Check for the case where we have fiber media and auto-neg failed
+	/*
+	 * Check for the case where we have fiber media and auto-neg failed
 	 * so we had to force link.  In this case, we need to force the
 	 * configuration of the MAC to match the "fc" parameter.
 	 */
 	if (mac->autoneg_failed) {
-		if (hw->media_type == e1000_media_type_fiber ||
-		    hw->media_type == e1000_media_type_internal_serdes)
+		if (hw->phy.media_type == e1000_media_type_fiber ||
+		    hw->phy.media_type == e1000_media_type_internal_serdes)
 			ret_val = e1000e_force_mac_fc(hw);
 	} else {
-		if (hw->media_type == e1000_media_type_copper)
+		if (hw->phy.media_type == e1000_media_type_copper)
 			ret_val = e1000e_force_mac_fc(hw);
 	}
 
@@ -988,13 +1019,15 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 		return ret_val;
 	}
 
-	/* Check for the case where we have copper media and auto-neg is
+	/*
+	 * Check for the case where we have copper media and auto-neg is
 	 * enabled.  In this case, we need to check and see if Auto-Neg
 	 * has completed, and if so, how the PHY and link partner has
 	 * flow control configured.
 	 */
-	if ((hw->media_type == e1000_media_type_copper) && mac->autoneg) {
-		/* Read the MII Status Register and check to see if AutoNeg
+	if ((hw->phy.media_type == e1000_media_type_copper) && mac->autoneg) {
+		/*
+		 * Read the MII Status Register and check to see if AutoNeg
 		 * has completed.  We read this twice because this reg has
 		 * some "sticky" (latched) bits.
 		 */
@@ -1011,7 +1044,8 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 			return ret_val;
 		}
 
-		/* The AutoNeg process has completed, so we now need to
+		/*
+		 * The AutoNeg process has completed, so we now need to
 		 * read both the Auto Negotiation Advertisement
 		 * Register (Address 4) and the Auto_Negotiation Base
 		 * Page Ability Register (Address 5) to determine how
@@ -1024,7 +1058,8 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 		if (ret_val)
 			return ret_val;
 
-		/* Two bits in the Auto Negotiation Advertisement Register
+		/*
+		 * Two bits in the Auto Negotiation Advertisement Register
 		 * (Address 4) and two bits in the Auto Negotiation Base
 		 * Page Ability Register (Address 5) determine flow control
 		 * for both the PHY and the link partner.  The following
@@ -1045,8 +1080,8 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 		 *   1   |    1    |   0   |    0    | e1000_fc_none
 		 *   1   |    1    |   0   |    1    | e1000_fc_rx_pause
 		 *
-		 */
-		/* Are both PAUSE bits set to 1?  If so, this implies
+		 *
+		 * Are both PAUSE bits set to 1?  If so, this implies
 		 * Symmetric Flow Control is enabled at both ends.  The
 		 * ASM_DIR bits are irrelevant per the spec.
 		 *
@@ -1060,22 +1095,24 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 		 */
 		if ((mii_nway_adv_reg & NWAY_AR_PAUSE) &&
 		    (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE)) {
-			/* Now we need to check if the user selected RX ONLY
+			/*
+			 * Now we need to check if the user selected Rx ONLY
 			 * of pause frames.  In this case, we had to advertise
-			 * FULL flow control because we could not advertise RX
+			 * FULL flow control because we could not advertise Rx
 			 * ONLY. Hence, we must now check to see if we need to
 			 * turn OFF  the TRANSMISSION of PAUSE frames.
 			 */
-			if (mac->original_fc == e1000_fc_full) {
-				mac->fc = e1000_fc_full;
+			if (hw->fc.original_type == e1000_fc_full) {
+				hw->fc.type = e1000_fc_full;
 				hw_dbg(hw, "Flow Control = FULL.\r\n");
 			} else {
-				mac->fc = e1000_fc_rx_pause;
+				hw->fc.type = e1000_fc_rx_pause;
 				hw_dbg(hw, "Flow Control = "
 					 "RX PAUSE frames only.\r\n");
 			}
 		}
-		/* For receiving PAUSE frames ONLY.
+		/*
+		 * For receiving PAUSE frames ONLY.
 		 *
 		 *   LOCAL DEVICE  |   LINK PARTNER
 		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
@@ -1087,10 +1124,11 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 			  (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
 			  (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
 			  (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-			mac->fc = e1000_fc_tx_pause;
-			hw_dbg(hw, "Flow Control = TX PAUSE frames only.\r\n");
+			hw->fc.type = e1000_fc_tx_pause;
+			hw_dbg(hw, "Flow Control = Tx PAUSE frames only.\r\n");
 		}
-		/* For transmitting PAUSE frames ONLY.
+		/*
+		 * For transmitting PAUSE frames ONLY.
 		 *
 		 *   LOCAL DEVICE  |   LINK PARTNER
 		 * PAUSE | ASM_DIR | PAUSE | ASM_DIR | Result
@@ -1102,18 +1140,19 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 			 (mii_nway_adv_reg & NWAY_AR_ASM_DIR) &&
 			 !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
 			 (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
-			mac->fc = e1000_fc_rx_pause;
-			hw_dbg(hw, "Flow Control = RX PAUSE frames only.\r\n");
+			hw->fc.type = e1000_fc_rx_pause;
+			hw_dbg(hw, "Flow Control = Rx PAUSE frames only.\r\n");
 		} else {
 			/*
 			 * Per the IEEE spec, at this point flow control
 			 * should be disabled.
 			 */
-			mac->fc = e1000_fc_none;
+			hw->fc.type = e1000_fc_none;
 			hw_dbg(hw, "Flow Control = NONE.\r\n");
 		}
 
-		/* Now we need to do one last check...  If we auto-
+		/*
+		 * Now we need to do one last check...  If we auto-
 		 * negotiated to HALF DUPLEX, flow control should not be
 		 * enabled per IEEE 802.3 spec.
 		 */
@@ -1124,9 +1163,10 @@ s32 e1000e_config_fc_after_link_up(struct e1000_hw *hw)
 		}
 
 		if (duplex == HALF_DUPLEX)
-			mac->fc = e1000_fc_none;
+			hw->fc.type = e1000_fc_none;
 
-		/* Now we call a subroutine to actually force the MAC
+		/*
+		 * Now we call a subroutine to actually force the MAC
 		 * controller to use the correct flow control settings.
 		 */
 		ret_val = e1000e_force_mac_fc(hw);
@@ -1393,13 +1433,15 @@ s32 e1000e_blink_led(struct e1000_hw *hw)
 	u32 ledctl_blink = 0;
 	u32 i;
 
-	if (hw->media_type == e1000_media_type_fiber) {
+	if (hw->phy.media_type == e1000_media_type_fiber) {
 		/* always blink LED0 for PCI-E fiber */
 		ledctl_blink = E1000_LEDCTL_LED0_BLINK |
 		     (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED0_MODE_SHIFT);
 	} else {
-		/* set the blink bit for each LED that's "on" (0x0E)
-		 * in ledctl_mode2 */
+		/*
+		 * set the blink bit for each LED that's "on" (0x0E)
+		 * in ledctl_mode2
+		 */
 		ledctl_blink = hw->mac.ledctl_mode2;
 		for (i = 0; i < 4; i++)
 			if (((hw->mac.ledctl_mode2 >> (i * 8)) & 0xFF) ==
@@ -1423,7 +1465,7 @@ s32 e1000e_led_on_generic(struct e1000_hw *hw)
 {
 	u32 ctrl;
 
-	switch (hw->media_type) {
+	switch (hw->phy.media_type) {
 	case e1000_media_type_fiber:
 		ctrl = er32(CTRL);
 		ctrl &= ~E1000_CTRL_SWDPIN0;
@@ -1450,7 +1492,7 @@ s32 e1000e_led_off_generic(struct e1000_hw *hw)
 {
 	u32 ctrl;
 
-	switch (hw->media_type) {
+	switch (hw->phy.media_type) {
 	case e1000_media_type_fiber:
 		ctrl = er32(CTRL);
 		ctrl |= E1000_CTRL_SWDPIN0;
@@ -1562,8 +1604,7 @@ void e1000e_update_adaptive(struct e1000_hw *hw)
 				else
 					mac->current_ifs_val +=
 						mac->ifs_step_size;
-				ew32(AIT,
-						mac->current_ifs_val);
+				ew32(AIT, mac->current_ifs_val);
 			}
 		}
 	} else {
@@ -1826,10 +1867,12 @@ static s32 e1000_ready_nvm_eeprom(struct e1000_hw *hw)
 		udelay(1);
 		timeout = NVM_MAX_RETRY_SPI;
 
-		/* Read "Status Register" repeatedly until the LSB is cleared.
+		/*
+		 * Read "Status Register" repeatedly until the LSB is cleared.
 		 * The EEPROM will signal that the command has been completed
 		 * by clearing bit 0 of the internal status register.  If it's
-		 * not cleared within 'timeout', then error out. */
+		 * not cleared within 'timeout', then error out.
+		 */
 		while (timeout) {
 			e1000_shift_out_eec_bits(hw, NVM_RDSR_OPCODE_SPI,
 						 hw->nvm.opcode_bits);
@@ -1866,8 +1909,10 @@ s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 	u32 i, eerd = 0;
 	s32 ret_val = 0;
 
-	/* A check for invalid values:  offset too large, too many words,
-	 * and not enough words. */
+	/*
+	 * A check for invalid values:  offset too large, too many words,
+	 * too many words for the offset, and not enough words.
+	 */
 	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
 	    (words == 0)) {
 		hw_dbg(hw, "nvm parameter(s) out of bounds\n");
@@ -1883,8 +1928,7 @@ s32 e1000e_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 		if (ret_val)
 			break;
 
-		data[i] = (er32(EERD) >>
-			   E1000_NVM_RW_REG_DATA);
+		data[i] = (er32(EERD) >> E1000_NVM_RW_REG_DATA);
 	}
 
 	return ret_val;
@@ -1908,8 +1952,10 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 	s32 ret_val;
 	u16 widx = 0;
 
-	/* A check for invalid values:  offset too large, too many words,
-	 * and not enough words. */
+	/*
+	 * A check for invalid values:  offset too large, too many words,
+	 * and not enough words.
+	 */
 	if ((offset >= nvm->word_size) || (words > (nvm->word_size - offset)) ||
 	    (words == 0)) {
 		hw_dbg(hw, "nvm parameter(s) out of bounds\n");
@@ -1939,8 +1985,10 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
 
 		e1000_standby_nvm(hw);
 
-		/* Some SPI eeproms use the 8th address bit embedded in the
-		 * opcode */
+		/*
+		 * Some SPI eeproms use the 8th address bit embedded in the
+		 * opcode
+		 */
 		if ((nvm->address_bits == 8) && (offset >= 128))
 			write_opcode |= NVM_A8_OPCODE_SPI;
 
@@ -1985,9 +2033,9 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
 		/* Check for an alternate MAC address.  An alternate MAC
 		 * address can be setup by pre-boot software and must be
 		 * treated like a permanent address and must override the
-		 * actual permanent MAC address. */
+		 * actual permanent MAC address.*/
 		ret_val = e1000_read_nvm(hw, NVM_ALT_MAC_ADDR_PTR, 1,
-						&mac_addr_offset);
+					 &mac_addr_offset);
 		if (ret_val) {
 			hw_dbg(hw, "NVM Read Error\n");
 			return ret_val;
@@ -2000,7 +2048,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
 				mac_addr_offset += ETH_ALEN/sizeof(u16);
 
 			/* make sure we have a valid mac address here
-			 * before using it */
+			* before using it */
 			ret_val = e1000_read_nvm(hw, mac_addr_offset, 1,
 						 &nvm_data);
 			if (ret_val) {
@@ -2012,7 +2060,7 @@ s32 e1000e_read_mac_addr(struct e1000_hw *hw)
 		}
 
 		if (mac_addr_offset)
-			hw->dev_spec.e82571.alt_mac_addr_is_present = 1;
+		hw->dev_spec.e82571.alt_mac_addr_is_present = 1;
 	}
 
 	for (i = 0; i < ETH_ALEN; i += 2) {
@@ -2188,7 +2236,7 @@ bool e1000e_check_mng_mode(struct e1000_hw *hw)
 }
 
 /**
- *  e1000e_enable_tx_pkt_filtering - Enable packet filtering on TX
+ *  e1000e_enable_tx_pkt_filtering - Enable packet filtering on Tx
  *  @hw: pointer to the HW structure
  *
  *  Enables packet filtering on transmit packets if manageability is enabled
@@ -2208,7 +2256,8 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
 		return 0;
 	}
 
-	/* If we can't read from the host interface for whatever
+	/*
+	 * If we can't read from the host interface for whatever
 	 * reason, disable filtering.
 	 */
 	ret_val = e1000_mng_enable_host_if(hw);
@@ -2226,7 +2275,8 @@ bool e1000e_enable_tx_pkt_filtering(struct e1000_hw *hw)
 	hdr->checksum = 0;
 	csum = e1000_calculate_checksum((u8 *)hdr,
 					E1000_MNG_DHCP_COOKIE_LENGTH);
-	/* If either the checksums or signature don't match, then
+	/*
+	 * If either the checksums or signature don't match, then
 	 * the cookie area isn't considered valid, in which case we
 	 * take the safe route of assuming Tx filtering is enabled.
 	 */
@@ -2318,8 +2368,10 @@ static s32 e1000_mng_host_if_write(struct e1000_hw *hw, u8 *buffer,
 	/* Calculate length in DWORDs */
 	length >>= 2;
 
-	/* The device driver writes the relevant command block into the
-	 * ram area. */
+	/*
+	 * The device driver writes the relevant command block into the
+	 * ram area.
+	 */
 	for (i = 0; i < length; i++) {
 		for (j = 0; j < sizeof(u32); j++) {
 			*(tmp + j) = *bufptr++;
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index f501dd5..d70bde0 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -82,7 +82,7 @@ static int e1000_desc_unused(struct e1000_ring *ring)
 }
 
 /**
- * e1000_receive_skb - helper function to handle rx indications
+ * e1000_receive_skb - helper function to handle Rx indications
  * @adapter: board private structure
  * @status: descriptor status field as written by hardware
  * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
@@ -138,8 +138,9 @@ static void e1000_rx_checksum(struct e1000_adapter *adapter, u32 status_err,
 		/* TCP checksum is good */
 		skb->ip_summed = CHECKSUM_UNNECESSARY;
 	} else {
-		/* IP fragment with UDP payload */
-		/* Hardware complements the payload checksum, so we undo it
+		/*
+		 * IP fragment with UDP payload
+		 * Hardware complements the payload checksum, so we undo it
 		 * and then put the value in host order for further stack use.
 		 */
 		__sum16 sum = (__force __sum16)htons(csum);
@@ -182,7 +183,8 @@ static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
 			break;
 		}
 
-		/* Make buffer alignment 2 beyond a 16 byte boundary
+		/*
+		 * Make buffer alignment 2 beyond a 16 byte boundary
 		 * this will result in a 16 byte aligned IP header after
 		 * the 14 byte MAC header is removed
 		 */
@@ -213,10 +215,12 @@ map_skb:
 		if (i-- == 0)
 			i = (rx_ring->count - 1);
 
-		/* Force memory writes to complete before letting h/w
+		/*
+		 * Force memory writes to complete before letting h/w
 		 * know there are new descriptors to fetch.  (Only
 		 * applicable for weak-ordered memory model archs,
-		 * such as IA-64). */
+		 * such as IA-64).
+		 */
 		wmb();
 		writel(i, adapter->hw.hw_addr + rx_ring->tail);
 	}
@@ -285,7 +289,8 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
 			break;
 		}
 
-		/* Make buffer alignment 2 beyond a 16 byte boundary
+		/*
+		 * Make buffer alignment 2 beyond a 16 byte boundary
 		 * this will result in a 16 byte aligned IP header after
 		 * the 14 byte MAC header is removed
 		 */
@@ -319,12 +324,15 @@ no_buffers:
 		if (!(i--))
 			i = (rx_ring->count - 1);
 
-		/* Force memory writes to complete before letting h/w
+		/*
+		 * Force memory writes to complete before letting h/w
 		 * know there are new descriptors to fetch.  (Only
 		 * applicable for weak-ordered memory model archs,
-		 * such as IA-64). */
+		 * such as IA-64).
+		 */
 		wmb();
-		/* Hardware increments by 16 bytes, but packet split
+		/*
+		 * Hardware increments by 16 bytes, but packet split
 		 * descriptors are 32 bytes...so we increment tail
 		 * twice as much.
 		 */
@@ -409,9 +417,11 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
 		total_rx_bytes += length;
 		total_rx_packets++;
 
-		/* code added for copybreak, this should improve
+		/*
+		 * code added for copybreak, this should improve
 		 * performance for small packets with large amounts
-		 * of reassembly being done in the stack */
+		 * of reassembly being done in the stack
+		 */
 		if (length < copybreak) {
 			struct sk_buff *new_skb =
 			    netdev_alloc_skb(netdev, length + NET_IP_ALIGN);
@@ -581,14 +591,15 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 	}
 
 	if (adapter->detect_tx_hung) {
-		/* Detect a transmit hang in hardware, this serializes the
-		 * check with the clearing of time_stamp and movement of i */
+		/*
+		 * Detect a transmit hang in hardware, this serializes the
+		 * check with the clearing of time_stamp and movement of i
+		 */
 		adapter->detect_tx_hung = 0;
 		if (tx_ring->buffer_info[eop].dma &&
 		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp
 			       + (adapter->tx_timeout_factor * HZ))
-		    && !(er32(STATUS) &
-			 E1000_STATUS_TXOFF)) {
+		    && !(er32(STATUS) & E1000_STATUS_TXOFF)) {
 			e1000_print_tx_hang(adapter);
 			netif_stop_queue(netdev);
 		}
@@ -677,21 +688,28 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
 		skb_put(skb, length);
 
 		{
-		/* this looks ugly, but it seems compiler issues make it
-		   more efficient than reusing j */
+		/*
+		 * this looks ugly, but it seems compiler issues make it
+		 * more efficient than reusing j
+		 */
 		int l1 = le16_to_cpu(rx_desc->wb.upper.length[0]);
 
-		/* page alloc/put takes too long and effects small packet
-		 * throughput, so unsplit small packets and save the alloc/put*/
+		/*
+		 * page alloc/put takes too long and effects small packet
+		 * throughput, so unsplit small packets and save the alloc/put
+		 * only valid in softirq (napi) context to call kmap_*
+		 */
 		if (l1 && (l1 <= copybreak) &&
 		    ((length + l1) <= adapter->rx_ps_bsize0)) {
 			u8 *vaddr;
 
 			ps_page = &buffer_info->ps_pages[0];
 
-			/* there is no documentation about how to call
+			/*
+			 * there is no documentation about how to call
 			 * kmap_atomic, so we can't hold the mapping
-			 * very long */
+			 * very long
+			 */
 			pci_dma_sync_single_for_cpu(pdev, ps_page->dma,
 				PAGE_SIZE, PCI_DMA_FROMDEVICE);
 			vaddr = kmap_atomic(ps_page->page, KM_SKB_DATA_SOFTIRQ);
@@ -836,24 +854,31 @@ static irqreturn_t e1000_intr_msi(int irq, void *data)
 	struct e1000_hw *hw = &adapter->hw;
 	u32 icr = er32(ICR);
 
-	/* read ICR disables interrupts using IAM */
+	/*
+	 * read ICR disables interrupts using IAM
+	 */
 
 	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
 		hw->mac.get_link_status = 1;
-		/* ICH8 workaround-- Call gig speed drop workaround on cable
-		 * disconnect (LSC) before accessing any PHY registers */
+		/*
+		 * ICH8 workaround-- Call gig speed drop workaround on cable
+		 * disconnect (LSC) before accessing any PHY registers
+		 */
 		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
 		    (!(er32(STATUS) & E1000_STATUS_LU)))
 			e1000e_gig_downshift_workaround_ich8lan(hw);
 
-		/* 80003ES2LAN workaround-- For packet buffer work-around on
+		/*
+		 * 80003ES2LAN workaround-- For packet buffer work-around on
 		 * link down event; disable receives here in the ISR and reset
-		 * adapter in watchdog */
+		 * adapter in watchdog
+		 */
 		if (netif_carrier_ok(netdev) &&
 		    adapter->flags & FLAG_RX_NEEDS_RESTART) {
 			/* disable receives */
 			u32 rctl = er32(RCTL);
 			ew32(RCTL, rctl & ~E1000_RCTL_EN);
+			adapter->flags |= FLAG_RX_RESTART_NOW;
 		}
 		/* guard against interrupt when we're going down */
 		if (!test_bit(__E1000_DOWN, &adapter->state))
@@ -886,23 +911,31 @@ static irqreturn_t e1000_intr(int irq, void *data)
 	if (!icr)
 		return IRQ_NONE;  /* Not our interrupt */
 
-	/* IMS will not auto-mask if INT_ASSERTED is not set, and if it is
-	 * not set, then the adapter didn't send an interrupt */
+	/*
+	 * IMS will not auto-mask if INT_ASSERTED is not set, and if it is
+	 * not set, then the adapter didn't send an interrupt
+	 */
 	if (!(icr & E1000_ICR_INT_ASSERTED))
 		return IRQ_NONE;
 
-	/* Interrupt Auto-Mask...upon reading ICR, interrupts are masked.  No
-	 * need for the IMC write */
+	/*
+	 * Interrupt Auto-Mask...upon reading ICR,
+	 * interrupts are masked.  No need for the
+	 * IMC write
+	 */
 
 	if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
 		hw->mac.get_link_status = 1;
-		/* ICH8 workaround-- Call gig speed drop workaround on cable
-		 * disconnect (LSC) before accessing any PHY registers */
+		/*
+		 * ICH8 workaround-- Call gig speed drop workaround on cable
+		 * disconnect (LSC) before accessing any PHY registers
+		 */
 		if ((adapter->flags & FLAG_LSC_GIG_SPEED_DROP) &&
 		    (!(er32(STATUS) & E1000_STATUS_LU)))
 			e1000e_gig_downshift_workaround_ich8lan(hw);
 
-		/* 80003ES2LAN workaround--
+		/*
+		 * 80003ES2LAN workaround--
 		 * For packet buffer work-around on link down event;
 		 * disable receives here in the ISR and
 		 * reset adapter in watchdog
@@ -912,6 +945,7 @@ static irqreturn_t e1000_intr(int irq, void *data)
 			/* disable receives */
 			rctl = er32(RCTL);
 			ew32(RCTL, rctl & ~E1000_RCTL_EN);
+			adapter->flags |= FLAG_RX_RESTART_NOW;
 		}
 		/* guard against interrupt when we're going down */
 		if (!test_bit(__E1000_DOWN, &adapter->state))
@@ -1011,8 +1045,7 @@ static void e1000_get_hw_control(struct e1000_adapter *adapter)
 		ew32(SWSM, swsm | E1000_SWSM_DRV_LOAD);
 	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
 		ctrl_ext = er32(CTRL_EXT);
-		ew32(CTRL_EXT,
-				ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+		ew32(CTRL_EXT, ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
 	}
 }
 
@@ -1038,8 +1071,7 @@ static void e1000_release_hw_control(struct e1000_adapter *adapter)
 		ew32(SWSM, swsm & ~E1000_SWSM_DRV_LOAD);
 	} else if (adapter->flags & FLAG_HAS_CTRLEXT_ON_LOAD) {
 		ctrl_ext = er32(CTRL_EXT);
-		ew32(CTRL_EXT,
-				ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+		ew32(CTRL_EXT, ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
 	}
 }
 
@@ -1341,9 +1373,11 @@ static void e1000_set_itr(struct e1000_adapter *adapter)
 
 set_itr_now:
 	if (new_itr != adapter->itr) {
-		/* this attempts to bias the interrupt rate towards Bulk
+		/*
+		 * this attempts to bias the interrupt rate towards Bulk
 		 * by adding intermediate steps when interrupt rate is
-		 * increasing */
+		 * increasing
+		 */
 		new_itr = new_itr > adapter->itr ?
 			     min(adapter->itr + (new_itr >> 2), new_itr) :
 			     new_itr;
@@ -1354,7 +1388,7 @@ set_itr_now:
 
 /**
  * e1000_clean - NAPI Rx polling callback
- * @adapter: board private structure
+ * @napi: struct associated with this polling callback
  * @budget: amount of packets driver is allowed to process this poll
  **/
 static int e1000_clean(struct napi_struct *napi, int budget)
@@ -1366,10 +1400,12 @@ static int e1000_clean(struct napi_struct *napi, int budget)
 	/* Must NOT use netdev_priv macro here. */
 	adapter = poll_dev->priv;
 
-	/* e1000_clean is called per-cpu.  This lock protects
+	/*
+	 * e1000_clean is called per-cpu.  This lock protects
 	 * tx_ring from being cleaned by multiple cpus
 	 * simultaneously.  A failure obtaining the lock means
-	 * tx_ring is currently being cleaned anyway. */
+	 * tx_ring is currently being cleaned anyway.
+	 */
 	if (spin_trylock(&adapter->tx_queue_lock)) {
 		tx_cleaned = e1000_clean_tx_irq(adapter);
 		spin_unlock(&adapter->tx_queue_lock);
@@ -1539,9 +1575,11 @@ static void e1000_init_manageability(struct e1000_adapter *adapter)
 
 	manc = er32(MANC);
 
-	/* enable receiving management packets to the host. this will probably
+	/*
+	 * enable receiving management packets to the host. this will probably
 	 * generate destination unreachable messages from the host OS, but
-	 * the packets will be handled on SMBUS */
+	 * the packets will be handled on SMBUS
+	 */
 	manc |= E1000_MANC_EN_MNG2HOST;
 	manc2h = er32(MANC2H);
 #define E1000_MNG2HOST_PORT_623 (1 << 5)
@@ -1591,7 +1629,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
 
 	/* Set the Tx Interrupt Delay register */
 	ew32(TIDV, adapter->tx_int_delay);
-	/* tx irq moderation */
+	/* Tx irq moderation */
 	ew32(TADV, adapter->tx_abs_int_delay);
 
 	/* Program the Transmit Control Register */
@@ -1602,8 +1640,10 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
 
 	if (adapter->flags & FLAG_TARC_SPEED_MODE_BIT) {
 		tarc = er32(TARC0);
-		/* set the speed mode bit, we'll clear it if we're not at
-		 * gigabit link later */
+		/*
+		 * set the speed mode bit, we'll clear it if we're not at
+		 * gigabit link later
+		 */
 #define SPEED_MODE_BIT (1 << 21)
 		tarc |= SPEED_MODE_BIT;
 		ew32(TARC0, tarc);
@@ -1724,8 +1764,10 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 		/* Configure extra packet-split registers */
 		rfctl = er32(RFCTL);
 		rfctl |= E1000_RFCTL_EXTEN;
-		/* disable packet split support for IPv6 extension headers,
-		 * because some malformed IPv6 headers can hang the RX */
+		/*
+		 * disable packet split support for IPv6 extension headers,
+		 * because some malformed IPv6 headers can hang the Rx
+		 */
 		rfctl |= (E1000_RFCTL_IPV6_EX_DIS |
 			  E1000_RFCTL_NEW_IPV6_EXT_DIS);
 
@@ -1754,6 +1796,8 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 	}
 
 	ew32(RCTL, rctl);
+	/* just started the receive unit, no need to restart */
+	adapter->flags &= ~FLAG_RX_RESTART_NOW;
 }
 
 /**
@@ -1794,8 +1838,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 	/* irq moderation */
 	ew32(RADV, adapter->rx_abs_int_delay);
 	if (adapter->itr_setting != 0)
-		ew32(ITR,
-			1000000000 / (adapter->itr * 256));
+		ew32(ITR, 1000000000 / (adapter->itr * 256));
 
 	ctrl_ext = er32(CTRL_EXT);
 	/* Reset delay timers after every interrupt */
@@ -1806,8 +1849,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 	ew32(CTRL_EXT, ctrl_ext);
 	e1e_flush();
 
-	/* Setup the HW Rx Head and Tail Descriptor Pointers and
-	 * the Base and Length of the Rx Descriptor Ring */
+	/*
+	 * Setup the HW Rx Head and Tail Descriptor Pointers and
+	 * the Base and Length of the Rx Descriptor Ring
+	 */
 	rdba = rx_ring->dma;
 	ew32(RDBAL, (rdba & DMA_32BIT_MASK));
 	ew32(RDBAH, (rdba >> 32));
@@ -1822,8 +1867,10 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 	if (adapter->flags & FLAG_RX_CSUM_ENABLED) {
 		rxcsum |= E1000_RXCSUM_TUOFL;
 
-		/* IPv4 payload checksum for UDP fragments must be
-		 * used in conjunction with packet-split. */
+		/*
+		 * IPv4 payload checksum for UDP fragments must be
+		 * used in conjunction with packet-split.
+		 */
 		if (adapter->rx_ps_pages)
 			rxcsum |= E1000_RXCSUM_IPPCSE;
 	} else {
@@ -1832,9 +1879,11 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 	}
 	ew32(RXCSUM, rxcsum);
 
-	/* Enable early receives on supported devices, only takes effect when
+	/*
+	 * Enable early receives on supported devices, only takes effect when
 	 * packet size is equal or larger than the specified value (in 8 byte
-	 * units), e.g. using jumbo frames when setting to E1000_ERT_2048 */
+	 * units), e.g. using jumbo frames when setting to E1000_ERT_2048
+	 */
 	if ((adapter->flags & FLAG_HAS_ERT) &&
 	    (adapter->netdev->mtu > ETH_DATA_LEN))
 		ew32(ERT, E1000_ERT_2048);
@@ -1844,7 +1893,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 }
 
 /**
- *  e1000_mc_addr_list_update - Update Multicast addresses
+ *  e1000_update_mc_addr_list - Update Multicast addresses
  *  @hw: pointer to the HW structure
  *  @mc_addr_list: array of multicast addresses to program
  *  @mc_addr_count: number of multicast addresses to program
@@ -1858,11 +1907,11 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
  *  exists and all implementations are handled in the generic version of this
  *  function.
  **/
-static void e1000_mc_addr_list_update(struct e1000_hw *hw, u8 *mc_addr_list,
-			       u32 mc_addr_count, u32 rar_used_count,
-			       u32 rar_count)
+static void e1000_update_mc_addr_list(struct e1000_hw *hw, u8 *mc_addr_list,
+				      u32 mc_addr_count, u32 rar_used_count,
+				      u32 rar_count)
 {
-	hw->mac.ops.mc_addr_list_update(hw, mc_addr_list, mc_addr_count,
+	hw->mac.ops.update_mc_addr_list(hw, mc_addr_list, mc_addr_count,
 				        rar_used_count, rar_count);
 }
 
@@ -1916,7 +1965,7 @@ static void e1000_set_multi(struct net_device *netdev)
 			mc_ptr = mc_ptr->next;
 		}
 
-		e1000_mc_addr_list_update(hw, mta_list, i, 1,
+		e1000_update_mc_addr_list(hw, mta_list, i, 1,
 					  mac->rar_entry_count);
 		kfree(mta_list);
 	} else {
@@ -1924,13 +1973,12 @@ static void e1000_set_multi(struct net_device *netdev)
 		 * if we're called from probe, we might not have
 		 * anything to do here, so clear out the list
 		 */
-		e1000_mc_addr_list_update(hw, NULL, 0, 1,
-					  mac->rar_entry_count);
+		e1000_update_mc_addr_list(hw, NULL, 0, 1, mac->rar_entry_count);
 	}
 }
 
 /**
- * e1000_configure - configure the hardware for RX and TX
+ * e1000_configure - configure the hardware for Rx and Tx
  * @adapter: private board structure
  **/
 static void e1000_configure(struct e1000_adapter *adapter)
@@ -1943,8 +1991,7 @@ static void e1000_configure(struct e1000_adapter *adapter)
 	e1000_configure_tx(adapter);
 	e1000_setup_rctl(adapter);
 	e1000_configure_rx(adapter);
-	adapter->alloc_rx_buf(adapter,
-			      e1000_desc_unused(adapter->rx_ring));
+	adapter->alloc_rx_buf(adapter, e1000_desc_unused(adapter->rx_ring));
 }
 
 /**
@@ -1960,9 +2007,11 @@ void e1000e_power_up_phy(struct e1000_adapter *adapter)
 	u16 mii_reg = 0;
 
 	/* Just clear the power down bit to wake the phy back up */
-	if (adapter->hw.media_type == e1000_media_type_copper) {
-		/* according to the manual, the phy will retain its
-		 * settings across a power-down/up cycle */
+	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
+		/*
+		 * According to the manual, the phy will retain its
+		 * settings across a power-down/up cycle
+		 */
 		e1e_rphy(&adapter->hw, PHY_CONTROL, &mii_reg);
 		mii_reg &= ~MII_CR_POWER_DOWN;
 		e1e_wphy(&adapter->hw, PHY_CONTROL, mii_reg);
@@ -1987,12 +2036,11 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter)
 		return;
 
 	/* non-copper PHY? */
-	if (adapter->hw.media_type != e1000_media_type_copper)
+	if (adapter->hw.phy.media_type != e1000_media_type_copper)
 		return;
 
 	/* reset is blocked because of a SoL/IDER session */
-	if (e1000e_check_mng_mode(hw) ||
-	    e1000_check_reset_block(hw))
+	if (e1000e_check_mng_mode(hw) || e1000_check_reset_block(hw))
 		return;
 
 	/* manageability (AMT) is enabled */
@@ -2012,51 +2060,61 @@ static void e1000_power_down_phy(struct e1000_adapter *adapter)
  * This function boots the hardware and enables some settings that
  * require a configuration cycle of the hardware - those cannot be
  * set/changed during runtime. After reset the device needs to be
- * properly configured for rx, tx etc.
+ * properly configured for Rx, Tx etc.
  */
 void e1000e_reset(struct e1000_adapter *adapter)
 {
 	struct e1000_mac_info *mac = &adapter->hw.mac;
+	struct e1000_fc_info *fc = &adapter->hw.fc;
 	struct e1000_hw *hw = &adapter->hw;
 	u32 tx_space, min_tx_space, min_rx_space;
-	u32 pba;
+	u32 pba = adapter->pba;
 	u16 hwm;
 
-	ew32(PBA, adapter->pba);
+	/* reset Packet Buffer Allocation to default */
+	ew32(PBA, pba);
 
-	if (mac->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN ) {
-		/* To maintain wire speed transmits, the Tx FIFO should be
+	if (adapter->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN) {
+		/*
+		 * To maintain wire speed transmits, the Tx FIFO should be
 		 * large enough to accommodate two full transmit packets,
 		 * rounded up to the next 1KB and expressed in KB.  Likewise,
 		 * the Rx FIFO should be large enough to accommodate at least
 		 * one full receive packet and is similarly rounded up and
-		 * expressed in KB. */
+		 * expressed in KB.
+		 */
 		pba = er32(PBA);
 		/* upper 16 bits has Tx packet buffer allocation size in KB */
 		tx_space = pba >> 16;
 		/* lower 16 bits has Rx packet buffer allocation size in KB */
 		pba &= 0xffff;
-		/* the tx fifo also stores 16 bytes of information about the tx
-		 * but don't include ethernet FCS because hardware appends it */
-		min_tx_space = (mac->max_frame_size +
+		/*
+		 * the Tx fifo also stores 16 bytes of information about the tx
+		 * but don't include ethernet FCS because hardware appends it
+		 */
+		min_tx_space = (adapter->max_frame_size +
 				sizeof(struct e1000_tx_desc) -
 				ETH_FCS_LEN) * 2;
 		min_tx_space = ALIGN(min_tx_space, 1024);
 		min_tx_space >>= 10;
 		/* software strips receive CRC, so leave room for it */
-		min_rx_space = mac->max_frame_size;
+		min_rx_space = adapter->max_frame_size;
 		min_rx_space = ALIGN(min_rx_space, 1024);
 		min_rx_space >>= 10;
 
-		/* If current Tx allocation is less than the min Tx FIFO size,
+		/*
+		 * If current Tx allocation is less than the min Tx FIFO size,
 		 * and the min Tx FIFO size is less than the current Rx FIFO
-		 * allocation, take space away from current Rx allocation */
+		 * allocation, take space away from current Rx allocation
+		 */
 		if ((tx_space < min_tx_space) &&
 		    ((min_tx_space - tx_space) < pba)) {
 			pba -= min_tx_space - tx_space;
 
-			/* if short on rx space, rx wins and must trump tx
-			 * adjustment or use Early Receive if available */
+			/*
+			 * if short on Rx space, Rx wins and must trump tx
+			 * adjustment or use Early Receive if available
+			 */
 			if ((pba < min_rx_space) &&
 			    (!(adapter->flags & FLAG_HAS_ERT)))
 				/* ERT enabled in e1000_configure_rx */
@@ -2067,29 +2125,33 @@ void e1000e_reset(struct e1000_adapter *adapter)
 	}
 
 
-	/* flow control settings */
-	/* The high water mark must be low enough to fit one full frame
+	/*
+	 * flow control settings
+	 *
+	 * The high water mark must be low enough to fit one full frame
 	 * (or the size used for early receive) above it in the Rx FIFO.
 	 * Set it to the lower of:
 	 * - 90% of the Rx FIFO size, and
 	 * - the full Rx FIFO size minus the early receive size (for parts
 	 *   with ERT support assuming ERT set to E1000_ERT_2048), or
-	 * - the full Rx FIFO size minus one full frame */
+	 * - the full Rx FIFO size minus one full frame
+	 */
 	if (adapter->flags & FLAG_HAS_ERT)
-		hwm = min(((adapter->pba << 10) * 9 / 10),
-			  ((adapter->pba << 10) - (E1000_ERT_2048 << 3)));
+		hwm = min(((pba << 10) * 9 / 10),
+			  ((pba << 10) - (E1000_ERT_2048 << 3)));
 	else
-		hwm = min(((adapter->pba << 10) * 9 / 10),
-			  ((adapter->pba << 10) - mac->max_frame_size));
+		hwm = min(((pba << 10) * 9 / 10),
+			  ((pba << 10) - adapter->max_frame_size));
 
-	mac->fc_high_water = hwm & 0xFFF8; /* 8-byte granularity */
-	mac->fc_low_water = mac->fc_high_water - 8;
+	fc->high_water = hwm & 0xFFF8; /* 8-byte granularity */
+	fc->low_water = fc->high_water - 8;
 
 	if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME)
-		mac->fc_pause_time = 0xFFFF;
+		fc->pause_time = 0xFFFF;
 	else
-		mac->fc_pause_time = E1000_FC_PAUSE_TIME;
-	mac->fc = mac->original_fc;
+		fc->pause_time = E1000_FC_PAUSE_TIME;
+	fc->send_xon = 1;
+	fc->type = fc->original_type;
 
 	/* Allow time for pending master requests to run */
 	mac->ops.reset_hw(hw);
@@ -2108,9 +2170,11 @@ void e1000e_reset(struct e1000_adapter *adapter)
 
 	if (!(adapter->flags & FLAG_SMART_POWER_DOWN)) {
 		u16 phy_data = 0;
-		/* speed up time to link by disabling smart power down, ignore
+		/*
+		 * speed up time to link by disabling smart power down, ignore
 		 * the return value of this function because there is nothing
-		 * different we would do if it failed */
+		 * different we would do if it failed
+		 */
 		e1e_rphy(hw, IGP02E1000_PHY_POWER_MGMT, &phy_data);
 		phy_data &= ~IGP02E1000_PM_SPD;
 		e1e_wphy(hw, IGP02E1000_PHY_POWER_MGMT, phy_data);
@@ -2140,8 +2204,10 @@ void e1000e_down(struct e1000_adapter *adapter)
 	struct e1000_hw *hw = &adapter->hw;
 	u32 tctl, rctl;
 
-	/* signal that we're down so the interrupt handler does not
-	 * reschedule our watchdog timer */
+	/*
+	 * signal that we're down so the interrupt handler does not
+	 * reschedule our watchdog timer
+	 */
 	set_bit(__E1000_DOWN, &adapter->state);
 
 	/* disable receives in the hardware */
@@ -2200,13 +2266,12 @@ void e1000e_reinit_locked(struct e1000_adapter *adapter)
  **/
 static int __devinit e1000_sw_init(struct e1000_adapter *adapter)
 {
-	struct e1000_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
 
 	adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN;
 	adapter->rx_ps_bsize0 = 128;
-	hw->mac.max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
-	hw->mac.min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
+	adapter->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+	adapter->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
 
 	adapter->tx_ring = kzalloc(sizeof(struct e1000_ring), GFP_KERNEL);
 	if (!adapter->tx_ring)
@@ -2272,16 +2337,20 @@ static int e1000_open(struct net_device *netdev)
 	     E1000_MNG_DHCP_COOKIE_STATUS_VLAN))
 		e1000_update_mng_vlan(adapter);
 
-	/* If AMT is enabled, let the firmware know that the network
-	 * interface is now open */
+	/*
+	 * If AMT is enabled, let the firmware know that the network
+	 * interface is now open
+	 */
 	if ((adapter->flags & FLAG_HAS_AMT) &&
 	    e1000e_check_mng_mode(&adapter->hw))
 		e1000_get_hw_control(adapter);
 
-	/* before we allocate an interrupt, we must be ready to handle it.
+	/*
+	 * before we allocate an interrupt, we must be ready to handle it.
 	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
 	 * as soon as we call pci_request_irq, so we have to setup our
-	 * clean_rx handler before we do so.  */
+	 * clean_rx handler before we do so.
+	 */
 	e1000_configure(adapter);
 
 	err = e1000_request_irq(adapter);
@@ -2335,16 +2404,20 @@ static int e1000_close(struct net_device *netdev)
 	e1000e_free_tx_resources(adapter);
 	e1000e_free_rx_resources(adapter);
 
-	/* kill manageability vlan ID if supported, but not if a vlan with
-	 * the same ID is registered on the host OS (let 8021q kill it) */
+	/*
+	 * kill manageability vlan ID if supported, but not if a vlan with
+	 * the same ID is registered on the host OS (let 8021q kill it)
+	 */
 	if ((adapter->hw.mng_cookie.status &
 			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN) &&
 	     !(adapter->vlgrp &&
 	       vlan_group_get_device(adapter->vlgrp, adapter->mng_vlan_id)))
 		e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id);
 
-	/* If AMT is enabled, let the firmware know that the network
-	 * interface is now closed */
+	/*
+	 * If AMT is enabled, let the firmware know that the network
+	 * interface is now closed
+	 */
 	if ((adapter->flags & FLAG_HAS_AMT) &&
 	    e1000e_check_mng_mode(&adapter->hw))
 		e1000_release_hw_control(adapter);
@@ -2375,12 +2448,14 @@ static int e1000_set_mac(struct net_device *netdev, void *p)
 		/* activate the work around */
 		e1000e_set_laa_state_82571(&adapter->hw, 1);
 
-		/* Hold a copy of the LAA in RAR[14] This is done so that
+		/*
+		 * Hold a copy of the LAA in RAR[14] This is done so that
 		 * between the time RAR[0] gets clobbered  and the time it
 		 * gets fixed (in e1000_watchdog), the actual LAA is in one
 		 * of the RARs and no incoming packets directed to this port
 		 * are dropped. Eventually the LAA will be in RAR[0] and
-		 * RAR[14] */
+		 * RAR[14]
+		 */
 		e1000e_rar_set(&adapter->hw,
 			      adapter->hw.mac.addr,
 			      adapter->hw.mac.rar_entry_count - 1);
@@ -2389,8 +2464,10 @@ static int e1000_set_mac(struct net_device *netdev, void *p)
 	return 0;
 }
 
-/* Need to wait a few seconds after link up to get diagnostic information from
- * the phy */
+/*
+ * Need to wait a few seconds after link up to get diagnostic information from
+ * the phy
+ */
 static void e1000_update_phy_info(unsigned long data)
 {
 	struct e1000_adapter *adapter = (struct e1000_adapter *) data;
@@ -2421,7 +2498,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 
 	spin_lock_irqsave(&adapter->stats_lock, irq_flags);
 
-	/* these counters are modified from e1000_adjust_tbi_stats,
+	/*
+	 * these counters are modified from e1000_adjust_tbi_stats,
 	 * called from the interrupt context, so they must only
 	 * be written while holding adapter->stats_lock
 	 */
@@ -2515,8 +2593,10 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 
 	/* Rx Errors */
 
-	/* RLEC on some newer hardware can be incorrect so build
-	* our own version based on RUC and ROC */
+	/*
+	 * RLEC on some newer hardware can be incorrect so build
+	 * our own version based on RUC and ROC
+	 */
 	adapter->net_stats.rx_errors = adapter->stats.rxerrc +
 		adapter->stats.crcerrs + adapter->stats.algnerrc +
 		adapter->stats.ruc + adapter->stats.roc +
@@ -2537,7 +2617,7 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 	/* Tx Dropped needs to be maintained elsewhere */
 
 	/* Phy Stats */
-	if (hw->media_type == e1000_media_type_copper) {
+	if (hw->phy.media_type == e1000_media_type_copper) {
 		if ((adapter->link_speed == SPEED_1000) &&
 		   (!e1e_rphy(hw, PHY_1000T_STATUS, &phy_tmp))) {
 			phy_tmp &= PHY_IDLE_ERROR_COUNT_MASK;
@@ -2555,8 +2635,8 @@ void e1000e_update_stats(struct e1000_adapter *adapter)
 
 static void e1000_print_link_info(struct e1000_adapter *adapter)
 {
-	struct net_device *netdev = adapter->netdev;
 	struct e1000_hw *hw = &adapter->hw;
+	struct net_device *netdev = adapter->netdev;
 	u32 ctrl = er32(CTRL);
 
 	ndev_info(netdev,
@@ -2570,6 +2650,62 @@ static void e1000_print_link_info(struct e1000_adapter *adapter)
 		((ctrl & E1000_CTRL_TFCE) ? "TX" : "None" )));
 }
 
+static bool e1000_has_link(struct e1000_adapter *adapter)
+{
+	struct e1000_hw *hw = &adapter->hw;
+	bool link_active = 0;
+	s32 ret_val = 0;
+
+	/*
+	 * get_link_status is set on LSC (link status) interrupt or
+	 * Rx sequence error interrupt.  get_link_status will stay
+	 * false until the check_for_link establishes link
+	 * for copper adapters ONLY
+	 */
+	switch (hw->phy.media_type) {
+	case e1000_media_type_copper:
+		if (hw->mac.get_link_status) {
+			ret_val = hw->mac.ops.check_for_link(hw);
+			link_active = !hw->mac.get_link_status;
+		} else {
+			link_active = 1;
+		}
+		break;
+	case e1000_media_type_fiber:
+		ret_val = hw->mac.ops.check_for_link(hw);
+		link_active = !!(er32(STATUS) & E1000_STATUS_LU);
+		break;
+	case e1000_media_type_internal_serdes:
+		ret_val = hw->mac.ops.check_for_link(hw);
+		link_active = adapter->hw.mac.serdes_has_link;
+		break;
+	default:
+	case e1000_media_type_unknown:
+		break;
+	}
+
+	if ((ret_val == E1000_ERR_PHY) && (hw->phy.type == e1000_phy_igp_3) &&
+	    (er32(CTRL) & E1000_PHY_CTRL_GBE_DISABLE)) {
+		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
+		ndev_info(adapter->netdev,
+			  "Gigabit has been disabled, downgrading speed\n");
+	}
+
+	return link_active;
+}
+
+static void e1000e_enable_receives(struct e1000_adapter *adapter)
+{
+	/* make sure the receive unit is started */
+	if ((adapter->flags & FLAG_RX_NEEDS_RESTART) &&
+	    (adapter->flags & FLAG_RX_RESTART_NOW)) {
+		struct e1000_hw *hw = &adapter->hw;
+		u32 rctl = er32(RCTL);
+		ew32(RCTL, rctl | E1000_RCTL_EN);
+		adapter->flags &= ~FLAG_RX_RESTART_NOW;
+	}
+}
+
 /**
  * e1000_watchdog - Timer Call-back
  * @data: pointer to adapter cast into an unsigned long
@@ -2588,48 +2724,35 @@ static void e1000_watchdog_task(struct work_struct *work)
 {
 	struct e1000_adapter *adapter = container_of(work,
 					struct e1000_adapter, watchdog_task);
-
 	struct net_device *netdev = adapter->netdev;
 	struct e1000_mac_info *mac = &adapter->hw.mac;
 	struct e1000_ring *tx_ring = adapter->tx_ring;
 	struct e1000_hw *hw = &adapter->hw;
 	u32 link, tctl;
-	s32 ret_val;
 	int tx_pending = 0;
 
-	if ((netif_carrier_ok(netdev)) &&
-	    (er32(STATUS) & E1000_STATUS_LU))
+	link = e1000_has_link(adapter);
+	if ((netif_carrier_ok(netdev)) && link) {
+		e1000e_enable_receives(adapter);
 		goto link_up;
-
-	ret_val = mac->ops.check_for_link(hw);
-	if ((ret_val == E1000_ERR_PHY) &&
-	    (adapter->hw.phy.type == e1000_phy_igp_3) &&
-	    (er32(CTRL) &
-	     E1000_PHY_CTRL_GBE_DISABLE)) {
-		/* See e1000_kmrn_lock_loss_workaround_ich8lan() */
-		ndev_info(netdev,
-			"Gigabit has been disabled, downgrading speed\n");
 	}
 
 	if ((e1000e_enable_tx_pkt_filtering(hw)) &&
 	    (adapter->mng_vlan_id != adapter->hw.mng_cookie.vlan_id))
 		e1000_update_mng_vlan(adapter);
 
-	if ((adapter->hw.media_type == e1000_media_type_internal_serdes) &&
-	   !(er32(TXCW) & E1000_TXCW_ANE))
-		link = adapter->hw.mac.serdes_has_link;
-	else
-		link = er32(STATUS) & E1000_STATUS_LU;
-
 	if (link) {
 		if (!netif_carrier_ok(netdev)) {
 			bool txb2b = 1;
+			/* update snapshot of PHY registers on LSC */
 			mac->ops.get_link_up_info(&adapter->hw,
 						   &adapter->link_speed,
 						   &adapter->link_duplex);
 			e1000_print_link_info(adapter);
-			/* tweak tx_queue_len according to speed/duplex
-			 * and adjust the timeout factor */
+			/*
+			 * tweak tx_queue_len according to speed/duplex
+			 * and adjust the timeout factor
+			 */
 			netdev->tx_queue_len = adapter->tx_queue_len;
 			adapter->tx_timeout_factor = 1;
 			switch (adapter->link_speed) {
@@ -2645,8 +2768,10 @@ static void e1000_watchdog_task(struct work_struct *work)
 				break;
 			}
 
-			/* workaround: re-program speed mode bit after
-			 * link-up event */
+			/*
+			 * workaround: re-program speed mode bit after
+			 * link-up event
+			 */
 			if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
 			    !txb2b) {
 				u32 tarc0;
@@ -2655,8 +2780,10 @@ static void e1000_watchdog_task(struct work_struct *work)
 				ew32(TARC0, tarc0);
 			}
 
-			/* disable TSO for pcie and 10/100 speeds, to avoid
-			 * some hardware issues */
+			/*
+			 * disable TSO for pcie and 10/100 speeds, to avoid
+			 * some hardware issues
+			 */
 			if (!(adapter->flags & FLAG_TSO_FORCE)) {
 				switch (adapter->link_speed) {
 				case SPEED_10:
@@ -2676,8 +2803,10 @@ static void e1000_watchdog_task(struct work_struct *work)
 				}
 			}
 
-			/* enable transmits in the hardware, need to do this
-			 * after setting TARC0 */
+			/*
+			 * enable transmits in the hardware, need to do this
+			 * after setting TARC(0)
+			 */
 			tctl = er32(TCTL);
 			tctl |= E1000_TCTL_EN;
 			ew32(TCTL, tctl);
@@ -2688,13 +2817,6 @@ static void e1000_watchdog_task(struct work_struct *work)
 			if (!test_bit(__E1000_DOWN, &adapter->state))
 				mod_timer(&adapter->phy_info_timer,
 					  round_jiffies(jiffies + 2 * HZ));
-		} else {
-			/* make sure the receive unit is started */
-			if (adapter->flags & FLAG_RX_NEEDS_RESTART) {
-				u32 rctl = er32(RCTL);
-				ew32(RCTL, rctl |
-						E1000_RCTL_EN);
-			}
 		}
 	} else {
 		if (netif_carrier_ok(netdev)) {
@@ -2731,23 +2853,27 @@ link_up:
 		tx_pending = (e1000_desc_unused(tx_ring) + 1 <
 			       tx_ring->count);
 		if (tx_pending) {
-			/* We've lost link, so the controller stops DMA,
+			/*
+			 * We've lost link, so the controller stops DMA,
 			 * but we've got queued Tx work that's never going
 			 * to get done, so reset controller to flush Tx.
-			 * (Do the reset outside of interrupt context). */
+			 * (Do the reset outside of interrupt context).
+			 */
 			adapter->tx_timeout_count++;
 			schedule_work(&adapter->reset_task);
 		}
 	}
 
-	/* Cause software interrupt to ensure rx ring is cleaned */
+	/* Cause software interrupt to ensure Rx ring is cleaned */
 	ew32(ICS, E1000_ICS_RXDMT0);
 
 	/* Force detection of hung controller every watchdog period */
 	adapter->detect_tx_hung = 1;
 
-	/* With 82571 controllers, LAA may be overwritten due to controller
-	 * reset from the other port. Set the appropriate LAA in RAR[0] */
+	/*
+	 * With 82571 controllers, LAA may be overwritten due to controller
+	 * reset from the other port. Set the appropriate LAA in RAR[0]
+	 */
 	if (e1000e_get_laa_state_82571(hw))
 		e1000e_rar_set(hw, adapter->hw.mac.addr, 0);
 
@@ -3023,16 +3149,20 @@ static void e1000_tx_queue(struct e1000_adapter *adapter,
 
 	tx_desc->lower.data |= cpu_to_le32(adapter->txd_cmd);
 
-	/* Force memory writes to complete before letting h/w
+	/*
+	 * Force memory writes to complete before letting h/w
 	 * know there are new descriptors to fetch.  (Only
 	 * applicable for weak-ordered memory model archs,
-	 * such as IA-64). */
+	 * such as IA-64).
+	 */
 	wmb();
 
 	tx_ring->next_to_use = i;
 	writel(i, adapter->hw.hw_addr + tx_ring->tail);
-	/* we need this if more than one processor can write to our tail
-	 * at a time, it synchronizes IO on IA64/Altix systems */
+	/*
+	 * we need this if more than one processor can write to our tail
+	 * at a time, it synchronizes IO on IA64/Altix systems
+	 */
 	mmiowb();
 }
 
@@ -3080,13 +3210,17 @@ static int __e1000_maybe_stop_tx(struct net_device *netdev, int size)
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 
 	netif_stop_queue(netdev);
-	/* Herbert's original patch had:
+	/*
+	 * Herbert's original patch had:
 	 *  smp_mb__after_netif_stop_queue();
-	 * but since that doesn't exist yet, just open code it. */
+	 * but since that doesn't exist yet, just open code it.
+	 */
 	smp_mb();
 
-	/* We need to check again in a case another CPU has just
-	 * made room available. */
+	/*
+	 * We need to check again in a case another CPU has just
+	 * made room available.
+	 */
 	if (e1000_desc_unused(adapter->tx_ring) < size)
 		return -EBUSY;
 
@@ -3133,21 +3267,29 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	}
 
 	mss = skb_shinfo(skb)->gso_size;
-	/* The controller does a simple calculation to
+	/*
+	 * The controller does a simple calculation to
 	 * make sure there is enough room in the FIFO before
 	 * initiating the DMA for each buffer.  The calc is:
 	 * 4 = ceil(buffer len/mss).  To make sure we don't
 	 * overrun the FIFO, adjust the max buffer len if mss
-	 * drops. */
+	 * drops.
+	 */
 	if (mss) {
 		u8 hdr_len;
 		max_per_txd = min(mss << 2, max_per_txd);
 		max_txd_pwr = fls(max_per_txd) - 1;
 
-		/* TSO Workaround for 82571/2/3 Controllers -- if skb->data
-		* points to just header, pull a few bytes of payload from
-		* frags into skb->data */
+		/*
+		 * TSO Workaround for 82571/2/3 Controllers -- if skb->data
+		 * points to just header, pull a few bytes of payload from
+		 * frags into skb->data
+		 */
 		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+		/*
+		 * we do this workaround for ES2LAN, but it is un-necessary,
+		 * avoiding it could save a lot of cycles
+		 */
 		if (skb->data_len && (hdr_len == len)) {
 			unsigned int pull_size;
 
@@ -3181,8 +3323,10 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		/* Collision - tell upper layer to requeue */
 		return NETDEV_TX_LOCKED;
 
-	/* need: count + 2 desc gap to keep tail from touching
-	 * head, otherwise try next time */
+	/*
+	 * need: count + 2 desc gap to keep tail from touching
+	 * head, otherwise try next time
+	 */
 	if (e1000_maybe_stop_tx(netdev, count + 2)) {
 		spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
 		return NETDEV_TX_BUSY;
@@ -3207,9 +3351,11 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	else if (e1000_tx_csum(adapter, skb))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
-	/* Old method was to assume IPv4 packet by default if TSO was enabled.
+	/*
+	 * Old method was to assume IPv4 packet by default if TSO was enabled.
 	 * 82571 hardware supports TSO capabilities for IPv6 as well...
-	 * no longer assume, we must. */
+	 * no longer assume, we must.
+	 */
 	if (skb->protocol == htons(ETH_P_IP))
 		tx_flags |= E1000_TX_FLAGS_IPV4;
 
@@ -3307,14 +3453,16 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
 		msleep(1);
 	/* e1000e_down has a dependency on max_frame_size */
-	adapter->hw.mac.max_frame_size = max_frame;
+	adapter->max_frame_size = max_frame;
 	if (netif_running(netdev))
 		e1000e_down(adapter);
 
-	/* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
+	/*
+	 * NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
 	 * means we reserve 2 more, this pushes us to allocate from the next
 	 * larger slab size.
-	 * i.e. RXBUFFER_2048 --> size-4096 slab */
+	 * i.e. RXBUFFER_2048 --> size-4096 slab
+	 */
 
 	if (max_frame <= 256)
 		adapter->rx_buffer_len = 256;
@@ -3331,7 +3479,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
 	if ((max_frame == ETH_FRAME_LEN + ETH_FCS_LEN) ||
 	     (max_frame == ETH_FRAME_LEN + VLAN_HLEN + ETH_FCS_LEN))
 		adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN
-					 + ETH_FCS_LEN ;
+					 + ETH_FCS_LEN;
 
 	ndev_info(netdev, "changing MTU from %d to %d\n",
 		netdev->mtu, new_mtu);
@@ -3354,7 +3502,7 @@ static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 	struct mii_ioctl_data *data = if_mii(ifr);
 	unsigned long irq_flags;
 
-	if (adapter->hw.media_type != e1000_media_type_copper)
+	if (adapter->hw.phy.media_type != e1000_media_type_copper)
 		return -EOPNOTSUPP;
 
 	switch (cmd) {
@@ -3436,8 +3584,9 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 			E1000_CTRL_EN_PHY_PWR_MGMT;
 		ew32(CTRL, ctrl);
 
-		if (adapter->hw.media_type == e1000_media_type_fiber ||
-		   adapter->hw.media_type == e1000_media_type_internal_serdes) {
+		if (adapter->hw.phy.media_type == e1000_media_type_fiber ||
+		    adapter->hw.phy.media_type ==
+		    e1000_media_type_internal_serdes) {
 			/* keep the laser running in D3 */
 			ctrl_ext = er32(CTRL_EXT);
 			ctrl_ext |= E1000_CTRL_EXT_SDP7_DATA;
@@ -3467,8 +3616,10 @@ static int e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 	if (adapter->hw.phy.type == e1000_phy_igp_3)
 		e1000e_igp3_phy_powerdown_workaround_ich8lan(&adapter->hw);
 
-	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
-	 * would have already happened in close and is redundant. */
+	/*
+	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
+	 * would have already happened in close and is redundant.
+	 */
 	e1000_release_hw_control(adapter);
 
 	pci_disable_device(pdev);
@@ -3543,9 +3694,11 @@ static int e1000_resume(struct pci_dev *pdev)
 
 	netif_device_attach(netdev);
 
-	/* If the controller has AMT, do not set DRV_LOAD until the interface
+	/*
+	 * If the controller has AMT, do not set DRV_LOAD until the interface
 	 * is up.  For all other cases, let the f/w know that the h/w is now
-	 * under the control of the driver. */
+	 * under the control of the driver.
+	 */
 	if (!(adapter->flags & FLAG_HAS_AMT) || !e1000e_check_mng_mode(&adapter->hw))
 		e1000_get_hw_control(adapter);
 
@@ -3656,9 +3809,11 @@ static void e1000_io_resume(struct pci_dev *pdev)
 
 	netif_device_attach(netdev);
 
-	/* If the controller has AMT, do not set DRV_LOAD until the interface
+	/*
+	 * If the controller has AMT, do not set DRV_LOAD until the interface
 	 * is up.  For all other cases, let the f/w know that the h/w is now
-	 * under the control of the driver. */
+	 * under the control of the driver.
+	 */
 	if (!(adapter->flags & FLAG_HAS_AMT) ||
 	    !e1000e_check_mng_mode(&adapter->hw))
 		e1000_get_hw_control(adapter);
@@ -3825,10 +3980,10 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 
 	hw->mac.ops.get_bus_info(&adapter->hw);
 
-	adapter->hw.phy.wait_for_link = 0;
+	adapter->hw.phy.autoneg_wait_to_complete = 0;
 
 	/* Copper options */
-	if (adapter->hw.media_type == e1000_media_type_copper) {
+	if (adapter->hw.phy.media_type == e1000_media_type_copper) {
 		adapter->hw.phy.mdix = AUTO_ALL_MODES;
 		adapter->hw.phy.disable_polarity_correction = 0;
 		adapter->hw.phy.ms_type = e1000_ms_hw_default;
@@ -3852,15 +4007,19 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	if (pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
-	/* We should not be using LLTX anymore, but we are still TX faster with
-	 * it. */
+	/*
+	 * We should not be using LLTX anymore, but we are still Tx faster with
+	 * it.
+	 */
 	netdev->features |= NETIF_F_LLTX;
 
 	if (e1000e_enable_mng_pass_thru(&adapter->hw))
 		adapter->flags |= FLAG_MNG_PT_ENABLED;
 
-	/* before reading the NVM, reset the controller to
-	 * put the device in a known good starting state */
+	/*
+	 * before reading the NVM, reset the controller to
+	 * put the device in a known good starting state
+	 */
 	adapter->hw.mac.ops.reset_hw(&adapter->hw);
 
 	/*
@@ -3910,8 +4069,8 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	/* Initialize link parameters. User can change them with ethtool */
 	adapter->hw.mac.autoneg = 1;
 	adapter->fc_autoneg = 1;
-	adapter->hw.mac.original_fc = e1000_fc_default;
-	adapter->hw.mac.fc = e1000_fc_default;
+	adapter->hw.fc.original_type = e1000_fc_default;
+	adapter->hw.fc.type = e1000_fc_default;
 	adapter->hw.phy.autoneg_advertised = 0x2f;
 
 	/* ring size defaults */
@@ -3954,9 +4113,11 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 	/* reset the hardware with the new settings */
 	e1000e_reset(adapter);
 
-	/* If the controller has AMT, do not set DRV_LOAD until the interface
+	/*
+	 * If the controller has AMT, do not set DRV_LOAD until the interface
 	 * is up.  For all other cases, let the f/w know that the h/w is now
-	 * under the control of the driver. */
+	 * under the control of the driver.
+	 */
 	if (!(adapter->flags & FLAG_HAS_AMT) ||
 	    !e1000e_check_mng_mode(&adapter->hw))
 		e1000_get_hw_control(adapter);
@@ -4013,16 +4174,20 @@ static void __devexit e1000_remove(struct pci_dev *pdev)
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 
-	/* flush_scheduled work may reschedule our watchdog task, so
-	 * explicitly disable watchdog tasks from being rescheduled  */
+	/*
+	 * flush_scheduled work may reschedule our watchdog task, so
+	 * explicitly disable watchdog tasks from being rescheduled
+	 */
 	set_bit(__E1000_DOWN, &adapter->state);
 	del_timer_sync(&adapter->watchdog_timer);
 	del_timer_sync(&adapter->phy_info_timer);
 
 	flush_scheduled_work();
 
-	/* Release control of h/w to f/w.  If f/w is AMT enabled, this
-	 * would have already happened in close and is redundant. */
+	/*
+	 * Release control of h/w to f/w.  If f/w is AMT enabled, this
+	 * would have already happened in close and is redundant.
+	 */
 	e1000_release_hw_control(adapter);
 
 	unregister_netdev(netdev);
@@ -4060,13 +4225,16 @@ static struct pci_device_id e1000_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_DUAL), board_82571 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_SERDES_QUAD), board_82571 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571PT_QUAD_COPPER), board_82571 },
+
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI), board_82572 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_COPPER), board_82572 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_FIBER), board_82572 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82572EI_SERDES), board_82572 },
+
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E), board_82573 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573E_IAMT), board_82573 },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82573L), board_82573 },
+
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_DPT),
 	  board_80003es2lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_COPPER_SPT),
@@ -4075,6 +4243,7 @@ static struct pci_device_id e1000_pci_tbl[] = {
 	  board_80003es2lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_80003ES2LAN_SERDES_SPT),
 	  board_80003es2lan },
+
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE), board_ich8lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_G), board_ich8lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IFE_GT), board_ich8lan },
@@ -4082,6 +4251,7 @@ static struct pci_device_id e1000_pci_tbl[] = {
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_C), board_ich8lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M), board_ich8lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH8_IGP_M_AMT), board_ich8lan },
+
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE), board_ich9lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_G), board_ich9lan },
 	{ PCI_VDEVICE(INTEL, E1000_DEV_ID_ICH9_IFE_GT), board_ich9lan },
@@ -4099,7 +4269,7 @@ static struct pci_driver e1000_driver = {
 	.probe    = e1000_probe,
 	.remove   = __devexit_p(e1000_remove),
 #ifdef CONFIG_PM
-	/* Power Managment Hooks */
+	/* Power Management Hooks */
 	.suspend  = e1000_suspend,
 	.resume   = e1000_resume,
 #endif
@@ -4118,7 +4288,7 @@ static int __init e1000_init_module(void)
 	int ret;
 	printk(KERN_INFO "%s: Intel(R) PRO/1000 Network Driver - %s\n",
 	       e1000e_driver_name, e1000e_driver_version);
-	printk(KERN_INFO "%s: Copyright (c) 1999-2007 Intel Corporation.\n",
+	printk(KERN_INFO "%s: Copyright (c) 1999-2008 Intel Corporation.\n",
 	       e1000e_driver_name);
 	ret = pci_register_driver(&e1000_driver);
 
diff --git a/drivers/net/e1000e/param.c b/drivers/net/e1000e/param.c
index df266c3..a66b92e 100644
--- a/drivers/net/e1000e/param.c
+++ b/drivers/net/e1000e/param.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -30,7 +30,8 @@
 
 #include "e1000.h"
 
-/* This is the only thing that needs to be changed to adjust the
+/*
+ * This is the only thing that needs to be changed to adjust the
  * maximum number of ports that the driver can manage.
  */
 
@@ -46,7 +47,8 @@ module_param(copybreak, uint, 0644);
 MODULE_PARM_DESC(copybreak,
 	"Maximum size of packet that is copied to a new buffer on receive");
 
-/* All parameters are treated the same, as an integer array of values.
+/*
+ * All parameters are treated the same, as an integer array of values.
  * This macro just reduces the need to repeat the same declaration code
  * over and over (plus this helps to avoid typo bugs).
  */
@@ -60,8 +62,9 @@ MODULE_PARM_DESC(copybreak,
 	MODULE_PARM_DESC(X, desc);
 
 
-/* Transmit Interrupt Delay in units of 1.024 microseconds
- *  Tx interrupt delay needs to typically be set to something non zero
+/*
+ * Transmit Interrupt Delay in units of 1.024 microseconds
+ * Tx interrupt delay needs to typically be set to something non zero
  *
  * Valid Range: 0-65535
  */
@@ -70,7 +73,8 @@ E1000_PARAM(TxIntDelay, "Transmit Interrupt Delay");
 #define MAX_TXDELAY 0xFFFF
 #define MIN_TXDELAY 0
 
-/* Transmit Absolute Interrupt Delay in units of 1.024 microseconds
+/*
+ * Transmit Absolute Interrupt Delay in units of 1.024 microseconds
  *
  * Valid Range: 0-65535
  */
@@ -79,8 +83,9 @@ E1000_PARAM(TxAbsIntDelay, "Transmit Absolute Interrupt Delay");
 #define MAX_TXABSDELAY 0xFFFF
 #define MIN_TXABSDELAY 0
 
-/* Receive Interrupt Delay in units of 1.024 microseconds
- *   hardware will likely hang if you set this to anything but zero.
+/*
+ * Receive Interrupt Delay in units of 1.024 microseconds
+ * hardware will likely hang if you set this to anything but zero.
  *
  * Valid Range: 0-65535
  */
@@ -89,7 +94,8 @@ E1000_PARAM(RxIntDelay, "Receive Interrupt Delay");
 #define MAX_RXDELAY 0xFFFF
 #define MIN_RXDELAY 0
 
-/* Receive Absolute Interrupt Delay in units of 1.024 microseconds
+/*
+ * Receive Absolute Interrupt Delay in units of 1.024 microseconds
  *
  * Valid Range: 0-65535
  */
@@ -98,7 +104,8 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay");
 #define MAX_RXABSDELAY 0xFFFF
 #define MIN_RXABSDELAY 0
 
-/* Interrupt Throttle Rate (interrupts/sec)
+/*
+ * Interrupt Throttle Rate (interrupts/sec)
  *
  * Valid Range: 100-100000 (0=off, 1=dynamic, 3=dynamic conservative)
  */
@@ -107,7 +114,8 @@ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
 #define MAX_ITR 100000
 #define MIN_ITR 100
 
-/* Enable Smart Power Down of the PHY
+/*
+ * Enable Smart Power Down of the PHY
  *
  * Valid Range: 0, 1
  *
@@ -115,7 +123,8 @@ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate");
  */
 E1000_PARAM(SmartPowerDownEnable, "Enable PHY smart power down");
 
-/* Enable Kumeran Lock Loss workaround
+/*
+ * Enable Kumeran Lock Loss workaround
  *
  * Valid Range: 0, 1
  *
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c
index dab3c46..3a4574c 100644
--- a/drivers/net/e1000e/phy.c
+++ b/drivers/net/e1000e/phy.c
@@ -1,7 +1,7 @@
 /*******************************************************************************
 
   Intel PRO/1000 Linux driver
-  Copyright(c) 1999 - 2007 Intel Corporation.
+  Copyright(c) 1999 - 2008 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,
@@ -134,7 +134,8 @@ static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
 		return -E1000_ERR_PARAM;
 	}
 
-	/* Set up Op-code, Phy Address, and register offset in the MDI
+	/*
+	 * Set up Op-code, Phy Address, and register offset in the MDI
 	 * Control register.  The MAC will take care of interfacing with the
 	 * PHY to retrieve the desired data.
 	 */
@@ -144,7 +145,11 @@ static s32 e1000_read_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 *data)
 
 	ew32(MDIC, mdic);
 
-	/* Poll the ready bit to see if the MDI read completed */
+	/*
+	 * Poll the ready bit to see if the MDI read completed
+	 * Increasing the time out as testing showed failures with
+	 * the lower time out
+	 */
 	for (i = 0; i < 64; i++) {
 		udelay(50);
 		mdic = er32(MDIC);
@@ -182,7 +187,8 @@ static s32 e1000_write_phy_reg_mdic(struct e1000_hw *hw, u32 offset, u16 data)
 		return -E1000_ERR_PARAM;
 	}
 
-	/* Set up Op-code, Phy Address, and register offset in the MDI
+	/*
+	 * Set up Op-code, Phy Address, and register offset in the MDI
 	 * Control register.  The MAC will take care of interfacing with the
 	 * PHY to retrieve the desired data.
 	 */
@@ -409,14 +415,15 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
 	s32 ret_val;
 	u16 phy_data;
 
-	/* Enable CRS on TX. This must be set for half-duplex operation. */
+	/* Enable CRS on Tx. This must be set for half-duplex operation. */
 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
 	if (ret_val)
 		return ret_val;
 
 	phy_data |= M88E1000_PSCR_ASSERT_CRS_ON_TX;
 
-	/* Options:
+	/*
+	 * Options:
 	 *   MDI/MDI-X = 0 (default)
 	 *   0 - Auto for all speeds
 	 *   1 - MDI mode
@@ -441,7 +448,8 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
 		break;
 	}
 
-	/* Options:
+	/*
+	 * Options:
 	 *   disable_polarity_correction = 0 (default)
 	 *       Automatic Correction for Reversed Cable Polarity
 	 *   0 - Disabled
@@ -456,7 +464,8 @@ s32 e1000e_copper_link_setup_m88(struct e1000_hw *hw)
 		return ret_val;
 
 	if (phy->revision < 4) {
-		/* Force TX_CLK in the Extended PHY Specific Control Register
+		/*
+		 * Force TX_CLK in the Extended PHY Specific Control Register
 		 * to 25MHz clock.
 		 */
 		ret_val = e1e_rphy(hw, M88E1000_EXT_PHY_SPEC_CTRL, &phy_data);
@@ -543,19 +552,21 @@ s32 e1000e_copper_link_setup_igp(struct e1000_hw *hw)
 
 	/* set auto-master slave resolution settings */
 	if (hw->mac.autoneg) {
-		/* when autonegotiation advertisement is only 1000Mbps then we
+		/*
+		 * when autonegotiation advertisement is only 1000Mbps then we
 		 * should disable SmartSpeed and enable Auto MasterSlave
-		 * resolution as hardware default. */
+		 * resolution as hardware default.
+		 */
 		if (phy->autoneg_advertised == ADVERTISE_1000_FULL) {
 			/* Disable SmartSpeed */
 			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     &data);
+					   &data);
 			if (ret_val)
 				return ret_val;
 
 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
 			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     data);
+					   data);
 			if (ret_val)
 				return ret_val;
 
@@ -630,14 +641,16 @@ static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
 			return ret_val;
 	}
 
-	/* Need to parse both autoneg_advertised and fc and set up
+	/*
+	 * Need to parse both autoneg_advertised and fc and set up
 	 * the appropriate PHY registers.  First we will parse for
 	 * autoneg_advertised software override.  Since we can advertise
 	 * a plethora of combinations, we need to check each bit
 	 * individually.
 	 */
 
-	/* First we clear all the 10/100 mb speed bits in the Auto-Neg
+	/*
+	 * First we clear all the 10/100 mb speed bits in the Auto-Neg
 	 * Advertisement Register (Address 4) and the 1000 mb speed bits in
 	 * the  1000Base-T Control Register (Address 9).
 	 */
@@ -683,7 +696,8 @@ static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
 		mii_1000t_ctrl_reg |= CR_1000T_FD_CAPS;
 	}
 
-	/* Check for a software override of the flow control settings, and
+	/*
+	 * Check for a software override of the flow control settings, and
 	 * setup the PHY advertisement registers accordingly.  If
 	 * auto-negotiation is enabled, then software will have to set the
 	 * "PAUSE" bits to the correct value in the Auto-Negotiation
@@ -696,38 +710,42 @@ static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
 	 *	  but not send pause frames).
 	 *      2:  Tx flow control is enabled (we can send pause frames
 	 *	  but we do not support receiving pause frames).
-	 *      3:  Both Rx and TX flow control (symmetric) are enabled.
+	 *      3:  Both Rx and Tx flow control (symmetric) are enabled.
 	 *  other:  No software override.  The flow control configuration
 	 *	  in the EEPROM is used.
 	 */
-	switch (hw->mac.fc) {
+	switch (hw->fc.type) {
 	case e1000_fc_none:
-		/* Flow control (RX & TX) is completely disabled by a
+		/*
+		 * Flow control (Rx & Tx) is completely disabled by a
 		 * software over-ride.
 		 */
 		mii_autoneg_adv_reg &= ~(NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
 		break;
 	case e1000_fc_rx_pause:
-		/* RX Flow control is enabled, and TX Flow control is
+		/*
+		 * Rx Flow control is enabled, and Tx Flow control is
 		 * disabled, by a software over-ride.
-		 */
-		/* Since there really isn't a way to advertise that we are
-		 * capable of RX Pause ONLY, we will advertise that we
-		 * support both symmetric and asymmetric RX PAUSE.  Later
+		 *
+		 * Since there really isn't a way to advertise that we are
+		 * capable of Rx Pause ONLY, we will advertise that we
+		 * support both symmetric and asymmetric Rx PAUSE.  Later
 		 * (in e1000e_config_fc_after_link_up) we will disable the
 		 * hw's ability to send PAUSE frames.
 		 */
 		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
 		break;
 	case e1000_fc_tx_pause:
-		/* TX Flow control is enabled, and RX Flow control is
+		/*
+		 * Tx Flow control is enabled, and Rx Flow control is
 		 * disabled, by a software over-ride.
 		 */
 		mii_autoneg_adv_reg |= NWAY_AR_ASM_DIR;
 		mii_autoneg_adv_reg &= ~NWAY_AR_PAUSE;
 		break;
 	case e1000_fc_full:
-		/* Flow control (both RX and TX) is enabled by a software
+		/*
+		 * Flow control (both Rx and Tx) is enabled by a software
 		 * over-ride.
 		 */
 		mii_autoneg_adv_reg |= (NWAY_AR_ASM_DIR | NWAY_AR_PAUSE);
@@ -758,7 +776,7 @@ static s32 e1000_phy_setup_autoneg(struct e1000_hw *hw)
  *  Performs initial bounds checking on autoneg advertisement parameter, then
  *  configure to advertise the full capability.  Setup the PHY to autoneg
  *  and restart the negotiation process between the link partner.  If
- *  wait_for_link, then wait for autoneg to complete before exiting.
+ *  autoneg_wait_to_complete, then wait for autoneg to complete before exiting.
  **/
 static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
 {
@@ -766,12 +784,14 @@ static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
 	s32 ret_val;
 	u16 phy_ctrl;
 
-	/* Perform some bounds checking on the autoneg advertisement
+	/*
+	 * Perform some bounds checking on the autoneg advertisement
 	 * parameter.
 	 */
 	phy->autoneg_advertised &= phy->autoneg_mask;
 
-	/* If autoneg_advertised is zero, we assume it was not defaulted
+	/*
+	 * If autoneg_advertised is zero, we assume it was not defaulted
 	 * by the calling code so we set to advertise full capability.
 	 */
 	if (phy->autoneg_advertised == 0)
@@ -785,7 +805,8 @@ static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
 	}
 	hw_dbg(hw, "Restarting Auto-Neg\n");
 
-	/* Restart auto-negotiation by setting the Auto Neg Enable bit and
+	/*
+	 * Restart auto-negotiation by setting the Auto Neg Enable bit and
 	 * the Auto Neg Restart bit in the PHY control register.
 	 */
 	ret_val = e1e_rphy(hw, PHY_CONTROL, &phy_ctrl);
@@ -797,10 +818,11 @@ static s32 e1000_copper_link_autoneg(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	/* Does the user want to wait for Auto-Neg to complete here, or
+	/*
+	 * Does the user want to wait for Auto-Neg to complete here, or
 	 * check at a later time (for example, callback routine).
 	 */
-	if (phy->wait_for_link) {
+	if (phy->autoneg_wait_to_complete) {
 		ret_val = e1000_wait_autoneg(hw);
 		if (ret_val) {
 			hw_dbg(hw, "Error while waiting for "
@@ -829,14 +851,18 @@ s32 e1000e_setup_copper_link(struct e1000_hw *hw)
 	bool link;
 
 	if (hw->mac.autoneg) {
-		/* Setup autoneg and flow control advertisement and perform
-		 * autonegotiation. */
+		/*
+		 * Setup autoneg and flow control advertisement and perform
+		 * autonegotiation.
+		 */
 		ret_val = e1000_copper_link_autoneg(hw);
 		if (ret_val)
 			return ret_val;
 	} else {
-		/* PHY will be set to 10H, 10F, 100H or 100F
-		 * depending on user settings. */
+		/*
+		 * PHY will be set to 10H, 10F, 100H or 100F
+		 * depending on user settings.
+		 */
 		hw_dbg(hw, "Forcing Speed and Duplex\n");
 		ret_val = e1000_phy_force_speed_duplex(hw);
 		if (ret_val) {
@@ -845,7 +871,8 @@ s32 e1000e_setup_copper_link(struct e1000_hw *hw)
 		}
 	}
 
-	/* Check link status. Wait up to 100 microseconds for link to become
+	/*
+	 * Check link status. Wait up to 100 microseconds for link to become
 	 * valid.
 	 */
 	ret_val = e1000e_phy_has_link_generic(hw,
@@ -891,7 +918,8 @@ s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	/* Clear Auto-Crossover to force MDI manually.  IGP requires MDI
+	/*
+	 * Clear Auto-Crossover to force MDI manually.  IGP requires MDI
 	 * forced whenever speed and duplex are forced.
 	 */
 	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CTRL, &phy_data);
@@ -909,7 +937,7 @@ s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw)
 
 	udelay(1);
 
-	if (phy->wait_for_link) {
+	if (phy->autoneg_wait_to_complete) {
 		hw_dbg(hw, "Waiting for forced speed/duplex link on IGP phy.\n");
 
 		ret_val = e1000e_phy_has_link_generic(hw,
@@ -941,7 +969,7 @@ s32 e1000e_phy_force_speed_duplex_igp(struct e1000_hw *hw)
  *  Calls the PHY setup function to force speed and duplex.  Clears the
  *  auto-crossover to force MDI manually.  Resets the PHY to commit the
  *  changes.  If time expires while waiting for link up, we reset the DSP.
- *  After reset, TX_CLK and CRS on TX must be set.  Return successful upon
+ *  After reset, TX_CLK and CRS on Tx must be set.  Return successful upon
  *  successful completion, else return corresponding error code.
  **/
 s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
@@ -951,7 +979,8 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
 	u16 phy_data;
 	bool link;
 
-	/* Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
+	/*
+	 * Clear Auto-Crossover to force MDI manually.  M88E1000 requires MDI
 	 * forced whenever speed and duplex are forced.
 	 */
 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
@@ -980,7 +1009,7 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
 
 	udelay(1);
 
-	if (phy->wait_for_link) {
+	if (phy->autoneg_wait_to_complete) {
 		hw_dbg(hw, "Waiting for forced speed/duplex link on M88 phy.\n");
 
 		ret_val = e1000e_phy_has_link_generic(hw, PHY_FORCE_LIMIT,
@@ -989,10 +1018,12 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
 			return ret_val;
 
 		if (!link) {
-			/* We didn't get link.
+			/*
+			 * We didn't get link.
 			 * Reset the DSP and cross our fingers.
 			 */
-			ret_val = e1e_wphy(hw, M88E1000_PHY_PAGE_SELECT, 0x001d);
+			ret_val = e1e_wphy(hw, M88E1000_PHY_PAGE_SELECT,
+					   0x001d);
 			if (ret_val)
 				return ret_val;
 			ret_val = e1000e_phy_reset_dsp(hw);
@@ -1011,7 +1042,8 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	/* Resetting the phy means we need to re-force TX_CLK in the
+	/*
+	 * Resetting the phy means we need to re-force TX_CLK in the
 	 * Extended PHY Specific Control Register to 25MHz clock from
 	 * the reset value of 2.5MHz.
 	 */
@@ -1020,7 +1052,8 @@ s32 e1000e_phy_force_speed_duplex_m88(struct e1000_hw *hw)
 	if (ret_val)
 		return ret_val;
 
-	/* In addition, we must re-enable CRS on Tx for both half and full
+	/*
+	 * In addition, we must re-enable CRS on Tx for both half and full
 	 * duplex.
 	 */
 	ret_val = e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
@@ -1051,7 +1084,7 @@ void e1000e_phy_force_speed_duplex_setup(struct e1000_hw *hw, u16 *phy_ctrl)
 	u32 ctrl;
 
 	/* Turn off flow control when forcing speed/duplex */
-	mac->fc = e1000_fc_none;
+	hw->fc.type = e1000_fc_none;
 
 	/* Force speed/duplex on the mac */
 	ctrl = er32(CTRL);
@@ -1124,30 +1157,32 @@ s32 e1000e_set_d3_lplu_state(struct e1000_hw *hw, bool active)
 					     data);
 		if (ret_val)
 			return ret_val;
-		/* LPLU and SmartSpeed are mutually exclusive.  LPLU is used
+		/*
+		 * LPLU and SmartSpeed are mutually exclusive.  LPLU is used
 		 * during Dx states where the power conservation is most
 		 * important.  During driver activity we should enable
-		 * SmartSpeed, so performance is maintained. */
+		 * SmartSpeed, so performance is maintained.
+		 */
 		if (phy->smart_speed == e1000_smart_speed_on) {
 			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						    &data);
+					   &data);
 			if (ret_val)
 				return ret_val;
 
 			data |= IGP01E1000_PSCFR_SMART_SPEED;
 			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     data);
+					   data);
 			if (ret_val)
 				return ret_val;
 		} else if (phy->smart_speed == e1000_smart_speed_off) {
 			ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     &data);
+					   &data);
 			if (ret_val)
 				return ret_val;
 
 			data &= ~IGP01E1000_PSCFR_SMART_SPEED;
 			ret_val = e1e_wphy(hw, IGP01E1000_PHY_PORT_CONFIG,
-						     data);
+					   data);
 			if (ret_val)
 				return ret_val;
 		}
@@ -1249,8 +1284,10 @@ static s32 e1000_check_polarity_igp(struct e1000_hw *hw)
 	s32 ret_val;
 	u16 data, offset, mask;
 
-	/* Polarity is determined based on the speed of
-	 * our connection. */
+	/*
+	 * Polarity is determined based on the speed of
+	 * our connection.
+	 */
 	ret_val = e1e_rphy(hw, IGP01E1000_PHY_PORT_STATUS, &data);
 	if (ret_val)
 		return ret_val;
@@ -1260,7 +1297,8 @@ static s32 e1000_check_polarity_igp(struct e1000_hw *hw)
 		offset	= IGP01E1000_PHY_PCS_INIT_REG;
 		mask	= IGP01E1000_PHY_POLARITY_MASK;
 	} else {
-		/* This really only applies to 10Mbps since
+		/*
+		 * This really only applies to 10Mbps since
 		 * there is no polarity for 100Mbps (always 0).
 		 */
 		offset	= IGP01E1000_PHY_PORT_STATUS;
@@ -1278,7 +1316,7 @@ static s32 e1000_check_polarity_igp(struct e1000_hw *hw)
 }
 
 /**
- *  e1000_wait_autoneg - Wait for auto-neg compeletion
+ *  e1000_wait_autoneg - Wait for auto-neg completion
  *  @hw: pointer to the HW structure
  *
  *  Waits for auto-negotiation to complete or for the auto-negotiation time
@@ -1302,7 +1340,8 @@ static s32 e1000_wait_autoneg(struct e1000_hw *hw)
 		msleep(100);
 	}
 
-	/* PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
+	/*
+	 * PHY_AUTO_NEG_TIME expiration doesn't guarantee auto-negotiation
 	 * has completed.
 	 */
 	return ret_val;
@@ -1324,7 +1363,8 @@ s32 e1000e_phy_has_link_generic(struct e1000_hw *hw, u32 iterations,
 	u16 i, phy_status;
 
 	for (i = 0; i < iterations; i++) {
-		/* Some PHYs require the PHY_STATUS register to be read
+		/*
+		 * Some PHYs require the PHY_STATUS register to be read
 		 * twice due to the link bit being sticky.  No harm doing
 		 * it across the board.
 		 */
@@ -1412,10 +1452,12 @@ s32 e1000e_get_cable_length_igp_2(struct e1000_hw *hw)
 		if (ret_val)
 			return ret_val;
 
-		/* Getting bits 15:9, which represent the combination of
+		/*
+		 * Getting bits 15:9, which represent the combination of
 		 * course and fine gain values.  The result is a number
 		 * that can be put into the lookup table to obtain the
-		 * approximate cable length. */
+		 * approximate cable length.
+		 */
 		cur_agc_index = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
 				IGP02E1000_AGC_LENGTH_MASK;
 
@@ -1466,7 +1508,7 @@ s32 e1000e_get_phy_info_m88(struct e1000_hw *hw)
 	u16 phy_data;
 	bool link;
 
-	if (hw->media_type != e1000_media_type_copper) {
+	if (hw->phy.media_type != e1000_media_type_copper) {
 		hw_dbg(hw, "Phy info is only valid for copper media\n");
 		return -E1000_ERR_CONFIG;
 	}
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 93b7fb2..26acd05 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -421,7 +421,7 @@ struct ehea_fw_handle_entry {
 struct ehea_fw_handle_array {
 	struct ehea_fw_handle_entry *arr;
 	int num_entries;
-	struct semaphore lock;
+	struct mutex lock;
 };
 
 struct ehea_bcmc_reg_entry {
@@ -434,7 +434,7 @@ struct ehea_bcmc_reg_entry {
 struct ehea_bcmc_reg_array {
 	struct ehea_bcmc_reg_entry *arr;
 	int num_entries;
-	struct semaphore lock;
+	struct mutex lock;
 };
 
 #define EHEA_PORT_UP 1
@@ -452,7 +452,7 @@ struct ehea_port {
 	struct vlan_group *vgrp;
 	struct ehea_eq *qp_eq;
 	struct work_struct reset_task;
-	struct semaphore port_lock;
+	struct mutex port_lock;
 	char int_aff_name[EHEA_IRQ_NAME_SIZE];
 	int allmulti;			 /* Indicates IFF_ALLMULTI state */
 	int promisc;		 	 /* Indicates IFF_PROMISC state */
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 07c742d..0c1c360 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -36,6 +36,7 @@
 #include <linux/notifier.h>
 #include <linux/reboot.h>
 #include <asm/kexec.h>
+#include <linux/mutex.h>
 
 #include <net/ip.h>
 
@@ -99,7 +100,7 @@ static int port_name_cnt;
 static LIST_HEAD(adapter_list);
 u64 ehea_driver_flags;
 struct work_struct ehea_rereg_mr_task;
-struct semaphore dlpar_mem_lock;
+static DEFINE_MUTEX(dlpar_mem_lock);
 struct ehea_fw_handle_array ehea_fw_handles;
 struct ehea_bcmc_reg_array ehea_bcmc_regs;
 
@@ -1758,7 +1759,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
 
 	memcpy(dev->dev_addr, mac_addr->sa_data, dev->addr_len);
 
-	down(&ehea_bcmc_regs.lock);
+	mutex_lock(&ehea_bcmc_regs.lock);
 
 	/* Deregister old MAC in pHYP */
 	ret = ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
@@ -1776,7 +1777,7 @@ static int ehea_set_mac_addr(struct net_device *dev, void *sa)
 
 out_upregs:
 	ehea_update_bcmc_registrations();
-	up(&ehea_bcmc_regs.lock);
+	mutex_unlock(&ehea_bcmc_regs.lock);
 out_free:
 	kfree(cb0);
 out:
@@ -1938,7 +1939,7 @@ static void ehea_set_multicast_list(struct net_device *dev)
 	}
 	ehea_promiscuous(dev, 0);
 
-	down(&ehea_bcmc_regs.lock);
+	mutex_lock(&ehea_bcmc_regs.lock);
 
 	if (dev->flags & IFF_ALLMULTI) {
 		ehea_allmulti(dev, 1);
@@ -1969,7 +1970,7 @@ static void ehea_set_multicast_list(struct net_device *dev)
 	}
 out:
 	ehea_update_bcmc_registrations();
-	up(&ehea_bcmc_regs.lock);
+	mutex_unlock(&ehea_bcmc_regs.lock);
 	return;
 }
 
@@ -2452,7 +2453,7 @@ static int ehea_up(struct net_device *dev)
 	if (port->state == EHEA_PORT_UP)
 		return 0;
 
-	down(&ehea_fw_handles.lock);
+	mutex_lock(&ehea_fw_handles.lock);
 
 	ret = ehea_port_res_setup(port, port->num_def_qps,
 				  port->num_add_tx_qps);
@@ -2490,7 +2491,7 @@ static int ehea_up(struct net_device *dev)
 		}
 	}
 
-	down(&ehea_bcmc_regs.lock);
+	mutex_lock(&ehea_bcmc_regs.lock);
 
 	ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
 	if (ret) {
@@ -2513,10 +2514,10 @@ out:
 		ehea_info("Failed starting %s. ret=%i", dev->name, ret);
 
 	ehea_update_bcmc_registrations();
-	up(&ehea_bcmc_regs.lock);
+	mutex_unlock(&ehea_bcmc_regs.lock);
 
 	ehea_update_firmware_handles();
-	up(&ehea_fw_handles.lock);
+	mutex_unlock(&ehea_fw_handles.lock);
 
 	return ret;
 }
@@ -2542,7 +2543,7 @@ static int ehea_open(struct net_device *dev)
 	int ret;
 	struct ehea_port *port = netdev_priv(dev);
 
-	down(&port->port_lock);
+	mutex_lock(&port->port_lock);
 
 	if (netif_msg_ifup(port))
 		ehea_info("enabling port %s", dev->name);
@@ -2553,7 +2554,7 @@ static int ehea_open(struct net_device *dev)
 		netif_start_queue(dev);
 	}
 
-	up(&port->port_lock);
+	mutex_unlock(&port->port_lock);
 
 	return ret;
 }
@@ -2566,18 +2567,18 @@ static int ehea_down(struct net_device *dev)
 	if (port->state == EHEA_PORT_DOWN)
 		return 0;
 
-	down(&ehea_bcmc_regs.lock);
+	mutex_lock(&ehea_fw_handles.lock);
+
+	mutex_lock(&ehea_bcmc_regs.lock);
 	ehea_drop_multicast_list(dev);
 	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
 
 	ehea_free_interrupts(dev);
 
-	down(&ehea_fw_handles.lock);
-
 	port->state = EHEA_PORT_DOWN;
 
 	ehea_update_bcmc_registrations();
-	up(&ehea_bcmc_regs.lock);
+	mutex_unlock(&ehea_bcmc_regs.lock);
 
 	ret = ehea_clean_all_portres(port);
 	if (ret)
@@ -2585,7 +2586,7 @@ static int ehea_down(struct net_device *dev)
 			  dev->name, ret);
 
 	ehea_update_firmware_handles();
-	up(&ehea_fw_handles.lock);
+	mutex_unlock(&ehea_fw_handles.lock);
 
 	return ret;
 }
@@ -2599,11 +2600,11 @@ static int ehea_stop(struct net_device *dev)
 		ehea_info("disabling port %s", dev->name);
 
 	flush_scheduled_work();
-	down(&port->port_lock);
+	mutex_lock(&port->port_lock);
 	netif_stop_queue(dev);
 	port_napi_disable(port);
 	ret = ehea_down(dev);
-	up(&port->port_lock);
+	mutex_unlock(&port->port_lock);
 	return ret;
 }
 
@@ -2801,7 +2802,7 @@ static void ehea_reset_port(struct work_struct *work)
 	struct net_device *dev = port->netdev;
 
 	port->resets++;
-	down(&port->port_lock);
+	mutex_lock(&port->port_lock);
 	netif_stop_queue(dev);
 
 	port_napi_disable(port);
@@ -2821,7 +2822,7 @@ static void ehea_reset_port(struct work_struct *work)
 
 	netif_wake_queue(dev);
 out:
-	up(&port->port_lock);
+	mutex_unlock(&port->port_lock);
 	return;
 }
 
@@ -2830,7 +2831,7 @@ static void ehea_rereg_mrs(struct work_struct *work)
 	int ret, i;
 	struct ehea_adapter *adapter;
 
-	down(&dlpar_mem_lock);
+	mutex_lock(&dlpar_mem_lock);
 	ehea_info("LPAR memory enlarged - re-initializing driver");
 
 	list_for_each_entry(adapter, &adapter_list, list)
@@ -2838,21 +2839,23 @@ static void ehea_rereg_mrs(struct work_struct *work)
 			/* Shutdown all ports */
 			for (i = 0; i < EHEA_MAX_PORTS; i++) {
 				struct ehea_port *port = adapter->port[i];
+				struct net_device *dev;
 
-				if (port) {
-					struct net_device *dev = port->netdev;
+				if (!port)
+					continue;
 
-					if (dev->flags & IFF_UP) {
-						down(&port->port_lock);
-						netif_stop_queue(dev);
-						ret = ehea_stop_qps(dev);
-						if (ret) {
-							up(&port->port_lock);
-							goto out;
-						}
-						port_napi_disable(port);
-						up(&port->port_lock);
+				dev = port->netdev;
+
+				if (dev->flags & IFF_UP) {
+					mutex_lock(&port->port_lock);
+					netif_stop_queue(dev);
+					ret = ehea_stop_qps(dev);
+					if (ret) {
+						mutex_unlock(&port->port_lock);
+						goto out;
 					}
+					port_napi_disable(port);
+					mutex_unlock(&port->port_lock);
 				}
 			}
 
@@ -2892,17 +2895,17 @@ static void ehea_rereg_mrs(struct work_struct *work)
 					struct net_device *dev = port->netdev;
 
 					if (dev->flags & IFF_UP) {
-						down(&port->port_lock);
+						mutex_lock(&port->port_lock);
 						port_napi_enable(port);
 						ret = ehea_restart_qps(dev);
 						if (!ret)
 							netif_wake_queue(dev);
-						up(&port->port_lock);
+						mutex_unlock(&port->port_lock);
 					}
 				}
 			}
 		}
-       up(&dlpar_mem_lock);
+       mutex_unlock(&dlpar_mem_lock);
        ehea_info("re-initializing driver complete");
 out:
 	return;
@@ -3063,7 +3066,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 
 	port = netdev_priv(dev);
 
-	sema_init(&port->port_lock, 1);
+	mutex_init(&port->port_lock);
 	port->state = EHEA_PORT_DOWN;
 	port->sig_comp_iv = sq_entries / 10;
 
@@ -3342,7 +3345,7 @@ static int __devinit ehea_probe_adapter(struct of_device *dev,
 		ehea_error("Invalid ibmebus device probed");
 		return -EINVAL;
 	}
-	down(&ehea_fw_handles.lock);
+	mutex_lock(&ehea_fw_handles.lock);
 
 	adapter = kzalloc(sizeof(*adapter), GFP_KERNEL);
 	if (!adapter) {
@@ -3426,7 +3429,7 @@ out_free_ad:
 
 out:
 	ehea_update_firmware_handles();
-	up(&ehea_fw_handles.lock);
+	mutex_unlock(&ehea_fw_handles.lock);
 	return ret;
 }
 
@@ -3445,7 +3448,7 @@ static int __devexit ehea_remove(struct of_device *dev)
 
 	flush_scheduled_work();
 
-	down(&ehea_fw_handles.lock);
+	mutex_lock(&ehea_fw_handles.lock);
 
 	ibmebus_free_irq(adapter->neq->attr.ist1, adapter);
 	tasklet_kill(&adapter->neq_tasklet);
@@ -3456,7 +3459,7 @@ static int __devexit ehea_remove(struct of_device *dev)
 	kfree(adapter);
 
 	ehea_update_firmware_handles();
-	up(&ehea_fw_handles.lock);
+	mutex_unlock(&ehea_fw_handles.lock);
 
 	return 0;
 }
@@ -3543,9 +3546,8 @@ int __init ehea_module_init(void)
 	memset(&ehea_fw_handles, 0, sizeof(ehea_fw_handles));
 	memset(&ehea_bcmc_regs, 0, sizeof(ehea_bcmc_regs));
 
-	sema_init(&dlpar_mem_lock, 1);
-	sema_init(&ehea_fw_handles.lock, 1);
-	sema_init(&ehea_bcmc_regs.lock, 1);
+	mutex_init(&ehea_fw_handles.lock);
+	mutex_init(&ehea_bcmc_regs.lock);
 
 	ret = check_module_parm();
 	if (ret)
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 7ad2993..cb371a8 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -367,7 +367,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
 		/* Always use CB2 mode, difference is masked
 		 * in the CB driver. */
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_DCA_CTRL, 2);
-		if (dca_add_requester(dev) == IXGBE_SUCCESS) {
+		if (dca_add_requester(dev) == 0) {
 			ixgbe_setup_dca(adapter);
 			break;
 		}
@@ -381,7 +381,7 @@ static int __ixgbe_notify_dca(struct device *dev, void *data)
 		break;
 	}
 
-	return IXGBE_SUCCESS;
+	return 0;
 }
 
 #endif /* CONFIG_DCA */
@@ -3605,7 +3605,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 		goto err_register;
 
 #ifdef CONFIG_DCA
-	if (dca_add_requester(&pdev->dev) == IXGBE_SUCCESS) {
+	if (dca_add_requester(&pdev->dev) == 0) {
 		adapter->flags |= IXGBE_FLAG_DCA_ENABLED;
 		/* always use CB2 mode, difference is masked
 		 * in the CB driver */
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index 44a06f8..45208a0 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -42,6 +42,7 @@
 
 #define XL_DEBUG 0
 
+#include <linux/jiffies.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
@@ -408,7 +409,7 @@ static int xl_hw_reset(struct net_device *dev)
 	t=jiffies;
 	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
 		schedule();		
-		if(jiffies-t > 40*HZ) {
+		if (time_after(jiffies, t + 40 * HZ)) {
 			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL  card not responding to global reset.\n", dev->name);
 			return -ENODEV;
 		}
@@ -519,7 +520,7 @@ static int xl_hw_reset(struct net_device *dev)
 	t=jiffies;
 	while ( !(readw(xl_mmio + MMIO_INTSTATUS_AUTO) & INTSTAT_SRB) ) { 
 		schedule();		
-		if(jiffies-t > 15*HZ) {
+		if (time_after(jiffies, t + 15 * HZ)) {
 			printk(KERN_ERR "3COM 3C359 Velocity XL  card not responding.\n");
 			return -ENODEV; 
 		}
@@ -790,7 +791,7 @@ static int xl_open_hw(struct net_device *dev)
 	t=jiffies;
 	while (! (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) { 
 		schedule();		
-		if(jiffies-t > 40*HZ) {
+		if (time_after(jiffies, t + 40 * HZ)) {
 			printk(KERN_ERR "3COM 3C359 Velocity XL  card not responding.\n");
 			break ; 
 		}
@@ -1003,7 +1004,7 @@ static void xl_reset(struct net_device *dev)
 
 	t=jiffies;
 	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
-		if(jiffies-t > 40*HZ) {
+		if (time_after(jiffies, t + 40 * HZ)) {
 			printk(KERN_ERR "3COM 3C359 Velocity XL  card not responding.\n");
 			break ; 
 		}
@@ -1270,7 +1271,7 @@ static int xl_close(struct net_device *dev)
 	t=jiffies;
 	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
 		schedule();		
-		if(jiffies-t > 10*HZ) {
+		if (time_after(jiffies, t + 10 * HZ)) {
 			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNSTALL not responding.\n", dev->name);
 			break ; 
 		}
@@ -1279,7 +1280,7 @@ static int xl_close(struct net_device *dev)
 	t=jiffies;
 	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
 		schedule();		
-		if(jiffies-t > 10*HZ) {
+		if (time_after(jiffies, t + 10 * HZ)) {
 			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNDISABLE not responding.\n", dev->name);
 			break ;
 		}
@@ -1288,7 +1289,7 @@ static int xl_close(struct net_device *dev)
 	t=jiffies;
 	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
 		schedule();		
-		if(jiffies-t > 10*HZ) {
+		if (time_after(jiffies, t + 10 * HZ)) {
 			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPSTALL not responding.\n", dev->name);
 			break ; 
 		}
@@ -1305,7 +1306,7 @@ static int xl_close(struct net_device *dev)
 	t=jiffies;
 	while (!(readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_SRB)) { 
 		schedule();		
-		if(jiffies-t > 10*HZ) {
+		if (time_after(jiffies, t + 10 * HZ)) {
 			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-CLOSENIC not responding.\n", dev->name);
 			break ; 
 		}
@@ -1334,7 +1335,7 @@ static int xl_close(struct net_device *dev)
 	t=jiffies;
 	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
 		schedule();		
-		if(jiffies-t > 10*HZ) {
+		if (time_after(jiffies, t + 10 * HZ)) {
 			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-UPRESET not responding.\n", dev->name);
 			break ; 
 		}
@@ -1343,7 +1344,7 @@ static int xl_close(struct net_device *dev)
 	t=jiffies;
 	while (readw(xl_mmio + MMIO_INTSTATUS) & INTSTAT_CMD_IN_PROGRESS) { 
 		schedule();		
-		if(jiffies-t > 10*HZ) {
+		if (time_after(jiffies, t + 10 * HZ)) {
 			printk(KERN_ERR "%s: 3COM 3C359 Velocity XL-DNRESET not responding.\n", dev->name);
 			break ; 
 		}
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index fe6ff3e..2464072 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -770,14 +770,14 @@ static void yellowfin_init_ring(struct net_device *dev)
 		/* Branch on Tx error. */
 		yp->tx_ring[j].dbdma_cmd = cpu_to_le32(CMD_STOP);
 		yp->tx_ring[j].branch_addr = cpu_to_le32(yp->tx_ring_dma +
-			(j+1)*sizeof(struct yellowfin_desc);
+			(j+1)*sizeof(struct yellowfin_desc));
 		j++;
 		if (yp->flags & FullTxStatus) {
 			yp->tx_ring[j].dbdma_cmd =
 				cpu_to_le32(CMD_TXSTATUS | sizeof(*yp->tx_status));
 			yp->tx_ring[j].request_cnt = sizeof(*yp->tx_status);
 			yp->tx_ring[j].addr = cpu_to_le32(yp->tx_status_dma +
-				i*sizeof(struct tx_status_words);
+				i*sizeof(struct tx_status_words));
 		} else {
 			/* Symbios chips write only tx_errs word. */
 			yp->tx_ring[j].dbdma_cmd =
diff --git a/include/linux/arcdevice.h b/include/linux/arcdevice.h
index fde6758..a191607 100644
--- a/include/linux/arcdevice.h
+++ b/include/linux/arcdevice.h
@@ -283,8 +283,8 @@ struct arcnet_local {
 	int next_buf, first_free_buf;
 
 	/* network "reconfiguration" handling */
-	time_t first_recon,	/* time of "first" RECON message to count */
-		last_recon;	/* time of most recent RECON */
+	unsigned long first_recon; /* time of "first" RECON message to count */
+	unsigned long last_recon;  /* time of most recent RECON */
 	int num_recons;		/* number of RECONs between first and last. */
 	bool network_down;	/* do we think the network is down? */
 

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-25 23:34                   ` Marin Mitov
  2008-02-25 23:36                     ` Jeff Garzik
@ 2008-02-26 20:52                     ` David Miller
  1 sibling, 0 replies; 101+ messages in thread
From: David Miller @ 2008-02-26 20:52 UTC (permalink / raw)
  To: mitov; +Cc: jeff, linux-kernel

From: Marin Mitov <mitov@issp.bas.bg>
Date: Tue, 26 Feb 2008 01:34:01 +0200

> On Tuesday 26 February 2008 12:59:04 am you wrote:
> > Divy Le Ray wrote:
> > >> From: "Divy Le Ray" <divy@chelsio.com>
> > >> Date: Wed, 20 Feb 2008 21:57:08 -0800
> > >>
> > >>> The driver is cxgb3 here, it uses LLTX.
> > >>
> > >> That's extremely unfortunate, hopefully you can update it to
> > >> use a model like tg3 and others use.  LLTX is a lost cause
> > >> for hardware device drivers, and in fact we'd like to remove
> > >> it tree wide eventually.
> 
> Just for info: loopback.c uses it too :-)

I know, as I said: "for hardware device drivers" it's a lost
cause.  Loopback is a software device.


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-26  0:13                   ` Divy Le Ray
@ 2008-02-26  0:17                     ` Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2008-02-26  0:17 UTC (permalink / raw)
  To: Divy Le Ray; +Cc: David Miller, krkumar2, linux-kernel, netdev

Divy Le Ray wrote:
> 
>>
>> So, it sounds like Krishna's patch is ok, because the race does not 
>> exist anymore in this driver?
> The first part is right indeed, but the second part is breaking the 
> current usage of txq_stopped and
> the logic that stops and restarts the Tx queue.
> I can submit a patch fixing it. Plese let me know what's more convenient 
> for you.

At this point, yes a fix (with a good patch description) would be 
preferred...

Thanks,

	Jeff




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-25 22:59                 ` Jeff Garzik
  2008-02-25 23:34                   ` Marin Mitov
@ 2008-02-26  0:13                   ` Divy Le Ray
  2008-02-26  0:17                     ` Jeff Garzik
  1 sibling, 1 reply; 101+ messages in thread
From: Divy Le Ray @ 2008-02-26  0:13 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David Miller, krkumar2, linux-kernel, netdev


>
> So, it sounds like Krishna's patch is ok, because the race does not 
> exist anymore in this driver?
The first part is right indeed, but the second part is breaking the 
current usage of txq_stopped and
the logic that stops and restarts the Tx queue.
I can submit a patch fixing it. Plese let me know what's more convenient 
for you.

Cheers,
Divy

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-25 23:34                   ` Marin Mitov
@ 2008-02-25 23:36                     ` Jeff Garzik
  2008-02-26 20:52                     ` David Miller
  1 sibling, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2008-02-25 23:36 UTC (permalink / raw)
  To: Marin Mitov; +Cc: linux-kernel, NetDev

Marin Mitov wrote:
> On Tuesday 26 February 2008 12:59:04 am you wrote:
>> Divy Le Ray wrote:
>>>> From: "Divy Le Ray" <divy@chelsio.com>
>>>> Date: Wed, 20 Feb 2008 21:57:08 -0800
>>>>
>>>>> The driver is cxgb3 here, it uses LLTX.
>>>> That's extremely unfortunate, hopefully you can update it to
>>>> use a model like tg3 and others use.  LLTX is a lost cause
>>>> for hardware device drivers, and in fact we'd like to remove
>>>> it tree wide eventually.
> 
> Just for info: loopback.c uses it too :-)

Yes, we're all aware of this.  Google for "david miller loopback lltx" 
for a few examples...

Also, please do not strip CC's, that's quite annoying.

	Jeff




^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-25 22:59                 ` Jeff Garzik
@ 2008-02-25 23:34                   ` Marin Mitov
  2008-02-25 23:36                     ` Jeff Garzik
  2008-02-26 20:52                     ` David Miller
  2008-02-26  0:13                   ` Divy Le Ray
  1 sibling, 2 replies; 101+ messages in thread
From: Marin Mitov @ 2008-02-25 23:34 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: linux-kernel

On Tuesday 26 February 2008 12:59:04 am you wrote:
> Divy Le Ray wrote:
> >> From: "Divy Le Ray" <divy@chelsio.com>
> >> Date: Wed, 20 Feb 2008 21:57:08 -0800
> >>
> >>> The driver is cxgb3 here, it uses LLTX.
> >>
> >> That's extremely unfortunate, hopefully you can update it to
> >> use a model like tg3 and others use.  LLTX is a lost cause
> >> for hardware device drivers, and in fact we'd like to remove
> >> it tree wide eventually.

Just for info: loopback.c uses it too :-)

> >
> > It sounds like I messed up.
> > cxgb3 does not use LLTX - The Chelsio driver does, thus should be
> > converted.
>
> So, it sounds like Krishna's patch is ok, because the race does not
> exist anymore in this driver?
>
> 	Jeff
>
>
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-21  6:54               ` Divy Le Ray
@ 2008-02-25 22:59                 ` Jeff Garzik
  2008-02-25 23:34                   ` Marin Mitov
  2008-02-26  0:13                   ` Divy Le Ray
  0 siblings, 2 replies; 101+ messages in thread
From: Jeff Garzik @ 2008-02-25 22:59 UTC (permalink / raw)
  To: Divy Le Ray; +Cc: David Miller, krkumar2, linux-kernel, netdev

Divy Le Ray wrote:
>> From: "Divy Le Ray" <divy@chelsio.com>
>> Date: Wed, 20 Feb 2008 21:57:08 -0800
>>
>>> The driver is cxgb3 here, it uses LLTX.
>> That's extremely unfortunate, hopefully you can update it to
>> use a model like tg3 and others use.  LLTX is a lost cause
>> for hardware device drivers, and in fact we'd like to remove
>> it tree wide eventually.
> 
> It sounds like I messed up.
> cxgb3 does not use LLTX - The Chelsio driver does, thus should be
> converted.

So, it sounds like Krishna's patch is ok, because the race does not 
exist anymore in this driver?

	Jeff




^ permalink raw reply	[flat|nested] 101+ messages in thread

* RE: [git patches] net driver updates
  2008-02-21  6:15             ` David Miller
@ 2008-02-21  6:54               ` Divy Le Ray
  2008-02-25 22:59                 ` Jeff Garzik
  0 siblings, 1 reply; 101+ messages in thread
From: Divy Le Ray @ 2008-02-21  6:54 UTC (permalink / raw)
  To: David Miller; +Cc: krkumar2, jeff, linux-kernel, netdev

> From: "Divy Le Ray" <divy@chelsio.com>
> Date: Wed, 20 Feb 2008 21:57:08 -0800
> 
> > The driver is cxgb3 here, it uses LLTX.
> 
> That's extremely unfortunate, hopefully you can update it to
> use a model like tg3 and others use.  LLTX is a lost cause
> for hardware device drivers, and in fact we'd like to remove
> it tree wide eventually.

It sounds like I messed up.
cxgb3 does not use LLTX - The Chelsio driver does, thus should be
converted.

Divy

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-21  5:57           ` Divy Le Ray
  2008-02-21  6:02             ` Krishna Kumar2
@ 2008-02-21  6:15             ` David Miller
  2008-02-21  6:54               ` Divy Le Ray
  1 sibling, 1 reply; 101+ messages in thread
From: David Miller @ 2008-02-21  6:15 UTC (permalink / raw)
  To: divy; +Cc: krkumar2, jeff, linux-kernel, netdev

From: "Divy Le Ray" <divy@chelsio.com>
Date: Wed, 20 Feb 2008 21:57:08 -0800

> The driver is cxgb3 here, it uses LLTX.

That's extremely unfortunate, hopefully you can update it to
use a model like tg3 and others use.  LLTX is a lost cause
for hardware device drivers, and in fact we'd like to remove
it tree wide eventually.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* RE: [git patches] net driver updates
  2008-02-21  5:57           ` Divy Le Ray
@ 2008-02-21  6:02             ` Krishna Kumar2
  2008-02-21  6:15             ` David Miller
  1 sibling, 0 replies; 101+ messages in thread
From: Krishna Kumar2 @ 2008-02-21  6:02 UTC (permalink / raw)
  To: Divy Le Ray; +Cc: David Miller, jeff, linux-kernel, netdev

Hi Divy,

But the race doesn't exist even for LLTX drivers these days. There is no
way two cpu's can execute the xmit handler at the same time.

Thanks,

- KK

> > > > The first part of the patch removes the !netif_queue_stopped(dev).
> > > > It opens the race discussed a while ago between Stephen hemminger
> > and
> > > > David Miller:
> > > > http://marc.info/?l=linux-netdev&m=113383224512427&w=2
> > >
> > > I feel this race cannot happen anymore. I think the fix for that
> race
> > was
> > > to introduce the
> > > __LINK_STATE_QDISC_RUNNING bit thus eliminating any races between
> > CPU's. If
> > > one
> > > CPU has called xmit, the other CPU will enqueue skbs (by holding the
> > > queue_lock) and
> > > exit from qdisc_run since it finds the bit set already.
> >
> > And the race is talking about LLTX, which S2IO doesn't use as
> > far as I can tell.
>
> Dave,
>
> The driver is cxgb3 here, it uses LLTX.
>
> Cheers,
> Divy


^ permalink raw reply	[flat|nested] 101+ messages in thread

* RE: [git patches] net driver updates
  2008-02-21  5:46         ` David Miller
@ 2008-02-21  5:57           ` Divy Le Ray
  2008-02-21  6:02             ` Krishna Kumar2
  2008-02-21  6:15             ` David Miller
  0 siblings, 2 replies; 101+ messages in thread
From: Divy Le Ray @ 2008-02-21  5:57 UTC (permalink / raw)
  To: David Miller, krkumar2; +Cc: jeff, linux-kernel, netdev



> -----Original Message-----
> From: David Miller [mailto:davem@davemloft.net]
> Sent: Wednesday, February 20, 2008 9:47 PM
> To: krkumar2@in.ibm.com
> Cc: Divy Le Ray; jeff@garzik.org; linux-kernel@vger.kernel.org;
> netdev@vger.kernel.org
> Subject: Re: [git patches] net driver updates
> 
> From: Krishna Kumar2 <krkumar2@in.ibm.com>
> Date: Thu, 21 Feb 2008 09:13:49 +0530
> 
> > Hi Divy,
> >
> > > > Explain why, so I can include it in the changelog please...
> > >
> > > Hi Jeff,
> > >
> > > The first part of the patch removes the !netif_queue_stopped(dev).
> > > It opens the race discussed a while ago between Stephen hemminger
> and
> > > David Miller:
> > > http://marc.info/?l=linux-netdev&m=113383224512427&w=2
> >
> > I feel this race cannot happen anymore. I think the fix for that
race
> was
> > to introduce the
> > __LINK_STATE_QDISC_RUNNING bit thus eliminating any races between
> CPU's. If
> > one
> > CPU has called xmit, the other CPU will enqueue skbs (by holding the
> > queue_lock) and
> > exit from qdisc_run since it finds the bit set already.
> 
> And the race is talking about LLTX, which S2IO doesn't use as
> far as I can tell.

Dave,

The driver is cxgb3 here, it uses LLTX.

Cheers,
Divy

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-21  3:43       ` Krishna Kumar2
@ 2008-02-21  5:46         ` David Miller
  2008-02-21  5:57           ` Divy Le Ray
  0 siblings, 1 reply; 101+ messages in thread
From: David Miller @ 2008-02-21  5:46 UTC (permalink / raw)
  To: krkumar2; +Cc: divy, jeff, linux-kernel, netdev

From: Krishna Kumar2 <krkumar2@in.ibm.com>
Date: Thu, 21 Feb 2008 09:13:49 +0530

> Hi Divy,
> 
> > > Explain why, so I can include it in the changelog please...
> >
> > Hi Jeff,
> >
> > The first part of the patch removes the !netif_queue_stopped(dev).
> > It opens the race discussed a while ago between Stephen hemminger and
> > David Miller:
> > http://marc.info/?l=linux-netdev&m=113383224512427&w=2
> 
> I feel this race cannot happen anymore. I think the fix for that race was
> to introduce the
> __LINK_STATE_QDISC_RUNNING bit thus eliminating any races between CPU's. If
> one
> CPU has called xmit, the other CPU will enqueue skbs (by holding the
> queue_lock) and
> exit from qdisc_run since it finds the bit set already.

And the race is talking about LLTX, which S2IO doesn't use as
far as I can tell.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-21  1:16     ` Divy Le Ray
@ 2008-02-21  3:43       ` Krishna Kumar2
  2008-02-21  5:46         ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Krishna Kumar2 @ 2008-02-21  3:43 UTC (permalink / raw)
  To: Divy Le Ray; +Cc: David Miller, Jeff Garzik, LKML, netdev

Hi Divy,

> > Explain why, so I can include it in the changelog please...
>
> Hi Jeff,
>
> The first part of the patch removes the !netif_queue_stopped(dev).
> It opens the race discussed a while ago between Stephen hemminger and
> David Miller:
> http://marc.info/?l=linux-netdev&m=113383224512427&w=2

I feel this race cannot happen anymore. I think the fix for that race was
to introduce the
__LINK_STATE_QDISC_RUNNING bit thus eliminating any races between CPU's. If
one
CPU has called xmit, the other CPU will enqueue skbs (by holding the
queue_lock) and
exit from qdisc_run since it finds the bit set already.

Thanks,

- KK


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-20 20:38   ` Jeff Garzik
@ 2008-02-21  1:16     ` Divy Le Ray
  2008-02-21  3:43       ` Krishna Kumar2
  0 siblings, 1 reply; 101+ messages in thread
From: Divy Le Ray @ 2008-02-21  1:16 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David Miller, netdev, LKML

Jeff Garzik wrote:
> Divy Le Ray wrote:
>> Jeff Garzik wrote:
>>> Mostly fixes, a few cleanups (generally assisting fixes), and an
>>> exception for PS3 wireless because it had been posted, reviewed and
>>> acked for a while, just not committed.
>>>
>>> Please pull from 'upstream-davem' branch of
>>> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git 
>>> upstream-davem
>>>
>>> to receive the following updates:
>>>
>>>  
>>>  drivers/net/cxgb3/sge.c          |   35 +-
>>>    diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
>>> index 9ca8c66..979f3fc 100644
>>> --- a/drivers/net/cxgb3/sge.c
>>> +++ b/drivers/net/cxgb3/sge.c
>>> @@ -1059,6 +1059,14 @@ static void write_tx_pkt_wr(struct adapter 
>>> *adap, struct sk_buff *skb,
>>>               htonl(V_WR_TID(q->token)));
>>>  }
>>>  
>>> +static inline void t3_stop_queue(struct net_device *dev, struct 
>>> sge_qset *qs,
>>> +                 struct sge_txq *q)
>>> +{
>>> +    netif_stop_queue(dev);
>>> +    set_bit(TXQ_ETH, &qs->txq_stopped);
>>> +    q->stops++;
>>> +}
>>> +
>>>  /**
>>>   *    eth_xmit - add a packet to the Ethernet Tx queue
>>>   *    @skb: the packet
>>> @@ -1090,31 +1098,18 @@ int t3_eth_xmit(struct sk_buff *skb, struct 
>>> net_device *dev)
>>>      ndesc = calc_tx_descs(skb);
>>>  
>>>      if (unlikely(credits < ndesc)) {
>>> -        if (!netif_queue_stopped(dev)) {
>>> -            netif_stop_queue(dev);
>>> -            set_bit(TXQ_ETH, &qs->txq_stopped);
>>> -            q->stops++;
>>> -            dev_err(&adap->pdev->dev,
>>> -                "%s: Tx ring %u full while queue awake!\n",
>>> -                dev->name, q->cntxt_id & 7);
>>> -        }
>>> +        t3_stop_queue(dev, qs, q);
>>> +        dev_err(&adap->pdev->dev,
>>> +            "%s: Tx ring %u full while queue awake!\n",
>>> +            dev->name, q->cntxt_id & 7);
>>>          spin_unlock(&q->lock);
>>>          return NETDEV_TX_BUSY;
>>>      }
>>>  
>>>      q->in_use += ndesc;
>>> -    if (unlikely(credits - ndesc < q->stop_thres)) {
>>> -        q->stops++;
>>> -        netif_stop_queue(dev);
>>> -        set_bit(TXQ_ETH, &qs->txq_stopped);
>>> -#if !USE_GTS
>>> -        if (should_restart_tx(q) &&
>>> -            test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
>>> -            q->restarts++;
>>> -            netif_wake_queue(dev);
>>> -        }
>>> -#endif
>>> -    }
>>> +    if (unlikely(credits - ndesc < q->stop_thres))
>>> +        if (USE_GTS || !should_restart_tx(q))
>>> +            t3_stop_queue(dev, qs, q);
>>>  
>>>      gen = q->gen;
>>>      q->unacked += ndesc;
>>>   
>> Hi Jeff,
>>
>> I thought I had NAK'ed the patch modifying sge.c from Krishna Kumar.
>> Looking back at my answer at the time, I was obviously unclear.
>> Can you please revert the drivers/net/cxgb3sge.c change ?
>
> Explain why, so I can include it in the changelog please...

Hi Jeff,

The first part of the patch removes the !netif_queue_stopped(dev).
It opens the race discussed a while ago between Stephen hemminger and 
David Miller:
http://marc.info/?l=linux-netdev&m=113383224512427&w=2

The second part of the patch breaks the current usage of txq_stopped and 
the logic that stops and restarts the Tx queue.

Cheers,
Divy


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-11 20:07 ` Divy Le Ray
@ 2008-02-20 20:38   ` Jeff Garzik
  2008-02-21  1:16     ` Divy Le Ray
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2008-02-20 20:38 UTC (permalink / raw)
  To: Divy Le Ray; +Cc: David Miller, netdev, LKML

Divy Le Ray wrote:
> Jeff Garzik wrote:
>> Mostly fixes, a few cleanups (generally assisting fixes), and an
>> exception for PS3 wireless because it had been posted, reviewed and
>> acked for a while, just not committed.
>>
>> Please pull from 'upstream-davem' branch of
>> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git 
>> upstream-davem
>>
>> to receive the following updates:
>>
>>  
>>  drivers/net/cxgb3/sge.c          |   35 +-
>>    
>> diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
>> index 9ca8c66..979f3fc 100644
>> --- a/drivers/net/cxgb3/sge.c
>> +++ b/drivers/net/cxgb3/sge.c
>> @@ -1059,6 +1059,14 @@ static void write_tx_pkt_wr(struct adapter 
>> *adap, struct sk_buff *skb,
>>               htonl(V_WR_TID(q->token)));
>>  }
>>  
>> +static inline void t3_stop_queue(struct net_device *dev, struct 
>> sge_qset *qs,
>> +                 struct sge_txq *q)
>> +{
>> +    netif_stop_queue(dev);
>> +    set_bit(TXQ_ETH, &qs->txq_stopped);
>> +    q->stops++;
>> +}
>> +
>>  /**
>>   *    eth_xmit - add a packet to the Ethernet Tx queue
>>   *    @skb: the packet
>> @@ -1090,31 +1098,18 @@ int t3_eth_xmit(struct sk_buff *skb, struct 
>> net_device *dev)
>>      ndesc = calc_tx_descs(skb);
>>  
>>      if (unlikely(credits < ndesc)) {
>> -        if (!netif_queue_stopped(dev)) {
>> -            netif_stop_queue(dev);
>> -            set_bit(TXQ_ETH, &qs->txq_stopped);
>> -            q->stops++;
>> -            dev_err(&adap->pdev->dev,
>> -                "%s: Tx ring %u full while queue awake!\n",
>> -                dev->name, q->cntxt_id & 7);
>> -        }
>> +        t3_stop_queue(dev, qs, q);
>> +        dev_err(&adap->pdev->dev,
>> +            "%s: Tx ring %u full while queue awake!\n",
>> +            dev->name, q->cntxt_id & 7);
>>          spin_unlock(&q->lock);
>>          return NETDEV_TX_BUSY;
>>      }
>>  
>>      q->in_use += ndesc;
>> -    if (unlikely(credits - ndesc < q->stop_thres)) {
>> -        q->stops++;
>> -        netif_stop_queue(dev);
>> -        set_bit(TXQ_ETH, &qs->txq_stopped);
>> -#if !USE_GTS
>> -        if (should_restart_tx(q) &&
>> -            test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
>> -            q->restarts++;
>> -            netif_wake_queue(dev);
>> -        }
>> -#endif
>> -    }
>> +    if (unlikely(credits - ndesc < q->stop_thres))
>> +        if (USE_GTS || !should_restart_tx(q))
>> +            t3_stop_queue(dev, qs, q);
>>  
>>      gen = q->gen;
>>      q->unacked += ndesc;
>>   
> Hi Jeff,
> 
> I thought I had NAK'ed the patch modifying sge.c from Krishna Kumar.
> Looking back at my answer at the time, I was obviously unclear.
> Can you please revert the drivers/net/cxgb3sge.c change ?

Explain why, so I can include it in the changelog please...

	Jeff





^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-12 12:38 ` Ben Dooks
@ 2008-02-12 16:01   ` Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2008-02-12 16:01 UTC (permalink / raw)
  To: Ben Dooks; +Cc: David Miller, netdev, Laurent Pinchart

Ben Dooks wrote:
> These two where meant to be from Laurent Pinchart, they do have
> the correct signed-off lines in for him and start with "Patch from:". Is
> there any chance of fixing the authour attribution now?

The first line of the changeset mentions it.  Other than that, nope.

	Jeff



^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-11 17:05 Jeff Garzik
  2008-02-11 20:07 ` Divy Le Ray
  2008-02-12  5:57 ` David Miller
@ 2008-02-12 12:38 ` Ben Dooks
  2008-02-12 16:01   ` Jeff Garzik
  2 siblings, 1 reply; 101+ messages in thread
From: Ben Dooks @ 2008-02-12 12:38 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David Miller, netdev, Laurent Pinchart

On Mon, Feb 11, 2008 at 12:05:16PM -0500, Jeff Garzik wrote:
> Mostly fixes, a few cleanups (generally assisting fixes), and an
> exception for PS3 wireless because it had been posted, reviewed and
> acked for a while, just not committed.

Thanks, good to get the DM9000 changes moving.
 
> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem
> 

> Ben Dooks (24):
>       DM9000: Fix endian-ness of data accesses.
>       DM9000: Add platform data to specify external phy

These two where meant to be from Laurent Pinchart, they do have
the correct signed-off lines in for him and start with "Patch from:". Is
there any chance of fixing the authour attribution now?

-- 
Ben (ben@fluff.org, http://www.fluff.org/)

  'a smiley only costs 4 bytes'

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-11 17:05 Jeff Garzik
  2008-02-11 20:07 ` Divy Le Ray
@ 2008-02-12  5:57 ` David Miller
  2008-02-12 12:38 ` Ben Dooks
  2 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2008-02-12  5:57 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Mon, 11 Feb 2008 12:05:16 -0500

> Mostly fixes, a few cleanups (generally assisting fixes), and an
> exception for PS3 wireless because it had been posted, reviewed and
> acked for a while, just not committed.
>
> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem
> 
> to receive the following updates:

Pulled, thanks a lot Jeff!

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-11 17:05 Jeff Garzik
@ 2008-02-11 20:07 ` Divy Le Ray
  2008-02-20 20:38   ` Jeff Garzik
  2008-02-12  5:57 ` David Miller
  2008-02-12 12:38 ` Ben Dooks
  2 siblings, 1 reply; 101+ messages in thread
From: Divy Le Ray @ 2008-02-11 20:07 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: David Miller, netdev, LKML

Jeff Garzik wrote:
> Mostly fixes, a few cleanups (generally assisting fixes), and an
> exception for PS3 wireless because it had been posted, reviewed and
> acked for a while, just not committed.
>
> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem
>
> to receive the following updates:
>
>  
>  drivers/net/cxgb3/sge.c          |   35 +-
>   
>  
> diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
> index 9ca8c66..979f3fc 100644
> --- a/drivers/net/cxgb3/sge.c
> +++ b/drivers/net/cxgb3/sge.c
> @@ -1059,6 +1059,14 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb,
>  			 htonl(V_WR_TID(q->token)));
>  }
>  
> +static inline void t3_stop_queue(struct net_device *dev, struct sge_qset *qs,
> +				 struct sge_txq *q)
> +{
> +	netif_stop_queue(dev);
> +	set_bit(TXQ_ETH, &qs->txq_stopped);
> +	q->stops++;
> +}
> +
>  /**
>   *	eth_xmit - add a packet to the Ethernet Tx queue
>   *	@skb: the packet
> @@ -1090,31 +1098,18 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
>  	ndesc = calc_tx_descs(skb);
>  
>  	if (unlikely(credits < ndesc)) {
> -		if (!netif_queue_stopped(dev)) {
> -			netif_stop_queue(dev);
> -			set_bit(TXQ_ETH, &qs->txq_stopped);
> -			q->stops++;
> -			dev_err(&adap->pdev->dev,
> -				"%s: Tx ring %u full while queue awake!\n",
> -				dev->name, q->cntxt_id & 7);
> -		}
> +		t3_stop_queue(dev, qs, q);
> +		dev_err(&adap->pdev->dev,
> +			"%s: Tx ring %u full while queue awake!\n",
> +			dev->name, q->cntxt_id & 7);
>  		spin_unlock(&q->lock);
>  		return NETDEV_TX_BUSY;
>  	}
>  
>  	q->in_use += ndesc;
> -	if (unlikely(credits - ndesc < q->stop_thres)) {
> -		q->stops++;
> -		netif_stop_queue(dev);
> -		set_bit(TXQ_ETH, &qs->txq_stopped);
> -#if !USE_GTS
> -		if (should_restart_tx(q) &&
> -		    test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
> -			q->restarts++;
> -			netif_wake_queue(dev);
> -		}
> -#endif
> -	}
> +	if (unlikely(credits - ndesc < q->stop_thres))
> +		if (USE_GTS || !should_restart_tx(q))
> +			t3_stop_queue(dev, qs, q);
>  
>  	gen = q->gen;
>  	q->unacked += ndesc;
>   
Hi Jeff,

I thought I had NAK'ed the patch modifying sge.c from Krishna Kumar.
Looking back at my answer at the time, I was obviously unclear.
Can you please revert the drivers/net/cxgb3sge.c change ?

Cheers,
Divy


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2008-02-11 17:05 Jeff Garzik
  2008-02-11 20:07 ` Divy Le Ray
                   ` (2 more replies)
  0 siblings, 3 replies; 101+ messages in thread
From: Jeff Garzik @ 2008-02-11 17:05 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML

Mostly fixes, a few cleanups (generally assisting fixes), and an
exception for PS3 wireless because it had been posted, reviewed and
acked for a while, just not committed.

Please pull from 'upstream-davem' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

to receive the following updates:

 drivers/net/8139too.c            |    2 +-
 drivers/net/Kconfig              |   18 +
 drivers/net/Makefile             |    3 +-
 drivers/net/cxgb3/l2t.c          |    2 +-
 drivers/net/cxgb3/sge.c          |   35 +-
 drivers/net/dm9000.c             |  654 ++++++----
 drivers/net/e1000/e1000_main.c   |   18 +-
 drivers/net/forcedeth.c          |  132 ++-
 drivers/net/ni52.c               | 1142 ++++++++--------
 drivers/net/ni52.h               |  158 ++--
 drivers/net/pcnet32.c            |   48 +-
 drivers/net/phy/fixed.c          |    4 +-
 drivers/net/ps3_gelic_net.c      | 1215 ++++++++++-------
 drivers/net/ps3_gelic_net.h      |  415 ++++--
 drivers/net/ps3_gelic_wireless.c | 2753 ++++++++++++++++++++++++++++++++++++++
 drivers/net/ps3_gelic_wireless.h |  329 +++++
 drivers/net/r6040.c              |  233 ++--
 drivers/net/sis190.c             |    3 +-
 drivers/s390/net/claw.h          |   19 +-
 drivers/s390/net/lcs.c           |    2 +-
 drivers/s390/net/lcs.h           |   16 +-
 drivers/s390/net/netiucv.c       |   29 +-
 include/linux/dm9000.h           |    2 +
 23 files changed, 5440 insertions(+), 1792 deletions(-)
 create mode 100644 drivers/net/ps3_gelic_wireless.c
 create mode 100644 drivers/net/ps3_gelic_wireless.h

Adrian Bunk (1):
      net/phy/fixed.c: fix a use-after-free

Adrian McMenamin (1):
      8139too fix for Dreamcast

Alan Cox (1):
      ni52: Remove 278 scripts/checkpatch errors

Ayaz Abdulla (2):
      forcedeth: tx collision fix
      forcedeth: tx pause watermarks

Ben Dooks (24):
      DM9000: Fix endian-ness of data accesses.
      DM9000: Add platform data to specify external phy
      DM9000 use dev_xxx() instead of printk for output.
      DM9000 update debugging macros to use debug level
      DM9000: Pass IRQ flags via platform resources
      DM9000: Remove old timer based poll routines
      DM9000: Add initial ethtool support
      DM9000: Do not sleep with spinlock and IRQs held
      DM9000: Use msleep() instead of udelay()
      DM9000: Remove barely used SROM array read.
      DM9000: Add mutex to protect access
      DM9000: Add ethtool support for reading and writing EEPROM
      DM9000: Add ethtool control of msg_enable value
      DM9000: Remove EEPROM initialisation code.
      DM9000: Ensure spinlock held whilst accessing EEPROM registers
      DM9000: Remove unnecessary changelog in header comment
      DM9000: Use netif_msg to enable debugging options
      DM9000: Fix delays used by EEPROM read and write
      DM9000: Remove cal_CRC() and use ether_crc_le instead
      DM9000: Remove redudant use of "& 0xff"
      DM9000: Add platform flag for no attached EEPROM
      DM9000: Add support for MII ioctl() calls
      DM9000: Update retry count whilst identifying chip
      DM9000: Show the MAC address source after printing MAC

Benjamin Herrenschmidt (1):
      e1000: Fix for 32 bits platforms with 64 bits resources

Cornelia Huck (1):
      netiucv: Remember to set driver->owner.

Don Fry (2):
      pcnet32: use NET_IP_ALIGN instead of 2
      pcnet32: Use print_mac

Florian Fainelli (4):
      r6040: do not use a private stats structure to store statistics
      r6040: add helpers to allocate and free the Tx/Rx buffers
      r6040: recover from transmit timeout
      r6040: cleanups

Krishna Kumar (1):
      Optimize cxgb3 xmit path (a bit)

Masakazu Mokuno (7):
      PS3: gelic: Fix the wrong dev_id passed
      PS3: gelic: Add endianness macros
      PS3: gelic: code cleanup
      PS3: gelic: remove duplicated ethtool handlers
      PS3: gelic: add support for port link status
      PS3: gelic: Add support for dual network interface
      PS3: gelic: Add wireless support for PS3

Peter Tiedemann (2):
      lcs: avoid/reduce unused s390dbf debug areas.
      claw/lcs/netiucv: check s390dbf level before sprints

Sergio Luis (1):
      drivers/net/sis190: fix section mismatch warning in sis190_get_mac_addr

Steve Wise (1):
      cxgb3: Handle ARP completions that mark neighbors stale.

Ursula Braun (2):
      claw: removal of volatile variables
      netiucv: change name of nop function

diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index eef6fec..be6e918 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -168,7 +168,7 @@ static int debug = -1;
  * Warning: 64K ring has hardware issues and may lock up.
  */
 #if defined(CONFIG_SH_DREAMCAST)
-#define RX_BUF_IDX	1	/* 16K ring */
+#define RX_BUF_IDX 0	/* 8K ring */
 #else
 #define RX_BUF_IDX	2	/* 32K ring */
 #endif
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 50c2b60..f337800 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -931,6 +931,14 @@ config ENC28J60_WRITEVERIFY
 	  Enable the verify after the buffer write useful for debugging purpose.
 	  If unsure, say N.
 
+config DM9000_DEBUGLEVEL
+	int "DM9000 maximum debug level"
+	depends on DM9000
+	default 4
+	help
+	  The maximum level of debugging code compiled into the DM9000
+	  driver.
+
 config SMC911X
 	tristate "SMSC LAN911[5678] support"
 	select CRC32
@@ -2352,6 +2360,16 @@ config GELIC_NET
 	  To compile this driver as a module, choose M here: the
 	  module will be called ps3_gelic.
 
+config GELIC_WIRELESS
+       bool "PS3 Wireless support"
+       depends on GELIC_NET
+       help
+        This option adds the support for the wireless feature of PS3.
+        If you have the wireless-less model of PS3 or have no plan to
+        use wireless feature, disabling this option saves memory.  As
+        the driver automatically distinguishes the models, you can
+        safely enable this option even if you have a wireless-less model.
+
 config GIANFAR
 	tristate "Gianfar Ethernet"
 	depends on FSL_SOC
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 9fc7794..3b1ea32 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -70,7 +70,8 @@ obj-$(CONFIG_BNX2X) += bnx2x.o
 spidernet-y += spider_net.o spider_net_ethtool.o
 obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
 obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
-ps3_gelic-objs += ps3_gelic_net.o
+gelic_wireless-$(CONFIG_GELIC_WIRELESS) += ps3_gelic_wireless.o
+ps3_gelic-objs += ps3_gelic_net.o $(gelic_wireless-y)
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SKY2) += sky2.o
diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c
index 17ed4c3..865faee 100644
--- a/drivers/net/cxgb3/l2t.c
+++ b/drivers/net/cxgb3/l2t.c
@@ -404,7 +404,7 @@ found:
 			if (neigh->nud_state & NUD_FAILED) {
 				arpq = e->arpq_head;
 				e->arpq_head = e->arpq_tail = NULL;
-			} else if (neigh_is_connected(neigh))
+			} else if (neigh->nud_state & (NUD_CONNECTED|NUD_STALE))
 				setup_l2e_send_pending(dev, NULL, e);
 		} else {
 			e->state = neigh_is_connected(neigh) ?
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 9ca8c66..979f3fc 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1059,6 +1059,14 @@ static void write_tx_pkt_wr(struct adapter *adap, struct sk_buff *skb,
 			 htonl(V_WR_TID(q->token)));
 }
 
+static inline void t3_stop_queue(struct net_device *dev, struct sge_qset *qs,
+				 struct sge_txq *q)
+{
+	netif_stop_queue(dev);
+	set_bit(TXQ_ETH, &qs->txq_stopped);
+	q->stops++;
+}
+
 /**
  *	eth_xmit - add a packet to the Ethernet Tx queue
  *	@skb: the packet
@@ -1090,31 +1098,18 @@ int t3_eth_xmit(struct sk_buff *skb, struct net_device *dev)
 	ndesc = calc_tx_descs(skb);
 
 	if (unlikely(credits < ndesc)) {
-		if (!netif_queue_stopped(dev)) {
-			netif_stop_queue(dev);
-			set_bit(TXQ_ETH, &qs->txq_stopped);
-			q->stops++;
-			dev_err(&adap->pdev->dev,
-				"%s: Tx ring %u full while queue awake!\n",
-				dev->name, q->cntxt_id & 7);
-		}
+		t3_stop_queue(dev, qs, q);
+		dev_err(&adap->pdev->dev,
+			"%s: Tx ring %u full while queue awake!\n",
+			dev->name, q->cntxt_id & 7);
 		spin_unlock(&q->lock);
 		return NETDEV_TX_BUSY;
 	}
 
 	q->in_use += ndesc;
-	if (unlikely(credits - ndesc < q->stop_thres)) {
-		q->stops++;
-		netif_stop_queue(dev);
-		set_bit(TXQ_ETH, &qs->txq_stopped);
-#if !USE_GTS
-		if (should_restart_tx(q) &&
-		    test_and_clear_bit(TXQ_ETH, &qs->txq_stopped)) {
-			q->restarts++;
-			netif_wake_queue(dev);
-		}
-#endif
-	}
+	if (unlikely(credits - ndesc < q->stop_thres))
+		if (USE_GTS || !should_restart_tx(q))
+			t3_stop_queue(dev, qs, q);
 
 	gen = q->gen;
 	q->unacked += ndesc;
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 6a20a54..1fe305c 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -1,7 +1,5 @@
 /*
- *   dm9000.c: Version 1.2 03/18/2003
- *
- *         A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
+ *      Davicom DM9000 Fast Ethernet driver for Linux.
  * 	Copyright (C) 1997  Sten Wang
  *
  * 	This program is free software; you can redistribute it and/or
@@ -14,44 +12,11 @@
  * 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * 	GNU General Public License for more details.
  *
- *   (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
- *
- * V0.11	06/20/2001	REG_0A bit3=1, default enable BP with DA match
- * 	06/22/2001 	Support DM9801 progrmming
- * 	 	 	E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
- * 		 	E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
- * 		     		R17 = (R17 & 0xfff0) | NF + 3
- * 		 	E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
- * 		     		R17 = (R17 & 0xfff0) | NF
- *
- * v1.00               	modify by simon 2001.9.5
- *                         change for kernel 2.4.x
- *
- * v1.1   11/09/2001      	fix force mode bug
- *
- * v1.2   03/18/2003       Weilun Huang <weilun_huang@davicom.com.tw>:
- * 			Fixed phy reset.
- * 			Added tx/rx 32 bit mode.
- * 			Cleaned up for kernel merge.
- *
- *        03/03/2004    Sascha Hauer <s.hauer@pengutronix.de>
- *                      Port to 2.6 kernel
- *
- *	  24-Sep-2004   Ben Dooks <ben@simtec.co.uk>
- *			Cleanup of code to remove ifdefs
- *			Allowed platform device data to influence access width
- *			Reformatting areas of code
- *
- *        17-Mar-2005   Sascha Hauer <s.hauer@pengutronix.de>
- *                      * removed 2.4 style module parameters
- *                      * removed removed unused stat counter and fixed
- *                        net_device_stats
- *                      * introduced tx_timeout function
- *                      * reworked locking
+ * (C) Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
  *
- *	  01-Jul-2005   Ben Dooks <ben@simtec.co.uk>
- *			* fixed spinlock call without pointer
- *			* ensure spinlock is initialised
+ * Additional updates, Copyright:
+ *	Ben Dooks <ben@simtec.co.uk>
+ *	Sascha Hauer <s.hauer@pengutronix.de>
  */
 
 #include <linux/module.h>
@@ -63,6 +28,7 @@
 #include <linux/spinlock.h>
 #include <linux/crc32.h>
 #include <linux/mii.h>
+#include <linux/ethtool.h>
 #include <linux/dm9000.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
@@ -80,30 +46,7 @@
 
 #define CARDNAME "dm9000"
 #define PFX CARDNAME ": "
-
-#define DM9000_TIMER_WUT  jiffies+(HZ*2)	/* timer wakeup time : 2 second */
-
-#define DM9000_DEBUG 0
-
-#if DM9000_DEBUG > 2
-#define PRINTK3(args...)  printk(CARDNAME ": " args)
-#else
-#define PRINTK3(args...)  do { } while(0)
-#endif
-
-#if DM9000_DEBUG > 1
-#define PRINTK2(args...)  printk(CARDNAME ": " args)
-#else
-#define PRINTK2(args...)  do { } while(0)
-#endif
-
-#if DM9000_DEBUG > 0
-#define PRINTK1(args...)  printk(CARDNAME ": " args)
-#define PRINTK(args...)   printk(CARDNAME ": " args)
-#else
-#define PRINTK1(args...)  do { } while(0)
-#define PRINTK(args...)   printk(KERN_DEBUG args)
-#endif
+#define DRV_VERSION	"1.30"
 
 #ifdef CONFIG_BLACKFIN
 #define readsb	insb
@@ -112,9 +55,9 @@
 #define writesb	outsb
 #define writesw	outsw
 #define writesl	outsl
-#define DM9000_IRQ_FLAGS	(IRQF_SHARED | IRQF_TRIGGER_HIGH)
+#define DEFAULT_TRIGGER IRQF_TRIGGER_HIGH
 #else
-#define DM9000_IRQ_FLAGS	(IRQF_SHARED | IRQT_RISING)
+#define DEFAULT_TRIGGER (0)
 #endif
 
 /*
@@ -124,6 +67,24 @@ static int watchdog = 5000;
 module_param(watchdog, int, 0400);
 MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
 
+/* DM9000 register address locking.
+ *
+ * The DM9000 uses an address register to control where data written
+ * to the data register goes. This means that the address register
+ * must be preserved over interrupts or similar calls.
+ *
+ * During interrupt and other critical calls, a spinlock is used to
+ * protect the system, but the calls themselves save the address
+ * in the address register in case they are interrupting another
+ * access to the device.
+ *
+ * For general accesses a lock is provided so that calls which are
+ * allowed to sleep are serialised so that the address register does
+ * not need to be saved. This lock also serves to serialise access
+ * to the EEPROM and PHY access registers which are shared between
+ * these two devices.
+ */
+
 /* Structure/enum declaration ------------------------------- */
 typedef struct board_info {
 
@@ -137,33 +98,52 @@ typedef struct board_info {
 	u16 dbug_cnt;
 	u8 io_mode;		/* 0:word, 2:byte */
 	u8 phy_addr;
+	unsigned int flags;
+	unsigned int in_suspend :1;
+
+	int debug_level;
 
 	void (*inblk)(void __iomem *port, void *data, int length);
 	void (*outblk)(void __iomem *port, void *data, int length);
 	void (*dumpblk)(void __iomem *port, int length);
 
+	struct device	*dev;	     /* parent device */
+
 	struct resource	*addr_res;   /* resources found */
 	struct resource *data_res;
 	struct resource	*addr_req;   /* resources requested */
 	struct resource *data_req;
 	struct resource *irq_res;
 
-	struct timer_list timer;
-	unsigned char srom[128];
+	struct mutex	 addr_lock;	/* phy and eeprom access lock */
+
 	spinlock_t lock;
 
 	struct mii_if_info mii;
 	u32 msg_enable;
 } board_info_t;
 
+/* debug code */
+
+#define dm9000_dbg(db, lev, msg...) do {		\
+	if ((lev) < CONFIG_DM9000_DEBUGLEVEL &&		\
+	    (lev) < db->debug_level) {			\
+		dev_dbg(db->dev, msg);			\
+	}						\
+} while (0)
+
+static inline board_info_t *to_dm9000_board(struct net_device *dev)
+{
+	return dev->priv;
+}
+
 /* function declaration ------------------------------------- */
 static int dm9000_probe(struct platform_device *);
 static int dm9000_open(struct net_device *);
 static int dm9000_start_xmit(struct sk_buff *, struct net_device *);
 static int dm9000_stop(struct net_device *);
+static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd);
 
-
-static void dm9000_timer(unsigned long);
 static void dm9000_init_dm9000(struct net_device *);
 
 static irqreturn_t dm9000_interrupt(int, void *);
@@ -171,20 +151,19 @@ static irqreturn_t dm9000_interrupt(int, void *);
 static int dm9000_phy_read(struct net_device *dev, int phyaddr_unsused, int reg);
 static void dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg,
 			   int value);
-static u16 read_srom_word(board_info_t *, int);
+
+static void dm9000_read_eeprom(board_info_t *, int addr, u8 *to);
+static void dm9000_write_eeprom(board_info_t *, int addr, u8 *dp);
 static void dm9000_rx(struct net_device *);
 static void dm9000_hash_table(struct net_device *);
 
-//#define DM9000_PROGRAM_EEPROM
-#ifdef DM9000_PROGRAM_EEPROM
-static void program_eeprom(board_info_t * db);
-#endif
 /* DM9000 network board routine ---------------------------- */
 
 static void
 dm9000_reset(board_info_t * db)
 {
-	PRINTK1("dm9000x: resetting\n");
+	dev_dbg(db->dev, "resetting device\n");
+
 	/* RESET device */
 	writeb(DM9000_NCR, db->io_addr);
 	udelay(200);
@@ -300,14 +279,10 @@ static void dm9000_set_io(struct board_info *db, int byte_width)
 		db->inblk   = dm9000_inblk_8bit;
 		break;
 
-	case 2:
-		db->dumpblk = dm9000_dumpblk_16bit;
-		db->outblk  = dm9000_outblk_16bit;
-		db->inblk   = dm9000_inblk_16bit;
-		break;
 
 	case 3:
-		printk(KERN_ERR PFX ": 3 byte IO, falling back to 16bit\n");
+		dev_dbg(db->dev, ": 3 byte IO, falling back to 16bit\n");
+	case 2:
 		db->dumpblk = dm9000_dumpblk_16bit;
 		db->outblk  = dm9000_outblk_16bit;
 		db->inblk   = dm9000_inblk_16bit;
@@ -358,6 +333,139 @@ static void dm9000_poll_controller(struct net_device *dev)
 }
 #endif
 
+static int dm9000_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	return generic_mii_ioctl(&dm->mii, if_mii(req), cmd, NULL);
+}
+
+/* ethtool ops */
+
+static void dm9000_get_drvinfo(struct net_device *dev,
+			       struct ethtool_drvinfo *info)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+
+	strcpy(info->driver, CARDNAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->bus_info, to_platform_device(dm->dev)->name);
+}
+
+static u32 dm9000_get_msglevel(struct net_device *dev)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+
+	return dm->msg_enable;
+}
+
+static void dm9000_set_msglevel(struct net_device *dev, u32 value)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+
+	dm->msg_enable = value;
+}
+
+static int dm9000_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+
+	mii_ethtool_gset(&dm->mii, cmd);
+	return 0;
+}
+
+static int dm9000_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+
+	return mii_ethtool_sset(&dm->mii, cmd);
+}
+
+static int dm9000_nway_reset(struct net_device *dev)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+	return mii_nway_restart(&dm->mii);
+}
+
+static u32 dm9000_get_link(struct net_device *dev)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+	return mii_link_ok(&dm->mii);
+}
+
+#define DM_EEPROM_MAGIC		(0x444D394B)
+
+static int dm9000_get_eeprom_len(struct net_device *dev)
+{
+	return 128;
+}
+
+static int dm9000_get_eeprom(struct net_device *dev,
+			     struct ethtool_eeprom *ee, u8 *data)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+	int offset = ee->offset;
+	int len = ee->len;
+	int i;
+
+	/* EEPROM access is aligned to two bytes */
+
+	if ((len & 1) != 0 || (offset & 1) != 0)
+		return -EINVAL;
+
+	if (dm->flags & DM9000_PLATF_NO_EEPROM)
+		return -ENOENT;
+
+	ee->magic = DM_EEPROM_MAGIC;
+
+	for (i = 0; i < len; i += 2)
+		dm9000_read_eeprom(dm, (offset + i) / 2, data + i);
+
+	return 0;
+}
+
+static int dm9000_set_eeprom(struct net_device *dev,
+			     struct ethtool_eeprom *ee, u8 *data)
+{
+	board_info_t *dm = to_dm9000_board(dev);
+	int offset = ee->offset;
+	int len = ee->len;
+	int i;
+
+	/* EEPROM access is aligned to two bytes */
+
+	if ((len & 1) != 0 || (offset & 1) != 0)
+		return -EINVAL;
+
+	if (dm->flags & DM9000_PLATF_NO_EEPROM)
+		return -ENOENT;
+
+	if (ee->magic != DM_EEPROM_MAGIC)
+		return -EINVAL;
+
+	for (i = 0; i < len; i += 2)
+		dm9000_write_eeprom(dm, (offset + i) / 2, data + i);
+
+	return 0;
+}
+
+static const struct ethtool_ops dm9000_ethtool_ops = {
+	.get_drvinfo		= dm9000_get_drvinfo,
+	.get_settings		= dm9000_get_settings,
+	.set_settings		= dm9000_set_settings,
+	.get_msglevel		= dm9000_get_msglevel,
+	.set_msglevel		= dm9000_set_msglevel,
+	.nway_reset		= dm9000_nway_reset,
+	.get_link		= dm9000_get_link,
+ 	.get_eeprom_len		= dm9000_get_eeprom_len,
+ 	.get_eeprom		= dm9000_get_eeprom,
+ 	.set_eeprom		= dm9000_set_eeprom,
+};
+
+
 /* dm9000_release_board
  *
  * release a board, and any mapped resources
@@ -401,6 +509,7 @@ dm9000_probe(struct platform_device *pdev)
 	struct dm9000_plat_data *pdata = pdev->dev.platform_data;
 	struct board_info *db;	/* Point a board information structure */
 	struct net_device *ndev;
+	const unsigned char *mac_src;
 	unsigned long base;
 	int ret = 0;
 	int iosize;
@@ -410,19 +519,22 @@ dm9000_probe(struct platform_device *pdev)
 	/* Init network device */
 	ndev = alloc_etherdev(sizeof (struct board_info));
 	if (!ndev) {
-		printk("%s: could not allocate device.\n", CARDNAME);
+		dev_err(&pdev->dev, "could not allocate device.\n");
 		return -ENOMEM;
 	}
 
 	SET_NETDEV_DEV(ndev, &pdev->dev);
 
-	PRINTK2("dm9000_probe()");
+	dev_dbg(&pdev->dev, "dm9000_probe()");
 
 	/* setup board info structure */
 	db = (struct board_info *) ndev->priv;
 	memset(db, 0, sizeof (*db));
 
+	db->dev = &pdev->dev;
+
 	spin_lock_init(&db->lock);
+	mutex_init(&db->addr_lock);
 
 	if (pdev->num_resources < 2) {
 		ret = -ENODEV;
@@ -450,7 +562,7 @@ dm9000_probe(struct platform_device *pdev)
 
 		if (db->addr_res == NULL || db->data_res == NULL ||
 		    db->irq_res == NULL) {
-			printk(KERN_ERR PFX "insufficient resources\n");
+			dev_err(db->dev, "insufficient resources\n");
 			ret = -ENOENT;
 			goto out;
 		}
@@ -460,7 +572,7 @@ dm9000_probe(struct platform_device *pdev)
 						  pdev->name);
 
 		if (db->addr_req == NULL) {
-			printk(KERN_ERR PFX "cannot claim address reg area\n");
+			dev_err(db->dev, "cannot claim address reg area\n");
 			ret = -EIO;
 			goto out;
 		}
@@ -468,7 +580,7 @@ dm9000_probe(struct platform_device *pdev)
 		db->io_addr = ioremap(db->addr_res->start, i);
 
 		if (db->io_addr == NULL) {
-			printk(KERN_ERR "failed to ioremap address reg\n");
+			dev_err(db->dev, "failed to ioremap address reg\n");
 			ret = -EINVAL;
 			goto out;
 		}
@@ -478,7 +590,7 @@ dm9000_probe(struct platform_device *pdev)
 						  pdev->name);
 
 		if (db->data_req == NULL) {
-			printk(KERN_ERR PFX "cannot claim data reg area\n");
+			dev_err(db->dev, "cannot claim data reg area\n");
 			ret = -EIO;
 			goto out;
 		}
@@ -486,7 +598,7 @@ dm9000_probe(struct platform_device *pdev)
 		db->io_data = ioremap(db->data_res->start, iosize);
 
 		if (db->io_data == NULL) {
-			printk(KERN_ERR "failed to ioremap data reg\n");
+			dev_err(db->dev,"failed to ioremap data reg\n");
 			ret = -EINVAL;
 			goto out;
 		}
@@ -525,12 +637,14 @@ dm9000_probe(struct platform_device *pdev)
 
 		if (pdata->dumpblk != NULL)
 			db->dumpblk = pdata->dumpblk;
+
+		db->flags = pdata->flags;
 	}
 
 	dm9000_reset(db);
 
 	/* try two times, DM9000 sometimes gets the first read wrong */
-	for (i = 0; i < 2; i++) {
+	for (i = 0; i < 8; i++) {
 		id_val  = ior(db, DM9000_VIDL);
 		id_val |= (u32)ior(db, DM9000_VIDH) << 8;
 		id_val |= (u32)ior(db, DM9000_PIDL) << 16;
@@ -538,11 +652,11 @@ dm9000_probe(struct platform_device *pdev)
 
 		if (id_val == DM9000_ID)
 			break;
-		printk("%s: read wrong id 0x%08x\n", CARDNAME, id_val);
+		dev_err(db->dev, "read wrong id 0x%08x\n", id_val);
 	}
 
 	if (id_val != DM9000_ID) {
-		printk("%s: wrong id: 0x%08x\n", CARDNAME, id_val);
+		dev_err(db->dev, "wrong id: 0x%08x\n", id_val);
 		ret = -ENODEV;
 		goto out;
 	}
@@ -558,13 +672,13 @@ dm9000_probe(struct platform_device *pdev)
 	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
 	ndev->stop		 = &dm9000_stop;
 	ndev->set_multicast_list = &dm9000_hash_table;
+	ndev->ethtool_ops	 = &dm9000_ethtool_ops;
+	ndev->do_ioctl		 = &dm9000_ioctl;
+
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	ndev->poll_controller	 = &dm9000_poll_controller;
 #endif
 
-#ifdef DM9000_PROGRAM_EEPROM
-	program_eeprom(db);
-#endif
 	db->msg_enable       = NETIF_MSG_LINK;
 	db->mii.phy_id_mask  = 0x1f;
 	db->mii.reg_num_mask = 0x1f;
@@ -574,38 +688,37 @@ dm9000_probe(struct platform_device *pdev)
 	db->mii.mdio_read    = dm9000_phy_read;
 	db->mii.mdio_write   = dm9000_phy_write;
 
-	/* Read SROM content */
-	for (i = 0; i < 64; i++)
-		((u16 *) db->srom)[i] = read_srom_word(db, i);
+	mac_src = "eeprom";
 
-	/* Set Node Address */
-	for (i = 0; i < 6; i++)
-		ndev->dev_addr[i] = db->srom[i];
+	/* try reading the node address from the attached EEPROM */
+	for (i = 0; i < 6; i += 2)
+		dm9000_read_eeprom(db, i / 2, ndev->dev_addr+i);
 
 	if (!is_valid_ether_addr(ndev->dev_addr)) {
 		/* try reading from mac */
-
+		
+		mac_src = "chip";
 		for (i = 0; i < 6; i++)
 			ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
 	}
 
 	if (!is_valid_ether_addr(ndev->dev_addr))
-		printk("%s: Invalid ethernet MAC address.  Please "
-		       "set using ifconfig\n", ndev->name);
+		dev_warn(db->dev, "%s: Invalid ethernet MAC address. Please "
+			 "set using ifconfig\n", ndev->name);
 
 	platform_set_drvdata(pdev, ndev);
 	ret = register_netdev(ndev);
 
 	if (ret == 0) {
 		DECLARE_MAC_BUF(mac);
-		printk("%s: dm9000 at %p,%p IRQ %d MAC: %s\n",
+		printk("%s: dm9000 at %p,%p IRQ %d MAC: %s (%s)\n",
 		       ndev->name,  db->io_addr, db->io_data, ndev->irq,
-		       print_mac(mac, ndev->dev_addr));
+		       print_mac(mac, ndev->dev_addr), mac_src);
 	}
 	return 0;
 
 out:
-	printk("%s: not found (%d).\n", CARDNAME, ret);
+	dev_err(db->dev, "not found (%d).\n", ret);
 
 	dm9000_release_board(pdev, db);
 	free_netdev(ndev);
@@ -621,10 +734,22 @@ static int
 dm9000_open(struct net_device *dev)
 {
 	board_info_t *db = (board_info_t *) dev->priv;
+	unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
 
-	PRINTK2("entering dm9000_open\n");
+	if (netif_msg_ifup(db))
+		dev_dbg(db->dev, "enabling %s\n", dev->name);
 
-	if (request_irq(dev->irq, &dm9000_interrupt, DM9000_IRQ_FLAGS, dev->name, dev))
+	/* If there is no IRQ type specified, default to something that
+	 * may work, and tell the user that this is a problem */
+
+	if (irqflags == IRQF_TRIGGER_NONE) {
+		dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
+		irqflags = DEFAULT_TRIGGER;
+	}
+	
+	irqflags |= IRQF_SHARED;
+
+	if (request_irq(dev->irq, &dm9000_interrupt, irqflags, dev->name, dev))
 		return -EAGAIN;
 
 	/* Initialize DM9000 board */
@@ -634,13 +759,6 @@ dm9000_open(struct net_device *dev)
 	/* Init driver variable */
 	db->dbug_cnt = 0;
 
-	/* set and active a timer process */
-	init_timer(&db->timer);
-	db->timer.expires  = DM9000_TIMER_WUT;
-	db->timer.data     = (unsigned long) dev;
-	db->timer.function = &dm9000_timer;
-	add_timer(&db->timer);
-
 	mii_check_media(&db->mii, netif_msg_link(db), 1);
 	netif_start_queue(dev);
 
@@ -655,7 +773,7 @@ dm9000_init_dm9000(struct net_device *dev)
 {
 	board_info_t *db = (board_info_t *) dev->priv;
 
-	PRINTK1("entering %s\n",__FUNCTION__);
+	dm9000_dbg(db, 1, "entering %s\n", __func__);
 
 	/* I/O mode */
 	db->io_mode = ior(db, DM9000_ISR) >> 6;	/* ISR bit7:6 keeps I/O mode */
@@ -665,6 +783,9 @@ dm9000_init_dm9000(struct net_device *dev)
 	iow(db, DM9000_GPCR, GPCR_GEP_CNTL);	/* Let GPIO0 output */
 	iow(db, DM9000_GPR, 0);	/* Enable PHY */
 
+	if (db->flags & DM9000_PLATF_EXT_PHY)
+		iow(db, DM9000_NCR, NCR_EXT_PHY);
+
 	/* Program operating register */
 	iow(db, DM9000_TCR, 0);	        /* TX Polling clear */
 	iow(db, DM9000_BPTR, 0x3f);	/* Less 3Kb, 200us */
@@ -698,7 +819,7 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	unsigned long flags;
 	board_info_t *db = (board_info_t *) dev->priv;
 
-	PRINTK3("dm9000_start_xmit\n");
+	dm9000_dbg(db, 3, "%s:\n", __func__);
 
 	if (db->tx_pkt_cnt > 1)
 		return 1;
@@ -715,8 +836,8 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* TX control: First packet immediately send, second packet queue */
 	if (db->tx_pkt_cnt == 1) {
 		/* Set TX length to DM9000 */
-		iow(db, DM9000_TXPLL, skb->len & 0xff);
-		iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff);
+		iow(db, DM9000_TXPLL, skb->len);
+		iow(db, DM9000_TXPLH, skb->len >> 8);
 
 		/* Issue TX polling command */
 		iow(db, DM9000_TCR, TCR_TXREQ);	/* Cleared after TX complete */
@@ -757,10 +878,8 @@ dm9000_stop(struct net_device *ndev)
 {
 	board_info_t *db = (board_info_t *) ndev->priv;
 
-	PRINTK1("entering %s\n",__FUNCTION__);
-
-	/* deleted timer */
-	del_timer(&db->timer);
+	if (netif_msg_ifdown(db))
+		dev_dbg(db->dev, "shutting down %s\n", ndev->name);
 
 	netif_stop_queue(ndev);
 	netif_carrier_off(ndev);
@@ -788,10 +907,13 @@ dm9000_tx_done(struct net_device *dev, board_info_t * db)
 		db->tx_pkt_cnt--;
 		dev->stats.tx_packets++;
 
+		if (netif_msg_tx_done(db))
+			dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);
+
 		/* Queue packet check & send */
 		if (db->tx_pkt_cnt > 0) {
-			iow(db, DM9000_TXPLL, db->queue_pkt_len & 0xff);
-			iow(db, DM9000_TXPLH, (db->queue_pkt_len >> 8) & 0xff);
+			iow(db, DM9000_TXPLL, db->queue_pkt_len);
+			iow(db, DM9000_TXPLH, db->queue_pkt_len >> 8);
 			iow(db, DM9000_TCR, TCR_TXREQ);
 			dev->trans_start = jiffies;
 		}
@@ -803,19 +925,14 @@ static irqreturn_t
 dm9000_interrupt(int irq, void *dev_id)
 {
 	struct net_device *dev = dev_id;
-	board_info_t *db;
+	board_info_t *db = (board_info_t *) dev->priv;
 	int int_status;
 	u8 reg_save;
 
-	PRINTK3("entering %s\n",__FUNCTION__);
-
-	if (!dev) {
-		PRINTK1("dm9000_interrupt() without DEVICE arg\n");
-		return IRQ_HANDLED;
-	}
+	dm9000_dbg(db, 3, "entering %s\n", __func__);
 
 	/* A real interrupt coming */
-	db = (board_info_t *) dev->priv;
+
 	spin_lock(&db->lock);
 
 	/* Save previous register address */
@@ -828,6 +945,9 @@ dm9000_interrupt(int irq, void *dev_id)
 	int_status = ior(db, DM9000_ISR);	/* Got ISR */
 	iow(db, DM9000_ISR, int_status);	/* Clear ISR status */
 
+	if (netif_msg_intr(db))
+		dev_dbg(db->dev, "interrupt status %02x\n", int_status);
+
 	/* Received the coming packet */
 	if (int_status & ISR_PRS)
 		dm9000_rx(dev);
@@ -847,27 +967,9 @@ dm9000_interrupt(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-/*
- *  A periodic timer routine
- *  Dynamic media sense, allocated Rx buffer...
- */
-static void
-dm9000_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *) data;
-	board_info_t *db = (board_info_t *) dev->priv;
-
-	PRINTK3("dm9000_timer()\n");
-
-	mii_check_media(&db->mii, netif_msg_link(db), 0);
-
-	/* Set timer again */
-	db->timer.expires = DM9000_TIMER_WUT;
-	add_timer(&db->timer);
-}
-
 struct dm9000_rxhdr {
-	u16	RxStatus;
+	u8	RxPktReady;
+	u8	RxStatus;
 	u16	RxLen;
 } __attribute__((__packed__));
 
@@ -893,7 +995,7 @@ dm9000_rx(struct net_device *dev)
 
 		/* Status check: this byte must be 0 or 1 */
 		if (rxbyte > DM9000_PKT_RDY) {
-			printk("status check failed: %d\n", rxbyte);
+			dev_warn(db->dev, "status check fail: %d\n", rxbyte);
 			iow(db, DM9000_RCR, 0x00);	/* Stop Device */
 			iow(db, DM9000_ISR, IMR_PAR);	/* Stop INT request */
 			return;
@@ -908,30 +1010,38 @@ dm9000_rx(struct net_device *dev)
 
 		(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));
 
-		RxLen = rxhdr.RxLen;
+		RxLen = le16_to_cpu(rxhdr.RxLen);
+
+		if (netif_msg_rx_status(db))
+			dev_dbg(db->dev, "RX: status %02x, length %04x\n",
+				rxhdr.RxStatus, RxLen);
 
 		/* Packet Status check */
 		if (RxLen < 0x40) {
 			GoodPacket = false;
-			PRINTK1("Bad Packet received (runt)\n");
+			if (netif_msg_rx_err(db))
+				dev_dbg(db->dev, "RX: Bad Packet (runt)\n");
 		}
 
 		if (RxLen > DM9000_PKT_MAX) {
-			PRINTK1("RST: RX Len:%x\n", RxLen);
+			dev_dbg(db->dev, "RST: RX Len:%x\n", RxLen);
 		}
 
-		if (rxhdr.RxStatus & 0xbf00) {
+		if (rxhdr.RxStatus & 0xbf) {
 			GoodPacket = false;
-			if (rxhdr.RxStatus & 0x100) {
-				PRINTK1("fifo error\n");
+			if (rxhdr.RxStatus & 0x01) {
+				if (netif_msg_rx_err(db))
+					dev_dbg(db->dev, "fifo error\n");
 				dev->stats.rx_fifo_errors++;
 			}
-			if (rxhdr.RxStatus & 0x200) {
-				PRINTK1("crc error\n");
+			if (rxhdr.RxStatus & 0x02) {
+				if (netif_msg_rx_err(db))
+					dev_dbg(db->dev, "crc error\n");
 				dev->stats.rx_crc_errors++;
 			}
-			if (rxhdr.RxStatus & 0x8000) {
-				PRINTK1("length error\n");
+			if (rxhdr.RxStatus & 0x80) {
+				if (netif_msg_rx_err(db))
+					dev_dbg(db->dev, "length error\n");
 				dev->stats.rx_length_errors++;
 			}
 		}
@@ -960,72 +1070,119 @@ dm9000_rx(struct net_device *dev)
 	} while (rxbyte == DM9000_PKT_RDY);
 }
 
-/*
- *  Read a word data from SROM
- */
-static u16
-read_srom_word(board_info_t * db, int offset)
+static unsigned int
+dm9000_read_locked(board_info_t *db, int reg)
 {
-	iow(db, DM9000_EPAR, offset);
-	iow(db, DM9000_EPCR, EPCR_ERPRR);
-	mdelay(8);		/* according to the datasheet 200us should be enough,
-				   but it doesn't work */
-	iow(db, DM9000_EPCR, 0x0);
-	return (ior(db, DM9000_EPDRL) + (ior(db, DM9000_EPDRH) << 8));
+	unsigned long flags;
+	unsigned int ret;
+
+	spin_lock_irqsave(&db->lock, flags);
+	ret = ior(db, reg);
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	return ret;
+}
+
+static int dm9000_wait_eeprom(board_info_t *db)
+{
+	unsigned int status;
+	int timeout = 8;	/* wait max 8msec */
+
+	/* The DM9000 data sheets say we should be able to
+	 * poll the ERRE bit in EPCR to wait for the EEPROM
+	 * operation. From testing several chips, this bit
+	 * does not seem to work. 
+	 *
+	 * We attempt to use the bit, but fall back to the
+	 * timeout (which is why we do not return an error
+	 * on expiry) to say that the EEPROM operation has
+	 * completed.
+	 */
+
+	while (1) {
+		status = dm9000_read_locked(db, DM9000_EPCR);
+
+		if ((status & EPCR_ERRE) == 0)
+			break;
+
+		if (timeout-- < 0) {
+			dev_dbg(db->dev, "timeout waiting EEPROM\n");
+			break;
+		}
+	}
+
+	return 0;
 }
 
-#ifdef DM9000_PROGRAM_EEPROM
 /*
- * Write a word data to SROM
+ *  Read a word data from EEPROM
  */
 static void
-write_srom_word(board_info_t * db, int offset, u16 val)
+dm9000_read_eeprom(board_info_t *db, int offset, u8 *to)
 {
+	unsigned long flags;
+
+	if (db->flags & DM9000_PLATF_NO_EEPROM) {
+		to[0] = 0xff;
+		to[1] = 0xff;
+		return;
+	}
+
+	mutex_lock(&db->addr_lock);
+
+	spin_lock_irqsave(&db->lock, flags);
+
 	iow(db, DM9000_EPAR, offset);
-	iow(db, DM9000_EPDRH, ((val >> 8) & 0xff));
-	iow(db, DM9000_EPDRL, (val & 0xff));
-	iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
-	mdelay(8);		/* same shit */
-	iow(db, DM9000_EPCR, 0);
+	iow(db, DM9000_EPCR, EPCR_ERPRR);
+
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	dm9000_wait_eeprom(db);
+
+	/* delay for at-least 150uS */
+	msleep(1);
+
+	spin_lock_irqsave(&db->lock, flags);
+
+	iow(db, DM9000_EPCR, 0x0);
+
+	to[0] = ior(db, DM9000_EPDRL);
+	to[1] = ior(db, DM9000_EPDRH);
+
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	mutex_unlock(&db->addr_lock);
 }
 
 /*
- * Only for development:
- * Here we write static data to the eeprom in case
- * we don't have valid content on a new board
+ * Write a word data to SROM
  */
 static void
-program_eeprom(board_info_t * db)
+dm9000_write_eeprom(board_info_t *db, int offset, u8 *data)
 {
-	u16 eeprom[] = { 0x0c00, 0x007f, 0x1300,	/* MAC Address */
-		0x0000,		/* Autoload: accept nothing */
-		0x0a46, 0x9000,	/* Vendor / Product ID */
-		0x0000,		/* pin control */
-		0x0000,
-	};			/* Wake-up mode control */
-	int i;
-	for (i = 0; i < 8; i++)
-		write_srom_word(db, i, eeprom[i]);
-}
-#endif
+	unsigned long flags;
 
+	if (db->flags & DM9000_PLATF_NO_EEPROM)
+		return;
 
-/*
- *  Calculate the CRC valude of the Rx packet
- *  flag = 1 : return the reverse CRC (for the received packet CRC)
- *         0 : return the normal CRC (for Hash Table index)
- */
+	mutex_lock(&db->addr_lock);
 
-static unsigned long
-cal_CRC(unsigned char *Data, unsigned int Len, u8 flag)
-{
+	spin_lock_irqsave(&db->lock, flags);
+	iow(db, DM9000_EPAR, offset);
+	iow(db, DM9000_EPDRH, data[1]);
+	iow(db, DM9000_EPDRL, data[0]);
+	iow(db, DM9000_EPCR, EPCR_WEP | EPCR_ERPRW);
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	dm9000_wait_eeprom(db);
 
-       u32 crc = ether_crc_le(Len, Data);
+	mdelay(1);	/* wait at least 150uS to clear */
 
-       if (flag)
-               return ~crc;
+	spin_lock_irqsave(&db->lock, flags);
+	iow(db, DM9000_EPCR, 0);
+	spin_unlock_irqrestore(&db->lock, flags);
 
-       return crc;
+	mutex_unlock(&db->addr_lock);
 }
 
 /*
@@ -1037,15 +1194,16 @@ dm9000_hash_table(struct net_device *dev)
 	board_info_t *db = (board_info_t *) dev->priv;
 	struct dev_mc_list *mcptr = dev->mc_list;
 	int mc_cnt = dev->mc_count;
+	int i, oft;
 	u32 hash_val;
-	u16 i, oft, hash_table[4];
+	u16 hash_table[4];
 	unsigned long flags;
 
-	PRINTK2("dm9000_hash_table()\n");
+	dm9000_dbg(db, 1, "entering %s\n", __func__);
 
-	spin_lock_irqsave(&db->lock,flags);
+	spin_lock_irqsave(&db->lock, flags);
 
-	for (i = 0, oft = 0x10; i < 6; i++, oft++)
+	for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++)
 		iow(db, oft, dev->dev_addr[i]);
 
 	/* Clear Hash Table */
@@ -1057,21 +1215,33 @@ dm9000_hash_table(struct net_device *dev)
 
 	/* the multicast address in Hash Table : 64 bits */
 	for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
-		hash_val = cal_CRC((char *) mcptr->dmi_addr, 6, 0) & 0x3f;
+		hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f;
 		hash_table[hash_val / 16] |= (u16) 1 << (hash_val % 16);
 	}
 
 	/* Write the hash table to MAC MD table */
-	for (i = 0, oft = 0x16; i < 4; i++) {
-		iow(db, oft++, hash_table[i] & 0xff);
-		iow(db, oft++, (hash_table[i] >> 8) & 0xff);
+	for (i = 0, oft = DM9000_MAR; i < 4; i++) {
+		iow(db, oft++, hash_table[i]);
+		iow(db, oft++, hash_table[i] >> 8);
 	}
 
-	spin_unlock_irqrestore(&db->lock,flags);
+	spin_unlock_irqrestore(&db->lock, flags);
 }
 
 
 /*
+ * Sleep, either by using msleep() or if we are suspending, then
+ * use mdelay() to sleep.
+ */
+static void dm9000_msleep(board_info_t *db, unsigned int ms)
+{
+	if (db->in_suspend)
+		mdelay(ms);
+	else
+		msleep(ms);
+}
+
+/*
  *   Read a word from phyxcer
  */
 static int
@@ -1082,6 +1252,8 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
 	unsigned int reg_save;
 	int ret;
 
+	mutex_lock(&db->addr_lock);
+
 	spin_lock_irqsave(&db->lock,flags);
 
 	/* Save previous register address */
@@ -1091,7 +1263,15 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
 	iow(db, DM9000_EPAR, DM9000_PHY | reg);
 
 	iow(db, DM9000_EPCR, 0xc);	/* Issue phyxcer read command */
-	udelay(100);		/* Wait read complete */
+
+	writeb(reg_save, db->io_addr);
+	spin_unlock_irqrestore(&db->lock,flags);
+
+	dm9000_msleep(db, 1);		/* Wait read complete */
+
+	spin_lock_irqsave(&db->lock,flags);
+	reg_save = readb(db->io_addr);
+
 	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer read command */
 
 	/* The read data keeps on REG_0D & REG_0E */
@@ -1099,9 +1279,9 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg)
 
 	/* restore the previous address */
 	writeb(reg_save, db->io_addr);
-
 	spin_unlock_irqrestore(&db->lock,flags);
 
+	mutex_unlock(&db->addr_lock);
 	return ret;
 }
 
@@ -1115,6 +1295,8 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
 	unsigned long flags;
 	unsigned long reg_save;
 
+	mutex_lock(&db->addr_lock);
+
 	spin_lock_irqsave(&db->lock,flags);
 
 	/* Save previous register address */
@@ -1124,25 +1306,38 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value)
 	iow(db, DM9000_EPAR, DM9000_PHY | reg);
 
 	/* Fill the written data into REG_0D & REG_0E */
-	iow(db, DM9000_EPDRL, (value & 0xff));
-	iow(db, DM9000_EPDRH, ((value >> 8) & 0xff));
+	iow(db, DM9000_EPDRL, value);
+	iow(db, DM9000_EPDRH, value >> 8);
 
 	iow(db, DM9000_EPCR, 0xa);	/* Issue phyxcer write command */
-	udelay(500);		/* Wait write complete */
+
+	writeb(reg_save, db->io_addr);
+	spin_unlock_irqrestore(&db->lock, flags);
+
+	dm9000_msleep(db, 1);		/* Wait write complete */
+
+	spin_lock_irqsave(&db->lock,flags);
+	reg_save = readb(db->io_addr);
+
 	iow(db, DM9000_EPCR, 0x0);	/* Clear phyxcer write command */
 
 	/* restore the previous address */
 	writeb(reg_save, db->io_addr);
 
-	spin_unlock_irqrestore(&db->lock,flags);
+	spin_unlock_irqrestore(&db->lock, flags);
+	mutex_unlock(&db->addr_lock);
 }
 
 static int
 dm9000_drv_suspend(struct platform_device *dev, pm_message_t state)
 {
 	struct net_device *ndev = platform_get_drvdata(dev);
+	board_info_t *db;
 
 	if (ndev) {
+		db = (board_info_t *) ndev->priv;
+		db->in_suspend = 1;
+
 		if (netif_running(ndev)) {
 			netif_device_detach(ndev);
 			dm9000_shutdown(ndev);
@@ -1165,6 +1360,8 @@ dm9000_drv_resume(struct platform_device *dev)
 
 			netif_device_attach(ndev);
 		}
+
+		db->in_suspend = 0;
 	}
 	return 0;
 }
@@ -1180,8 +1377,7 @@ dm9000_drv_remove(struct platform_device *pdev)
 	dm9000_release_board(pdev, (board_info_t *) ndev->priv);
 	free_netdev(ndev);		/* free device structure */
 
-	PRINTK1("clean_module() exit\n");
-
+	dev_dbg(&pdev->dev, "released and freed device\n");
 	return 0;
 }
 
@@ -1199,7 +1395,7 @@ static struct platform_driver dm9000_driver = {
 static int __init
 dm9000_init(void)
 {
-	printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME);
+	printk(KERN_INFO "%s Ethernet Driver, V%s\n", CARDNAME, DRV_VERSION);
 
 	return platform_driver_register(&dm9000_driver);	/* search board and register */
 }
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 7c5b05a..d4ee8ec 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -926,8 +926,6 @@ e1000_probe(struct pci_dev *pdev,
 {
 	struct net_device *netdev;
 	struct e1000_adapter *adapter;
-	unsigned long mmio_start, mmio_len;
-	unsigned long flash_start, flash_len;
 
 	static int cards_found = 0;
 	static int global_quad_port_a = 0; /* global ksp3 port a indication */
@@ -970,11 +968,9 @@ e1000_probe(struct pci_dev *pdev,
 	adapter->hw.back = adapter;
 	adapter->msg_enable = (1 << debug) - 1;
 
-	mmio_start = pci_resource_start(pdev, BAR_0);
-	mmio_len = pci_resource_len(pdev, BAR_0);
-
 	err = -EIO;
-	adapter->hw.hw_addr = ioremap(mmio_start, mmio_len);
+	adapter->hw.hw_addr = ioremap(pci_resource_start(pdev, BAR_0),
+				      pci_resource_len(pdev, BAR_0));
 	if (!adapter->hw.hw_addr)
 		goto err_ioremap;
 
@@ -1009,10 +1005,6 @@ e1000_probe(struct pci_dev *pdev,
 #endif
 	strncpy(netdev->name, pci_name(pdev), sizeof(netdev->name) - 1);
 
-	netdev->mem_start = mmio_start;
-	netdev->mem_end = mmio_start + mmio_len;
-	netdev->base_addr = adapter->hw.io_base;
-
 	adapter->bd_number = cards_found;
 
 	/* setup the private structure */
@@ -1025,9 +1017,9 @@ e1000_probe(struct pci_dev *pdev,
 	 * because it depends on mac_type */
 	if ((adapter->hw.mac_type == e1000_ich8lan) &&
 	   (pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
-		flash_start = pci_resource_start(pdev, 1);
-		flash_len = pci_resource_len(pdev, 1);
-		adapter->hw.flash_address = ioremap(flash_start, flash_len);
+		adapter->hw.flash_address =
+			ioremap(pci_resource_start(pdev, 1),
+				pci_resource_len(pdev, 1));
 		if (!adapter->hw.flash_address)
 			goto err_flashmap;
 	}
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index d4843d0..801b4d9 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -166,21 +166,24 @@
  * Hardware access:
  */
 
-#define DEV_NEED_TIMERIRQ	0x0001  /* set the timer irq flag in the irq mask */
-#define DEV_NEED_LINKTIMER	0x0002	/* poll link settings. Relies on the timer irq */
-#define DEV_HAS_LARGEDESC	0x0004	/* device supports jumbo frames and needs packet format 2 */
-#define DEV_HAS_HIGH_DMA        0x0008  /* device supports 64bit dma */
-#define DEV_HAS_CHECKSUM        0x0010  /* device supports tx and rx checksum offloads */
-#define DEV_HAS_VLAN            0x0020  /* device supports vlan tagging and striping */
-#define DEV_HAS_MSI             0x0040  /* device supports MSI */
-#define DEV_HAS_MSI_X           0x0080  /* device supports MSI-X */
-#define DEV_HAS_POWER_CNTRL     0x0100  /* device supports power savings */
-#define DEV_HAS_PAUSEFRAME_TX   0x0200  /* device supports tx pause frames */
-#define DEV_HAS_STATISTICS_V1   0x0400  /* device supports hw statistics version 1 */
-#define DEV_HAS_STATISTICS_V2   0x0800  /* device supports hw statistics version 2 */
-#define DEV_HAS_TEST_EXTENDED   0x1000  /* device supports extended diagnostic test */
-#define DEV_HAS_MGMT_UNIT       0x2000  /* device supports management unit */
-#define DEV_HAS_CORRECT_MACADDR 0x4000  /* device supports correct mac address order */
+#define DEV_NEED_TIMERIRQ          0x00001  /* set the timer irq flag in the irq mask */
+#define DEV_NEED_LINKTIMER         0x00002  /* poll link settings. Relies on the timer irq */
+#define DEV_HAS_LARGEDESC          0x00004  /* device supports jumbo frames and needs packet format 2 */
+#define DEV_HAS_HIGH_DMA           0x00008  /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM           0x00010  /* device supports tx and rx checksum offloads */
+#define DEV_HAS_VLAN               0x00020  /* device supports vlan tagging and striping */
+#define DEV_HAS_MSI                0x00040  /* device supports MSI */
+#define DEV_HAS_MSI_X              0x00080  /* device supports MSI-X */
+#define DEV_HAS_POWER_CNTRL        0x00100  /* device supports power savings */
+#define DEV_HAS_STATISTICS_V1      0x00200  /* device supports hw statistics version 1 */
+#define DEV_HAS_STATISTICS_V2      0x00400  /* device supports hw statistics version 2 */
+#define DEV_HAS_TEST_EXTENDED      0x00800  /* device supports extended diagnostic test */
+#define DEV_HAS_MGMT_UNIT          0x01000  /* device supports management unit */
+#define DEV_HAS_CORRECT_MACADDR    0x02000  /* device supports correct mac address order */
+#define DEV_HAS_COLLISION_FIX      0x04000  /* device supports tx collision fix */
+#define DEV_HAS_PAUSEFRAME_TX_V1   0x08000  /* device supports tx pause frames version 1 */
+#define DEV_HAS_PAUSEFRAME_TX_V2   0x10000  /* device supports tx pause frames version 2 */
+#define DEV_HAS_PAUSEFRAME_TX_V3   0x20000  /* device supports tx pause frames version 3 */
 
 enum {
 	NvRegIrqStatus = 0x000,
@@ -266,9 +269,12 @@ enum {
 #define NVREG_RNDSEED_FORCE3	0x7400
 
 	NvRegTxDeferral = 0xA0,
-#define NVREG_TX_DEFERRAL_DEFAULT	0x15050f
-#define NVREG_TX_DEFERRAL_RGMII_10_100	0x16070f
-#define NVREG_TX_DEFERRAL_RGMII_1000	0x14050f
+#define NVREG_TX_DEFERRAL_DEFAULT		0x15050f
+#define NVREG_TX_DEFERRAL_RGMII_10_100		0x16070f
+#define NVREG_TX_DEFERRAL_RGMII_1000		0x14050f
+#define NVREG_TX_DEFERRAL_RGMII_STRETCH_10	0x16190f
+#define NVREG_TX_DEFERRAL_RGMII_STRETCH_100	0x16300f
+#define NVREG_TX_DEFERRAL_MII_STRETCH		0x152000
 	NvRegRxDeferral = 0xA4,
 #define NVREG_RX_DEFERRAL_DEFAULT	0x16
 	NvRegMacAddrA = 0xA8,
@@ -318,8 +324,10 @@ enum {
 	NvRegTxRingPhysAddrHigh = 0x148,
 	NvRegRxRingPhysAddrHigh = 0x14C,
 	NvRegTxPauseFrame = 0x170,
-#define NVREG_TX_PAUSEFRAME_DISABLE	0x01ff0080
-#define NVREG_TX_PAUSEFRAME_ENABLE	0x01800010
+#define NVREG_TX_PAUSEFRAME_DISABLE	0x0fff0080
+#define NVREG_TX_PAUSEFRAME_ENABLE_V1	0x01800010
+#define NVREG_TX_PAUSEFRAME_ENABLE_V2	0x056003f0
+#define NVREG_TX_PAUSEFRAME_ENABLE_V3	0x09f00880
 	NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR		0x0001
 #define NVREG_MIISTAT_LINKCHANGE	0x0008
@@ -2751,7 +2759,12 @@ static void nv_update_pause(struct net_device *dev, u32 pause_flags)
 	if (np->pause_flags & NV_PAUSEFRAME_TX_CAPABLE) {
 		u32 regmisc = readl(base + NvRegMisc1) & ~NVREG_MISC1_PAUSE_TX;
 		if (pause_flags & NV_PAUSEFRAME_TX_ENABLE) {
-			writel(NVREG_TX_PAUSEFRAME_ENABLE,  base + NvRegTxPauseFrame);
+			u32 pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V1;
+			if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V2)
+				pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V2;
+			if (np->driver_data & DEV_HAS_PAUSEFRAME_TX_V3)
+				pause_enable = NVREG_TX_PAUSEFRAME_ENABLE_V3;
+			writel(pause_enable,  base + NvRegTxPauseFrame);
 			writel(regmisc|NVREG_MISC1_PAUSE_TX, base + NvRegMisc1);
 			np->pause_flags |= NV_PAUSEFRAME_TX_ENABLE;
 		} else {
@@ -2785,6 +2798,7 @@ static int nv_update_linkspeed(struct net_device *dev)
 	int retval = 0;
 	u32 control_1000, status_1000, phyreg, pause_flags, txreg;
 	u32 txrxFlags = 0;
+	u32 phy_exp;
 
 	/* BMSR_LSTATUS is latched, read it twice:
 	 * we want the current value.
@@ -2912,13 +2926,25 @@ set_speed:
 		phyreg |= PHY_1000;
 	writel(phyreg, base + NvRegPhyInterface);
 
+	phy_exp = mii_rw(dev, np->phyaddr, MII_EXPANSION, MII_READ) & EXPANSION_NWAY; /* autoneg capable */
 	if (phyreg & PHY_RGMII) {
-		if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_1000)
+		if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_1000) {
 			txreg = NVREG_TX_DEFERRAL_RGMII_1000;
-		else
-			txreg = NVREG_TX_DEFERRAL_RGMII_10_100;
+		} else {
+			if (!phy_exp && !np->duplex && (np->driver_data & DEV_HAS_COLLISION_FIX)) {
+				if ((np->linkspeed & NVREG_LINKSPEED_MASK) == NVREG_LINKSPEED_10)
+					txreg = NVREG_TX_DEFERRAL_RGMII_STRETCH_10;
+				else
+					txreg = NVREG_TX_DEFERRAL_RGMII_STRETCH_100;
+			} else {
+				txreg = NVREG_TX_DEFERRAL_RGMII_10_100;
+			}
+		}
 	} else {
-		txreg = NVREG_TX_DEFERRAL_DEFAULT;
+		if (!phy_exp && !np->duplex && (np->driver_data & DEV_HAS_COLLISION_FIX))
+			txreg = NVREG_TX_DEFERRAL_MII_STRETCH;
+		else
+			txreg = NVREG_TX_DEFERRAL_DEFAULT;
 	}
 	writel(txreg, base + NvRegTxDeferral);
 
@@ -5155,7 +5181,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 	}
 
 	np->pause_flags = NV_PAUSEFRAME_RX_CAPABLE | NV_PAUSEFRAME_RX_REQ | NV_PAUSEFRAME_AUTONEG;
-	if (id->driver_data & DEV_HAS_PAUSEFRAME_TX) {
+	if ((id->driver_data & DEV_HAS_PAUSEFRAME_TX_V1) ||
+	    (id->driver_data & DEV_HAS_PAUSEFRAME_TX_V2) ||
+	    (id->driver_data & DEV_HAS_PAUSEFRAME_TX_V3)) {
 		np->pause_flags |= NV_PAUSEFRAME_TX_CAPABLE | NV_PAUSEFRAME_TX_REQ;
 	}
 
@@ -5559,107 +5587,107 @@ static struct pci_device_id pci_tbl[] = {
 	},
 	{	/* MCP55 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
 	},
 	{	/* MCP55 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
 	},
 	{	/* MCP61 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_16),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP61 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_17),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP61 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_18),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP61 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_19),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_20),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_21),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_22),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP65 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_23),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_24),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_25),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_26),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP67 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP73 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX_V1|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP77 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V2|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{	/* MCP79 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX,
 	},
 	{0,},
 };
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index 6b3384a..26aa8fe 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -33,20 +33,20 @@
  * I have also done a look in the following sources: (mail me if you need them)
  *   crynwr-packet-driver by Russ Nelson
  *   Garret A. Wollman's (fourth) i82586-driver for BSD
- *   (before getting an i82596 (yes 596 not 586) manual, the existing drivers helped
- *    me a lot to understand this tricky chip.)
+ *   (before getting an i82596 (yes 596 not 586) manual, the existing drivers
+ *    helped me a lot to understand this tricky chip.)
  *
  * Known Problems:
  *   The internal sysbus seems to be slow. So we often lose packets because of
  *   overruns while receiving from a fast remote host.
- *   This can slow down TCP connections. Maybe the newer ni5210 cards are better.
- *   my experience is, that if a machine sends with more than about 500-600K/s
- *   the fifo/sysbus overflows.
+ *   This can slow down TCP connections. Maybe the newer ni5210 cards are
+ *   better. My experience is, that if a machine sends with more than about
+ *   500-600K/s the fifo/sysbus overflows.
  *
  * IMPORTANT NOTE:
  *   On fast networks, it's a (very) good idea to have 16K shared memory. With
- *   8K, we can store only 4 receive frames, so it can (easily) happen that a remote
- *   machine 'overruns' our system.
+ *   8K, we can store only 4 receive frames, so it can (easily) happen that a
+ *   remote machine 'overruns' our system.
  *
  * Known i82586/card problems (I'm sure, there are many more!):
  *   Running the NOP-mode, the i82586 sometimes seems to forget to report
@@ -60,7 +60,8 @@
  *
  * results from ftp performance tests with Linux 1.2.5
  *   send and receive about 350-400 KByte/s (peak up to 460 kbytes/s)
- *   sending in NOP-mode: peak performance up to 530K/s (but better don't run this mode)
+ *   sending in NOP-mode: peak performance up to 530K/s (but better don't
+ *   run this mode)
  */
 
 /*
@@ -94,7 +95,8 @@
  *
  * 26.March.94: patches for Linux 1.0 and iomem-auto-probe (MH)
  *
- * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff, too (MH)
+ * 30.Sep.93: Added nop-chain .. driver now runs with only one Xmit-Buff,
+ *				too (MH)
  *
  * < 30.Sep.93: first versions
  */
@@ -102,7 +104,7 @@
 static int debuglevel;	/* debug-printk 0: off 1: a few 2: more */
 static int automatic_resume; /* experimental .. better should be zero */
 static int rfdadd;	/* rfdadd=1 may be better for 8K MEM cards */
-static int fifo=0x8;	/* don't change */
+static int fifo = 0x8;	/* don't change */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -127,14 +129,15 @@ static int fifo=0x8;	/* don't change */
 #define DEBUG       /* debug on */
 #define SYSBUSVAL 1 /* 8 Bit */
 
-#define ni_attn586()  {outb(0,dev->base_addr+NI52_ATTENTION);}
-#define ni_reset586() {outb(0,dev->base_addr+NI52_RESET);}
-#define ni_disint()   {outb(0,dev->base_addr+NI52_INTDIS);}
-#define ni_enaint()   {outb(0,dev->base_addr+NI52_INTENA);}
+#define ni_attn586()  { outb(0, dev->base_addr + NI52_ATTENTION); }
+#define ni_reset586() { outb(0, dev->base_addr + NI52_RESET); }
+#define ni_disint()   { outb(0, dev->base_addr + NI52_INTDIS); }
+#define ni_enaint()   { outb(0, dev->base_addr + NI52_INTENA); }
 
-#define make32(ptr16) (p->memtop + (short) (ptr16) )
-#define make24(ptr32) ( ((char *) (ptr32)) - p->base)
-#define make16(ptr32) ((unsigned short) ((unsigned long)(ptr32) - (unsigned long) p->memtop ))
+#define make32(ptr16) (p->memtop + (short) (ptr16))
+#define make24(ptr32) ((unsigned long)(ptr32)) - p->base
+#define make16(ptr32) ((unsigned short) ((unsigned long)(ptr32)\
+					- (unsigned long) p->memtop))
 
 /******************* how to calculate the buffers *****************************
 
@@ -159,96 +162,112 @@ sizeof(nop_cmd) = 8;
 
 /**************************************************************************/
 
-/* different DELAYs */
-#define DELAY(x) mdelay(32 * x);
-#define DELAY_16(); { udelay(16); }
-#define DELAY_18(); { udelay(4); }
-
-/* wait for command with timeout: */
-#define WAIT_4_SCB_CMD() \
-{ int i; \
-  for(i=0;i<16384;i++) { \
-    if(!p->scb->cmd_cuc) break; \
-    DELAY_18(); \
-    if(i == 16383) { \
-      printk("%s: scb_cmd timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_cuc,p->scb->cus); \
-       if(!p->reseted) { p->reseted = 1; ni_reset586(); } } } }
-
-#define WAIT_4_SCB_CMD_RUC() { int i; \
-  for(i=0;i<16384;i++) { \
-    if(!p->scb->cmd_ruc) break; \
-    DELAY_18(); \
-    if(i == 16383) { \
-      printk("%s: scb_cmd (ruc) timed out: %04x,%04x .. disabling i82586!!\n",dev->name,p->scb->cmd_ruc,p->scb->rus); \
-       if(!p->reseted) { p->reseted = 1; ni_reset586(); } } } }
-
-#define WAIT_4_STAT_COMPL(addr) { int i; \
-   for(i=0;i<32767;i++) { \
-     if((addr)->cmd_status & STAT_COMPL) break; \
-     DELAY_16(); DELAY_16(); } }
 
 #define NI52_TOTAL_SIZE 16
 #define NI52_ADDR0 0x02
 #define NI52_ADDR1 0x07
 #define NI52_ADDR2 0x01
 
-static int     ni52_probe1(struct net_device *dev,int ioaddr);
-static irqreturn_t ni52_interrupt(int irq,void *dev_id);
+static int     ni52_probe1(struct net_device *dev, int ioaddr);
+static irqreturn_t ni52_interrupt(int irq, void *dev_id);
 static int     ni52_open(struct net_device *dev);
 static int     ni52_close(struct net_device *dev);
-static int     ni52_send_packet(struct sk_buff *,struct net_device *);
+static int     ni52_send_packet(struct sk_buff *, struct net_device *);
 static struct  net_device_stats *ni52_get_stats(struct net_device *dev);
 static void    set_multicast_list(struct net_device *dev);
 static void    ni52_timeout(struct net_device *dev);
-#if 0
-static void    ni52_dump(struct net_device *,void *);
-#endif
 
 /* helper-functions */
 static int     init586(struct net_device *dev);
-static int     check586(struct net_device *dev,char *where,unsigned size);
+static int     check586(struct net_device *dev, char *where, unsigned size);
 static void    alloc586(struct net_device *dev);
 static void    startrecv586(struct net_device *dev);
-static void   *alloc_rfa(struct net_device *dev,void *ptr);
+static void   *alloc_rfa(struct net_device *dev, void *ptr);
 static void    ni52_rcv_int(struct net_device *dev);
 static void    ni52_xmt_int(struct net_device *dev);
 static void    ni52_rnr_int(struct net_device *dev);
 
-struct priv
-{
+struct priv {
 	struct net_device_stats stats;
 	unsigned long base;
 	char *memtop;
-	long int lock;
-	int reseted;
-	volatile struct rfd_struct	*rfd_last,*rfd_top,*rfd_first;
-	volatile struct scp_struct	*scp;	/* volatile is important */
-	volatile struct iscp_struct	*iscp;	/* volatile is important */
-	volatile struct scb_struct	*scb;	/* volatile is important */
-	volatile struct tbd_struct	*xmit_buffs[NUM_XMIT_BUFFS];
+	spinlock_t spinlock;
+	int reset;
+	struct rfd_struct *rfd_last, *rfd_top, *rfd_first;
+	struct scp_struct *scp;
+	struct iscp_struct *iscp;
+	struct scb_struct *scb;
+	struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
 #if (NUM_XMIT_BUFFS == 1)
-	volatile struct transmit_cmd_struct *xmit_cmds[2];
-	volatile struct nop_cmd_struct *nop_cmds[2];
+	struct transmit_cmd_struct *xmit_cmds[2];
+	struct nop_cmd_struct *nop_cmds[2];
 #else
-	volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
-	volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
+	struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
+	struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
 #endif
-	volatile int		nop_point,num_recv_buffs;
-	volatile char		*xmit_cbuffs[NUM_XMIT_BUFFS];
-	volatile int		xmit_count,xmit_last;
+	int nop_point, num_recv_buffs;
+	char *xmit_cbuffs[NUM_XMIT_BUFFS];
+	int xmit_count, xmit_last;
 };
 
+/* wait for command with timeout: */
+static void wait_for_scb_cmd(struct net_device *dev)
+{
+	struct priv *p = dev->priv;
+	int i;
+	for (i = 0; i < 16384; i++) {
+		if (readb(&p->scb->cmd_cuc) == 0)
+		      break;
+		udelay(4);
+		if (i == 16383) {
+			printk(KERN_ERR "%s: scb_cmd timed out: %04x,%04x .. disabling i82586!!\n",
+				dev->name, readb(&p->scb->cmd_cuc), readb(&p->scb->cus));
+			if (!p->reset) {
+				p->reset = 1;
+				ni_reset586();
+			}
+		}
+	}
+}
+
+static void wait_for_scb_cmd_ruc(struct net_device *dev)
+{
+	struct priv *p = dev->priv;
+	int i;
+	for (i = 0; i < 16384; i++) {
+		if (readb(&p->scb->cmd_ruc) == 0)
+			break;
+		udelay(4);
+		if (i == 16383) {
+			printk(KERN_ERR "%s: scb_cmd (ruc) timed out: %04x,%04x .. disabling i82586!!\n",
+				dev->name, p->scb->cmd_ruc, p->scb->rus);
+			if (!p->reset) {
+				p->reset = 1;
+				ni_reset586();
+			}
+		}
+	}
+}
+
+static void wait_for_stat_compl(void *p)
+{
+	struct nop_cmd_struct *addr = p;
+	int i;
+	for (i = 0; i < 32767; i++) {
+		if (readw(&((addr)->cmd_status)) & STAT_COMPL)
+			break;
+		udelay(32);
+	}
+}
+
 /**********************************************
  * close device
  */
 static int ni52_close(struct net_device *dev)
 {
 	free_irq(dev->irq, dev);
-
 	ni_reset586(); /* the hard way to stop the receiver */
-
 	netif_stop_queue(dev);
-
 	return 0;
 }
 
@@ -265,55 +284,53 @@ static int ni52_open(struct net_device *dev)
 	startrecv586(dev);
 	ni_enaint();
 
-	ret = request_irq(dev->irq, &ni52_interrupt,0,dev->name,dev);
-	if (ret)
-	{
+	ret = request_irq(dev->irq, &ni52_interrupt, 0, dev->name, dev);
+	if (ret) {
 		ni_reset586();
 		return ret;
 	}
-
 	netif_start_queue(dev);
-
 	return 0; /* most done by init */
 }
 
 /**********************************************
  * Check to see if there's an 82586 out there.
  */
-static int check586(struct net_device *dev,char *where,unsigned size)
+static int check586(struct net_device *dev, char *where, unsigned size)
 {
 	struct priv pb;
 	struct priv *p = /* (struct priv *) dev->priv*/ &pb;
 	char *iscp_addrs[2];
 	int i;
 
-	p->base = (unsigned long) isa_bus_to_virt((unsigned long)where) + size - 0x01000000;
+	p->base = (unsigned long) isa_bus_to_virt((unsigned long)where)
+							+ size - 0x01000000;
 	p->memtop = isa_bus_to_virt((unsigned long)where) + size;
 	p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
-	memset((char *)p->scp,0, sizeof(struct scp_struct));
-	for(i=0;i<sizeof(struct scp_struct);i++) /* memory was writeable? */
-		if(((char *)p->scp)[i])
+	memset_io((char *)p->scp, 0, sizeof(struct scp_struct));
+	for (i = 0; i < sizeof(struct scp_struct); i++)
+		/* memory was writeable? */
+		if (readb((char *)p->scp + i))
 			return 0;
-	p->scp->sysbus = SYSBUSVAL;				/* 1 = 8Bit-Bus, 0 = 16 Bit */
-	if(p->scp->sysbus != SYSBUSVAL)
+	writeb(SYSBUSVAL, &p->scp->sysbus);	/* 1 = 8Bit-Bus, 0 = 16 Bit */
+	if (readb(&p->scp->sysbus) != SYSBUSVAL)
 		return 0;
 
 	iscp_addrs[0] = isa_bus_to_virt((unsigned long)where);
-	iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct);
+	iscp_addrs[1] = (char *) p->scp - sizeof(struct iscp_struct);
 
-	for(i=0;i<2;i++)
-	{
+	for (i = 0; i < 2; i++) {
 		p->iscp = (struct iscp_struct *) iscp_addrs[i];
-		memset((char *)p->iscp,0, sizeof(struct iscp_struct));
+		memset_io((char *)p->iscp, 0, sizeof(struct iscp_struct));
 
-		p->scp->iscp = make24(p->iscp);
-		p->iscp->busy = 1;
+		writel(make24(p->iscp), &p->scp->iscp);
+		writeb(1, &p->iscp->busy);
 
 		ni_reset586();
 		ni_attn586();
-		DELAY(1);	/* wait a while... */
-
-		if(p->iscp->busy) /* i82586 clears 'busy' after successful init */
+		mdelay(32);	/* wait a while... */
+		/* i82586 clears 'busy' after successful init */
+		if (readb(&p->iscp->busy))
 			return 0;
 	}
 	return 1;
@@ -327,36 +344,39 @@ static void alloc586(struct net_device *dev)
 	struct priv *p =	(struct priv *) dev->priv;
 
 	ni_reset586();
-	DELAY(1);
+	mdelay(32);
+
+	spin_lock_init(&p->spinlock);
 
 	p->scp	= (struct scp_struct *)	(p->base + SCP_DEFAULT_ADDRESS);
 	p->scb	= (struct scb_struct *)	isa_bus_to_virt(dev->mem_start);
-	p->iscp = (struct iscp_struct *) ((char *)p->scp - sizeof(struct iscp_struct));
+	p->iscp = (struct iscp_struct *)
+			((char *)p->scp - sizeof(struct iscp_struct));
 
-	memset((char *) p->iscp,0,sizeof(struct iscp_struct));
-	memset((char *) p->scp ,0,sizeof(struct scp_struct));
+	memset_io(p->iscp, 0, sizeof(struct iscp_struct));
+	memset_io(p->scp , 0, sizeof(struct scp_struct));
 
-	p->scp->iscp = make24(p->iscp);
-	p->scp->sysbus = SYSBUSVAL;
-	p->iscp->scb_offset = make16(p->scb);
+	writel(make24(p->iscp), &p->scp->iscp);
+	writeb(SYSBUSVAL, &p->scp->sysbus);
+	writew(make16(p->scb), &p->iscp->scb_offset);
 
-	p->iscp->busy = 1;
+	writeb(1, &p->iscp->busy);
 	ni_reset586();
 	ni_attn586();
 
-	DELAY(1);
+	mdelay(32);
 
-	if(p->iscp->busy)
-		printk("%s: Init-Problems (alloc).\n",dev->name);
+	if (readb(&p->iscp->busy))
+		printk(KERN_ERR "%s: Init-Problems (alloc).\n", dev->name);
 
-	p->reseted = 0;
+	p->reset = 0;
 
-	memset((char *)p->scb,0,sizeof(struct scb_struct));
+	memset_io((char *)p->scb, 0, sizeof(struct scb_struct));
 }
 
 /* set: io,irq,memstart,memend or set it when calling insmod */
-static int irq=9;
-static int io=0x300;
+static int irq = 9;
+static int io = 0x300;
 static long memstart;	/* e.g 0xd0000 */
 static long memend;	/* e.g 0xd4000 */
 
@@ -413,7 +433,7 @@ out:
 	return ERR_PTR(err);
 }
 
-static int __init ni52_probe1(struct net_device *dev,int ioaddr)
+static int __init ni52_probe1(struct net_device *dev, int ioaddr)
 {
 	int i, size, retval;
 
@@ -425,90 +445,96 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr)
 	if (!request_region(ioaddr, NI52_TOTAL_SIZE, DRV_NAME))
 		return -EBUSY;
 
-	if( !(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
+	if (!(inb(ioaddr+NI52_MAGIC1) == NI52_MAGICVAL1) ||
 	    !(inb(ioaddr+NI52_MAGIC2) == NI52_MAGICVAL2)) {
 		retval = -ENODEV;
 		goto out;
 	}
 
-	for(i=0;i<ETH_ALEN;i++)
+	for (i = 0; i < ETH_ALEN; i++)
 		dev->dev_addr[i] = inb(dev->base_addr+i);
 
-	if(dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1
+	if (dev->dev_addr[0] != NI52_ADDR0 || dev->dev_addr[1] != NI52_ADDR1
 		 || dev->dev_addr[2] != NI52_ADDR2) {
 		retval = -ENODEV;
 		goto out;
 	}
 
-	printk(KERN_INFO "%s: NI5210 found at %#3lx, ",dev->name,dev->base_addr);
+	printk(KERN_INFO "%s: NI5210 found at %#3lx, ",
+				dev->name, dev->base_addr);
 
 	/*
 	 * check (or search) IO-Memory, 8K and 16K
 	 */
 #ifdef MODULE
 	size = dev->mem_end - dev->mem_start;
-	if(size != 0x2000 && size != 0x4000) {
-		printk("\n%s: Illegal memory size %d. Allowed is 0x2000 or 0x4000 bytes.\n",dev->name,size);
+	if (size != 0x2000 && size != 0x4000) {
+		printk("\n");
+		printk(KERN_ERR "%s: Invalid memory size %d. Allowed is 0x2000 or 0x4000 bytes.\n", dev->name, size);
 		retval = -ENODEV;
 		goto out;
 	}
-	if(!check586(dev,(char *) dev->mem_start,size)) {
-		printk("?memcheck, Can't find memory at 0x%lx with size %d!\n",dev->mem_start,size);
+	if (!check586(dev, (char *)dev->mem_start, size)) {
+		printk(KERN_ERR "?memcheck, Can't find memory at 0x%lx with size %d!\n", dev->mem_start, size);
 		retval = -ENODEV;
 		goto out;
 	}
 #else
-	if(dev->mem_start != 0) /* no auto-mem-probe */
-	{
+	if (dev->mem_start != 0) {
+		/* no auto-mem-probe */
 		size = 0x4000; /* check for 16K mem */
-		if(!check586(dev,(char *) dev->mem_start,size)) {
+		if (!check586(dev, (char *) dev->mem_start, size)) {
 			size = 0x2000; /* check for 8K mem */
-			if(!check586(dev,(char *) dev->mem_start,size)) {
-				printk("?memprobe, Can't find memory at 0x%lx!\n",dev->mem_start);
+			if (!check586(dev, (char *)dev->mem_start, size)) {
+				printk(KERN_ERR "?memprobe, Can't find memory at 0x%lx!\n", dev->mem_start);
 				retval = -ENODEV;
 				goto out;
 			}
 		}
-	}
-	else
-	{
-		static long memaddrs[] = { 0xc8000,0xca000,0xcc000,0xce000,0xd0000,0xd2000,
-					0xd4000,0xd6000,0xd8000,0xda000,0xdc000, 0 };
-		for(i=0;;i++)
-		{
-			if(!memaddrs[i]) {
-				printk("?memprobe, Can't find io-memory!\n");
+	} else {
+		static const unsigned long memaddrs[] = {
+			0xc8000, 0xca000, 0xcc000, 0xce000, 0xd0000, 0xd2000,
+			0xd4000, 0xd6000, 0xd8000, 0xda000, 0xdc000, 0
+		};
+		for (i = 0;; i++) {
+			if (!memaddrs[i]) {
+				printk(KERN_ERR "?memprobe, Can't find io-memory!\n");
 				retval = -ENODEV;
 				goto out;
 			}
 			dev->mem_start = memaddrs[i];
 			size = 0x2000; /* check for 8K mem */
-			if(check586(dev,(char *)dev->mem_start,size)) /* 8K-check */
+			if (check586(dev, (char *)dev->mem_start, size))
+				/* 8K-check */
 				break;
 			size = 0x4000; /* check for 16K mem */
-			if(check586(dev,(char *)dev->mem_start,size)) /* 16K-check */
+			if (check586(dev, (char *)dev->mem_start, size))
+				/* 16K-check */
 				break;
 		}
 	}
-	dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
+	/* set mem_end showed by 'ifconfig' */
+	dev->mem_end = dev->mem_start + size;
 #endif
 
-	memset((char *) dev->priv,0,sizeof(struct priv));
+	memset((char *)dev->priv, 0, sizeof(struct priv));
 
-	((struct priv *) (dev->priv))->memtop = isa_bus_to_virt(dev->mem_start) + size;
-	((struct priv *) (dev->priv))->base =	(unsigned long) isa_bus_to_virt(dev->mem_start) + size - 0x01000000;
+	((struct priv *)(dev->priv))->memtop =
+				isa_bus_to_virt(dev->mem_start) + size;
+	((struct priv *)(dev->priv))->base =  (unsigned long)
+			isa_bus_to_virt(dev->mem_start) + size - 0x01000000;
 	alloc586(dev);
 
 	/* set number of receive-buffs according to memsize */
-	if(size == 0x2000)
+	if (size == 0x2000)
 		((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_8;
 	else
 		((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16;
 
-	printk("Memaddr: 0x%lx, Memsize: %d, ",dev->mem_start,size);
+	printk(KERN_DEBUG "Memaddr: 0x%lx, Memsize: %d, ",
+				dev->mem_start, size);
 
-	if(dev->irq < 2)
-	{
+	if (dev->irq < 2) {
 		unsigned long irq_mask;
 
 		irq_mask = probe_irq_on();
@@ -517,18 +543,16 @@ static int __init ni52_probe1(struct net_device *dev,int ioaddr)
 
 		mdelay(20);
 		dev->irq = probe_irq_off(irq_mask);
-		if(!dev->irq)
-		{
+		if (!dev->irq) {
 			printk("?autoirq, Failed to detect IRQ line!\n");
 			retval = -EAGAIN;
 			goto out;
 		}
-		printk("IRQ %d (autodetected).\n",dev->irq);
-	}
-	else	{
-		if(dev->irq == 2)
+		printk("IRQ %d (autodetected).\n", dev->irq);
+	} else {
+		if (dev->irq == 2)
 			dev->irq = 9;
-		printk("IRQ %d (assigned and not checked!).\n",dev->irq);
+		printk("IRQ %d (assigned and not checked!).\n", dev->irq);
 	}
 
 	dev->open		= ni52_open;
@@ -555,56 +579,58 @@ out:
 static int init586(struct net_device *dev)
 {
 	void *ptr;
-	int i,result=0;
-	struct priv *p = (struct priv *) dev->priv;
-	volatile struct configure_cmd_struct	*cfg_cmd;
-	volatile struct iasetup_cmd_struct *ias_cmd;
-	volatile struct tdr_cmd_struct *tdr_cmd;
-	volatile struct mcsetup_cmd_struct *mc_cmd;
-	struct dev_mc_list *dmi=dev->mc_list;
-	int num_addrs=dev->mc_count;
+	int i, result = 0;
+	struct priv *p = (struct priv *)dev->priv;
+	struct configure_cmd_struct *cfg_cmd;
+	struct iasetup_cmd_struct *ias_cmd;
+	struct tdr_cmd_struct *tdr_cmd;
+	struct mcsetup_cmd_struct *mc_cmd;
+	struct dev_mc_list *dmi = dev->mc_list;
+	int num_addrs = dev->mc_count;
 
 	ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct));
 
 	cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */
-	cfg_cmd->cmd_status	= 0;
-	cfg_cmd->cmd_cmd	= CMD_CONFIGURE | CMD_LAST;
-	cfg_cmd->cmd_link	= 0xffff;
-
-	cfg_cmd->byte_cnt	= 0x0a; /* number of cfg bytes */
-	cfg_cmd->fifo		= fifo; /* fifo-limit (8=tx:32/rx:64) */
-	cfg_cmd->sav_bf		= 0x40; /* hold or discard bad recv frames (bit 7) */
-	cfg_cmd->adr_len	= 0x2e; /* addr_len |!src_insert |pre-len |loopback */
-	cfg_cmd->priority	= 0x00;
-	cfg_cmd->ifs		= 0x60;
-	cfg_cmd->time_low	= 0x00;
-	cfg_cmd->time_high	= 0xf2;
-	cfg_cmd->promisc	= 0;
-	if(dev->flags & IFF_ALLMULTI) {
+	writew(0, &cfg_cmd->cmd_status);
+	writew(CMD_CONFIGURE | CMD_LAST, &cfg_cmd->cmd_cmd);
+	writew(0xFFFF, &cfg_cmd->cmd_link);
+
+	/* number of cfg bytes */
+	writeb(0x0a, &cfg_cmd->byte_cnt);
+	/* fifo-limit (8=tx:32/rx:64) */
+	writeb(fifo, &cfg_cmd->fifo);
+	/* hold or discard bad recv frames (bit 7) */
+	writeb(0x40, &cfg_cmd->sav_bf);
+	/* addr_len |!src_insert |pre-len |loopback */
+	writeb(0x2e, &cfg_cmd->adr_len);
+	writeb(0x00, &cfg_cmd->priority);
+	writeb(0x60, &cfg_cmd->ifs);;
+	writeb(0x00, &cfg_cmd->time_low);
+	writeb(0xf2, &cfg_cmd->time_high);
+	writeb(0x00, &cfg_cmd->promisc);;
+	if (dev->flags & IFF_ALLMULTI) {
 		int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
-		if(num_addrs > len)	{
-			printk("%s: switching to promisc. mode\n",dev->name);
-			dev->flags|=IFF_PROMISC;
+		if (num_addrs > len) {
+			printk(KERN_ERR "%s: switching to promisc. mode\n",
+				dev->name);
+			dev->flags |= IFF_PROMISC;
 		}
 	}
-	if(dev->flags&IFF_PROMISC)
-	{
-			 cfg_cmd->promisc=1;
-			 dev->flags|=IFF_PROMISC;
-	}
-	cfg_cmd->carr_coll	= 0x00;
+	if (dev->flags & IFF_PROMISC)
+		writeb(0x01, &cfg_cmd->promisc);
+	writeb(0x00, &cfg_cmd->carr_coll);
+	writew(make16(cfg_cmd), &p->scb->cbl_offset);
+	writew(0, &p->scb->cmd_ruc);
 
-	p->scb->cbl_offset	= make16(cfg_cmd);
-	p->scb->cmd_ruc		= 0;
-
-	p->scb->cmd_cuc		= CUC_START; /* cmd.-unit start */
+	writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
 	ni_attn586();
 
-	WAIT_4_STAT_COMPL(cfg_cmd);
+	wait_for_stat_compl(cfg_cmd);
 
-	if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK))
-	{
-		printk("%s: configure command failed: %x\n",dev->name,cfg_cmd->cmd_status);
+	if ((readw(&cfg_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) !=
+							(STAT_COMPL|STAT_OK)) {
+		printk(KERN_ERR "%s: configure command failed: %x\n",
+				dev->name, readw(&cfg_cmd->cmd_status));
 		return 1;
 	}
 
@@ -614,21 +640,22 @@ static int init586(struct net_device *dev)
 
 	ias_cmd = (struct iasetup_cmd_struct *)ptr;
 
-	ias_cmd->cmd_status	= 0;
-	ias_cmd->cmd_cmd	= CMD_IASETUP | CMD_LAST;
-	ias_cmd->cmd_link	= 0xffff;
+	writew(0, &ias_cmd->cmd_status);
+	writew(CMD_IASETUP | CMD_LAST, &ias_cmd->cmd_cmd);
+	writew(0xffff, &ias_cmd->cmd_link);
 
-	memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN);
+	memcpy_toio((char *)&ias_cmd->iaddr, (char *)dev->dev_addr, ETH_ALEN);
 
-	p->scb->cbl_offset = make16(ias_cmd);
+	writew(make16(ias_cmd), &p->scb->cbl_offset);
 
-	p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
+	writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
 	ni_attn586();
 
-	WAIT_4_STAT_COMPL(ias_cmd);
+	wait_for_stat_compl(ias_cmd);
 
-	if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
-		printk("%s (ni52): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status);
+	if ((readw(&ias_cmd->cmd_status) & (STAT_OK|STAT_COMPL)) !=
+							(STAT_OK|STAT_COMPL)) {
+		printk(KERN_ERR "%s (ni52): individual address setup command failed: %04x\n", dev->name, readw(&ias_cmd->cmd_status));
 		return 1;
 	}
 
@@ -638,117 +665,119 @@ static int init586(struct net_device *dev)
 
 	tdr_cmd = (struct tdr_cmd_struct *)ptr;
 
-	tdr_cmd->cmd_status	= 0;
-	tdr_cmd->cmd_cmd	= CMD_TDR | CMD_LAST;
-	tdr_cmd->cmd_link	= 0xffff;
-	tdr_cmd->status		= 0;
+	writew(0, &tdr_cmd->cmd_status);
+	writew(CMD_TDR | CMD_LAST, &tdr_cmd->cmd_cmd);
+	writew(0xffff, &tdr_cmd->cmd_link);
+	writew(0, &tdr_cmd->status);
 
-	p->scb->cbl_offset = make16(tdr_cmd);
-	p->scb->cmd_cuc = CUC_START; /* cmd.-unit start */
+	writew(make16(tdr_cmd), &p->scb->cbl_offset);
+	writeb(CUC_START, &p->scb->cmd_cuc); /* cmd.-unit start */
 	ni_attn586();
 
-	WAIT_4_STAT_COMPL(tdr_cmd);
-
-	if(!(tdr_cmd->cmd_status & STAT_COMPL))
-	{
-		printk("%s: Problems while running the TDR.\n",dev->name);
-	}
-	else
-	{
-		DELAY_16(); /* wait for result */
-		result = tdr_cmd->status;
+	wait_for_stat_compl(tdr_cmd);
 
-		p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
+	if (!(readw(&tdr_cmd->cmd_status) & STAT_COMPL))
+		printk(KERN_ERR "%s: Problems while running the TDR.\n",
+				dev->name);
+	else {
+		udelay(16);
+		result = readw(&tdr_cmd->status);
+		writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc);
 		ni_attn586(); /* ack the interrupts */
 
-		if(result & TDR_LNK_OK)
+		if (result & TDR_LNK_OK)
 			;
-		else if(result & TDR_XCVR_PRB)
-			printk("%s: TDR: Transceiver problem. Check the cable(s)!\n",dev->name);
-		else if(result & TDR_ET_OPN)
-			printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
-		else if(result & TDR_ET_SRT)
-		{
-			if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
-				printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
-		}
-		else
-			printk("%s: TDR: Unknown status %04x\n",dev->name,result);
+		else if (result & TDR_XCVR_PRB)
+			printk(KERN_ERR "%s: TDR: Transceiver problem. Check the cable(s)!\n",
+				dev->name);
+		else if (result & TDR_ET_OPN)
+			printk(KERN_ERR "%s: TDR: No correct termination %d clocks away.\n",
+				dev->name, result & TDR_TIMEMASK);
+		else if (result & TDR_ET_SRT) {
+			/* time == 0 -> strange :-) */
+			if (result & TDR_TIMEMASK)
+				printk(KERN_ERR "%s: TDR: Detected a short circuit %d clocks away.\n",
+					dev->name, result & TDR_TIMEMASK);
+		} else
+			printk(KERN_ERR "%s: TDR: Unknown status %04x\n",
+						dev->name, result);
 	}
 
 	/*
 	 * Multicast setup
 	 */
-	if(num_addrs && !(dev->flags & IFF_PROMISC) )
-	{
+	if (num_addrs && !(dev->flags & IFF_PROMISC)) {
 		mc_cmd = (struct mcsetup_cmd_struct *) ptr;
-		mc_cmd->cmd_status = 0;
-		mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
-		mc_cmd->cmd_link = 0xffff;
-		mc_cmd->mc_cnt = num_addrs * 6;
+		writew(0, &mc_cmd->cmd_status);
+		writew(CMD_MCSETUP | CMD_LAST, &mc_cmd->cmd_cmd);
+		writew(0xffff, &mc_cmd->cmd_link);
+		writew(num_addrs * 6, &mc_cmd->mc_cnt);
 
-		for(i=0;i<num_addrs;i++,dmi=dmi->next)
-			memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr,6);
+		for (i = 0; i < num_addrs; i++, dmi = dmi->next)
+			memcpy_toio((char *) mc_cmd->mc_list[i],
+							dmi->dmi_addr, 6);
 
-		p->scb->cbl_offset = make16(mc_cmd);
-		p->scb->cmd_cuc = CUC_START;
+		writew(make16(mc_cmd), &p->scb->cbl_offset);
+		writeb(CUC_START, &p->scb->cmd_cuc);
 		ni_attn586();
 
-		WAIT_4_STAT_COMPL(mc_cmd);
+		wait_for_stat_compl(mc_cmd);
 
-		if( (mc_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )
-			printk("%s: Can't apply multicast-address-list.\n",dev->name);
+		if ((readw(&mc_cmd->cmd_status) & (STAT_COMPL|STAT_OK))
+						 != (STAT_COMPL|STAT_OK))
+			printk(KERN_ERR "%s: Can't apply multicast-address-list.\n", dev->name);
 	}
 
 	/*
 	 * alloc nop/xmit-cmds
 	 */
 #if (NUM_XMIT_BUFFS == 1)
-	for(i=0;i<2;i++)
-	{
-		p->nop_cmds[i] 			= (struct nop_cmd_struct *)ptr;
-		p->nop_cmds[i]->cmd_cmd		= CMD_NOP;
-		p->nop_cmds[i]->cmd_status 	= 0;
-		p->nop_cmds[i]->cmd_link	= make16((p->nop_cmds[i]));
+	for (i = 0; i < 2; i++) {
+		p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
+		writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd);
+		writew(0, &p->nop_cmds[i]->cmd_status);
+		writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link);
 		ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
 	}
 #else
-	for(i=0;i<NUM_XMIT_BUFFS;i++)
-	{
-		p->nop_cmds[i]			= (struct nop_cmd_struct *)ptr;
-		p->nop_cmds[i]->cmd_cmd		= CMD_NOP;
-		p->nop_cmds[i]->cmd_status	= 0;
-		p->nop_cmds[i]->cmd_link	= make16((p->nop_cmds[i]));
+	for (i = 0; i < NUM_XMIT_BUFFS; i++) {
+		p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
+		writew(CMD_NOP, &p->nop_cmds[i]->cmd_cmd);
+		writew(0, &p->nop_cmds[i]->cmd_status);
+		writew(make16(p->nop_cmds[i]), &p->nop_cmds[i]->cmd_link);
 		ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
 	}
 #endif
 
-	ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */
+	ptr = alloc_rfa(dev, (void *)ptr); /* init receive-frame-area */
 
 	/*
 	 * alloc xmit-buffs / init xmit_cmds
 	 */
-	for(i=0;i<NUM_XMIT_BUFFS;i++)
-	{
-		p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr; /*transmit cmd/buff 0*/
+	for (i = 0; i < NUM_XMIT_BUFFS; i++) {
+		/* Transmit cmd/buff 0 */
+		p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr;
 		ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
 		p->xmit_cbuffs[i] = (char *)ptr; /* char-buffs */
 		ptr = (char *) ptr + XMIT_BUFF_SIZE;
 		p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */
 		ptr = (char *) ptr + sizeof(struct tbd_struct);
-		if((void *)ptr > (void *)p->iscp)
-		{
-			printk("%s: not enough shared-mem for your configuration!\n",dev->name);
+		if ((void *)ptr > (void *)p->iscp) {
+			printk(KERN_ERR "%s: not enough shared-mem for your configuration!\n",
+				dev->name);
 			return 1;
 		}
-		memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
-		memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
-		p->xmit_cmds[i]->cmd_link = make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]);
-		p->xmit_cmds[i]->cmd_status = STAT_COMPL;
-		p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT;
-		p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
-		p->xmit_buffs[i]->next = 0xffff;
-		p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
+		memset_io((char *)(p->xmit_cmds[i]), 0,
+					sizeof(struct transmit_cmd_struct));
+		memset_io((char *)(p->xmit_buffs[i]), 0,
+					sizeof(struct tbd_struct));
+		writew(make16(p->nop_cmds[(i+1)%NUM_XMIT_BUFFS]),
+					&p->xmit_cmds[i]->cmd_link);
+		writew(STAT_COMPL, &p->xmit_cmds[i]->cmd_status);
+		writew(CMD_XMIT|CMD_INT, &p->xmit_cmds[i]->cmd_cmd);
+		writew(make16(p->xmit_buffs[i]), &p->xmit_cmds[i]->tbd_offset);
+		writew(0xffff, &p->xmit_buffs[i]->next);
+		writel(make24(p->xmit_cbuffs[i]), &p->xmit_buffs[i]->buffer);
 	}
 
 	p->xmit_count = 0;
@@ -761,21 +790,21 @@ static int init586(struct net_device *dev)
 		* 'start transmitter'
 		*/
 #ifndef NO_NOPCOMMANDS
-	p->scb->cbl_offset = make16(p->nop_cmds[0]);
-	p->scb->cmd_cuc = CUC_START;
+	writew(make16(p->nop_cmds[0]), &p->scb->cbl_offset);
+	writeb(CUC_START, &p->scb->cmd_cuc);
 	ni_attn586();
-	WAIT_4_SCB_CMD();
+	wait_for_scb_cmd(dev);
 #else
-	p->xmit_cmds[0]->cmd_link = make16(p->xmit_cmds[0]);
-	p->xmit_cmds[0]->cmd_cmd	= CMD_XMIT | CMD_SUSPEND | CMD_INT;
+	writew(make16(p->xmit_cmds[0]), &p->xmit_cmds[0]->cmd_link);
+	writew(CMD_XMIT | CMD_SUSPEND | CMD_INT, &p->xmit_cmds[0]->cmd_cmd);
 #endif
 
 	/*
 	 * ack. interrupts
 	 */
-	p->scb->cmd_cuc = p->scb->cus & STAT_MASK;
+	writeb(readb(&p->scb->cus) & STAT_MASK, &p->scb->cmd_cuc);
 	ni_attn586();
-	DELAY_16();
+	udelay(16);
 
 	ni_enaint();
 
@@ -787,43 +816,45 @@ static int init586(struct net_device *dev)
  * It sets up the Receive Frame Area (RFA).
  */
 
-static void *alloc_rfa(struct net_device *dev,void *ptr)
+static void *alloc_rfa(struct net_device *dev, void *ptr)
 {
-	volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
-	volatile struct rbd_struct *rbd;
+	struct rfd_struct *rfd = (struct rfd_struct *)ptr;
+	struct rbd_struct *rbd;
 	int i;
 	struct priv *p = (struct priv *) dev->priv;
 
-	memset((char *) rfd,0,sizeof(struct rfd_struct)*(p->num_recv_buffs+rfdadd));
+	memset_io((char *) rfd, 0,
+		sizeof(struct rfd_struct) * (p->num_recv_buffs + rfdadd));
 	p->rfd_first = rfd;
 
-	for(i = 0; i < (p->num_recv_buffs+rfdadd); i++) {
-		rfd[i].next = make16(rfd + (i+1) % (p->num_recv_buffs+rfdadd) );
-		rfd[i].rbd_offset = 0xffff;
+	for (i = 0; i < (p->num_recv_buffs + rfdadd); i++) {
+		writew(make16(rfd + (i+1) % (p->num_recv_buffs+rfdadd)),
+			&rfd[i].next);
+		writew(0xffff, &rfd[i].rbd_offset);
 	}
-	rfd[p->num_recv_buffs-1+rfdadd].last = RFD_SUSP;	 /* RU suspend */
+	/* RU suspend */
+	writeb(RFD_SUSP, &rfd[p->num_recv_buffs-1+rfdadd].last);
 
-	ptr = (void *) (rfd + (p->num_recv_buffs + rfdadd) );
+	ptr = (void *) (rfd + (p->num_recv_buffs + rfdadd));
 
 	rbd = (struct rbd_struct *) ptr;
 	ptr = (void *) (rbd + p->num_recv_buffs);
 
 	 /* clr descriptors */
-	memset((char *) rbd,0,sizeof(struct rbd_struct)*(p->num_recv_buffs));
+	memset_io((char *)rbd, 0,
+			sizeof(struct rbd_struct) * (p->num_recv_buffs));
 
-	for(i=0;i<p->num_recv_buffs;i++)
-	{
-		rbd[i].next = make16((rbd + (i+1) % p->num_recv_buffs));
-		rbd[i].size = RECV_BUFF_SIZE;
-		rbd[i].buffer = make24(ptr);
+	for (i = 0; i < p->num_recv_buffs; i++) {
+		writew(make16(rbd + (i+1) % p->num_recv_buffs), &rbd[i].next);
+		writew(RECV_BUFF_SIZE, &rbd[i].size);
+		writel(make24(ptr), &rbd[i].buffer);
 		ptr = (char *) ptr + RECV_BUFF_SIZE;
 	}
-
 	p->rfd_top	= p->rfd_first;
 	p->rfd_last = p->rfd_first + (p->num_recv_buffs - 1 + rfdadd);
 
-	p->scb->rfa_offset		= make16(p->rfd_first);
-	p->rfd_first->rbd_offset	= make16(rbd);
+	writew(make16(p->rfd_first), &p->scb->rfa_offset);
+	writew(make16(rbd), &p->rfd_first->rbd_offset);
 
 	return ptr;
 }
@@ -833,73 +864,71 @@ static void *alloc_rfa(struct net_device *dev,void *ptr)
  * Interrupt Handler ...
  */
 
-static irqreturn_t ni52_interrupt(int irq,void *dev_id)
+static irqreturn_t ni52_interrupt(int irq, void *dev_id)
 {
 	struct net_device *dev = dev_id;
-	unsigned short stat;
-	int cnt=0;
+	unsigned int stat;
+	int cnt = 0;
 	struct priv *p;
 
-	if (!dev) {
-		printk ("ni5210-interrupt: irq %d for unknown device.\n",irq);
-		return IRQ_NONE;
-	}
 	p = (struct priv *) dev->priv;
 
-	if(debuglevel > 1)
+	if (debuglevel > 1)
 		printk("I");
 
-	WAIT_4_SCB_CMD(); /* wait for last command	*/
+	spin_lock(&p->spinlock);
 
-	while((stat=p->scb->cus & STAT_MASK))
-	{
-		p->scb->cmd_cuc = stat;
+	wait_for_scb_cmd(dev); /* wait for last command	*/
+
+	while ((stat = readb(&p->scb->cus) & STAT_MASK)) {
+		writeb(stat, &p->scb->cmd_cuc);
 		ni_attn586();
 
-		if(stat & STAT_FR)	 /* received a frame */
+		if (stat & STAT_FR)	 /* received a frame */
 			ni52_rcv_int(dev);
 
-		if(stat & STAT_RNR) /* RU went 'not ready' */
-		{
+		if (stat & STAT_RNR) { /* RU went 'not ready' */
 			printk("(R)");
-			if(p->scb->rus & RU_SUSPEND) /* special case: RU_SUSPEND */
-			{
-				WAIT_4_SCB_CMD();
+			if (readb(&p->scb->rus) & RU_SUSPEND) {
+				/* special case: RU_SUSPEND */
+				wait_for_scb_cmd(dev);
 				p->scb->cmd_ruc = RUC_RESUME;
 				ni_attn586();
-				WAIT_4_SCB_CMD_RUC();
-			}
-			else
-			{
-				printk("%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->rus);
+				wait_for_scb_cmd_ruc(dev);
+			} else {
+				printk(KERN_ERR "%s: Receiver-Unit went 'NOT READY': %04x/%02x.\n",
+					dev->name, stat, readb(&p->scb->rus));
 				ni52_rnr_int(dev);
 			}
 		}
 
-		if(stat & STAT_CX)		/* command with I-bit set complete */
+		/* Command with I-bit set complete */
+		if (stat & STAT_CX)
 			 ni52_xmt_int(dev);
 
 #ifndef NO_NOPCOMMANDS
-		if(stat & STAT_CNA)	/* CU went 'not ready' */
-		{
-			if(netif_running(dev))
-				printk("%s: oops! CU has left active state. stat: %04x/%02x.\n",dev->name,(int) stat,(int) p->scb->cus);
+		if (stat & STAT_CNA) {	/* CU went 'not ready' */
+			if (netif_running(dev))
+				printk(KERN_ERR "%s: oops! CU has left active state. stat: %04x/%02x.\n",
+					dev->name, stat, readb(&p->scb->cus));
 		}
 #endif
 
-		if(debuglevel > 1)
-			printk("%d",cnt++);
+		if (debuglevel > 1)
+			printk("%d", cnt++);
 
-		WAIT_4_SCB_CMD(); /* wait for ack. (ni52_xmt_int can be faster than ack!!) */
-		if(p->scb->cmd_cuc)	 /* timed out? */
-		{
-			printk("%s: Acknowledge timed out.\n",dev->name);
+		/* Wait for ack. (ni52_xmt_int can be faster than ack!!) */
+		wait_for_scb_cmd(dev);
+		if (p->scb->cmd_cuc) {	 /* timed out? */
+			printk(KERN_ERR "%s: Acknowledge timed out.\n",
+				dev->name);
 			ni_disint();
 			break;
 		}
 	}
+	spin_unlock(&p->spinlock);
 
-	if(debuglevel > 1)
+	if (debuglevel > 1)
 		printk("i");
 	return IRQ_HANDLED;
 }
@@ -910,121 +939,91 @@ static irqreturn_t ni52_interrupt(int irq,void *dev_id)
 
 static void ni52_rcv_int(struct net_device *dev)
 {
-	int status,cnt=0;
+	int status, cnt = 0;
 	unsigned short totlen;
 	struct sk_buff *skb;
 	struct rbd_struct *rbd;
-	struct priv *p = (struct priv *) dev->priv;
+	struct priv *p = (struct priv *)dev->priv;
 
-	if(debuglevel > 0)
+	if (debuglevel > 0)
 		printk("R");
 
-	for(;(status = p->rfd_top->stat_high) & RFD_COMPL;)
-	{
-			rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
-
-			if(status & RFD_OK) /* frame received without error? */
-			{
-				if( (totlen = rbd->status) & RBD_LAST) /* the first and the last buffer? */
-				{
-					totlen &= RBD_MASK; /* length of this frame */
-					rbd->status = 0;
-					skb = (struct sk_buff *) dev_alloc_skb(totlen+2);
-					if(skb != NULL)
-					{
-						skb_reserve(skb,2);
-						skb_put(skb,totlen);
-						skb_copy_to_linear_data(skb,(char *) p->base+(unsigned long) rbd->buffer,totlen);
-						skb->protocol=eth_type_trans(skb,dev);
-						netif_rx(skb);
-						dev->last_rx = jiffies;
-						p->stats.rx_packets++;
-						p->stats.rx_bytes += totlen;
+	for (; (status = readb(&p->rfd_top->stat_high)) & RFD_COMPL;) {
+		rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
+		if (status & RFD_OK) { /* frame received without error? */
+			totlen = readw(&rbd->status);
+			if (totlen & RBD_LAST) {
+				/* the first and the last buffer? */
+				totlen &= RBD_MASK; /* length of this frame */
+				writew(0x00, &rbd->status);
+				skb = (struct sk_buff *)dev_alloc_skb(totlen+2);
+				if (skb != NULL) {
+					skb_reserve(skb, 2);
+					skb_put(skb, totlen);
+					skb_copy_to_linear_data(skb, (char *)p->base + (unsigned long) rbd->buffer, totlen);
+					skb->protocol = eth_type_trans(skb, dev);
+					netif_rx(skb);
+					dev->last_rx = jiffies;
+					p->stats.rx_packets++;
+					p->stats.rx_bytes += totlen;
+				} else
+					p->stats.rx_dropped++;
+			} else {
+				int rstat;
+				 /* free all RBD's until RBD_LAST is set */
+				totlen = 0;
+				while (!((rstat = readw(&rbd->status)) & RBD_LAST)) {
+					totlen += rstat & RBD_MASK;
+					if (!rstat) {
+						printk(KERN_ERR "%s: Whoops .. no end mark in RBD list\n", dev->name);
+						break;
 					}
-					else
-						p->stats.rx_dropped++;
+					writew(0, &rbd->status);
+					rbd = (struct rbd_struct *) make32(readl(&rbd->next));
 				}
-				else
-				{
-					int rstat;
-						 /* free all RBD's until RBD_LAST is set */
-					totlen = 0;
-					while(!((rstat=rbd->status) & RBD_LAST))
-					{
-						totlen += rstat & RBD_MASK;
-						if(!rstat)
-						{
-							printk("%s: Whoops .. no end mark in RBD list\n",dev->name);
-							break;
-						}
-						rbd->status = 0;
-						rbd = (struct rbd_struct *) make32(rbd->next);
-					}
-					totlen += rstat & RBD_MASK;
-					rbd->status = 0;
-					printk("%s: received oversized frame! length: %d\n",dev->name,totlen);
-					p->stats.rx_dropped++;
+				totlen += rstat & RBD_MASK;
+				writew(0, &rbd->status);
+				printk(KERN_ERR "%s: received oversized frame! length: %d\n",
+					dev->name, totlen);
+				p->stats.rx_dropped++;
 			 }
-		}
-		else /* frame !(ok), only with 'save-bad-frames' */
-		{
-			printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);
+		} else {/* frame !(ok), only with 'save-bad-frames' */
+			printk(KERN_ERR "%s: oops! rfd-error-status: %04x\n",
+				dev->name, status);
 			p->stats.rx_errors++;
 		}
-		p->rfd_top->stat_high = 0;
-		p->rfd_top->last = RFD_SUSP; /* maybe exchange by RFD_LAST */
-		p->rfd_top->rbd_offset = 0xffff;
-		p->rfd_last->last = 0;				/* delete RFD_SUSP	*/
+		writeb(0, &p->rfd_top->stat_high);
+		writeb(RFD_SUSP, &p->rfd_top->last); /* maybe exchange by RFD_LAST */
+		writew(0xffff, &p->rfd_top->rbd_offset);
+		writeb(0, &p->rfd_last->last);	/* delete RFD_SUSP	*/
 		p->rfd_last = p->rfd_top;
 		p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
-		p->scb->rfa_offset = make16(p->rfd_top);
+		writew(make16(p->rfd_top), &p->scb->rfa_offset);
 
-		if(debuglevel > 0)
-			printk("%d",cnt++);
+		if (debuglevel > 0)
+			printk("%d", cnt++);
 	}
 
-	if(automatic_resume)
-	{
-		WAIT_4_SCB_CMD();
-		p->scb->cmd_ruc = RUC_RESUME;
+	if (automatic_resume) {
+		wait_for_scb_cmd(dev);
+		writeb(RUC_RESUME, &p->scb->cmd_ruc);
 		ni_attn586();
-		WAIT_4_SCB_CMD_RUC();
+		wait_for_scb_cmd_ruc(dev);
 	}
 
 #ifdef WAIT_4_BUSY
 	{
 		int i;
-		for(i=0;i<1024;i++)
-		{
-			if(p->rfd_top->status)
+		for (i = 0; i < 1024; i++) {
+			if (p->rfd_top->status)
 				break;
-			DELAY_16();
-			if(i == 1023)
-				printk("%s: RU hasn't fetched next RFD (not busy/complete)\n",dev->name);
+			udelay(16);
+			if (i == 1023)
+				printk(KERN_ERR "%s: RU hasn't fetched next RFD (not busy/complete)\n", dev->name);
 		}
 	}
 #endif
-
-#if 0
-	if(!at_least_one)
-	{
-		int i;
-		volatile struct rfd_struct *rfds=p->rfd_top;
-		volatile struct rbd_struct *rbds;
-		printk("%s: received a FC intr. without having a frame: %04x %d\n",dev->name,status,old_at_least);
-		for(i=0;i< (p->num_recv_buffs+4);i++)
-		{
-			rbds = (struct rbd_struct *) make32(rfds->rbd_offset);
-			printk("%04x:%04x ",rfds->status,rbds->status);
-			rfds = (struct rfd_struct *) make32(rfds->next);
-		}
-		printk("\nerrs: %04x %04x stat: %04x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->status);
-		printk("\nerrs: %04x %04x rus: %02x, cus: %02x\n",(int)p->scb->rsc_errs,(int)p->scb->ovrn_errs,(int)p->scb->rus,(int)p->scb->cus);
-	}
-	old_at_least = at_least_one;
-#endif
-
-	if(debuglevel > 0)
+	if (debuglevel > 0)
 		printk("r");
 }
 
@@ -1038,16 +1037,16 @@ static void ni52_rnr_int(struct net_device *dev)
 
 	p->stats.rx_errors++;
 
-	WAIT_4_SCB_CMD();		/* wait for the last cmd, WAIT_4_FULLSTAT?? */
-	p->scb->cmd_ruc = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
+	wait_for_scb_cmd(dev);		/* wait for the last cmd, WAIT_4_FULLSTAT?? */
+	writeb(RUC_ABORT, &p->scb->cmd_ruc); /* usually the RU is in the 'no resource'-state .. abort it now. */
 	ni_attn586();
-	WAIT_4_SCB_CMD_RUC();		/* wait for accept cmd. */
+	wait_for_scb_cmd_ruc(dev);		/* wait for accept cmd. */
 
-	alloc_rfa(dev,(char *)p->rfd_first);
-/* maybe add a check here, before restarting the RU */
+	alloc_rfa(dev, (char *)p->rfd_first);
+	/* maybe add a check here, before restarting the RU */
 	startrecv586(dev); /* restart RU */
 
-	printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->rus);
+	printk(KERN_ERR "%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->rus);
 
 }
 
@@ -1060,43 +1059,41 @@ static void ni52_xmt_int(struct net_device *dev)
 	int status;
 	struct priv *p = (struct priv *) dev->priv;
 
-	if(debuglevel > 0)
+	if (debuglevel > 0)
 		printk("X");
 
-	status = p->xmit_cmds[p->xmit_last]->cmd_status;
-	if(!(status & STAT_COMPL))
-		printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);
+	status = readw(&p->xmit_cmds[p->xmit_last]->cmd_status);
+	if (!(status & STAT_COMPL))
+		printk(KERN_ERR "%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
 
-	if(status & STAT_OK)
-	{
+	if (status & STAT_OK) {
 		p->stats.tx_packets++;
 		p->stats.collisions += (status & TCMD_MAXCOLLMASK);
-	}
-	else
-	{
+	} else {
 		p->stats.tx_errors++;
-		if(status & TCMD_LATECOLL) {
-			printk("%s: late collision detected.\n",dev->name);
+		if (status & TCMD_LATECOLL) {
+			printk(KERN_ERR "%s: late collision detected.\n",
+				dev->name);
 			p->stats.collisions++;
-		}
-		else if(status & TCMD_NOCARRIER) {
+		} else if (status & TCMD_NOCARRIER) {
 			p->stats.tx_carrier_errors++;
-			printk("%s: no carrier detected.\n",dev->name);
-		}
-		else if(status & TCMD_LOSTCTS)
-			printk("%s: loss of CTS detected.\n",dev->name);
-		else if(status & TCMD_UNDERRUN) {
+			printk(KERN_ERR "%s: no carrier detected.\n",
+				dev->name);
+		} else if (status & TCMD_LOSTCTS)
+			printk(KERN_ERR "%s: loss of CTS detected.\n",
+				dev->name);
+		else if (status & TCMD_UNDERRUN) {
 			p->stats.tx_fifo_errors++;
-			printk("%s: DMA underrun detected.\n",dev->name);
-		}
-		else if(status & TCMD_MAXCOLL) {
-			printk("%s: Max. collisions exceeded.\n",dev->name);
+			printk(KERN_ERR "%s: DMA underrun detected.\n",
+				dev->name);
+		} else if (status & TCMD_MAXCOLL) {
+			printk(KERN_ERR "%s: Max. collisions exceeded.\n",
+				dev->name);
 			p->stats.collisions += 16;
 		}
 	}
-
 #if (NUM_XMIT_BUFFS > 1)
-	if( (++p->xmit_last) == NUM_XMIT_BUFFS)
+	if ((++p->xmit_last) == NUM_XMIT_BUFFS)
 		p->xmit_last = 0;
 #endif
 	netif_wake_queue(dev);
@@ -1110,41 +1107,51 @@ static void startrecv586(struct net_device *dev)
 {
 	struct priv *p = (struct priv *) dev->priv;
 
-	WAIT_4_SCB_CMD();
-	WAIT_4_SCB_CMD_RUC();
-	p->scb->rfa_offset = make16(p->rfd_first);
-	p->scb->cmd_ruc = RUC_START;
+	wait_for_scb_cmd(dev);
+	wait_for_scb_cmd_ruc(dev);
+	writew(make16(p->rfd_first), &p->scb->rfa_offset);
+	writeb(RUC_START, &p->scb->cmd_ruc);
 	ni_attn586();		/* start cmd. */
-	WAIT_4_SCB_CMD_RUC();	/* wait for accept cmd. (no timeout!!) */
+	wait_for_scb_cmd_ruc(dev);
+	/* wait for accept cmd. (no timeout!!) */
 }
 
 static void ni52_timeout(struct net_device *dev)
 {
 	struct priv *p = (struct priv *) dev->priv;
 #ifndef NO_NOPCOMMANDS
-	if(p->scb->cus & CU_ACTIVE) /* COMMAND-UNIT active? */
-	{
+	if (readb(&p->scb->cus) & CU_ACTIVE) { /* COMMAND-UNIT active? */
 		netif_wake_queue(dev);
 #ifdef DEBUG
-		printk("%s: strange ... timeout with CU active?!?\n",dev->name);
-		printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)p->xmit_cmds[0]->cmd_status,(int)p->nop_cmds[0]->cmd_status,(int)p->nop_cmds[1]->cmd_status,(int)p->nop_point);
+		printk(KERN_ERR "%s: strange ... timeout with CU active?!?\n",
+			dev->name);
+		printk(KERN_ERR "%s: X0: %04x N0: %04x N1: %04x %d\n",
+			dev->name, (int)p->xmit_cmds[0]->cmd_status,
+			readw(&p->nop_cmds[0]->cmd_status),
+			readw(&p->nop_cmds[1]->cmd_status),
+			p->nop_point);
 #endif
-		p->scb->cmd_cuc = CUC_ABORT;
+		writeb(CUC_ABORT, &p->scb->cmd_cuc);
 		ni_attn586();
-		WAIT_4_SCB_CMD();
-		p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
-		p->scb->cmd_cuc = CUC_START;
+		wait_for_scb_cmd(dev);
+		writew(make16(p->nop_cmds[p->nop_point]), &p->scb->cbl_offset);
+		writeb(CUC_START, &p->scb->cmd_cuc);
 		ni_attn586();
-		WAIT_4_SCB_CMD();
+		wait_for_scb_cmd(dev);
 		dev->trans_start = jiffies;
 		return 0;
 	}
 #endif
 	{
 #ifdef DEBUG
-		printk("%s: xmitter timed out, try to restart! stat: %02x\n",dev->name,p->scb->cus);
-		printk("%s: command-stats: %04x %04x\n",dev->name,p->xmit_cmds[0]->cmd_status,p->xmit_cmds[1]->cmd_status);
-		printk("%s: check, whether you set the right interrupt number!\n",dev->name);
+		printk(KERN_ERR "%s: xmitter timed out, try to restart! stat: %02x\n",
+				dev->name, readb(&p->scb->cus));
+		printk(KERN_ERR "%s: command-stats: %04x %04x\n",
+				dev->name,
+				readw(&p->xmit_cmds[0]->cmd_status),
+				readw(&p->xmit_cmds[1]->cmd_status));
+		printk(KERN_ERR "%s: check, whether you set the right interrupt number!\n",
+				dev->name);
 #endif
 		ni52_close(dev);
 		ni52_open(dev);
@@ -1158,110 +1165,99 @@ static void ni52_timeout(struct net_device *dev)
 
 static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
-	int len,i;
+	int len, i;
 #ifndef NO_NOPCOMMANDS
 	int next_nop;
 #endif
 	struct priv *p = (struct priv *) dev->priv;
 
-	if(skb->len > XMIT_BUFF_SIZE)
-	{
-		printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len);
+	if (skb->len > XMIT_BUFF_SIZE) {
+		printk(KERN_ERR "%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n", dev->name, XMIT_BUFF_SIZE, skb->len);
 		return 0;
 	}
 
 	netif_stop_queue(dev);
 
-#if(NUM_XMIT_BUFFS > 1)
-	if(test_and_set_bit(0,(void *) &p->lock)) {
-		printk("%s: Queue was locked\n",dev->name);
-		return 1;
+	skb_copy_from_linear_data(skb, (char *)p->xmit_cbuffs[p->xmit_count],
+							skb->len);
+	len = skb->len;
+	if (len < ETH_ZLEN) {
+		len = ETH_ZLEN;
+		memset((char *)p->xmit_cbuffs[p->xmit_count]+skb->len, 0,
+							len - skb->len);
 	}
-	else
-#endif
-	{
-		skb_copy_from_linear_data(skb, (char *) p->xmit_cbuffs[p->xmit_count], skb->len);
-		len = skb->len;
-		if (len < ETH_ZLEN) {
-			len = ETH_ZLEN;
-			memset((char *)p->xmit_cbuffs[p->xmit_count]+skb->len, 0, len - skb->len);
-		}
 
 #if (NUM_XMIT_BUFFS == 1)
 #	ifdef NO_NOPCOMMANDS
 
 #ifdef DEBUG
-		if(p->scb->cus & CU_ACTIVE)
-		{
-			printk("%s: Hmmm .. CU is still running and we wanna send a new packet.\n",dev->name);
-			printk("%s: stat: %04x %04x\n",dev->name,p->scb->cus,p->xmit_cmds[0]->cmd_status);
-		}
+	if (p->scb->cus & CU_ACTIVE) {
+		printk(KERN_ERR "%s: Hmmm .. CU is still running and we wanna send a new packet.\n", dev->name);
+		printk(KERN_ERR "%s: stat: %04x %04x\n",
+				dev->name, readb(&p->scb->cus),
+				readw(&p->xmit_cmds[0]->cmd_status));
+	}
 #endif
-
-		p->xmit_buffs[0]->size = TBD_LAST | len;
-		for(i=0;i<16;i++)
-		{
-			p->xmit_cmds[0]->cmd_status = 0;
-			WAIT_4_SCB_CMD();
-			if( (p->scb->cus & CU_STATUS) == CU_SUSPEND)
-				p->scb->cmd_cuc = CUC_RESUME;
-			else
-			{
-				p->scb->cbl_offset = make16(p->xmit_cmds[0]);
-				p->scb->cmd_cuc = CUC_START;
-			}
-
-			ni_attn586();
-			dev->trans_start = jiffies;
-			if(!i)
-				dev_kfree_skb(skb);
-			WAIT_4_SCB_CMD();
-			if( (p->scb->cus & CU_ACTIVE)) /* test it, because CU sometimes doesn't start immediately */
-				break;
-			if(p->xmit_cmds[0]->cmd_status)
-				break;
-			if(i==15)
-				printk("%s: Can't start transmit-command.\n",dev->name);
+	writew(TBD_LAST | len, &p->xmit_buffs[0]->size);;
+	for (i = 0; i < 16; i++) {
+		writew(0, &p->xmit_cmds[0]->cmd_status);
+		wait_for_scb_cmd(dev);
+		if ((readb(&p->scb->cus) & CU_STATUS) == CU_SUSPEND)
+			writeb(CUC_RESUME, &p->scb->cmd_cuc);
+		else {
+			writew(make16(p->xmit_cmds[0]), &p->scb->cbl_offset);
+			writeb(CUC_START, &p->scb->cmd_cuc);
 		}
-#	else
-		next_nop = (p->nop_point + 1) & 0x1;
-		p->xmit_buffs[0]->size = TBD_LAST | len;
-
-		p->xmit_cmds[0]->cmd_link	 = p->nop_cmds[next_nop]->cmd_link
-																= make16((p->nop_cmds[next_nop]));
-		p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
-
-		p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
+		ni_attn586();
 		dev->trans_start = jiffies;
-		p->nop_point = next_nop;
-		dev_kfree_skb(skb);
+		if (!i)
+			dev_kfree_skb(skb);
+		wait_for_scb_cmd(dev);
+		/* test it, because CU sometimes doesn't start immediately */
+		if (readb(&p->scb->cus) & CU_ACTIVE)
+			break;
+		if (readw(&p->xmit_cmds[0]->cmd_status))
+			break;
+		if (i == 15)
+			printk(KERN_WARNING "%s: Can't start transmit-command.\n", dev->name);
+	}
+#	else
+	next_nop = (p->nop_point + 1) & 0x1;
+	writew(TBD_LAST | len, &p->xmit_buffs[0]->size);
+	writew(make16(p->nop_cmds[next_nop]), &p->xmit_cmds[0]->cmd_link);
+	writew(make16(p->nop_cmds[next_nop]),
+				&p->nop_cmds[next_nop]->cmd_link);
+	writew(0, &p->xmit_cmds[0]->cmd_status);
+	writew(0, &p->nop_cmds[next_nop]->cmd_status);
+
+	writew(make16(p->xmit_cmds[0]), &p->nop_cmds[p->nop_point]->cmd_link);
+	dev->trans_start = jiffies;
+	p->nop_point = next_nop;
+	dev_kfree_skb(skb);
 #	endif
 #else
-		p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
-		if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS )
-			next_nop = 0;
-
-		p->xmit_cmds[p->xmit_count]->cmd_status	= 0;
-		/* linkpointer of xmit-command already points to next nop cmd */
-		p->nop_cmds[next_nop]->cmd_link = make16((p->nop_cmds[next_nop]));
-		p->nop_cmds[next_nop]->cmd_status = 0;
-
-		p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
-		dev->trans_start = jiffies;
-		p->xmit_count = next_nop;
-
-		{
-			unsigned long flags;
-			save_flags(flags);
-			cli();
-			if(p->xmit_count != p->xmit_last)
-				netif_wake_queue(dev);
-			p->lock = 0;
-			restore_flags(flags);
-		}
-		dev_kfree_skb(skb);
-#endif
+	writew(TBD_LAST | len, &p->xmit_buffs[p->xmit_count]->size);
+	next_nop = p->xmit_count + 1
+	if (next_nop == NUM_XMIT_BUFFS)
+		next_nop = 0;
+	writew(0, &p->xmit_cmds[p->xmit_count]->cmd_status);
+	/* linkpointer of xmit-command already points to next nop cmd */
+	writew(make16(p->nop_cmds[next_nop]),
+				&p->nop_cmds[next_nop]->cmd_link);
+	writew(0, &p->nop_cmds[next_nop]->cmd_status);
+	writew(make16(p->xmit_cmds[p->xmit_count]),
+				&p->nop_cmds[p->xmit_count]->cmd_link);
+	dev->trans_start = jiffies;
+	p->xmit_count = next_nop;
+	{
+		unsigned long flags;
+		spin_lock_irqsave(&p->spinlock);
+		if (p->xmit_count != p->xmit_last)
+			netif_wake_queue(dev);
+		spin_unlock_irqrestore(&p->spinlock);
 	}
+	dev_kfree_skb(skb);
+#endif
 	return 0;
 }
 
@@ -1272,16 +1268,17 @@ static int ni52_send_packet(struct sk_buff *skb, struct net_device *dev)
 static struct net_device_stats *ni52_get_stats(struct net_device *dev)
 {
 	struct priv *p = (struct priv *) dev->priv;
-	unsigned short crc,aln,rsc,ovrn;
-
-	crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */
-	p->scb->crc_errs = 0;
-	aln = p->scb->aln_errs;
-	p->scb->aln_errs = 0;
-	rsc = p->scb->rsc_errs;
-	p->scb->rsc_errs = 0;
-	ovrn = p->scb->ovrn_errs;
-	p->scb->ovrn_errs = 0;
+	unsigned short crc, aln, rsc, ovrn;
+
+	/* Get error-statistics from the ni82586 */
+	crc = readw(&p->scb->crc_errs);
+	writew(0, &p->scb->crc_errs);
+	aln = readw(&p->scb->aln_errs);
+	writew(0, &p->scb->aln_errs);
+	rsc = readw(&p->scb->rsc_errs);
+	writew(0, &p->scb->rsc_errs);
+	ovrn = readw(&p->scb->ovrn_errs);
+	writew(0, &p->scb->ovrn_errs);
 
 	p->stats.rx_crc_errors += crc;
 	p->stats.rx_fifo_errors += ovrn;
@@ -1320,8 +1317,9 @@ MODULE_PARM_DESC(memend, "NI5210 memory end address,required");
 
 int __init init_module(void)
 {
-	if(io <= 0x0 || !memend || !memstart || irq < 2) {
-		printk("ni52: Autoprobing not allowed for modules.\nni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n");
+	if (io <= 0x0 || !memend || !memstart || irq < 2) {
+		printk(KERN_ERR "ni52: Autoprobing not allowed for modules.\n");
+		printk(KERN_ERR "ni52: Set symbols 'io' 'irq' 'memstart' and 'memend'\n");
 		return -ENODEV;
 	}
 	dev_ni52 = ni52_probe(-1);
@@ -1338,42 +1336,6 @@ void __exit cleanup_module(void)
 }
 #endif /* MODULE */
 
-#if 0
-/*
- * DUMP .. we expect a not running CMD unit and enough space
- */
-void ni52_dump(struct net_device *dev,void *ptr)
-{
-	struct priv *p = (struct priv *) dev->priv;
-	struct dump_cmd_struct *dump_cmd = (struct dump_cmd_struct *) ptr;
-	int i;
-
-	p->scb->cmd_cuc = CUC_ABORT;
-	ni_attn586();
-	WAIT_4_SCB_CMD();
-	WAIT_4_SCB_CMD_RUC();
-
-	dump_cmd->cmd_status = 0;
-	dump_cmd->cmd_cmd = CMD_DUMP | CMD_LAST;
-	dump_cmd->dump_offset = make16((dump_cmd + 1));
-	dump_cmd->cmd_link = 0xffff;
-
-	p->scb->cbl_offset = make16(dump_cmd);
-	p->scb->cmd_cuc = CUC_START;
-	ni_attn586();
-	WAIT_4_STAT_COMPL(dump_cmd);
-
-	if( (dump_cmd->cmd_status & (STAT_COMPL|STAT_OK)) != (STAT_COMPL|STAT_OK) )
-				printk("%s: Can't get dump information.\n",dev->name);
-
-	for(i=0;i<170;i++) {
-		printk("%02x ",(int) ((unsigned char *) (dump_cmd + 1))[i]);
-		if(i % 24 == 23)
-			printk("\n");
-	}
-	printk("\n");
-}
-#endif
 MODULE_LICENSE("GPL");
 
 /*
diff --git a/drivers/net/ni52.h b/drivers/net/ni52.h
index a33ea08..1f28a4d 100644
--- a/drivers/net/ni52.h
+++ b/drivers/net/ni52.h
@@ -36,12 +36,12 @@
 
 struct scp_struct
 {
-  unsigned short zero_dum0;	/* has to be zero */
-  unsigned char  sysbus;	/* 0=16Bit,1=8Bit */
-  unsigned char  zero_dum1;	/* has to be zero for 586 */
-  unsigned short zero_dum2;
-  unsigned short zero_dum3;
-  char          *iscp;		/* pointer to the iscp-block */
+	u16 zero_dum0;	/* has to be zero */
+	u8 sysbus;	/* 0=16Bit,1=8Bit */
+	u8 zero_dum1;	/* has to be zero for 586 */
+	u8 zero_dum2;
+	u8 zero_dum3;
+	u32 iscp;		/* pointer to the iscp-block */
 };
 
 
@@ -50,10 +50,10 @@ struct scp_struct
  */
 struct iscp_struct
 {
-  unsigned char  busy;          /* 586 clears after successful init */
-  unsigned char  zero_dummy;    /* has to be zero */
-  unsigned short scb_offset;    /* pointeroffset to the scb_base */
-  char          *scb_base;      /* base-address of all 16-bit offsets */
+	u8 busy;          /* 586 clears after successful init */
+	u8 zero_dummy;    /* has to be zero */
+	u16 scb_offset;    /* pointeroffset to the scb_base */
+	u32 scb_base;      /* base-address of all 16-bit offsets */
 };
 
 /*
@@ -61,16 +61,16 @@ struct iscp_struct
  */
 struct scb_struct
 {
-  unsigned char rus;
-  unsigned char cus;
-  unsigned char cmd_ruc;           /* command word: RU part */
-  unsigned char cmd_cuc;           /* command word: CU part & ACK */
-  unsigned short cbl_offset;    /* pointeroffset, command block list */
-  unsigned short rfa_offset;    /* pointeroffset, receive frame area */
-  unsigned short crc_errs;      /* CRC-Error counter */
-  unsigned short aln_errs;      /* alignmenterror counter */
-  unsigned short rsc_errs;      /* Resourceerror counter */
-  unsigned short ovrn_errs;     /* OVerrunerror counter */
+	u8 rus;
+	u8 cus;
+	u8 cmd_ruc;        /* command word: RU part */
+	u8 cmd_cuc;        /* command word: CU part & ACK */
+	u16 cbl_offset;    /* pointeroffset, command block list */
+	u16 rfa_offset;    /* pointeroffset, receive frame area */
+	u16 crc_errs;      /* CRC-Error counter */
+	u16 aln_errs;      /* alignmenterror counter */
+	u16 rsc_errs;      /* Resourceerror counter */
+	u16 ovrn_errs;     /* OVerrunerror counter */
 };
 
 /*
@@ -119,16 +119,16 @@ struct scb_struct
  */
 struct rfd_struct
 {
-  unsigned char  stat_low;	/* status word */
-  unsigned char  stat_high;	/* status word */
-  unsigned char  rfd_sf;	/* 82596 mode only */
-  unsigned char  last;		/* Bit15,Last Frame on List / Bit14,suspend */
-  unsigned short next;		/* linkoffset to next RFD */
-  unsigned short rbd_offset;	/* pointeroffset to RBD-buffer */
-  unsigned char  dest[6];	/* ethernet-address, destination */
-  unsigned char  source[6];	/* ethernet-address, source */
-  unsigned short length;	/* 802.3 frame-length */
-  unsigned short zero_dummy;	/* dummy */
+	u8  stat_low;	/* status word */
+	u8  stat_high;	/* status word */
+	u8  rfd_sf;	/* 82596 mode only */
+	u8  last;		/* Bit15,Last Frame on List / Bit14,suspend */
+	u16 next;		/* linkoffset to next RFD */
+	u16 rbd_offset;	/* pointeroffset to RBD-buffer */
+	u8  dest[6];	/* ethernet-address, destination */
+	u8  source[6];	/* ethernet-address, source */
+	u16 length;	/* 802.3 frame-length */
+	u16 zero_dummy;	/* dummy */
 };
 
 #define RFD_LAST     0x80	/* last: last rfd in the list */
@@ -153,11 +153,11 @@ struct rfd_struct
  */
 struct rbd_struct
 {
-  unsigned short status;	/* status word,number of used bytes in buff */
-  unsigned short next;		/* pointeroffset to next RBD */
-  char          *buffer;	/* receive buffer address pointer */
-  unsigned short size;		/* size of this buffer */
-  unsigned short zero_dummy;    /* dummy */
+	u16 status;	/* status word,number of used bytes in buff */
+	u16 next;		/* pointeroffset to next RBD */
+	u32 buffer;	/* receive buffer address pointer */
+	u16 size;		/* size of this buffer */
+	u16 zero_dummy;    /* dummy */
 };
 
 #define RBD_LAST	0x8000	/* last buffer */
@@ -195,9 +195,9 @@ struct rbd_struct
  */
 struct nop_cmd_struct
 {
-  unsigned short cmd_status;	/* status of this command */
-  unsigned short cmd_cmd;       /* the command itself (+bits) */
-  unsigned short cmd_link;      /* offsetpointer to next command */
+	u16 cmd_status;	/* status of this command */
+	u16 cmd_cmd;       /* the command itself (+bits) */
+	u16 cmd_link;      /* offsetpointer to next command */
 };
 
 /*
@@ -205,10 +205,10 @@ struct nop_cmd_struct
  */
 struct iasetup_cmd_struct
 {
-  unsigned short cmd_status;
-  unsigned short cmd_cmd;
-  unsigned short cmd_link;
-  unsigned char  iaddr[6];
+	u16 cmd_status;
+	u16 cmd_cmd;
+	u16 cmd_link;
+	u8  iaddr[6];
 };
 
 /*
@@ -216,21 +216,21 @@ struct iasetup_cmd_struct
  */
 struct configure_cmd_struct
 {
-  unsigned short cmd_status;
-  unsigned short cmd_cmd;
-  unsigned short cmd_link;
-  unsigned char  byte_cnt;   /* size of the config-cmd */
-  unsigned char  fifo;       /* fifo/recv monitor */
-  unsigned char  sav_bf;     /* save bad frames (bit7=1)*/
-  unsigned char  adr_len;    /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/
-  unsigned char  priority;   /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */
-  unsigned char  ifs;        /* inter frame spacing */
-  unsigned char  time_low;   /* slot time low */
-  unsigned char  time_high;  /* slot time high(0-2) and max. retries(4-7) */
-  unsigned char  promisc;    /* promisc-mode(0) , et al (1-7) */
-  unsigned char  carr_coll;  /* carrier(0-3)/collision(4-7) stuff */
-  unsigned char  fram_len;   /* minimal frame len */
-  unsigned char  dummy;	     /* dummy */
+	u16 cmd_status;
+	u16 cmd_cmd;
+	u16 cmd_link;
+	u8  byte_cnt;   /* size of the config-cmd */
+	u8  fifo;       /* fifo/recv monitor */
+	u8  sav_bf;     /* save bad frames (bit7=1)*/
+	u8  adr_len;    /* adr_len(0-2),al_loc(3),pream(4-5),loopbak(6-7)*/
+	u8  priority;   /* lin_prio(0-2),exp_prio(4-6),bof_metd(7) */
+	u8  ifs;        /* inter frame spacing */
+	u8  time_low;   /* slot time low */
+	u8  time_high;  /* slot time high(0-2) and max. retries(4-7) */
+	u8  promisc;    /* promisc-mode(0) , et al (1-7) */
+	u8  carr_coll;  /* carrier(0-3)/collision(4-7) stuff */
+	u8  fram_len;   /* minimal frame len */
+	u8  dummy;	     /* dummy */
 };
 
 /*
@@ -238,11 +238,11 @@ struct configure_cmd_struct
  */
 struct mcsetup_cmd_struct
 {
-  unsigned short cmd_status;
-  unsigned short cmd_cmd;
-  unsigned short cmd_link;
-  unsigned short mc_cnt;		/* number of bytes in the MC-List */
-  unsigned char  mc_list[0][6];  	/* pointer to 6 bytes entries */
+	u16 cmd_status;
+	u16 cmd_cmd;
+	u16 cmd_link;
+	u16 mc_cnt;		/* number of bytes in the MC-List */
+	u8  mc_list[0][6];  	/* pointer to 6 bytes entries */
 };
 
 /*
@@ -250,10 +250,10 @@ struct mcsetup_cmd_struct
  */
 struct dump_cmd_struct
 {
-  unsigned short cmd_status;
-  unsigned short cmd_cmd;
-  unsigned short cmd_link;
-  unsigned short dump_offset;    /* pointeroffset to DUMP space */
+	u16 cmd_status;
+	u16 cmd_cmd;
+	u16 cmd_link;
+	u16 dump_offset;    /* pointeroffset to DUMP space */
 };
 
 /*
@@ -261,12 +261,12 @@ struct dump_cmd_struct
  */
 struct transmit_cmd_struct
 {
-  unsigned short cmd_status;
-  unsigned short cmd_cmd;
-  unsigned short cmd_link;
-  unsigned short tbd_offset;	/* pointeroffset to TBD */
-  unsigned char  dest[6];       /* destination address of the frame */
-  unsigned short length;	/* user defined: 802.3 length / Ether type */
+	u16 cmd_status;
+	u16 cmd_cmd;
+	u16 cmd_link;
+	u16 tbd_offset;	/* pointeroffset to TBD */
+	u8  dest[6];       /* destination address of the frame */
+	u16 length;	/* user defined: 802.3 length / Ether type */
 };
 
 #define TCMD_ERRMASK     0x0fa0
@@ -281,10 +281,10 @@ struct transmit_cmd_struct
 
 struct tdr_cmd_struct
 {
-  unsigned short cmd_status;
-  unsigned short cmd_cmd;
-  unsigned short cmd_link;
-  unsigned short status;
+	u16 cmd_status;
+	u16 cmd_cmd;
+	u16 cmd_link;
+	u16 status;
 };
 
 #define TDR_LNK_OK	0x8000	/* No link problem identified */
@@ -298,9 +298,9 @@ struct tdr_cmd_struct
  */
 struct tbd_struct
 {
-  unsigned short size;		/* size + EOF-Flag(15) */
-  unsigned short next;          /* pointeroffset to next TBD */
-  char          *buffer;        /* pointer to buffer */
+	u16 size;		/* size + EOF-Flag(15) */
+	u16 next;          /* pointeroffset to next TBD */
+	u32 buffer;        /* pointer to buffer */
 };
 
 #define TBD_LAST 0x8000         /* EOF-Flag, indicates last buffer in list */
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index c4b74e9..4eb322e 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -174,7 +174,11 @@ static int homepna[MAX_UNITS];
 #define RX_RING_SIZE		(1 << (PCNET32_LOG_RX_BUFFERS))
 #define RX_MAX_RING_SIZE	(1 << (PCNET32_LOG_MAX_RX_BUFFERS))
 
-#define PKT_BUF_SZ		1544
+#define PKT_BUF_SKB		1544
+/* actual buffer length after being aligned */
+#define PKT_BUF_SIZE		(PKT_BUF_SKB - NET_IP_ALIGN)
+/* chip wants twos complement of the (aligned) buffer length */
+#define NEG_BUF_SIZE		(NET_IP_ALIGN - PKT_BUF_SKB)
 
 /* Offsets from base I/O address. */
 #define PCNET32_WIO_RDP		0x10
@@ -604,7 +608,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
 	/* now allocate any new buffers needed */
 	for (; new < size; new++ ) {
 		struct sk_buff *rx_skbuff;
-		new_skb_list[new] = dev_alloc_skb(PKT_BUF_SZ);
+		new_skb_list[new] = dev_alloc_skb(PKT_BUF_SKB);
 		if (!(rx_skbuff = new_skb_list[new])) {
 			/* keep the original lists and buffers */
 			if (netif_msg_drv(lp))
@@ -613,20 +617,20 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
 				       dev->name);
 			goto free_all_new;
 		}
-		skb_reserve(rx_skbuff, 2);
+		skb_reserve(rx_skbuff, NET_IP_ALIGN);
 
 		new_dma_addr_list[new] =
 			    pci_map_single(lp->pci_dev, rx_skbuff->data,
-					   PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
+					   PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
 		new_rx_ring[new].base = cpu_to_le32(new_dma_addr_list[new]);
-		new_rx_ring[new].buf_length = cpu_to_le16(2 - PKT_BUF_SZ);
+		new_rx_ring[new].buf_length = cpu_to_le16(NEG_BUF_SIZE);
 		new_rx_ring[new].status = cpu_to_le16(0x8000);
 	}
 	/* and free any unneeded buffers */
 	for (; new < lp->rx_ring_size; new++) {
 		if (lp->rx_skbuff[new]) {
 			pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[new],
-					 PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
+					 PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
 			dev_kfree_skb(lp->rx_skbuff[new]);
 		}
 	}
@@ -651,7 +655,7 @@ static void pcnet32_realloc_rx_ring(struct net_device *dev,
 	for (; --new >= lp->rx_ring_size; ) {
 		if (new_skb_list[new]) {
 			pci_unmap_single(lp->pci_dev, new_dma_addr_list[new],
-					 PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
+					 PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
 			dev_kfree_skb(new_skb_list[new]);
 		}
 	}
@@ -678,7 +682,7 @@ static void pcnet32_purge_rx_ring(struct net_device *dev)
 		wmb();		/* Make sure adapter sees owner change */
 		if (lp->rx_skbuff[i]) {
 			pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i],
-					 PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
+					 PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
 			dev_kfree_skb_any(lp->rx_skbuff[i]);
 		}
 		lp->rx_skbuff[i] = NULL;
@@ -1201,7 +1205,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
 	pkt_len = (le32_to_cpu(rxp->msg_length) & 0xfff) - 4;
 
 	/* Discard oversize frames. */
-	if (unlikely(pkt_len > PKT_BUF_SZ - 2)) {
+	if (unlikely(pkt_len > PKT_BUF_SIZE)) {
 		if (netif_msg_drv(lp))
 			printk(KERN_ERR "%s: Impossible packet size %d!\n",
 			       dev->name, pkt_len);
@@ -1218,26 +1222,26 @@ static void pcnet32_rx_entry(struct net_device *dev,
 	if (pkt_len > rx_copybreak) {
 		struct sk_buff *newskb;
 
-		if ((newskb = dev_alloc_skb(PKT_BUF_SZ))) {
-			skb_reserve(newskb, 2);
+		if ((newskb = dev_alloc_skb(PKT_BUF_SKB))) {
+			skb_reserve(newskb, NET_IP_ALIGN);
 			skb = lp->rx_skbuff[entry];
 			pci_unmap_single(lp->pci_dev,
 					 lp->rx_dma_addr[entry],
-					 PKT_BUF_SZ - 2,
+					 PKT_BUF_SIZE,
 					 PCI_DMA_FROMDEVICE);
 			skb_put(skb, pkt_len);
 			lp->rx_skbuff[entry] = newskb;
 			lp->rx_dma_addr[entry] =
 					    pci_map_single(lp->pci_dev,
 							   newskb->data,
-							   PKT_BUF_SZ - 2,
+							   PKT_BUF_SIZE,
 							   PCI_DMA_FROMDEVICE);
 			rxp->base = cpu_to_le32(lp->rx_dma_addr[entry]);
 			rx_in_place = 1;
 		} else
 			skb = NULL;
 	} else {
-		skb = dev_alloc_skb(pkt_len + 2);
+		skb = dev_alloc_skb(pkt_len + NET_IP_ALIGN);
 	}
 
 	if (skb == NULL) {
@@ -1250,7 +1254,7 @@ static void pcnet32_rx_entry(struct net_device *dev,
 	}
 	skb->dev = dev;
 	if (!rx_in_place) {
-		skb_reserve(skb, 2);	/* 16 byte align */
+		skb_reserve(skb, NET_IP_ALIGN);
 		skb_put(skb, pkt_len);	/* Make room */
 		pci_dma_sync_single_for_cpu(lp->pci_dev,
 					    lp->rx_dma_addr[entry],
@@ -1291,7 +1295,7 @@ static int pcnet32_rx(struct net_device *dev, int budget)
 		 * The docs say that the buffer length isn't touched, but Andrew
 		 * Boyd of QNX reports that some revs of the 79C965 clear it.
 		 */
-		rxp->buf_length = cpu_to_le16(2 - PKT_BUF_SZ);
+		rxp->buf_length = cpu_to_le16(NEG_BUF_SIZE);
 		wmb();	/* Make sure owner changes after others are visible */
 		rxp->status = cpu_to_le16(0x8000);
 		entry = (++lp->cur_rx) & lp->rx_mod_mask;
@@ -1774,8 +1778,8 @@ pcnet32_probe1(unsigned long ioaddr, int shared, struct pci_dev *pdev)
 		memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
 
 	if (pcnet32_debug & NETIF_MSG_PROBE) {
-		for (i = 0; i < 6; i++)
-			printk(" %2.2x", dev->dev_addr[i]);
+		DECLARE_MAC_BUF(mac);
+		printk(" %s", print_mac(mac, dev->dev_addr));
 
 		/* Version 0x2623 and 0x2624 */
 		if (((chip_version + 1) & 0xfffe) == 0x2624) {
@@ -2396,7 +2400,7 @@ static int pcnet32_init_ring(struct net_device *dev)
 		if (rx_skbuff == NULL) {
 			if (!
 			    (rx_skbuff = lp->rx_skbuff[i] =
-			     dev_alloc_skb(PKT_BUF_SZ))) {
+			     dev_alloc_skb(PKT_BUF_SKB))) {
 				/* there is not much, we can do at this point */
 				if (netif_msg_drv(lp))
 					printk(KERN_ERR
@@ -2404,16 +2408,16 @@ static int pcnet32_init_ring(struct net_device *dev)
 					       dev->name);
 				return -1;
 			}
-			skb_reserve(rx_skbuff, 2);
+			skb_reserve(rx_skbuff, NET_IP_ALIGN);
 		}
 
 		rmb();
 		if (lp->rx_dma_addr[i] == 0)
 			lp->rx_dma_addr[i] =
 			    pci_map_single(lp->pci_dev, rx_skbuff->data,
-					   PKT_BUF_SZ - 2, PCI_DMA_FROMDEVICE);
+					   PKT_BUF_SIZE, PCI_DMA_FROMDEVICE);
 		lp->rx_ring[i].base = cpu_to_le32(lp->rx_dma_addr[i]);
-		lp->rx_ring[i].buf_length = cpu_to_le16(2 - PKT_BUF_SZ);
+		lp->rx_ring[i].buf_length = cpu_to_le16(NEG_BUF_SIZE);
 		wmb();		/* Make sure owner changes after all others are visible */
 		lp->rx_ring[i].status = cpu_to_le16(0x8000);
 	}
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index 73b6d39..ca9b040 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -236,12 +236,12 @@ module_init(fixed_mdio_bus_init);
 static void __exit fixed_mdio_bus_exit(void)
 {
 	struct fixed_mdio_bus *fmb = &platform_fmb;
-	struct fixed_phy *fp;
+	struct fixed_phy *fp, *tmp;
 
 	mdiobus_unregister(&fmb->mii_bus);
 	platform_device_unregister(pdev);
 
-	list_for_each_entry(fp, &fmb->phys, node) {
+	list_for_each_entry_safe(fp, tmp, &fmb->phys, node) {
 		list_del(&fp->node);
 		kfree(fp);
 	}
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 055af08..7eb6e7e 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -46,29 +46,25 @@
 #include <asm/lv1call.h>
 
 #include "ps3_gelic_net.h"
+#include "ps3_gelic_wireless.h"
 
 #define DRV_NAME "Gelic Network Driver"
-#define DRV_VERSION "1.0"
+#define DRV_VERSION "2.0"
 
 MODULE_AUTHOR("SCE Inc.");
 MODULE_DESCRIPTION("Gelic Network driver");
 MODULE_LICENSE("GPL");
 
-static inline struct device *ctodev(struct gelic_net_card *card)
-{
-	return &card->dev->core;
-}
-static inline u64 bus_id(struct gelic_net_card *card)
-{
-	return card->dev->bus_id;
-}
-static inline u64 dev_id(struct gelic_net_card *card)
-{
-	return card->dev->dev_id;
-}
+
+static inline void gelic_card_enable_rxdmac(struct gelic_card *card);
+static inline void gelic_card_disable_rxdmac(struct gelic_card *card);
+static inline void gelic_card_disable_txdmac(struct gelic_card *card);
+static inline void gelic_card_reset_chain(struct gelic_card *card,
+					  struct gelic_descr_chain *chain,
+					  struct gelic_descr *start_descr);
 
 /* set irq_mask */
-static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask)
+int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask)
 {
 	int status;
 
@@ -76,54 +72,110 @@ static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask)
 					    mask, 0);
 	if (status)
 		dev_info(ctodev(card),
-			 "lv1_net_set_interrupt_mask failed %d\n", status);
+			 "%s failed %d\n", __func__, status);
 	return status;
 }
-static inline void gelic_net_rx_irq_on(struct gelic_net_card *card)
+
+static inline void gelic_card_rx_irq_on(struct gelic_card *card)
 {
-	gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT);
+	card->irq_mask |= GELIC_CARD_RXINT;
+	gelic_card_set_irq_mask(card, card->irq_mask);
 }
-static inline void gelic_net_rx_irq_off(struct gelic_net_card *card)
+static inline void gelic_card_rx_irq_off(struct gelic_card *card)
 {
-	gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT);
+	card->irq_mask &= ~GELIC_CARD_RXINT;
+	gelic_card_set_irq_mask(card, card->irq_mask);
+}
+
+static void gelic_card_get_ether_port_status(struct gelic_card *card,
+					     int inform)
+{
+	u64 v2;
+	struct net_device *ether_netdev;
+
+	lv1_net_control(bus_id(card), dev_id(card),
+			GELIC_LV1_GET_ETH_PORT_STATUS,
+			GELIC_LV1_VLAN_TX_ETHERNET, 0, 0,
+			&card->ether_port_status, &v2);
+
+	if (inform) {
+		ether_netdev = card->netdev[GELIC_PORT_ETHERNET];
+		if (card->ether_port_status & GELIC_LV1_ETHER_LINK_UP)
+			netif_carrier_on(ether_netdev);
+		else
+			netif_carrier_off(ether_netdev);
+	}
+}
+
+void gelic_card_up(struct gelic_card *card)
+{
+	pr_debug("%s: called\n", __func__);
+	down(&card->updown_lock);
+	if (atomic_inc_return(&card->users) == 1) {
+		pr_debug("%s: real do\n", __func__);
+		/* enable irq */
+		gelic_card_set_irq_mask(card, card->irq_mask);
+		/* start rx */
+		gelic_card_enable_rxdmac(card);
+
+		napi_enable(&card->napi);
+	}
+	up(&card->updown_lock);
+	pr_debug("%s: done\n", __func__);
 }
+
+void gelic_card_down(struct gelic_card *card)
+{
+	u64 mask;
+	pr_debug("%s: called\n", __func__);
+	down(&card->updown_lock);
+	if (atomic_dec_if_positive(&card->users) == 0) {
+		pr_debug("%s: real do\n", __func__);
+		napi_disable(&card->napi);
+		/*
+		 * Disable irq. Wireless interrupts will
+		 * be disabled later if any
+		 */
+		mask = card->irq_mask & (GELIC_CARD_WLAN_EVENT_RECEIVED |
+					 GELIC_CARD_WLAN_COMMAND_COMPLETED);
+		gelic_card_set_irq_mask(card, mask);
+		/* stop rx */
+		gelic_card_disable_rxdmac(card);
+		gelic_card_reset_chain(card, &card->rx_chain,
+				       card->descr + GELIC_NET_TX_DESCRIPTORS);
+		/* stop tx */
+		gelic_card_disable_txdmac(card);
+	}
+	up(&card->updown_lock);
+	pr_debug("%s: done\n", __func__);
+}
+
 /**
- * gelic_net_get_descr_status -- returns the status of a descriptor
+ * gelic_descr_get_status -- returns the status of a descriptor
  * @descr: descriptor to look at
  *
  * returns the status as in the dmac_cmd_status field of the descriptor
  */
-static enum gelic_net_descr_status
-gelic_net_get_descr_status(struct gelic_net_descr *descr)
+static enum gelic_descr_dma_status
+gelic_descr_get_status(struct gelic_descr *descr)
 {
-	u32 cmd_status;
-
-	cmd_status = descr->dmac_cmd_status;
-	cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT;
-	return cmd_status;
+	return be32_to_cpu(descr->dmac_cmd_status) & GELIC_DESCR_DMA_STAT_MASK;
 }
 
 /**
- * gelic_net_set_descr_status -- sets the status of a descriptor
+ * gelic_descr_set_status -- sets the status of a descriptor
  * @descr: descriptor to change
  * @status: status to set in the descriptor
  *
  * changes the status to the specified value. Doesn't change other bits
  * in the status
  */
-static void gelic_net_set_descr_status(struct gelic_net_descr *descr,
-				       enum gelic_net_descr_status status)
+static void gelic_descr_set_status(struct gelic_descr *descr,
+				   enum gelic_descr_dma_status status)
 {
-	u32 cmd_status;
-
-	/* read the status */
-	cmd_status = descr->dmac_cmd_status;
-	/* clean the upper 4 bits */
-	cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO;
-	/* add the status to it */
-	cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT;
-	/* and write it back */
-	descr->dmac_cmd_status = cmd_status;
+	descr->dmac_cmd_status = cpu_to_be32(status |
+			(be32_to_cpu(descr->dmac_cmd_status) &
+			 ~GELIC_DESCR_DMA_STAT_MASK));
 	/*
 	 * dma_cmd_status field is used to indicate whether the descriptor
 	 * is valid or not.
@@ -134,24 +186,24 @@ static void gelic_net_set_descr_status(struct gelic_net_descr *descr,
 }
 
 /**
- * gelic_net_free_chain - free descriptor chain
+ * gelic_card_free_chain - free descriptor chain
  * @card: card structure
  * @descr_in: address of desc
  */
-static void gelic_net_free_chain(struct gelic_net_card *card,
-				 struct gelic_net_descr *descr_in)
+static void gelic_card_free_chain(struct gelic_card *card,
+				  struct gelic_descr *descr_in)
 {
-	struct gelic_net_descr *descr;
+	struct gelic_descr *descr;
 
 	for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) {
 		dma_unmap_single(ctodev(card), descr->bus_addr,
-				 GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL);
+				 GELIC_DESCR_SIZE, DMA_BIDIRECTIONAL);
 		descr->bus_addr = 0;
 	}
 }
 
 /**
- * gelic_net_init_chain - links descriptor chain
+ * gelic_card_init_chain - links descriptor chain
  * @card: card structure
  * @chain: address of chain
  * @start_descr: address of descriptor array
@@ -162,22 +214,22 @@ static void gelic_net_free_chain(struct gelic_net_card *card,
  *
  * returns 0 on success, <0 on failure
  */
-static int gelic_net_init_chain(struct gelic_net_card *card,
-				struct gelic_net_descr_chain *chain,
-				struct gelic_net_descr *start_descr, int no)
+static int gelic_card_init_chain(struct gelic_card *card,
+				 struct gelic_descr_chain *chain,
+				 struct gelic_descr *start_descr, int no)
 {
 	int i;
-	struct gelic_net_descr *descr;
+	struct gelic_descr *descr;
 
 	descr = start_descr;
 	memset(descr, 0, sizeof(*descr) * no);
 
 	/* set up the hardware pointers in each descriptor */
 	for (i = 0; i < no; i++, descr++) {
-		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+		gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
 		descr->bus_addr =
 			dma_map_single(ctodev(card), descr,
-				       GELIC_NET_DESCR_SIZE,
+				       GELIC_DESCR_SIZE,
 				       DMA_BIDIRECTIONAL);
 
 		if (!descr->bus_addr)
@@ -193,7 +245,7 @@ static int gelic_net_init_chain(struct gelic_net_card *card,
 	/* chain bus addr of hw descriptor */
 	descr = start_descr;
 	for (i = 0; i < no; i++, descr++) {
-		descr->next_descr_addr = descr->next->bus_addr;
+		descr->next_descr_addr = cpu_to_be32(descr->next->bus_addr);
 	}
 
 	chain->head = start_descr;
@@ -208,13 +260,38 @@ iommu_error:
 	for (i--, descr--; 0 <= i; i--, descr--)
 		if (descr->bus_addr)
 			dma_unmap_single(ctodev(card), descr->bus_addr,
-					 GELIC_NET_DESCR_SIZE,
+					 GELIC_DESCR_SIZE,
 					 DMA_BIDIRECTIONAL);
 	return -ENOMEM;
 }
 
 /**
- * gelic_net_prepare_rx_descr - reinitializes a rx descriptor
+ * gelic_card_reset_chain - reset status of a descriptor chain
+ * @card: card structure
+ * @chain: address of chain
+ * @start_descr: address of descriptor array
+ *
+ * Reset the status of dma descriptors to ready state
+ * and re-initialize the hardware chain for later use
+ */
+static void gelic_card_reset_chain(struct gelic_card *card,
+				   struct gelic_descr_chain *chain,
+				   struct gelic_descr *start_descr)
+{
+	struct gelic_descr *descr;
+
+	for (descr = start_descr; start_descr != descr->next; descr++) {
+		gelic_descr_set_status(descr, GELIC_DESCR_DMA_CARDOWNED);
+		descr->next_descr_addr = cpu_to_be32(descr->next->bus_addr);
+	}
+
+	chain->head = start_descr;
+	chain->tail = (descr - 1);
+
+	(descr - 1)->next_descr_addr = 0;
+}
+/**
+ * gelic_descr_prepare_rx - reinitializes a rx descriptor
  * @card: card structure
  * @descr: descriptor to re-init
  *
@@ -223,29 +300,27 @@ iommu_error:
  * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
  * Activate the descriptor state-wise
  */
-static int gelic_net_prepare_rx_descr(struct gelic_net_card *card,
-				      struct gelic_net_descr *descr)
+static int gelic_descr_prepare_rx(struct gelic_card *card,
+				  struct gelic_descr *descr)
 {
 	int offset;
 	unsigned int bufsize;
 
-	if (gelic_net_get_descr_status(descr) !=  GELIC_NET_DESCR_NOT_IN_USE) {
+	if (gelic_descr_get_status(descr) !=  GELIC_DESCR_DMA_NOT_IN_USE)
 		dev_info(ctodev(card), "%s: ERROR status \n", __func__);
-	}
 	/* we need to round up the buffer size to a multiple of 128 */
 	bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);
 
 	/* and we need to have it 128 byte aligned, therefore we allocate a
 	 * bit more */
-	descr->skb = netdev_alloc_skb(card->netdev,
-		bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+	descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
 	if (!descr->skb) {
 		descr->buf_addr = 0; /* tell DMAC don't touch memory */
 		dev_info(ctodev(card),
 			 "%s:allocate skb failed !!\n", __func__);
 		return -ENOMEM;
 	}
-	descr->buf_size = bufsize;
+	descr->buf_size = cpu_to_be32(bufsize);
 	descr->dmac_cmd_status = 0;
 	descr->result_size = 0;
 	descr->valid_size = 0;
@@ -256,63 +331,64 @@ static int gelic_net_prepare_rx_descr(struct gelic_net_card *card,
 	if (offset)
 		skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
 	/* io-mmu-map the skb */
-	descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data,
-					 GELIC_NET_MAX_MTU,
-					 DMA_FROM_DEVICE);
+	descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card),
+						     descr->skb->data,
+						     GELIC_NET_MAX_MTU,
+						     DMA_FROM_DEVICE));
 	if (!descr->buf_addr) {
 		dev_kfree_skb_any(descr->skb);
 		descr->skb = NULL;
 		dev_info(ctodev(card),
 			 "%s:Could not iommu-map rx buffer\n", __func__);
-		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+		gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
 		return -ENOMEM;
 	} else {
-		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED);
+		gelic_descr_set_status(descr, GELIC_DESCR_DMA_CARDOWNED);
 		return 0;
 	}
 }
 
 /**
- * gelic_net_release_rx_chain - free all skb of rx descr
+ * gelic_card_release_rx_chain - free all skb of rx descr
  * @card: card structure
  *
  */
-static void gelic_net_release_rx_chain(struct gelic_net_card *card)
+static void gelic_card_release_rx_chain(struct gelic_card *card)
 {
-	struct gelic_net_descr *descr = card->rx_chain.head;
+	struct gelic_descr *descr = card->rx_chain.head;
 
 	do {
 		if (descr->skb) {
 			dma_unmap_single(ctodev(card),
-					 descr->buf_addr,
+					 be32_to_cpu(descr->buf_addr),
 					 descr->skb->len,
 					 DMA_FROM_DEVICE);
 			descr->buf_addr = 0;
 			dev_kfree_skb_any(descr->skb);
 			descr->skb = NULL;
-			gelic_net_set_descr_status(descr,
-						   GELIC_NET_DESCR_NOT_IN_USE);
+			gelic_descr_set_status(descr,
+					       GELIC_DESCR_DMA_NOT_IN_USE);
 		}
 		descr = descr->next;
 	} while (descr != card->rx_chain.head);
 }
 
 /**
- * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains
+ * gelic_card_fill_rx_chain - fills descriptors/skbs in the rx chains
  * @card: card structure
  *
  * fills all descriptors in the rx chain: allocates skbs
  * and iommu-maps them.
- * returns 0 on success, <0 on failure
+ * returns 0 on success, < 0 on failure
  */
-static int gelic_net_fill_rx_chain(struct gelic_net_card *card)
+static int gelic_card_fill_rx_chain(struct gelic_card *card)
 {
-	struct gelic_net_descr *descr = card->rx_chain.head;
+	struct gelic_descr *descr = card->rx_chain.head;
 	int ret;
 
 	do {
 		if (!descr->skb) {
-			ret = gelic_net_prepare_rx_descr(card, descr);
+			ret = gelic_descr_prepare_rx(card, descr);
 			if (ret)
 				goto rewind;
 		}
@@ -321,41 +397,41 @@ static int gelic_net_fill_rx_chain(struct gelic_net_card *card)
 
 	return 0;
 rewind:
-	gelic_net_release_rx_chain(card);
+	gelic_card_release_rx_chain(card);
 	return ret;
 }
 
 /**
- * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
+ * gelic_card_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
  * @card: card structure
  *
- * returns 0 on success, <0 on failure
+ * returns 0 on success, < 0 on failure
  */
-static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card)
+static int gelic_card_alloc_rx_skbs(struct gelic_card *card)
 {
-	struct gelic_net_descr_chain *chain;
+	struct gelic_descr_chain *chain;
 	int ret;
 	chain = &card->rx_chain;
-	ret = gelic_net_fill_rx_chain(card);
-	chain->head = card->rx_top->prev; /* point to the last */
+	ret = gelic_card_fill_rx_chain(card);
+	chain->tail = card->rx_top->prev; /* point to the last */
 	return ret;
 }
 
 /**
- * gelic_net_release_tx_descr - processes a used tx descriptor
+ * gelic_descr_release_tx - processes a used tx descriptor
  * @card: card structure
  * @descr: descriptor to release
  *
  * releases a used tx descriptor (unmapping, freeing of skb)
  */
-static void gelic_net_release_tx_descr(struct gelic_net_card *card,
-			    struct gelic_net_descr *descr)
+static void gelic_descr_release_tx(struct gelic_card *card,
+				       struct gelic_descr *descr)
 {
 	struct sk_buff *skb = descr->skb;
 
-	BUG_ON(!(descr->data_status & (1 << GELIC_NET_TXDESC_TAIL)));
+	BUG_ON(!(be32_to_cpu(descr->data_status) & GELIC_DESCR_TX_TAIL));
 
-	dma_unmap_single(ctodev(card), descr->buf_addr, skb->len,
+	dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr), skb->len,
 			 DMA_TO_DEVICE);
 	dev_kfree_skb_any(skb);
 
@@ -369,59 +445,75 @@ static void gelic_net_release_tx_descr(struct gelic_net_card *card,
 	descr->skb = NULL;
 
 	/* set descr status */
-	gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+	gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
+}
+
+static void gelic_card_stop_queues(struct gelic_card *card)
+{
+	netif_stop_queue(card->netdev[GELIC_PORT_ETHERNET]);
+
+	if (card->netdev[GELIC_PORT_WIRELESS])
+		netif_stop_queue(card->netdev[GELIC_PORT_WIRELESS]);
 }
+static void gelic_card_wake_queues(struct gelic_card *card)
+{
+	netif_wake_queue(card->netdev[GELIC_PORT_ETHERNET]);
 
+	if (card->netdev[GELIC_PORT_WIRELESS])
+		netif_wake_queue(card->netdev[GELIC_PORT_WIRELESS]);
+}
 /**
- * gelic_net_release_tx_chain - processes sent tx descriptors
+ * gelic_card_release_tx_chain - processes sent tx descriptors
  * @card: adapter structure
  * @stop: net_stop sequence
  *
  * releases the tx descriptors that gelic has finished with
  */
-static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
+static void gelic_card_release_tx_chain(struct gelic_card *card, int stop)
 {
-	struct gelic_net_descr_chain *tx_chain;
-	enum gelic_net_descr_status status;
+	struct gelic_descr_chain *tx_chain;
+	enum gelic_descr_dma_status status;
+	struct net_device *netdev;
 	int release = 0;
 
 	for (tx_chain = &card->tx_chain;
 	     tx_chain->head != tx_chain->tail && tx_chain->tail;
 	     tx_chain->tail = tx_chain->tail->next) {
-		status = gelic_net_get_descr_status(tx_chain->tail);
+		status = gelic_descr_get_status(tx_chain->tail);
+		netdev = tx_chain->tail->skb->dev;
 		switch (status) {
-		case GELIC_NET_DESCR_RESPONSE_ERROR:
-		case GELIC_NET_DESCR_PROTECTION_ERROR:
-		case GELIC_NET_DESCR_FORCE_END:
+		case GELIC_DESCR_DMA_RESPONSE_ERROR:
+		case GELIC_DESCR_DMA_PROTECTION_ERROR:
+		case GELIC_DESCR_DMA_FORCE_END:
 			if (printk_ratelimit())
 				dev_info(ctodev(card),
 					 "%s: forcing end of tx descriptor " \
 					 "with status %x\n",
 					 __func__, status);
-			card->netdev->stats.tx_dropped++;
+			netdev->stats.tx_dropped++;
 			break;
 
-		case GELIC_NET_DESCR_COMPLETE:
+		case GELIC_DESCR_DMA_COMPLETE:
 			if (tx_chain->tail->skb) {
-				card->netdev->stats.tx_packets++;
-				card->netdev->stats.tx_bytes +=
+				netdev->stats.tx_packets++;
+				netdev->stats.tx_bytes +=
 					tx_chain->tail->skb->len;
 			}
 			break;
 
-		case GELIC_NET_DESCR_CARDOWNED:
+		case GELIC_DESCR_DMA_CARDOWNED:
 			/* pending tx request */
 		default:
-			/* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
+			/* any other value (== GELIC_DESCR_DMA_NOT_IN_USE) */
 			if (!stop)
 				goto out;
 		}
-		gelic_net_release_tx_descr(card, tx_chain->tail);
+		gelic_descr_release_tx(card, tx_chain->tail);
 		release ++;
 	}
 out:
 	if (!stop && release)
-		netif_wake_queue(card->netdev);
+		gelic_card_wake_queues(card);
 }
 
 /**
@@ -432,9 +524,9 @@ out:
  * netdev interface. It also sets up multicast, allmulti and promisc
  * flags appropriately
  */
-static void gelic_net_set_multi(struct net_device *netdev)
+void gelic_net_set_multi(struct net_device *netdev)
 {
-	struct gelic_net_card *card = netdev_priv(netdev);
+	struct gelic_card *card = netdev_card(netdev);
 	struct dev_mc_list *mc;
 	unsigned int i;
 	uint8_t *p;
@@ -456,8 +548,8 @@ static void gelic_net_set_multi(struct net_device *netdev)
 			"lv1_net_add_multicast_address failed, %d\n",
 			status);
 
-	if (netdev->flags & IFF_ALLMULTI
-		|| netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */
+	if ((netdev->flags & IFF_ALLMULTI) ||
+	    (netdev->mc_count > GELIC_NET_MC_COUNT_MAX)) {
 		status = lv1_net_add_multicast_address(bus_id(card),
 						       dev_id(card),
 						       0, 1);
@@ -468,7 +560,7 @@ static void gelic_net_set_multi(struct net_device *netdev)
 		return;
 	}
 
-	/* set multicast address */
+	/* set multicast addresses */
 	for (mc = netdev->mc_list; mc; mc = mc->next) {
 		addr = 0;
 		p = mc->dmi_addr;
@@ -487,31 +579,42 @@ static void gelic_net_set_multi(struct net_device *netdev)
 }
 
 /**
- * gelic_net_enable_rxdmac - enables the receive DMA controller
+ * gelic_card_enable_rxdmac - enables the receive DMA controller
  * @card: card structure
  *
- * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
+ * gelic_card_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
  * in the GDADMACCNTR register
  */
-static inline void gelic_net_enable_rxdmac(struct gelic_net_card *card)
+static inline void gelic_card_enable_rxdmac(struct gelic_card *card)
 {
 	int status;
 
+#ifdef DEBUG
+	if (gelic_descr_get_status(card->rx_chain.head) !=
+	    GELIC_DESCR_DMA_CARDOWNED) {
+		printk(KERN_ERR "%s: status=%x\n", __func__,
+		       be32_to_cpu(card->rx_chain.head->dmac_cmd_status));
+		printk(KERN_ERR "%s: nextphy=%x\n", __func__,
+		       be32_to_cpu(card->rx_chain.head->next_descr_addr));
+		printk(KERN_ERR "%s: head=%p\n", __func__,
+		       card->rx_chain.head);
+	}
+#endif
 	status = lv1_net_start_rx_dma(bus_id(card), dev_id(card),
-				card->rx_chain.tail->bus_addr, 0);
+				card->rx_chain.head->bus_addr, 0);
 	if (status)
 		dev_info(ctodev(card),
 			 "lv1_net_start_rx_dma failed, status=%d\n", status);
 }
 
 /**
- * gelic_net_disable_rxdmac - disables the receive DMA controller
+ * gelic_card_disable_rxdmac - disables the receive DMA controller
  * @card: card structure
  *
- * gelic_net_disable_rxdmac terminates processing on the DMA controller by
+ * gelic_card_disable_rxdmac terminates processing on the DMA controller by
  * turing off DMA and issueing a force end
  */
-static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card)
+static inline void gelic_card_disable_rxdmac(struct gelic_card *card)
 {
 	int status;
 
@@ -523,13 +626,13 @@ static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card)
 }
 
 /**
- * gelic_net_disable_txdmac - disables the transmit DMA controller
+ * gelic_card_disable_txdmac - disables the transmit DMA controller
  * @card: card structure
  *
- * gelic_net_disable_txdmac terminates processing on the DMA controller by
+ * gelic_card_disable_txdmac terminates processing on the DMA controller by
  * turing off DMA and issueing a force end
  */
-static inline void gelic_net_disable_txdmac(struct gelic_net_card *card)
+static inline void gelic_card_disable_txdmac(struct gelic_card *card)
 {
 	int status;
 
@@ -546,51 +649,37 @@ static inline void gelic_net_disable_txdmac(struct gelic_net_card *card)
  *
  * always returns 0
  */
-static int gelic_net_stop(struct net_device *netdev)
+int gelic_net_stop(struct net_device *netdev)
 {
-	struct gelic_net_card *card = netdev_priv(netdev);
-
-	napi_disable(&card->napi);
-	netif_stop_queue(netdev);
+	struct gelic_card *card;
 
-	/* turn off DMA, force end */
-	gelic_net_disable_rxdmac(card);
-	gelic_net_disable_txdmac(card);
-
-	gelic_net_set_irq_mask(card, 0);
-
-	/* disconnect event port */
-	free_irq(card->netdev->irq, card->netdev);
-	ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
-	card->netdev->irq = NO_IRQ;
+	pr_debug("%s: start\n", __func__);
 
+	netif_stop_queue(netdev);
 	netif_carrier_off(netdev);
 
-	/* release chains */
-	gelic_net_release_tx_chain(card, 1);
-	gelic_net_release_rx_chain(card);
-
-	gelic_net_free_chain(card, card->tx_top);
-	gelic_net_free_chain(card, card->rx_top);
+	card = netdev_card(netdev);
+	gelic_card_down(card);
 
+	pr_debug("%s: done\n", __func__);
 	return 0;
 }
 
 /**
- * gelic_net_get_next_tx_descr - returns the next available tx descriptor
+ * gelic_card_get_next_tx_descr - returns the next available tx descriptor
  * @card: device structure to get descriptor from
  *
  * returns the address of the next descriptor, or NULL if not available.
  */
-static struct gelic_net_descr *
-gelic_net_get_next_tx_descr(struct gelic_net_card *card)
+static struct gelic_descr *
+gelic_card_get_next_tx_descr(struct gelic_card *card)
 {
 	if (!card->tx_chain.head)
 		return NULL;
 	/*  see if the next descriptor is free */
 	if (card->tx_chain.tail != card->tx_chain.head->next &&
-	    gelic_net_get_descr_status(card->tx_chain.head) ==
-	    GELIC_NET_DESCR_NOT_IN_USE)
+	    gelic_descr_get_status(card->tx_chain.head) ==
+	    GELIC_DESCR_DMA_NOT_IN_USE)
 		return card->tx_chain.head;
 	else
 		return NULL;
@@ -606,32 +695,33 @@ gelic_net_get_next_tx_descr(struct gelic_net_card *card)
  * depending on hardware checksum settings. This function assumes a wmb()
  * has executed before.
  */
-static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr,
-					  struct sk_buff *skb)
+static void gelic_descr_set_tx_cmdstat(struct gelic_descr *descr,
+				       struct sk_buff *skb)
 {
 	if (skb->ip_summed != CHECKSUM_PARTIAL)
-		descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS |
-			GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+		descr->dmac_cmd_status =
+			cpu_to_be32(GELIC_DESCR_DMA_CMD_NO_CHKSUM |
+				    GELIC_DESCR_TX_DMA_FRAME_TAIL);
 	else {
 		/* is packet ip?
 		 * if yes: tcp? udp? */
 		if (skb->protocol == htons(ETH_P_IP)) {
 			if (ip_hdr(skb)->protocol == IPPROTO_TCP)
 				descr->dmac_cmd_status =
-					GELIC_NET_DMAC_CMDSTAT_TCPCS |
-					GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+				cpu_to_be32(GELIC_DESCR_DMA_CMD_TCP_CHKSUM |
+					    GELIC_DESCR_TX_DMA_FRAME_TAIL);
 
 			else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
 				descr->dmac_cmd_status =
-					GELIC_NET_DMAC_CMDSTAT_UDPCS |
-					GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+				cpu_to_be32(GELIC_DESCR_DMA_CMD_UDP_CHKSUM |
+					    GELIC_DESCR_TX_DMA_FRAME_TAIL);
 			else	/*
 				 * the stack should checksum non-tcp and non-udp
 				 * packets on his own: NETIF_F_IP_CSUM
 				 */
 				descr->dmac_cmd_status =
-					GELIC_NET_DMAC_CMDSTAT_NOCS |
-					GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+				cpu_to_be32(GELIC_DESCR_DMA_CMD_NO_CHKSUM |
+					    GELIC_DESCR_TX_DMA_FRAME_TAIL);
 		}
 	}
 }
@@ -662,7 +752,7 @@ static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb,
 }
 
 /**
- * gelic_net_prepare_tx_descr_v - get dma address of skb_data
+ * gelic_descr_prepare_tx - setup a descriptor for sending packets
  * @card: card structure
  * @descr: descriptor structure
  * @skb: packet to use
@@ -670,16 +760,19 @@ static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb,
  * returns 0 on success, <0 on failure.
  *
  */
-static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
-					struct gelic_net_descr *descr,
-					struct sk_buff *skb)
+static int gelic_descr_prepare_tx(struct gelic_card *card,
+				  struct gelic_descr *descr,
+				  struct sk_buff *skb)
 {
 	dma_addr_t buf;
 
-	if (card->vlan_index != -1) {
+	if (card->vlan_required) {
 		struct sk_buff *skb_tmp;
+		enum gelic_port_type type;
+
+		type = netdev_port(skb->dev)->type;
 		skb_tmp = gelic_put_vlan_tag(skb,
-					     card->vlan_id[card->vlan_index]);
+					     card->vlan[type].tx);
 		if (!skb_tmp)
 			return -ENOMEM;
 		skb = skb_tmp;
@@ -694,12 +787,12 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
 		return -ENOMEM;
 	}
 
-	descr->buf_addr = buf;
-	descr->buf_size = skb->len;
+	descr->buf_addr = cpu_to_be32(buf);
+	descr->buf_size = cpu_to_be32(skb->len);
 	descr->skb = skb;
 	descr->data_status = 0;
 	descr->next_descr_addr = 0; /* terminate hw descr */
-	gelic_net_set_txdescr_cmdstat(descr, skb);
+	gelic_descr_set_tx_cmdstat(descr, skb);
 
 	/* bump free descriptor pointer */
 	card->tx_chain.head = descr->next;
@@ -707,20 +800,20 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
 }
 
 /**
- * gelic_net_kick_txdma - enables TX DMA processing
+ * gelic_card_kick_txdma - enables TX DMA processing
  * @card: card structure
  * @descr: descriptor address to enable TX processing at
  *
  */
-static int gelic_net_kick_txdma(struct gelic_net_card *card,
-				struct gelic_net_descr *descr)
+static int gelic_card_kick_txdma(struct gelic_card *card,
+				 struct gelic_descr *descr)
 {
 	int status = 0;
 
 	if (card->tx_dma_progress)
 		return 0;
 
-	if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) {
+	if (gelic_descr_get_status(descr) == GELIC_DESCR_DMA_CARDOWNED) {
 		card->tx_dma_progress = 1;
 		status = lv1_net_start_tx_dma(bus_id(card), dev_id(card),
 					      descr->bus_addr, 0);
@@ -738,56 +831,56 @@ static int gelic_net_kick_txdma(struct gelic_net_card *card,
  *
  * returns 0 on success, <0 on failure
  */
-static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
-	struct gelic_net_card *card = netdev_priv(netdev);
-	struct gelic_net_descr *descr;
+	struct gelic_card *card = netdev_card(netdev);
+	struct gelic_descr *descr;
 	int result;
 	unsigned long flags;
 
-	spin_lock_irqsave(&card->tx_dma_lock, flags);
+	spin_lock_irqsave(&card->tx_lock, flags);
 
-	gelic_net_release_tx_chain(card, 0);
+	gelic_card_release_tx_chain(card, 0);
 
-	descr = gelic_net_get_next_tx_descr(card);
+	descr = gelic_card_get_next_tx_descr(card);
 	if (!descr) {
 		/*
 		 * no more descriptors free
 		 */
-		netif_stop_queue(netdev);
-		spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+		gelic_card_stop_queues(card);
+		spin_unlock_irqrestore(&card->tx_lock, flags);
 		return NETDEV_TX_BUSY;
 	}
 
-	result = gelic_net_prepare_tx_descr_v(card, descr, skb);
+	result = gelic_descr_prepare_tx(card, descr, skb);
 	if (result) {
 		/*
 		 * DMA map failed.  As chanses are that failure
 		 * would continue, just release skb and return
 		 */
-		card->netdev->stats.tx_dropped++;
+		netdev->stats.tx_dropped++;
 		dev_kfree_skb_any(skb);
-		spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+		spin_unlock_irqrestore(&card->tx_lock, flags);
 		return NETDEV_TX_OK;
 	}
 	/*
 	 * link this prepared descriptor to previous one
 	 * to achieve high performance
 	 */
-	descr->prev->next_descr_addr = descr->bus_addr;
+	descr->prev->next_descr_addr = cpu_to_be32(descr->bus_addr);
 	/*
 	 * as hardware descriptor is modified in the above lines,
 	 * ensure that the hardware sees it
 	 */
 	wmb();
-	if (gelic_net_kick_txdma(card, descr)) {
+	if (gelic_card_kick_txdma(card, descr)) {
 		/*
 		 * kick failed.
 		 * release descriptors which were just prepared
 		 */
-		card->netdev->stats.tx_dropped++;
-		gelic_net_release_tx_descr(card, descr);
-		gelic_net_release_tx_descr(card, descr->next);
+		netdev->stats.tx_dropped++;
+		gelic_descr_release_tx(card, descr);
+		gelic_descr_release_tx(card, descr->next);
 		card->tx_chain.tail = descr->next->next;
 		dev_info(ctodev(card), "%s: kick failure\n", __func__);
 	} else {
@@ -795,7 +888,7 @@ static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 		netdev->trans_start = jiffies;
 	}
 
-	spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+	spin_unlock_irqrestore(&card->tx_lock, flags);
 	return NETDEV_TX_OK;
 }
 
@@ -803,30 +896,34 @@ static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
  * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on
  * @descr: descriptor to process
  * @card: card structure
+ * @netdev: net_device structure to be passed packet
  *
  * iommu-unmaps the skb, fills out skb structure and passes the data to the
  * stack. The descriptor state is not changed.
  */
-static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
-				 struct gelic_net_card *card)
+static void gelic_net_pass_skb_up(struct gelic_descr *descr,
+				  struct gelic_card *card,
+				  struct net_device *netdev)
+
 {
-	struct sk_buff *skb;
-	struct net_device *netdev;
+	struct sk_buff *skb = descr->skb;
 	u32 data_status, data_error;
 
-	data_status = descr->data_status;
-	data_error = descr->data_error;
-	netdev = card->netdev;
+	data_status = be32_to_cpu(descr->data_status);
+	data_error = be32_to_cpu(descr->data_error);
 	/* unmap skb buffer */
-	skb = descr->skb;
-	dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU,
+	dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr),
+			 GELIC_NET_MAX_MTU,
 			 DMA_FROM_DEVICE);
 
-	skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size);
+	skb_put(skb, be32_to_cpu(descr->valid_size)?
+		be32_to_cpu(descr->valid_size) :
+		be32_to_cpu(descr->result_size));
 	if (!descr->valid_size)
 		dev_info(ctodev(card), "buffer full %x %x %x\n",
-			 descr->result_size, descr->buf_size,
-			 descr->dmac_cmd_status);
+			 be32_to_cpu(descr->result_size),
+			 be32_to_cpu(descr->buf_size),
+			 be32_to_cpu(descr->dmac_cmd_status));
 
 	descr->skb = NULL;
 	/*
@@ -838,8 +935,8 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
 
 	/* checksum offload */
 	if (card->rx_csum) {
-		if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) &&
-		    (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK)))
+		if ((data_status & GELIC_DESCR_DATA_STATUS_CHK_MASK) &&
+		    (!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK)))
 			skb->ip_summed = CHECKSUM_UNNECESSARY;
 		else
 			skb->ip_summed = CHECKSUM_NONE;
@@ -847,15 +944,15 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
 		skb->ip_summed = CHECKSUM_NONE;
 
 	/* update netdevice statistics */
-	card->netdev->stats.rx_packets++;
-	card->netdev->stats.rx_bytes += skb->len;
+	netdev->stats.rx_packets++;
+	netdev->stats.rx_bytes += skb->len;
 
 	/* pass skb up to stack */
 	netif_receive_skb(skb);
 }
 
 /**
- * gelic_net_decode_one_descr - processes an rx descriptor
+ * gelic_card_decode_one_descr - processes an rx descriptor
  * @card: card structure
  *
  * returns 1 if a packet has been sent to the stack, otherwise 0
@@ -863,36 +960,56 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
  * processes an rx descriptor by iommu-unmapping the data buffer and passing
  * the packet up to the stack
  */
-static int gelic_net_decode_one_descr(struct gelic_net_card *card)
+static int gelic_card_decode_one_descr(struct gelic_card *card)
 {
-	enum gelic_net_descr_status status;
-	struct gelic_net_descr_chain *chain = &card->rx_chain;
-	struct gelic_net_descr *descr = chain->tail;
+	enum gelic_descr_dma_status status;
+	struct gelic_descr_chain *chain = &card->rx_chain;
+	struct gelic_descr *descr = chain->head;
+	struct net_device *netdev = NULL;
 	int dmac_chain_ended;
 
-	status = gelic_net_get_descr_status(descr);
+	status = gelic_descr_get_status(descr);
 	/* is this descriptor terminated with next_descr == NULL? */
 	dmac_chain_ended =
-		descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS;
+		be32_to_cpu(descr->dmac_cmd_status) &
+		GELIC_DESCR_RX_DMA_CHAIN_END;
 
-	if (status == GELIC_NET_DESCR_CARDOWNED)
+	if (status == GELIC_DESCR_DMA_CARDOWNED)
 		return 0;
 
-	if (status == GELIC_NET_DESCR_NOT_IN_USE) {
+	if (status == GELIC_DESCR_DMA_NOT_IN_USE) {
 		dev_dbg(ctodev(card), "dormant descr? %p\n", descr);
 		return 0;
 	}
 
-	if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) ||
-	    (status == GELIC_NET_DESCR_PROTECTION_ERROR) ||
-	    (status == GELIC_NET_DESCR_FORCE_END)) {
+	/* netdevice select */
+	if (card->vlan_required) {
+		unsigned int i;
+		u16 vid;
+		vid = *(u16 *)(descr->skb->data) & VLAN_VID_MASK;
+		for (i = 0; i < GELIC_PORT_MAX; i++) {
+			if (card->vlan[i].rx == vid) {
+				netdev = card->netdev[i];
+				break;
+			}
+		};
+		if (GELIC_PORT_MAX <= i) {
+			pr_info("%s: unknown packet vid=%x\n", __func__, vid);
+			goto refill;
+		}
+	} else
+		netdev = card->netdev[GELIC_PORT_ETHERNET];
+
+	if ((status == GELIC_DESCR_DMA_RESPONSE_ERROR) ||
+	    (status == GELIC_DESCR_DMA_PROTECTION_ERROR) ||
+	    (status == GELIC_DESCR_DMA_FORCE_END)) {
 		dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
 			 status);
-		card->netdev->stats.rx_dropped++;
+		netdev->stats.rx_dropped++;
 		goto refill;
 	}
 
-	if (status == GELIC_NET_DESCR_BUFFER_FULL) {
+	if (status == GELIC_DESCR_DMA_BUFFER_FULL) {
 		/*
 		 * Buffer full would occur if and only if
 		 * the frame length was longer than the size of this
@@ -909,14 +1026,14 @@ static int gelic_net_decode_one_descr(struct gelic_net_card *card)
 	 * descriptoers any other than FRAME_END here should
 	 * be treated as error.
 	 */
-	if (status != GELIC_NET_DESCR_FRAME_END) {
+	if (status != GELIC_DESCR_DMA_FRAME_END) {
 		dev_dbg(ctodev(card), "RX descriptor with state %x\n",
 			status);
 		goto refill;
 	}
 
 	/* ok, we've got a packet in descr */
-	gelic_net_pass_skb_up(descr, card);
+	gelic_net_pass_skb_up(descr, card, netdev);
 refill:
 	/*
 	 * So that always DMAC can see the end
@@ -926,21 +1043,21 @@ refill:
 	descr->next_descr_addr = 0;
 
 	/* change the descriptor state: */
-	gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+	gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
 
 	/*
 	 * this call can fail, but for now, just leave this
 	 * decriptor without skb
 	 */
-	gelic_net_prepare_rx_descr(card, descr);
+	gelic_descr_prepare_rx(card, descr);
 
-	chain->head = descr;
-	chain->tail = descr->next;
+	chain->tail = descr;
+	chain->head = descr->next;
 
 	/*
 	 * Set this descriptor the end of the chain.
 	 */
-	descr->prev->next_descr_addr = descr->bus_addr;
+	descr->prev->next_descr_addr = cpu_to_be32(descr->bus_addr);
 
 	/*
 	 * If dmac chain was met, DMAC stopped.
@@ -956,29 +1073,27 @@ refill:
 
 /**
  * gelic_net_poll - NAPI poll function called by the stack to return packets
- * @netdev: interface device structure
+ * @napi: napi structure
  * @budget: number of packets we can pass to the stack at most
  *
- * returns 0 if no more packets available to the driver/stack. Returns 1,
- * if the quota is exceeded, but the driver has still packets.
+ * returns the number of the processed packets
  *
  */
 static int gelic_net_poll(struct napi_struct *napi, int budget)
 {
-	struct gelic_net_card *card = container_of(napi, struct gelic_net_card, napi);
-	struct net_device *netdev = card->netdev;
+	struct gelic_card *card = container_of(napi, struct gelic_card, napi);
 	int packets_done = 0;
 
 	while (packets_done < budget) {
-		if (!gelic_net_decode_one_descr(card))
+		if (!gelic_card_decode_one_descr(card))
 			break;
 
 		packets_done++;
 	}
 
 	if (packets_done < budget) {
-		netif_rx_complete(netdev, napi);
-		gelic_net_rx_irq_on(card);
+		napi_complete(napi);
+		gelic_card_rx_irq_on(card);
 	}
 	return packets_done;
 }
@@ -989,7 +1104,7 @@ static int gelic_net_poll(struct napi_struct *napi, int budget)
  *
  * returns 0 on success, <0 on failure
  */
-static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
+int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
 {
 	/* no need to re-alloc skbs or so -- the max mtu is about 2.3k
 	 * and mtu is outbound only anyway */
@@ -1002,13 +1117,12 @@ static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
 }
 
 /**
- * gelic_net_interrupt - event handler for gelic_net
+ * gelic_card_interrupt - event handler for gelic_net
  */
-static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
+static irqreturn_t gelic_card_interrupt(int irq, void *ptr)
 {
 	unsigned long flags;
-	struct net_device *netdev = ptr;
-	struct gelic_net_card *card = netdev_priv(netdev);
+	struct gelic_card *card = ptr;
 	u64 status;
 
 	status = card->irq_status;
@@ -1016,24 +1130,37 @@ static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
 	if (!status)
 		return IRQ_NONE;
 
+	status &= card->irq_mask;
+
 	if (card->rx_dma_restart_required) {
 		card->rx_dma_restart_required = 0;
-		gelic_net_enable_rxdmac(card);
+		gelic_card_enable_rxdmac(card);
 	}
 
-	if (status & GELIC_NET_RXINT) {
-		gelic_net_rx_irq_off(card);
-		netif_rx_schedule(netdev, &card->napi);
+	if (status & GELIC_CARD_RXINT) {
+		gelic_card_rx_irq_off(card);
+		napi_schedule(&card->napi);
 	}
 
-	if (status & GELIC_NET_TXINT) {
-		spin_lock_irqsave(&card->tx_dma_lock, flags);
+	if (status & GELIC_CARD_TXINT) {
+		spin_lock_irqsave(&card->tx_lock, flags);
 		card->tx_dma_progress = 0;
-		gelic_net_release_tx_chain(card, 0);
+		gelic_card_release_tx_chain(card, 0);
 		/* kick outstanding tx descriptor if any */
-		gelic_net_kick_txdma(card, card->tx_chain.tail);
-		spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+		gelic_card_kick_txdma(card, card->tx_chain.tail);
+		spin_unlock_irqrestore(&card->tx_lock, flags);
 	}
+
+	/* ether port status changed */
+	if (status & GELIC_CARD_PORT_STATUS_CHANGED)
+		gelic_card_get_ether_port_status(card, 1);
+
+#ifdef CONFIG_GELIC_WIRELESS
+	if (status & (GELIC_CARD_WLAN_EVENT_RECEIVED |
+		      GELIC_CARD_WLAN_COMMAND_COMPLETED))
+		gelic_wl_interrupt(card->netdev[GELIC_PORT_WIRELESS], status);
+#endif
+
 	return IRQ_HANDLED;
 }
 
@@ -1044,55 +1171,17 @@ static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
  *
  * see Documentation/networking/netconsole.txt
  */
-static void gelic_net_poll_controller(struct net_device *netdev)
+void gelic_net_poll_controller(struct net_device *netdev)
 {
-	struct gelic_net_card *card = netdev_priv(netdev);
+	struct gelic_card *card = netdev_card(netdev);
 
-	gelic_net_set_irq_mask(card, 0);
-	gelic_net_interrupt(netdev->irq, netdev);
-	gelic_net_set_irq_mask(card, card->ghiintmask);
+	gelic_card_set_irq_mask(card, 0);
+	gelic_card_interrupt(netdev->irq, netdev);
+	gelic_card_set_irq_mask(card, card->irq_mask);
 }
 #endif /* CONFIG_NET_POLL_CONTROLLER */
 
 /**
- * gelic_net_open_device - open device and map dma region
- * @card: card structure
- */
-static int gelic_net_open_device(struct gelic_net_card *card)
-{
-	int result;
-
-	result = ps3_sb_event_receive_port_setup(card->dev, PS3_BINDING_CPU_ANY,
-		&card->netdev->irq);
-
-	if (result) {
-		dev_info(ctodev(card),
-			 "%s:%d: gelic_net_open_device failed (%d)\n",
-			 __func__, __LINE__, result);
-		result = -EPERM;
-		goto fail_alloc_irq;
-	}
-
-	result = request_irq(card->netdev->irq, gelic_net_interrupt,
-			     IRQF_DISABLED, card->netdev->name, card->netdev);
-
-	if (result) {
-		dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n",
-			__func__, __LINE__, result);
-		goto fail_request_irq;
-	}
-
-	return 0;
-
-fail_request_irq:
-	ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
-	card->netdev->irq = NO_IRQ;
-fail_alloc_irq:
-	return result;
-}
-
-
-/**
  * gelic_net_open - called upon ifonfig up
  * @netdev: interface device structure
  *
@@ -1101,169 +1190,88 @@ fail_alloc_irq:
  * gelic_net_open allocates all the descriptors and memory needed for
  * operation, sets up multicast list and enables interrupts
  */
-static int gelic_net_open(struct net_device *netdev)
+int gelic_net_open(struct net_device *netdev)
 {
-	struct gelic_net_card *card = netdev_priv(netdev);
-
-	dev_dbg(ctodev(card), " -> %s:%d\n", __func__, __LINE__);
-
-	gelic_net_open_device(card);
-
-	if (gelic_net_init_chain(card, &card->tx_chain,
-			card->descr, GELIC_NET_TX_DESCRIPTORS))
-		goto alloc_tx_failed;
-	if (gelic_net_init_chain(card, &card->rx_chain,
-				 card->descr + GELIC_NET_TX_DESCRIPTORS,
-				 GELIC_NET_RX_DESCRIPTORS))
-		goto alloc_rx_failed;
-
-	/* head of chain */
-	card->tx_top = card->tx_chain.head;
-	card->rx_top = card->rx_chain.head;
-	dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n",
-		card->rx_top, card->tx_top, sizeof(struct gelic_net_descr),
-		GELIC_NET_RX_DESCRIPTORS);
-	/* allocate rx skbs */
-	if (gelic_net_alloc_rx_skbs(card))
-		goto alloc_skbs_failed;
+	struct gelic_card *card = netdev_card(netdev);
 
-	napi_enable(&card->napi);
-
-	card->tx_dma_progress = 0;
-	card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT;
+	dev_dbg(ctodev(card), " -> %s %p\n", __func__, netdev);
 
-	gelic_net_set_irq_mask(card, card->ghiintmask);
-	gelic_net_enable_rxdmac(card);
+	gelic_card_up(card);
 
 	netif_start_queue(netdev);
-	netif_carrier_on(netdev);
+	gelic_card_get_ether_port_status(card, 1);
 
+	dev_dbg(ctodev(card), " <- %s\n", __func__);
 	return 0;
-
-alloc_skbs_failed:
-	gelic_net_free_chain(card, card->rx_top);
-alloc_rx_failed:
-	gelic_net_free_chain(card, card->tx_top);
-alloc_tx_failed:
-	return -ENOMEM;
 }
 
-static void gelic_net_get_drvinfo (struct net_device *netdev,
-				   struct ethtool_drvinfo *info)
+void gelic_net_get_drvinfo(struct net_device *netdev,
+			   struct ethtool_drvinfo *info)
 {
 	strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1);
 	strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1);
 }
 
-static int gelic_net_get_settings(struct net_device *netdev,
-				  struct ethtool_cmd *cmd)
+static int gelic_ether_get_settings(struct net_device *netdev,
+				    struct ethtool_cmd *cmd)
 {
-	struct gelic_net_card *card = netdev_priv(netdev);
-	int status;
-	u64 v1, v2;
-	int speed, duplex;
+	struct gelic_card *card = netdev_card(netdev);
 
-	speed = duplex = -1;
-	status = lv1_net_control(bus_id(card), dev_id(card),
-			GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
-			&v1, &v2);
-	if (status) {
-		/* link down */
-	} else {
-		if (v1 & GELIC_NET_FULL_DUPLEX) {
-			duplex = DUPLEX_FULL;
-		} else {
-			duplex = DUPLEX_HALF;
-		}
+	gelic_card_get_ether_port_status(card, 0);
 
-		if (v1 & GELIC_NET_SPEED_10 ) {
-			speed = SPEED_10;
-		} else if (v1 & GELIC_NET_SPEED_100) {
-			speed = SPEED_100;
-		} else if (v1 & GELIC_NET_SPEED_1000) {
-			speed = SPEED_1000;
-		}
+	if (card->ether_port_status & GELIC_LV1_ETHER_FULL_DUPLEX)
+		cmd->duplex = DUPLEX_FULL;
+	else
+		cmd->duplex = DUPLEX_HALF;
+
+	switch (card->ether_port_status & GELIC_LV1_ETHER_SPEED_MASK) {
+	case GELIC_LV1_ETHER_SPEED_10:
+		cmd->speed = SPEED_10;
+		break;
+	case GELIC_LV1_ETHER_SPEED_100:
+		cmd->speed = SPEED_100;
+		break;
+	case GELIC_LV1_ETHER_SPEED_1000:
+		cmd->speed = SPEED_1000;
+		break;
+	default:
+		pr_info("%s: speed unknown\n", __func__);
+		cmd->speed = SPEED_10;
+		break;
 	}
+
 	cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
 			SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
 			SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
 			SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
 	cmd->advertising = cmd->supported;
-	cmd->speed = speed;
-	cmd->duplex = duplex;
 	cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
 	cmd->port = PORT_TP;
 
 	return 0;
 }
 
-static u32 gelic_net_get_link(struct net_device *netdev)
+u32 gelic_net_get_rx_csum(struct net_device *netdev)
 {
-	struct gelic_net_card *card = netdev_priv(netdev);
-	int status;
-	u64 v1, v2;
-	int link;
-
-	status = lv1_net_control(bus_id(card), dev_id(card),
-			GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
-			&v1, &v2);
-	if (status)
-		return 0; /* link down */
-
-	if (v1 & GELIC_NET_LINK_UP)
-		link = 1;
-	else
-		link = 0;
-
-	return link;
-}
-
-static int gelic_net_nway_reset(struct net_device *netdev)
-{
-	if (netif_running(netdev)) {
-		gelic_net_stop(netdev);
-		gelic_net_open(netdev);
-	}
-	return 0;
-}
-
-static u32 gelic_net_get_tx_csum(struct net_device *netdev)
-{
-	return (netdev->features & NETIF_F_IP_CSUM) != 0;
-}
-
-static int gelic_net_set_tx_csum(struct net_device *netdev, u32 data)
-{
-	if (data)
-		netdev->features |= NETIF_F_IP_CSUM;
-	else
-		netdev->features &= ~NETIF_F_IP_CSUM;
-
-	return 0;
-}
-
-static u32 gelic_net_get_rx_csum(struct net_device *netdev)
-{
-	struct gelic_net_card *card = netdev_priv(netdev);
+	struct gelic_card *card = netdev_card(netdev);
 
 	return card->rx_csum;
 }
 
-static int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
+int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
 {
-	struct gelic_net_card *card = netdev_priv(netdev);
+	struct gelic_card *card = netdev_card(netdev);
 
 	card->rx_csum = data;
 	return 0;
 }
 
-static struct ethtool_ops gelic_net_ethtool_ops = {
+static struct ethtool_ops gelic_ether_ethtool_ops = {
 	.get_drvinfo	= gelic_net_get_drvinfo,
-	.get_settings	= gelic_net_get_settings,
-	.get_link	= gelic_net_get_link,
-	.nway_reset	= gelic_net_nway_reset,
-	.get_tx_csum	= gelic_net_get_tx_csum,
-	.set_tx_csum	= gelic_net_set_tx_csum,
+	.get_settings	= gelic_ether_get_settings,
+	.get_link	= ethtool_op_get_link,
+	.get_tx_csum	= ethtool_op_get_tx_csum,
+	.set_tx_csum	= ethtool_op_set_tx_csum,
 	.get_rx_csum	= gelic_net_get_rx_csum,
 	.set_rx_csum	= gelic_net_set_rx_csum,
 };
@@ -1277,9 +1285,9 @@ static struct ethtool_ops gelic_net_ethtool_ops = {
  */
 static void gelic_net_tx_timeout_task(struct work_struct *work)
 {
-	struct gelic_net_card *card =
-		container_of(work, struct gelic_net_card, tx_timeout_task);
-	struct net_device *netdev = card->netdev;
+	struct gelic_card *card =
+		container_of(work, struct gelic_card, tx_timeout_task);
+	struct net_device *netdev = card->netdev[GELIC_PORT_ETHERNET];
 
 	dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__);
 
@@ -1302,11 +1310,11 @@ out:
  *
  * called, if tx hangs. Schedules a task that resets the interface
  */
-static void gelic_net_tx_timeout(struct net_device *netdev)
+void gelic_net_tx_timeout(struct net_device *netdev)
 {
-	struct gelic_net_card *card;
+	struct gelic_card *card;
 
-	card = netdev_priv(netdev);
+	card = netdev_card(netdev);
 	atomic_inc(&card->tx_timeout_task_counter);
 	if (netdev->flags & IFF_UP)
 		schedule_work(&card->tx_timeout_task);
@@ -1315,12 +1323,13 @@ static void gelic_net_tx_timeout(struct net_device *netdev)
 }
 
 /**
- * gelic_net_setup_netdev_ops - initialization of net_device operations
+ * gelic_ether_setup_netdev_ops - initialization of net_device operations
  * @netdev: net_device structure
  *
  * fills out function pointers in the net_device structure
  */
-static void gelic_net_setup_netdev_ops(struct net_device *netdev)
+static void gelic_ether_setup_netdev_ops(struct net_device *netdev,
+					 struct napi_struct *napi)
 {
 	netdev->open = &gelic_net_open;
 	netdev->stop = &gelic_net_stop;
@@ -1330,163 +1339,239 @@ static void gelic_net_setup_netdev_ops(struct net_device *netdev)
 	/* tx watchdog */
 	netdev->tx_timeout = &gelic_net_tx_timeout;
 	netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
-	netdev->ethtool_ops = &gelic_net_ethtool_ops;
+	/* NAPI */
+	netif_napi_add(netdev, napi,
+		       gelic_net_poll, GELIC_NET_NAPI_WEIGHT);
+	netdev->ethtool_ops = &gelic_ether_ethtool_ops;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	netdev->poll_controller = gelic_net_poll_controller;
+#endif
 }
 
 /**
- * gelic_net_setup_netdev - initialization of net_device
+ * gelic_ether_setup_netdev - initialization of net_device
+ * @netdev: net_device structure
  * @card: card structure
  *
  * Returns 0 on success or <0 on failure
  *
- * gelic_net_setup_netdev initializes the net_device structure
+ * gelic_ether_setup_netdev initializes the net_device structure
+ * and register it.
  **/
-static int gelic_net_setup_netdev(struct gelic_net_card *card)
+int gelic_net_setup_netdev(struct net_device *netdev, struct gelic_card *card)
 {
-	struct net_device *netdev = card->netdev;
-	struct sockaddr addr;
-	unsigned int i;
 	int status;
 	u64 v1, v2;
 	DECLARE_MAC_BUF(mac);
 
-	SET_NETDEV_DEV(netdev, &card->dev->core);
-	spin_lock_init(&card->tx_dma_lock);
-
-	card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT;
-
-	gelic_net_setup_netdev_ops(netdev);
-
-	netif_napi_add(netdev, &card->napi,
-		       gelic_net_poll, GELIC_NET_NAPI_WEIGHT);
-
 	netdev->features = NETIF_F_IP_CSUM;
 
 	status = lv1_net_control(bus_id(card), dev_id(card),
-				 GELIC_NET_GET_MAC_ADDRESS,
+				 GELIC_LV1_GET_MAC_ADDRESS,
 				 0, 0, 0, &v1, &v2);
+	v1 <<= 16;
 	if (status || !is_valid_ether_addr((u8 *)&v1)) {
 		dev_info(ctodev(card),
 			 "%s:lv1_net_control GET_MAC_ADDR failed %d\n",
 			 __func__, status);
 		return -EINVAL;
 	}
-	v1 <<= 16;
-	memcpy(addr.sa_data, &v1, ETH_ALEN);
-	memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN);
-	dev_info(ctodev(card), "MAC addr %s\n",
-		 print_mac(mac, netdev->dev_addr));
+	memcpy(netdev->dev_addr, &v1, ETH_ALEN);
 
-	card->vlan_index = -1;	/* no vlan */
-	for (i = 0; i < GELIC_NET_VLAN_MAX; i++) {
-		status = lv1_net_control(bus_id(card), dev_id(card),
-					GELIC_NET_GET_VLAN_ID,
-					i + 1, /* index; one based */
-					0, 0, &v1, &v2);
-		if (status == GELIC_NET_VLAN_NO_ENTRY) {
-			dev_dbg(ctodev(card),
-				"GELIC_VLAN_ID no entry:%d, VLAN disabled\n",
-				status);
-			card->vlan_id[i] = 0;
-		} else if (status) {
-			dev_dbg(ctodev(card),
-				"%s:GELIC_NET_VLAN_ID faild, status=%d\n",
-				__func__, status);
-			card->vlan_id[i] = 0;
-		} else {
-			card->vlan_id[i] = (u32)v1;
-			dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1);
-		}
-	}
-
-	if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1]) {
-		card->vlan_index = GELIC_NET_VLAN_WIRED - 1;
+	if (card->vlan_required) {
 		netdev->hard_header_len += VLAN_HLEN;
+		/*
+		 * As vlan is internally used,
+		 * we can not receive vlan packets
+		 */
+		netdev->features |= NETIF_F_VLAN_CHALLENGED;
 	}
 
 	status = register_netdev(netdev);
 	if (status) {
-		dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n",
-			__func__, status);
+		dev_err(ctodev(card), "%s:Couldn't register %s %d\n",
+			__func__, netdev->name, status);
 		return status;
 	}
+	dev_info(ctodev(card), "%s: MAC addr %s\n",
+		 netdev->name,
+		 print_mac(mac, netdev->dev_addr));
 
 	return 0;
 }
 
 /**
- * gelic_net_alloc_card - allocates net_device and card structure
+ * gelic_alloc_card_net - allocates net_device and card structure
  *
  * returns the card structure or NULL in case of errors
  *
  * the card and net_device structures are linked to each other
  */
-static struct gelic_net_card *gelic_net_alloc_card(void)
+#define GELIC_ALIGN (32)
+static struct gelic_card *gelic_alloc_card_net(struct net_device **netdev)
 {
-	struct net_device *netdev;
-	struct gelic_net_card *card;
+	struct gelic_card *card;
+	struct gelic_port *port;
+	void *p;
 	size_t alloc_size;
-
-	alloc_size = sizeof (*card) +
-		sizeof (struct gelic_net_descr) * GELIC_NET_RX_DESCRIPTORS +
-		sizeof (struct gelic_net_descr) * GELIC_NET_TX_DESCRIPTORS;
 	/*
-	 * we assume private data is allocated 32 bytes (or more) aligned
-	 * so that gelic_net_descr should be 32 bytes aligned.
-	 * Current alloc_etherdev() does do it because NETDEV_ALIGN
-	 * is 32.
-	 * check this assumption here.
+	 * gelic requires dma descriptor is 32 bytes aligned and
+	 * the hypervisor requires irq_status is 8 bytes aligned.
 	 */
-	BUILD_BUG_ON(NETDEV_ALIGN < 32);
-	BUILD_BUG_ON(offsetof(struct gelic_net_card, irq_status) % 8);
-	BUILD_BUG_ON(offsetof(struct gelic_net_card, descr) % 32);
+	BUILD_BUG_ON(offsetof(struct gelic_card, irq_status) % 8);
+	BUILD_BUG_ON(offsetof(struct gelic_card, descr) % 32);
+	alloc_size =
+		sizeof(struct gelic_card) +
+		sizeof(struct gelic_descr) * GELIC_NET_RX_DESCRIPTORS +
+		sizeof(struct gelic_descr) * GELIC_NET_TX_DESCRIPTORS +
+		GELIC_ALIGN - 1;
+
+	p  = kzalloc(alloc_size, GFP_KERNEL);
+	if (!p)
+		return NULL;
+	card = PTR_ALIGN(p, GELIC_ALIGN);
+	card->unalign = p;
 
-	netdev = alloc_etherdev(alloc_size);
-	if (!netdev)
+	/*
+	 * alloc netdev
+	 */
+	*netdev = alloc_etherdev(sizeof(struct gelic_port));
+	if (!netdev) {
+		kfree(card->unalign);
 		return NULL;
+	}
+	port = netdev_priv(*netdev);
+
+	/* gelic_port */
+	port->netdev = *netdev;
+	port->card = card;
+	port->type = GELIC_PORT_ETHERNET;
+
+	/* gelic_card */
+	card->netdev[GELIC_PORT_ETHERNET] = *netdev;
 
-	card = netdev_priv(netdev);
-	card->netdev = netdev;
 	INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
 	init_waitqueue_head(&card->waitq);
 	atomic_set(&card->tx_timeout_task_counter, 0);
+	init_MUTEX(&card->updown_lock);
+	atomic_set(&card->users, 0);
 
 	return card;
 }
 
+static void gelic_card_get_vlan_info(struct gelic_card *card)
+{
+	u64 v1, v2;
+	int status;
+	unsigned int i;
+	struct {
+		int tx;
+		int rx;
+	} vlan_id_ix[2] = {
+		[GELIC_PORT_ETHERNET] = {
+			.tx = GELIC_LV1_VLAN_TX_ETHERNET,
+			.rx = GELIC_LV1_VLAN_RX_ETHERNET
+		},
+		[GELIC_PORT_WIRELESS] = {
+			.tx = GELIC_LV1_VLAN_TX_WIRELESS,
+			.rx = GELIC_LV1_VLAN_RX_WIRELESS
+		}
+	};
+
+	for (i = 0; i < ARRAY_SIZE(vlan_id_ix); i++) {
+		/* tx tag */
+		status = lv1_net_control(bus_id(card), dev_id(card),
+					 GELIC_LV1_GET_VLAN_ID,
+					 vlan_id_ix[i].tx,
+					 0, 0, &v1, &v2);
+		if (status || !v1) {
+			if (status != LV1_NO_ENTRY)
+				dev_dbg(ctodev(card),
+					"get vlan id for tx(%d) failed(%d)\n",
+					vlan_id_ix[i].tx, status);
+			card->vlan[i].tx = 0;
+			card->vlan[i].rx = 0;
+			continue;
+		}
+		card->vlan[i].tx = (u16)v1;
+
+		/* rx tag */
+		status = lv1_net_control(bus_id(card), dev_id(card),
+					 GELIC_LV1_GET_VLAN_ID,
+					 vlan_id_ix[i].rx,
+					 0, 0, &v1, &v2);
+		if (status || !v1) {
+			if (status != LV1_NO_ENTRY)
+				dev_info(ctodev(card),
+					 "get vlan id for rx(%d) failed(%d)\n",
+					 vlan_id_ix[i].rx, status);
+			card->vlan[i].tx = 0;
+			card->vlan[i].rx = 0;
+			continue;
+		}
+		card->vlan[i].rx = (u16)v1;
+
+		dev_dbg(ctodev(card), "vlan_id[%d] tx=%02x rx=%02x\n",
+			i, card->vlan[i].tx, card->vlan[i].rx);
+	}
+
+	if (card->vlan[GELIC_PORT_ETHERNET].tx) {
+		BUG_ON(!card->vlan[GELIC_PORT_WIRELESS].tx);
+		card->vlan_required = 1;
+	} else
+		card->vlan_required = 0;
+
+	/* check wirelss capable firmware */
+	if (ps3_compare_firmware_version(1, 6, 0) < 0) {
+		card->vlan[GELIC_PORT_WIRELESS].tx = 0;
+		card->vlan[GELIC_PORT_WIRELESS].rx = 0;
+	}
+
+	dev_info(ctodev(card), "internal vlan %s\n",
+		 card->vlan_required? "enabled" : "disabled");
+}
 /**
  * ps3_gelic_driver_probe - add a device to the control of this driver
  */
-static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
+static int ps3_gelic_driver_probe(struct ps3_system_bus_device *dev)
 {
-	struct gelic_net_card *card = gelic_net_alloc_card();
+	struct gelic_card *card;
+	struct net_device *netdev;
 	int result;
 
-	if (!card) {
-		dev_info(&dev->core, "gelic_net_alloc_card failed\n");
-		result = -ENOMEM;
-		goto fail_alloc_card;
-	}
-
-	ps3_system_bus_set_driver_data(dev, card);
-	card->dev = dev;
-
+	pr_debug("%s: called\n", __func__);
 	result = ps3_open_hv_device(dev);
 
 	if (result) {
-		dev_dbg(&dev->core, "ps3_open_hv_device failed\n");
+		dev_dbg(&dev->core, "%s:ps3_open_hv_device failed\n",
+			__func__);
 		goto fail_open;
 	}
 
 	result = ps3_dma_region_create(dev->d_region);
 
 	if (result) {
-		dev_dbg(&dev->core, "ps3_dma_region_create failed(%d)\n",
-			result);
+		dev_dbg(&dev->core, "%s:ps3_dma_region_create failed(%d)\n",
+			__func__, result);
 		BUG_ON("check region type");
 		goto fail_dma_region;
 	}
 
+	/* alloc card/netdevice */
+	card = gelic_alloc_card_net(&netdev);
+	if (!card) {
+		dev_info(&dev->core, "%s:gelic_net_alloc_card failed\n",
+			 __func__);
+		result = -ENOMEM;
+		goto fail_alloc_card;
+	}
+	ps3_system_bus_set_driver_data(dev, card);
+	card->dev = dev;
+
+	/* get internal vlan info */
+	gelic_card_get_vlan_info(card);
+
+	/* setup interrupt */
 	result = lv1_net_set_interrupt_status_indicator(bus_id(card),
 							dev_id(card),
 		ps3_mm_phys_to_lpar(__pa(&card->irq_status)),
@@ -1494,34 +1579,101 @@ static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
 
 	if (result) {
 		dev_dbg(&dev->core,
-			"lv1_net_set_interrupt_status_indicator failed: %s\n",
-			ps3_result(result));
+			"%s:set_interrupt_status_indicator failed: %s\n",
+			__func__, ps3_result(result));
 		result = -EIO;
 		goto fail_status_indicator;
 	}
 
-	result = gelic_net_setup_netdev(card);
+	result = ps3_sb_event_receive_port_setup(dev, PS3_BINDING_CPU_ANY,
+		&card->irq);
+
+	if (result) {
+		dev_info(ctodev(card),
+			 "%s:gelic_net_open_device failed (%d)\n",
+			 __func__, result);
+		result = -EPERM;
+		goto fail_alloc_irq;
+	}
+	result = request_irq(card->irq, gelic_card_interrupt,
+			     IRQF_DISABLED, netdev->name, card);
+
+	if (result) {
+		dev_info(ctodev(card), "%s:request_irq failed (%d)\n",
+			__func__, result);
+		goto fail_request_irq;
+	}
+
+	/* setup card structure */
+	card->irq_mask = GELIC_CARD_RXINT | GELIC_CARD_TXINT |
+		GELIC_CARD_PORT_STATUS_CHANGED;
+	card->rx_csum = GELIC_CARD_RX_CSUM_DEFAULT;
 
+
+	if (gelic_card_init_chain(card, &card->tx_chain,
+			card->descr, GELIC_NET_TX_DESCRIPTORS))
+		goto fail_alloc_tx;
+	if (gelic_card_init_chain(card, &card->rx_chain,
+				 card->descr + GELIC_NET_TX_DESCRIPTORS,
+				 GELIC_NET_RX_DESCRIPTORS))
+		goto fail_alloc_rx;
+
+	/* head of chain */
+	card->tx_top = card->tx_chain.head;
+	card->rx_top = card->rx_chain.head;
+	dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n",
+		card->rx_top, card->tx_top, sizeof(struct gelic_descr),
+		GELIC_NET_RX_DESCRIPTORS);
+	/* allocate rx skbs */
+	if (gelic_card_alloc_rx_skbs(card))
+		goto fail_alloc_skbs;
+
+	spin_lock_init(&card->tx_lock);
+	card->tx_dma_progress = 0;
+
+	/* setup net_device structure */
+	netdev->irq = card->irq;
+	SET_NETDEV_DEV(netdev, &card->dev->core);
+	gelic_ether_setup_netdev_ops(netdev, &card->napi);
+	result = gelic_net_setup_netdev(netdev, card);
 	if (result) {
-		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
-			"(%d)\n", __func__, __LINE__, result);
+		dev_dbg(&dev->core, "%s: setup_netdev failed %d",
+			__func__, result);
 		goto fail_setup_netdev;
 	}
 
+#ifdef CONFIG_GELIC_WIRELESS
+	if (gelic_wl_driver_probe(card)) {
+		dev_dbg(&dev->core, "%s: WL init failed\n", __func__);
+		goto fail_setup_netdev;
+	}
+#endif
+	pr_debug("%s: done\n", __func__);
 	return 0;
 
 fail_setup_netdev:
+fail_alloc_skbs:
+	gelic_card_free_chain(card, card->rx_chain.head);
+fail_alloc_rx:
+	gelic_card_free_chain(card, card->tx_chain.head);
+fail_alloc_tx:
+	free_irq(card->irq, card);
+	netdev->irq = NO_IRQ;
+fail_request_irq:
+	ps3_sb_event_receive_port_destroy(dev, card->irq);
+fail_alloc_irq:
 	lv1_net_set_interrupt_status_indicator(bus_id(card),
 					       bus_id(card),
-					       0 , 0);
+					       0, 0);
 fail_status_indicator:
+	ps3_system_bus_set_driver_data(dev, NULL);
+	kfree(netdev_card(netdev)->unalign);
+	free_netdev(netdev);
+fail_alloc_card:
 	ps3_dma_region_free(dev->d_region);
 fail_dma_region:
 	ps3_close_hv_device(dev);
 fail_open:
-	ps3_system_bus_set_driver_data(dev, NULL);
-	free_netdev(card->netdev);
-fail_alloc_card:
 	return result;
 }
 
@@ -1529,9 +1681,34 @@ fail_alloc_card:
  * ps3_gelic_driver_remove - remove a device from the control of this driver
  */
 
-static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
+static int ps3_gelic_driver_remove(struct ps3_system_bus_device *dev)
 {
-	struct gelic_net_card *card = ps3_system_bus_get_driver_data(dev);
+	struct gelic_card *card = ps3_system_bus_get_driver_data(dev);
+	struct net_device *netdev0;
+	pr_debug("%s: called\n", __func__);
+
+#ifdef CONFIG_GELIC_WIRELESS
+	gelic_wl_driver_remove(card);
+#endif
+	/* stop interrupt */
+	gelic_card_set_irq_mask(card, 0);
+
+	/* turn off DMA, force end */
+	gelic_card_disable_rxdmac(card);
+	gelic_card_disable_txdmac(card);
+
+	/* release chains */
+	gelic_card_release_tx_chain(card, 1);
+	gelic_card_release_rx_chain(card);
+
+	gelic_card_free_chain(card, card->tx_top);
+	gelic_card_free_chain(card, card->rx_top);
+
+	netdev0 = card->netdev[GELIC_PORT_ETHERNET];
+	/* disconnect event port */
+	free_irq(card->irq, card);
+	netdev0->irq = NO_IRQ;
+	ps3_sb_event_receive_port_destroy(card->dev, card->irq);
 
 	wait_event(card->waitq,
 		   atomic_read(&card->tx_timeout_task_counter) == 0);
@@ -1539,8 +1716,9 @@ static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
 	lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card),
 					       0 , 0);
 
-	unregister_netdev(card->netdev);
-	free_netdev(card->netdev);
+	unregister_netdev(netdev0);
+	kfree(netdev_card(netdev0)->unalign);
+	free_netdev(netdev0);
 
 	ps3_system_bus_set_driver_data(dev, NULL);
 
@@ -1548,6 +1726,7 @@ static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
 
 	ps3_close_hv_device(dev);
 
+	pr_debug("%s: done\n", __func__);
 	return 0;
 }
 
@@ -1572,8 +1751,8 @@ static void __exit ps3_gelic_driver_exit (void)
 	ps3_system_bus_driver_unregister(&ps3_gelic_driver);
 }
 
-module_init (ps3_gelic_driver_init);
-module_exit (ps3_gelic_driver_exit);
+module_init(ps3_gelic_driver_init);
+module_exit(ps3_gelic_driver_exit);
 
 MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC);
 
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
index 9685602..1d39d06 100644
--- a/drivers/net/ps3_gelic_net.h
+++ b/drivers/net/ps3_gelic_net.h
@@ -35,198 +35,323 @@
 #define GELIC_NET_MAX_MTU               VLAN_ETH_FRAME_LEN
 #define GELIC_NET_MIN_MTU               VLAN_ETH_ZLEN
 #define GELIC_NET_RXBUF_ALIGN           128
-#define GELIC_NET_RX_CSUM_DEFAULT       1 /* hw chksum */
+#define GELIC_CARD_RX_CSUM_DEFAULT      1 /* hw chksum */
 #define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
 #define GELIC_NET_NAPI_WEIGHT           (GELIC_NET_RX_DESCRIPTORS)
 #define GELIC_NET_BROADCAST_ADDR        0xffffffffffffL
-#define GELIC_NET_VLAN_POS              (VLAN_ETH_ALEN * 2)
-#define GELIC_NET_VLAN_MAX              4
+
 #define GELIC_NET_MC_COUNT_MAX          32 /* multicast address list */
 
-enum gelic_net_int0_status {
-	GELIC_NET_GDTDCEINT  = 24,
-	GELIC_NET_GRFANMINT  = 28,
-};
+/* virtual interrupt status register bits */
+	/* INT1 */
+#define GELIC_CARD_TX_RAM_FULL_ERR           0x0000000000000001L
+#define GELIC_CARD_RX_RAM_FULL_ERR           0x0000000000000002L
+#define GELIC_CARD_TX_SHORT_FRAME_ERR        0x0000000000000004L
+#define GELIC_CARD_TX_INVALID_DESCR_ERR      0x0000000000000008L
+#define GELIC_CARD_RX_FIFO_FULL_ERR          0x0000000000002000L
+#define GELIC_CARD_RX_DESCR_CHAIN_END        0x0000000000004000L
+#define GELIC_CARD_RX_INVALID_DESCR_ERR      0x0000000000008000L
+#define GELIC_CARD_TX_RESPONCE_ERR           0x0000000000010000L
+#define GELIC_CARD_RX_RESPONCE_ERR           0x0000000000100000L
+#define GELIC_CARD_TX_PROTECTION_ERR         0x0000000000400000L
+#define GELIC_CARD_RX_PROTECTION_ERR         0x0000000004000000L
+#define GELIC_CARD_TX_TCP_UDP_CHECKSUM_ERR   0x0000000008000000L
+#define GELIC_CARD_PORT_STATUS_CHANGED       0x0000000020000000L
+#define GELIC_CARD_WLAN_EVENT_RECEIVED       0x0000000040000000L
+#define GELIC_CARD_WLAN_COMMAND_COMPLETED    0x0000000080000000L
+	/* INT 0 */
+#define GELIC_CARD_TX_FLAGGED_DESCR          0x0004000000000000L
+#define GELIC_CARD_RX_FLAGGED_DESCR          0x0040000000000000L
+#define GELIC_CARD_TX_TRANSFER_END           0x0080000000000000L
+#define GELIC_CARD_TX_DESCR_CHAIN_END        0x0100000000000000L
+#define GELIC_CARD_NUMBER_OF_RX_FRAME        0x1000000000000000L
+#define GELIC_CARD_ONE_TIME_COUNT_TIMER      0x4000000000000000L
+#define GELIC_CARD_FREE_RUN_COUNT_TIMER      0x8000000000000000L
+
+/* initial interrupt mask */
+#define GELIC_CARD_TXINT	GELIC_CARD_TX_DESCR_CHAIN_END
 
-/* GHIINT1STS bits */
-enum gelic_net_int1_status {
-	GELIC_NET_GDADCEINT = 14,
+#define GELIC_CARD_RXINT	(GELIC_CARD_RX_DESCR_CHAIN_END | \
+				 GELIC_CARD_NUMBER_OF_RX_FRAME)
+
+ /* RX descriptor data_status bits */
+enum gelic_descr_rx_status {
+	GELIC_DESCR_RXDMADU	= 0x80000000, /* destination MAC addr unknown */
+	GELIC_DESCR_RXLSTFBF	= 0x40000000, /* last frame buffer            */
+	GELIC_DESCR_RXIPCHK	= 0x20000000, /* IP checksum performed        */
+	GELIC_DESCR_RXTCPCHK	= 0x10000000, /* TCP/UDP checksup performed   */
+	GELIC_DESCR_RXWTPKT	= 0x00C00000, /*
+					       * wakeup trigger packet
+					       * 01: Magic Packet (TM)
+					       * 10: ARP packet
+					       * 11: Multicast MAC addr
+					       */
+	GELIC_DESCR_RXVLNPKT	= 0x00200000, /* VLAN packet */
+	/* bit 20..16 reserved */
+	GELIC_DESCR_RXRRECNUM	= 0x0000ff00, /* reception receipt number */
+	/* bit 7..0 reserved */
 };
 
-/* interrupt mask */
-#define GELIC_NET_TXINT                   (1L << (GELIC_NET_GDTDCEINT + 32))
+#define GELIC_DESCR_DATA_STATUS_CHK_MASK	\
+	(GELIC_DESCR_RXIPCHK | GELIC_DESCR_RXTCPCHK)
 
-#define GELIC_NET_RXINT0                  (1L << (GELIC_NET_GRFANMINT + 32))
-#define GELIC_NET_RXINT1                  (1L << GELIC_NET_GDADCEINT)
-#define GELIC_NET_RXINT                   (GELIC_NET_RXINT0 | GELIC_NET_RXINT1)
+ /* TX descriptor data_status bits */
+enum gelic_descr_tx_status {
+	GELIC_DESCR_TX_TAIL	= 0x00000001, /* gelic treated this
+					       * descriptor was end of
+					       * a tx frame
+					       */
+};
 
- /* RX descriptor data_status bits */
-#define GELIC_NET_RXDMADU	0x80000000 /* destination MAC addr unknown */
-#define GELIC_NET_RXLSTFBF	0x40000000 /* last frame buffer            */
-#define GELIC_NET_RXIPCHK	0x20000000 /* IP checksum performed        */
-#define GELIC_NET_RXTCPCHK	0x10000000 /* TCP/UDP checksup performed   */
-#define GELIC_NET_RXIPSPKT	0x08000000 /* IPsec packet   */
-#define GELIC_NET_RXIPSAHPRT	0x04000000 /* IPsec AH protocol performed */
-#define GELIC_NET_RXIPSESPPRT	0x02000000 /* IPsec ESP protocol performed */
-#define GELIC_NET_RXSESPAH	0x01000000 /*
-					    * IPsec ESP protocol auth
-					    * performed
-					    */
-
-#define GELIC_NET_RXWTPKT	0x00C00000 /*
-					    * wakeup trigger packet
-					    * 01: Magic Packet (TM)
-					    * 10: ARP packet
-					    * 11: Multicast MAC addr
-					    */
-#define GELIC_NET_RXVLNPKT	0x00200000 /* VLAN packet */
-/* bit 20..16 reserved */
-#define GELIC_NET_RXRRECNUM	0x0000ff00 /* reception receipt number */
-#define GELIC_NET_RXRRECNUM_SHIFT	8
-/* bit 7..0 reserved */
-
-#define GELIC_NET_TXDESC_TAIL		0
-#define GELIC_NET_DATA_STATUS_CHK_MASK	(GELIC_NET_RXIPCHK | GELIC_NET_RXTCPCHK)
-
-/* RX descriptor data_error bits */
-/* bit 31 reserved */
-#define GELIC_NET_RXALNERR	0x40000000 /* alignement error 10/100M */
-#define GELIC_NET_RXOVERERR	0x20000000 /* oversize error */
-#define GELIC_NET_RXRNTERR	0x10000000 /* Runt error */
-#define GELIC_NET_RXIPCHKERR	0x08000000 /* IP checksum  error */
-#define GELIC_NET_RXTCPCHKERR	0x04000000 /* TCP/UDP checksum  error */
-#define GELIC_NET_RXUMCHSP	0x02000000 /* unmatched sp on sp */
-#define GELIC_NET_RXUMCHSPI	0x01000000 /* unmatched SPI on SAD */
-#define GELIC_NET_RXUMCHSAD	0x00800000 /* unmatched SAD */
-#define GELIC_NET_RXIPSAHERR	0x00400000 /* auth error on AH protocol
-					    * processing */
-#define GELIC_NET_RXIPSESPAHERR	0x00200000 /* auth error on ESP protocol
-					    * processing */
-#define GELIC_NET_RXDRPPKT	0x00100000 /* drop packet */
-#define GELIC_NET_RXIPFMTERR	0x00080000 /* IP packet format error */
-/* bit 18 reserved */
-#define GELIC_NET_RXDATAERR	0x00020000 /* IP packet format error */
-#define GELIC_NET_RXCALERR	0x00010000 /* cariier extension length
-					    * error */
-#define GELIC_NET_RXCREXERR	0x00008000 /* carrier extention error */
-#define GELIC_NET_RXMLTCST	0x00004000 /* multicast address frame */
-/* bit 13..0 reserved */
-#define GELIC_NET_DATA_ERROR_CHK_MASK		\
-	(GELIC_NET_RXIPCHKERR | GELIC_NET_RXTCPCHKERR)
+/* RX descriptor data error bits */
+enum gelic_descr_rx_error {
+	/* bit 31 reserved */
+	GELIC_DESCR_RXALNERR	= 0x40000000, /* alignement error 10/100M */
+	GELIC_DESCR_RXOVERERR	= 0x20000000, /* oversize error */
+	GELIC_DESCR_RXRNTERR	= 0x10000000, /* Runt error */
+	GELIC_DESCR_RXIPCHKERR	= 0x08000000, /* IP checksum  error */
+	GELIC_DESCR_RXTCPCHKERR	= 0x04000000, /* TCP/UDP checksum  error */
+	GELIC_DESCR_RXDRPPKT	= 0x00100000, /* drop packet */
+	GELIC_DESCR_RXIPFMTERR	= 0x00080000, /* IP packet format error */
+	/* bit 18 reserved */
+	GELIC_DESCR_RXDATAERR	= 0x00020000, /* IP packet format error */
+	GELIC_DESCR_RXCALERR	= 0x00010000, /* cariier extension length
+					      * error */
+	GELIC_DESCR_RXCREXERR	= 0x00008000, /* carrier extention error */
+	GELIC_DESCR_RXMLTCST	= 0x00004000, /* multicast address frame */
+	/* bit 13..0 reserved */
+};
+#define GELIC_DESCR_DATA_ERROR_CHK_MASK		\
+	(GELIC_DESCR_RXIPCHKERR | GELIC_DESCR_RXTCPCHKERR)
 
+/* DMA command and status (RX and TX)*/
+enum gelic_descr_dma_status {
+	GELIC_DESCR_DMA_COMPLETE            = 0x00000000, /* used in tx */
+	GELIC_DESCR_DMA_BUFFER_FULL         = 0x00000000, /* used in rx */
+	GELIC_DESCR_DMA_RESPONSE_ERROR      = 0x10000000, /* used in rx, tx */
+	GELIC_DESCR_DMA_PROTECTION_ERROR    = 0x20000000, /* used in rx, tx */
+	GELIC_DESCR_DMA_FRAME_END           = 0x40000000, /* used in rx */
+	GELIC_DESCR_DMA_FORCE_END           = 0x50000000, /* used in rx, tx */
+	GELIC_DESCR_DMA_CARDOWNED           = 0xa0000000, /* used in rx, tx */
+	GELIC_DESCR_DMA_NOT_IN_USE          = 0xb0000000, /* any other value */
+};
+
+#define GELIC_DESCR_DMA_STAT_MASK	(0xf0000000)
 
 /* tx descriptor command and status */
-#define GELIC_NET_DMAC_CMDSTAT_NOCS       0xa0080000 /* middle of frame */
-#define GELIC_NET_DMAC_CMDSTAT_TCPCS      0xa00a0000
-#define GELIC_NET_DMAC_CMDSTAT_UDPCS      0xa00b0000
-#define GELIC_NET_DMAC_CMDSTAT_END_FRAME  0x00040000 /* end of frame */
-
-#define GELIC_NET_DMAC_CMDSTAT_RXDCEIS	  0x00000002 /* descriptor chain end
-						      * interrupt status */
-
-#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END  0x00000002 /* RXDCEIS:DMA stopped */
-#define GELIC_NET_DESCR_IND_PROC_SHIFT    28
-#define GELIC_NET_DESCR_IND_PROC_MASKO    0x0fffffff
-
-
-enum gelic_net_descr_status {
-	GELIC_NET_DESCR_COMPLETE            = 0x00, /* used in tx */
-	GELIC_NET_DESCR_BUFFER_FULL         = 0x00, /* used in rx */
-	GELIC_NET_DESCR_RESPONSE_ERROR      = 0x01, /* used in rx and tx */
-	GELIC_NET_DESCR_PROTECTION_ERROR    = 0x02, /* used in rx and tx */
-	GELIC_NET_DESCR_FRAME_END           = 0x04, /* used in rx */
-	GELIC_NET_DESCR_FORCE_END           = 0x05, /* used in rx and tx */
-	GELIC_NET_DESCR_CARDOWNED           = 0x0a, /* used in rx and tx */
-	GELIC_NET_DESCR_NOT_IN_USE          = 0x0b  /* any other value */
+enum gelic_descr_tx_dma_status {
+	/* [19] */
+	GELIC_DESCR_TX_DMA_IKE		= 0x00080000, /* IPSEC off */
+	/* [18] */
+	GELIC_DESCR_TX_DMA_FRAME_TAIL	= 0x00040000, /* last descriptor of
+						       * the packet
+						       */
+	/* [17..16] */
+	GELIC_DESCR_TX_DMA_TCP_CHKSUM	= 0x00020000, /* TCP packet */
+	GELIC_DESCR_TX_DMA_UDP_CHKSUM	= 0x00030000, /* UDP packet */
+	GELIC_DESCR_TX_DMA_NO_CHKSUM	= 0x00000000, /* no checksum */
+
+	/* [1] */
+	GELIC_DESCR_TX_DMA_CHAIN_END	= 0x00000002, /* DMA terminated
+						       * due to chain end
+						       */
 };
+
+#define GELIC_DESCR_DMA_CMD_NO_CHKSUM	\
+	(GELIC_DESCR_DMA_CARDOWNED | GELIC_DESCR_TX_DMA_IKE | \
+	GELIC_DESCR_TX_DMA_NO_CHKSUM)
+
+#define GELIC_DESCR_DMA_CMD_TCP_CHKSUM	\
+	(GELIC_DESCR_DMA_CARDOWNED | GELIC_DESCR_TX_DMA_IKE | \
+	GELIC_DESCR_TX_DMA_TCP_CHKSUM)
+
+#define GELIC_DESCR_DMA_CMD_UDP_CHKSUM	\
+	(GELIC_DESCR_DMA_CARDOWNED | GELIC_DESCR_TX_DMA_IKE | \
+	GELIC_DESCR_TX_DMA_UDP_CHKSUM)
+
+enum gelic_descr_rx_dma_status {
+	/* [ 1 ] */
+	GELIC_DESCR_RX_DMA_CHAIN_END	= 0x00000002, /* DMA terminated
+						       * due to chain end
+						       */
+};
+
 /* for lv1_net_control */
-#define GELIC_NET_GET_MAC_ADDRESS               0x0000000000000001
-#define GELIC_NET_GET_ETH_PORT_STATUS           0x0000000000000002
-#define GELIC_NET_SET_NEGOTIATION_MODE          0x0000000000000003
-#define GELIC_NET_GET_VLAN_ID                   0x0000000000000004
-
-#define GELIC_NET_LINK_UP                       0x0000000000000001
-#define GELIC_NET_FULL_DUPLEX                   0x0000000000000002
-#define GELIC_NET_AUTO_NEG                      0x0000000000000004
-#define GELIC_NET_SPEED_10                      0x0000000000000010
-#define GELIC_NET_SPEED_100                     0x0000000000000020
-#define GELIC_NET_SPEED_1000                    0x0000000000000040
-
-#define GELIC_NET_VLAN_ALL                      0x0000000000000001
-#define GELIC_NET_VLAN_WIRED                    0x0000000000000002
-#define GELIC_NET_VLAN_WIRELESS                 0x0000000000000003
-#define GELIC_NET_VLAN_PSP                      0x0000000000000004
-#define GELIC_NET_VLAN_PORT0                    0x0000000000000010
-#define GELIC_NET_VLAN_PORT1                    0x0000000000000011
-#define GELIC_NET_VLAN_PORT2                    0x0000000000000012
-#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS        0x0000000000000013
-#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS        0x0000000000000014
-#define GELIC_NET_VLAN_NO_ENTRY                 -6
-
-#define GELIC_NET_PORT                          2 /* for port status */
+enum gelic_lv1_net_control_code {
+	GELIC_LV1_GET_MAC_ADDRESS	= 1,
+	GELIC_LV1_GET_ETH_PORT_STATUS	= 2,
+	GELIC_LV1_SET_NEGOTIATION_MODE	= 3,
+	GELIC_LV1_GET_VLAN_ID		= 4,
+	GELIC_LV1_GET_CHANNEL           = 6,
+	GELIC_LV1_POST_WLAN_CMD		= 9,
+	GELIC_LV1_GET_WLAN_CMD_RESULT	= 10,
+	GELIC_LV1_GET_WLAN_EVENT	= 11
+};
+
+/* status returened from GET_ETH_PORT_STATUS */
+enum gelic_lv1_ether_port_status {
+	GELIC_LV1_ETHER_LINK_UP		= 0x0000000000000001L,
+	GELIC_LV1_ETHER_FULL_DUPLEX	= 0x0000000000000002L,
+	GELIC_LV1_ETHER_AUTO_NEG	= 0x0000000000000004L,
+
+	GELIC_LV1_ETHER_SPEED_10	= 0x0000000000000010L,
+	GELIC_LV1_ETHER_SPEED_100	= 0x0000000000000020L,
+	GELIC_LV1_ETHER_SPEED_1000	= 0x0000000000000040L,
+	GELIC_LV1_ETHER_SPEED_MASK	= 0x0000000000000070L
+};
+
+enum gelic_lv1_vlan_index {
+	/* for outgoing packets */
+	GELIC_LV1_VLAN_TX_ETHERNET	= 0x0000000000000002L,
+	GELIC_LV1_VLAN_TX_WIRELESS	= 0x0000000000000003L,
+	/* for incoming packets */
+	GELIC_LV1_VLAN_RX_ETHERNET	= 0x0000000000000012L,
+	GELIC_LV1_VLAN_RX_WIRELESS	= 0x0000000000000013L
+};
 
 /* size of hardware part of gelic descriptor */
-#define GELIC_NET_DESCR_SIZE	(32)
-struct gelic_net_descr {
+#define GELIC_DESCR_SIZE	(32)
+
+enum gelic_port_type {
+	GELIC_PORT_ETHERNET = 0,
+	GELIC_PORT_WIRELESS = 1,
+	GELIC_PORT_MAX
+};
+
+struct gelic_descr {
 	/* as defined by the hardware */
-	u32 buf_addr;
-	u32 buf_size;
-	u32 next_descr_addr;
-	u32 dmac_cmd_status;
-	u32 result_size;
-	u32 valid_size;	/* all zeroes for tx */
-	u32 data_status;
-	u32 data_error;	/* all zeroes for tx */
+	__be32 buf_addr;
+	__be32 buf_size;
+	__be32 next_descr_addr;
+	__be32 dmac_cmd_status;
+	__be32 result_size;
+	__be32 valid_size;	/* all zeroes for tx */
+	__be32 data_status;
+	__be32 data_error;	/* all zeroes for tx */
 
 	/* used in the driver */
 	struct sk_buff *skb;
 	dma_addr_t bus_addr;
-	struct gelic_net_descr *next;
-	struct gelic_net_descr *prev;
-	struct vlan_ethhdr vlan;
+	struct gelic_descr *next;
+	struct gelic_descr *prev;
 } __attribute__((aligned(32)));
 
-struct gelic_net_descr_chain {
+struct gelic_descr_chain {
 	/* we walk from tail to head */
-	struct gelic_net_descr *head;
-	struct gelic_net_descr *tail;
+	struct gelic_descr *head;
+	struct gelic_descr *tail;
 };
 
-struct gelic_net_card {
-	struct net_device *netdev;
+struct gelic_vlan_id {
+	u16 tx;
+	u16 rx;
+};
+
+struct gelic_card {
 	struct napi_struct napi;
+	struct net_device *netdev[GELIC_PORT_MAX];
 	/*
 	 * hypervisor requires irq_status should be
 	 * 8 bytes aligned, but u64 member is
 	 * always disposed in that manner
 	 */
 	u64 irq_status;
-	u64 ghiintmask;
+	u64 irq_mask;
 
 	struct ps3_system_bus_device *dev;
-	u32 vlan_id[GELIC_NET_VLAN_MAX];
-	int vlan_index;
+	struct gelic_vlan_id vlan[GELIC_PORT_MAX];
+	int vlan_required;
 
-	struct gelic_net_descr_chain tx_chain;
-	struct gelic_net_descr_chain rx_chain;
+	struct gelic_descr_chain tx_chain;
+	struct gelic_descr_chain rx_chain;
 	int rx_dma_restart_required;
-	/* gurad dmac descriptor chain*/
-	spinlock_t chain_lock;
-
 	int rx_csum;
-	/* guard tx_dma_progress */
-	spinlock_t tx_dma_lock;
+	/*
+	 * tx_lock guards tx descriptor list and
+	 * tx_dma_progress.
+	 */
+	spinlock_t tx_lock;
 	int tx_dma_progress;
 
 	struct work_struct tx_timeout_task;
 	atomic_t tx_timeout_task_counter;
 	wait_queue_head_t waitq;
 
-	struct gelic_net_descr *tx_top, *rx_top;
-	struct gelic_net_descr descr[0];
+	/* only first user should up the card */
+	struct semaphore updown_lock;
+	atomic_t users;
+
+	u64 ether_port_status;
+	/* original address returned by kzalloc */
+	void *unalign;
+
+	/*
+	 * each netdevice has copy of irq
+	 */
+	unsigned int irq;
+	struct gelic_descr *tx_top, *rx_top;
+	struct gelic_descr descr[0]; /* must be the last */
+};
+
+struct gelic_port {
+	struct gelic_card *card;
+	struct net_device *netdev;
+	enum gelic_port_type type;
+	long priv[0]; /* long for alignment */
 };
 
+static inline struct gelic_card *port_to_card(struct gelic_port *p)
+{
+	return p->card;
+}
+static inline struct net_device *port_to_netdev(struct gelic_port *p)
+{
+	return p->netdev;
+}
+static inline struct gelic_card *netdev_card(struct net_device *d)
+{
+	return ((struct gelic_port *)netdev_priv(d))->card;
+}
+static inline struct gelic_port *netdev_port(struct net_device *d)
+{
+	return (struct gelic_port *)netdev_priv(d);
+}
+static inline struct device *ctodev(struct gelic_card *card)
+{
+	return &card->dev->core;
+}
+static inline u64 bus_id(struct gelic_card *card)
+{
+	return card->dev->bus_id;
+}
+static inline u64 dev_id(struct gelic_card *card)
+{
+	return card->dev->dev_id;
+}
+
+static inline void *port_priv(struct gelic_port *port)
+{
+	return port->priv;
+}
+
+extern int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask);
+/* shared netdev ops */
+extern void gelic_card_up(struct gelic_card *card);
+extern void gelic_card_down(struct gelic_card *card);
+extern int gelic_net_open(struct net_device *netdev);
+extern int gelic_net_stop(struct net_device *netdev);
+extern int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev);
+extern void gelic_net_set_multi(struct net_device *netdev);
+extern void gelic_net_tx_timeout(struct net_device *netdev);
+extern int gelic_net_change_mtu(struct net_device *netdev, int new_mtu);
+extern int gelic_net_setup_netdev(struct net_device *netdev,
+				  struct gelic_card *card);
 
-extern unsigned long p_to_lp(long pa);
+/* shared ethtool ops */
+extern void gelic_net_get_drvinfo(struct net_device *netdev,
+				  struct ethtool_drvinfo *info);
+extern u32 gelic_net_get_rx_csum(struct net_device *netdev);
+extern int gelic_net_set_rx_csum(struct net_device *netdev, u32 data);
+extern void gelic_net_poll_controller(struct net_device *netdev);
 
 #endif /* _GELIC_NET_H */
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
new file mode 100644
index 0000000..750d2a9
--- /dev/null
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -0,0 +1,2753 @@
+/*
+ *  PS3 gelic network driver.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/wireless.h>
+#include <linux/ctype.h>
+#include <linux/string.h>
+#include <net/iw_handler.h>
+#include <net/ieee80211.h>
+
+#include <linux/dma-mapping.h>
+#include <net/checksum.h>
+#include <asm/firmware.h>
+#include <asm/ps3.h>
+#include <asm/lv1call.h>
+
+#include "ps3_gelic_net.h"
+#include "ps3_gelic_wireless.h"
+
+
+static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan);
+static int gelic_wl_try_associate(struct net_device *netdev);
+
+/*
+ * tables
+ */
+
+/* 802.11b/g channel to freq in MHz */
+static const int channel_freq[] = {
+	2412, 2417, 2422, 2427, 2432,
+	2437, 2442, 2447, 2452, 2457,
+	2462, 2467, 2472, 2484
+};
+#define NUM_CHANNELS ARRAY_SIZE(channel_freq)
+
+/* in bps */
+static const int bitrate_list[] = {
+	  1000000,
+	  2000000,
+	  5500000,
+	 11000000,
+	  6000000,
+	  9000000,
+	 12000000,
+	 18000000,
+	 24000000,
+	 36000000,
+	 48000000,
+	 54000000
+};
+#define NUM_BITRATES ARRAY_SIZE(bitrate_list)
+
+/*
+ * wpa2 support requires the hypervisor version 2.0 or later
+ */
+static inline int wpa2_capable(void)
+{
+	return (0 <= ps3_compare_firmware_version(2, 0, 0));
+}
+
+static inline int precise_ie(void)
+{
+	return 0; /* FIXME */
+}
+/*
+ * post_eurus_cmd helpers
+ */
+struct eurus_cmd_arg_info {
+	int pre_arg; /* command requres arg1, arg2 at POST COMMAND */
+	int post_arg; /* command requires arg1, arg2 at GET_RESULT */
+};
+
+static const struct eurus_cmd_arg_info cmd_info[GELIC_EURUS_CMD_MAX_INDEX] = {
+	[GELIC_EURUS_CMD_SET_COMMON_CFG] = { .pre_arg = 1},
+	[GELIC_EURUS_CMD_SET_WEP_CFG]    = { .pre_arg = 1},
+	[GELIC_EURUS_CMD_SET_WPA_CFG]    = { .pre_arg = 1},
+	[GELIC_EURUS_CMD_GET_COMMON_CFG] = { .post_arg = 1},
+	[GELIC_EURUS_CMD_GET_WEP_CFG]    = { .post_arg = 1},
+	[GELIC_EURUS_CMD_GET_WPA_CFG]    = { .post_arg = 1},
+	[GELIC_EURUS_CMD_GET_RSSI_CFG]   = { .post_arg = 1},
+	[GELIC_EURUS_CMD_GET_SCAN]       = { .post_arg = 1},
+};
+
+#ifdef DEBUG
+static const char *cmdstr(enum gelic_eurus_command ix)
+{
+	switch (ix) {
+	case GELIC_EURUS_CMD_ASSOC:
+		return "ASSOC";
+	case GELIC_EURUS_CMD_DISASSOC:
+		return "DISASSOC";
+	case GELIC_EURUS_CMD_START_SCAN:
+		return "SCAN";
+	case GELIC_EURUS_CMD_GET_SCAN:
+		return "GET SCAN";
+	case GELIC_EURUS_CMD_SET_COMMON_CFG:
+		return "SET_COMMON_CFG";
+	case GELIC_EURUS_CMD_GET_COMMON_CFG:
+		return "GET_COMMON_CFG";
+	case GELIC_EURUS_CMD_SET_WEP_CFG:
+		return "SET_WEP_CFG";
+	case GELIC_EURUS_CMD_GET_WEP_CFG:
+		return "GET_WEP_CFG";
+	case GELIC_EURUS_CMD_SET_WPA_CFG:
+		return "SET_WPA_CFG";
+	case GELIC_EURUS_CMD_GET_WPA_CFG:
+		return "GET_WPA_CFG";
+	case GELIC_EURUS_CMD_GET_RSSI_CFG:
+		return "GET_RSSI";
+	default:
+		break;
+	}
+	return "";
+};
+#else
+static inline const char *cmdstr(enum gelic_eurus_command ix)
+{
+	return "";
+}
+#endif
+
+/* synchronously do eurus commands */
+static void gelic_eurus_sync_cmd_worker(struct work_struct *work)
+{
+	struct gelic_eurus_cmd *cmd;
+	struct gelic_card *card;
+	struct gelic_wl_info *wl;
+
+	u64 arg1, arg2;
+
+	pr_debug("%s: <-\n", __func__);
+	cmd = container_of(work, struct gelic_eurus_cmd, work);
+	BUG_ON(cmd_info[cmd->cmd].pre_arg &&
+	       cmd_info[cmd->cmd].post_arg);
+	wl = cmd->wl;
+	card = port_to_card(wl_port(wl));
+
+	if (cmd_info[cmd->cmd].pre_arg) {
+		arg1 = ps3_mm_phys_to_lpar(__pa(cmd->buffer));
+		arg2 = cmd->buf_size;
+	} else {
+		arg1 = 0;
+		arg2 = 0;
+	}
+	init_completion(&wl->cmd_done_intr);
+	pr_debug("%s: cmd='%s' start\n", __func__, cmdstr(cmd->cmd));
+	cmd->status = lv1_net_control(bus_id(card), dev_id(card),
+				      GELIC_LV1_POST_WLAN_CMD,
+				      cmd->cmd, arg1, arg2,
+				      &cmd->tag, &cmd->size);
+	if (cmd->status) {
+		complete(&cmd->done);
+		pr_info("%s: cmd issue failed\n", __func__);
+		return;
+	}
+
+	wait_for_completion(&wl->cmd_done_intr);
+
+	if (cmd_info[cmd->cmd].post_arg) {
+		arg1 = ps3_mm_phys_to_lpar(__pa(cmd->buffer));
+		arg2 = cmd->buf_size;
+	} else {
+		arg1 = 0;
+		arg2 = 0;
+	}
+
+	cmd->status = lv1_net_control(bus_id(card), dev_id(card),
+				      GELIC_LV1_GET_WLAN_CMD_RESULT,
+				      cmd->tag, arg1, arg2,
+				      &cmd->cmd_status, &cmd->size);
+#ifdef DEBUG
+	if (cmd->status || cmd->cmd_status) {
+	pr_debug("%s: cmd done tag=%#lx arg1=%#lx, arg2=%#lx\n", __func__,
+		 cmd->tag, arg1, arg2);
+	pr_debug("%s: cmd done status=%#x cmd_status=%#lx size=%#lx\n",
+		 __func__, cmd->status, cmd->cmd_status, cmd->size);
+	}
+#endif
+	complete(&cmd->done);
+	pr_debug("%s: cmd='%s' done\n", __func__, cmdstr(cmd->cmd));
+}
+
+static struct gelic_eurus_cmd *gelic_eurus_sync_cmd(struct gelic_wl_info *wl,
+						    unsigned int eurus_cmd,
+						    void *buffer,
+						    unsigned int buf_size)
+{
+	struct gelic_eurus_cmd *cmd;
+
+	/* allocate cmd */
+	cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
+	if (!cmd)
+		return NULL;
+
+	/* initialize members */
+	cmd->cmd = eurus_cmd;
+	cmd->buffer = buffer;
+	cmd->buf_size = buf_size;
+	cmd->wl = wl;
+	INIT_WORK(&cmd->work, gelic_eurus_sync_cmd_worker);
+	init_completion(&cmd->done);
+	queue_work(wl->eurus_cmd_queue, &cmd->work);
+
+	/* wait for command completion */
+	wait_for_completion(&cmd->done);
+
+	return cmd;
+}
+
+static u32 gelic_wl_get_link(struct net_device *netdev)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_port(netdev));
+	u32 ret;
+
+	pr_debug("%s: <-\n", __func__);
+	down(&wl->assoc_stat_lock);
+	if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED)
+		ret = 1;
+	else
+		ret = 0;
+	up(&wl->assoc_stat_lock);
+	pr_debug("%s: ->\n", __func__);
+	return ret;
+}
+
+static void gelic_wl_send_iwap_event(struct gelic_wl_info *wl, u8 *bssid)
+{
+	union iwreq_data data;
+
+	memset(&data, 0, sizeof(data));
+	if (bssid)
+		memcpy(data.ap_addr.sa_data, bssid, ETH_ALEN);
+	data.ap_addr.sa_family = ARPHRD_ETHER;
+	wireless_send_event(port_to_netdev(wl_port(wl)), SIOCGIWAP,
+			    &data, NULL);
+}
+
+/*
+ * wireless extension handlers and helpers
+ */
+
+/* SIOGIWNAME */
+static int gelic_wl_get_name(struct net_device *dev,
+			     struct iw_request_info *info,
+			     union iwreq_data *iwreq, char *extra)
+{
+	strcpy(iwreq->name, "IEEE 802.11bg");
+	return 0;
+}
+
+static void gelic_wl_get_ch_info(struct gelic_wl_info *wl)
+{
+	struct gelic_card *card = port_to_card(wl_port(wl));
+	u64 ch_info_raw, tmp;
+	int status;
+
+	if (!test_and_set_bit(GELIC_WL_STAT_CH_INFO, &wl->stat)) {
+		status = lv1_net_control(bus_id(card), dev_id(card),
+					 GELIC_LV1_GET_CHANNEL, 0, 0, 0,
+					 &ch_info_raw,
+					 &tmp);
+		/* some fw versions may return error */
+		if (status) {
+			if (status != LV1_NO_ENTRY)
+				pr_info("%s: available ch unknown\n", __func__);
+			wl->ch_info = 0x07ff;/* 11 ch */
+		} else
+			/* 16 bits of MSB has available channels */
+			wl->ch_info = ch_info_raw >> 48;
+	}
+	return;
+}
+
+/* SIOGIWRANGE */
+static int gelic_wl_get_range(struct net_device *netdev,
+			      struct iw_request_info *info,
+			      union iwreq_data *iwreq, char *extra)
+{
+	struct iw_point *point = &iwreq->data;
+	struct iw_range *range = (struct iw_range *)extra;
+	struct gelic_wl_info *wl = port_wl(netdev_port(netdev));
+	unsigned int i, chs;
+
+	pr_debug("%s: <-\n", __func__);
+	point->length = sizeof(struct iw_range);
+	memset(range, 0, sizeof(struct iw_range));
+
+	range->we_version_compiled = WIRELESS_EXT;
+	range->we_version_source = 22;
+
+	/* available channels and frequencies */
+	gelic_wl_get_ch_info(wl);
+
+	for (i = 0, chs = 0;
+	     i < NUM_CHANNELS && chs < IW_MAX_FREQUENCIES; i++)
+		if (wl->ch_info & (1 << i)) {
+			range->freq[chs].i = i + 1;
+			range->freq[chs].m = channel_freq[i];
+			range->freq[chs].e = 6;
+			chs++;
+		}
+	range->num_frequency = chs;
+	range->old_num_frequency = chs;
+	range->num_channels = chs;
+	range->old_num_channels = chs;
+
+	/* bitrates */
+	for (i = 0; i < NUM_BITRATES; i++)
+		range->bitrate[i] = bitrate_list[i];
+	range->num_bitrates = i;
+
+	/* signal levels */
+	range->max_qual.qual = 100; /* relative value */
+	range->max_qual.level = 100;
+	range->avg_qual.qual = 50;
+	range->avg_qual.level = 50;
+	range->sensitivity = 0;
+
+	/* Event capability */
+	IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
+	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
+	IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
+
+	/* encryption capability */
+	range->enc_capa = IW_ENC_CAPA_WPA |
+		IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
+	if (wpa2_capable())
+		range->enc_capa |= IW_ENC_CAPA_WPA2;
+	range->encoding_size[0] = 5;	/* 40bit WEP */
+	range->encoding_size[1] = 13;	/* 104bit WEP */
+	range->encoding_size[2] = 32;	/* WPA-PSK */
+	range->num_encoding_sizes = 3;
+	range->max_encoding_tokens = GELIC_WEP_KEYS;
+
+	pr_debug("%s: ->\n", __func__);
+	return 0;
+
+}
+
+/* SIOC{G,S}IWSCAN */
+static int gelic_wl_set_scan(struct net_device *netdev,
+			   struct iw_request_info *info,
+			   union iwreq_data *wrqu, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+
+	return gelic_wl_start_scan(wl, 1);
+}
+
+#define OUI_LEN 3
+static const u8 rsn_oui[OUI_LEN] = { 0x00, 0x0f, 0xac };
+static const u8 wpa_oui[OUI_LEN] = { 0x00, 0x50, 0xf2 };
+
+/*
+ * synthesize WPA/RSN IE data
+ * See WiFi WPA specification and IEEE 802.11-2007 7.3.2.25
+ * for the format
+ */
+static size_t gelic_wl_synthesize_ie(u8 *buf,
+				     struct gelic_eurus_scan_info *scan)
+{
+
+	const u8 *oui_header;
+	u8 *start = buf;
+	int rsn;
+	int ccmp;
+
+	pr_debug("%s: <- sec=%16x\n", __func__, scan->security);
+	switch (be16_to_cpu(scan->security) & GELIC_EURUS_SCAN_SEC_MASK) {
+	case GELIC_EURUS_SCAN_SEC_WPA:
+		rsn = 0;
+		break;
+	case GELIC_EURUS_SCAN_SEC_WPA2:
+		rsn = 1;
+		break;
+	default:
+		/* WEP or none.  No IE returned */
+		return 0;
+	}
+
+	switch (be16_to_cpu(scan->security) & GELIC_EURUS_SCAN_SEC_WPA_MASK) {
+	case GELIC_EURUS_SCAN_SEC_WPA_TKIP:
+		ccmp = 0;
+		break;
+	case GELIC_EURUS_SCAN_SEC_WPA_AES:
+		ccmp = 1;
+		break;
+	default:
+		if (rsn) {
+			ccmp = 1;
+			pr_info("%s: no cipher info. defaulted to CCMP\n",
+				__func__);
+		} else {
+			ccmp = 0;
+			pr_info("%s: no cipher info. defaulted to TKIP\n",
+				__func__);
+		}
+	}
+
+	if (rsn)
+		oui_header = rsn_oui;
+	else
+		oui_header = wpa_oui;
+
+	/* element id */
+	if (rsn)
+		*buf++ = MFIE_TYPE_RSN;
+	else
+		*buf++ = MFIE_TYPE_GENERIC;
+
+	/* length filed; set later */
+	buf++;
+
+	/* wpa special header */
+	if (!rsn) {
+		memcpy(buf, wpa_oui, OUI_LEN);
+		buf += OUI_LEN;
+		*buf++ = 0x01;
+	}
+
+	/* version */
+	*buf++ = 0x01; /* version 1.0 */
+	*buf++ = 0x00;
+
+	/* group cipher */
+	memcpy(buf, oui_header, OUI_LEN);
+	buf += OUI_LEN;
+
+	if (ccmp)
+		*buf++ = 0x04; /* CCMP */
+	else
+		*buf++ = 0x02; /* TKIP */
+
+	/* pairwise key count always 1 */
+	*buf++ = 0x01;
+	*buf++ = 0x00;
+
+	/* pairwise key suit */
+	memcpy(buf, oui_header, OUI_LEN);
+	buf += OUI_LEN;
+	if (ccmp)
+		*buf++ = 0x04; /* CCMP */
+	else
+		*buf++ = 0x02; /* TKIP */
+
+	/* AKM count is 1 */
+	*buf++ = 0x01;
+	*buf++ = 0x00;
+
+	/* AKM suite is assumed as PSK*/
+	memcpy(buf, oui_header, OUI_LEN);
+	buf += OUI_LEN;
+	*buf++ = 0x02; /* PSK */
+
+	/* RSN capabilities is 0 */
+	*buf++ = 0x00;
+	*buf++ = 0x00;
+
+	/* set length field */
+	start[1] = (buf - start - 2);
+
+	pr_debug("%s: ->\n", __func__);
+	return (buf - start);
+}
+
+struct ie_item {
+	u8 *data;
+	u8 len;
+};
+
+struct ie_info {
+	struct ie_item wpa;
+	struct ie_item rsn;
+};
+
+static void gelic_wl_parse_ie(u8 *data, size_t len,
+			      struct ie_info *ie_info)
+{
+	size_t data_left = len;
+	u8 *pos = data;
+	u8 item_len;
+	u8 item_id;
+
+	pr_debug("%s: data=%p len=%ld \n", __func__,
+		 data, len);
+	memset(ie_info, 0, sizeof(struct ie_info));
+
+	while (0 < data_left) {
+		item_id = *pos++;
+		item_len = *pos++;
+
+		switch (item_id) {
+		case MFIE_TYPE_GENERIC:
+			if (!memcmp(pos, wpa_oui, OUI_LEN) &&
+			    pos[OUI_LEN] == 0x01) {
+				ie_info->wpa.data = pos - 2;
+				ie_info->wpa.len = item_len + 2;
+			}
+			break;
+		case MFIE_TYPE_RSN:
+			ie_info->rsn.data = pos - 2;
+			/* length includes the header */
+			ie_info->rsn.len = item_len + 2;
+			break;
+		default:
+			pr_debug("%s: ignore %#x,%d\n", __func__,
+				 item_id, item_len);
+			break;
+		}
+		pos += item_len;
+		data_left -= item_len + 2;
+	}
+	pr_debug("%s: wpa=%p,%d wpa2=%p,%d\n", __func__,
+		 ie_info->wpa.data, ie_info->wpa.len,
+		 ie_info->rsn.data, ie_info->rsn.len);
+}
+
+
+/*
+ * translate the scan informations from hypervisor to a
+ * independent format
+ */
+static char *gelic_wl_translate_scan(struct net_device *netdev,
+				     char *ev,
+				     char *stop,
+				     struct gelic_wl_scan_info *network)
+{
+	struct iw_event iwe;
+	struct gelic_eurus_scan_info *scan = network->hwinfo;
+	char *tmp;
+	u8 rate;
+	unsigned int i, j, len;
+	u8 buf[MAX_WPA_IE_LEN];
+
+	pr_debug("%s: <-\n", __func__);
+
+	/* first entry should be AP's mac address */
+	iwe.cmd = SIOCGIWAP;
+	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
+	memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN);
+	ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_ADDR_LEN);
+
+	/* ESSID */
+	iwe.cmd = SIOCGIWESSID;
+	iwe.u.data.flags = 1;
+	iwe.u.data.length = strnlen(scan->essid, 32);
+	ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid);
+
+	/* FREQUENCY */
+	iwe.cmd = SIOCGIWFREQ;
+	iwe.u.freq.m = be16_to_cpu(scan->channel);
+	iwe.u.freq.e = 0; /* table value in MHz */
+	iwe.u.freq.i = 0;
+	ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_FREQ_LEN);
+
+	/* RATES */
+	iwe.cmd = SIOCGIWRATE;
+	iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
+	/* to stuff multiple values in one event */
+	tmp = ev + IW_EV_LCP_LEN;
+	/* put them in ascendant order (older is first) */
+	i = 0;
+	j = 0;
+	pr_debug("%s: rates=%d rate=%d\n", __func__,
+		 network->rate_len, network->rate_ext_len);
+	while (i < network->rate_len) {
+		if (j < network->rate_ext_len &&
+		    ((scan->ext_rate[j] & 0x7f) < (scan->rate[i] & 0x7f)))
+		    rate = scan->ext_rate[j++] & 0x7f;
+		else
+		    rate = scan->rate[i++] & 0x7f;
+		iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */
+		tmp = iwe_stream_add_value(ev, tmp, stop, &iwe,
+					   IW_EV_PARAM_LEN);
+	}
+	while (j < network->rate_ext_len) {
+		iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000;
+		tmp = iwe_stream_add_value(ev, tmp, stop, &iwe,
+					   IW_EV_PARAM_LEN);
+	}
+	/* Check if we added any rate */
+	if (IW_EV_LCP_LEN < (tmp - ev))
+		ev = tmp;
+
+	/* ENCODE */
+	iwe.cmd = SIOCGIWENCODE;
+	if (be16_to_cpu(scan->capability) & WLAN_CAPABILITY_PRIVACY)
+		iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
+	else
+		iwe.u.data.flags = IW_ENCODE_DISABLED;
+	iwe.u.data.length = 0;
+	ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid);
+
+	/* MODE */
+	iwe.cmd = SIOCGIWMODE;
+	if (be16_to_cpu(scan->capability) &
+	    (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
+		if (be16_to_cpu(scan->capability) & WLAN_CAPABILITY_ESS)
+			iwe.u.mode = IW_MODE_MASTER;
+		else
+			iwe.u.mode = IW_MODE_ADHOC;
+		ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_UINT_LEN);
+	}
+
+	/* QUAL */
+	iwe.cmd = IWEVQUAL;
+	iwe.u.qual.updated  = IW_QUAL_ALL_UPDATED |
+			IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
+	iwe.u.qual.level = be16_to_cpu(scan->rssi);
+	iwe.u.qual.qual = be16_to_cpu(scan->rssi);
+	iwe.u.qual.noise = 0;
+	ev  = iwe_stream_add_event(ev, stop, &iwe, IW_EV_QUAL_LEN);
+
+	/* RSN */
+	memset(&iwe, 0, sizeof(iwe));
+	if (be16_to_cpu(scan->size) <= sizeof(*scan)) {
+		/* If wpa[2] capable station, synthesize IE and put it */
+		len = gelic_wl_synthesize_ie(buf, scan);
+		if (len) {
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.length = len;
+			ev = iwe_stream_add_point(ev, stop, &iwe, buf);
+		}
+	} else {
+		/* this scan info has IE data */
+		struct ie_info ie_info;
+		size_t data_len;
+
+		data_len = be16_to_cpu(scan->size) - sizeof(*scan);
+
+		gelic_wl_parse_ie(scan->elements, data_len, &ie_info);
+
+		if (ie_info.wpa.len && (ie_info.wpa.len <= sizeof(buf))) {
+			memcpy(buf, ie_info.wpa.data, ie_info.wpa.len);
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.length = ie_info.wpa.len;
+			ev = iwe_stream_add_point(ev, stop, &iwe, buf);
+		}
+
+		if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) {
+			memset(&iwe, 0, sizeof(iwe));
+			memcpy(buf, ie_info.rsn.data, ie_info.rsn.len);
+			iwe.cmd = IWEVGENIE;
+			iwe.u.data.length = ie_info.rsn.len;
+			ev = iwe_stream_add_point(ev, stop, &iwe, buf);
+		}
+	}
+
+	pr_debug("%s: ->\n", __func__);
+	return ev;
+}
+
+
+static int gelic_wl_get_scan(struct net_device *netdev,
+			     struct iw_request_info *info,
+			     union iwreq_data *wrqu, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	struct gelic_wl_scan_info *scan_info;
+	char *ev = extra;
+	char *stop = ev + wrqu->data.length;
+	int ret = 0;
+	unsigned long this_time = jiffies;
+
+	pr_debug("%s: <-\n", __func__);
+	if (down_interruptible(&wl->scan_lock))
+		return -EAGAIN;
+
+	switch (wl->scan_stat) {
+	case GELIC_WL_SCAN_STAT_SCANNING:
+		/* If a scan in progress, caller should call me again */
+		ret = -EAGAIN;
+		goto out;
+		break;
+
+	case GELIC_WL_SCAN_STAT_INIT:
+		/* last scan request failed or never issued */
+		ret = -ENODEV;
+		goto out;
+		break;
+	case GELIC_WL_SCAN_STAT_GOT_LIST:
+		/* ok, use current list */
+		break;
+	}
+
+	list_for_each_entry(scan_info, &wl->network_list, list) {
+		if (wl->scan_age == 0 ||
+		    time_after(scan_info->last_scanned + wl->scan_age,
+			       this_time))
+			ev = gelic_wl_translate_scan(netdev, ev, stop,
+						     scan_info);
+		else
+			pr_debug("%s:entry too old\n", __func__);
+
+		if (stop - ev <= IW_EV_ADDR_LEN) {
+			ret = -E2BIG;
+			goto out;
+		}
+	}
+
+	wrqu->data.length = ev - extra;
+	wrqu->data.flags = 0;
+out:
+	up(&wl->scan_lock);
+	pr_debug("%s: -> %d %d\n", __func__, ret, wrqu->data.length);
+	return ret;
+}
+
+#ifdef DEBUG
+static void scan_list_dump(struct gelic_wl_info *wl)
+{
+	struct gelic_wl_scan_info *scan_info;
+	int i;
+	DECLARE_MAC_BUF(mac);
+
+	i = 0;
+	list_for_each_entry(scan_info, &wl->network_list, list) {
+		pr_debug("%s: item %d\n", __func__, i++);
+		pr_debug("valid=%d eurusindex=%d last=%lx\n",
+			 scan_info->valid, scan_info->eurus_index,
+			 scan_info->last_scanned);
+		pr_debug("r_len=%d r_ext_len=%d essid_len=%d\n",
+			 scan_info->rate_len, scan_info->rate_ext_len,
+			 scan_info->essid_len);
+		/* -- */
+		pr_debug("bssid=%s\n",
+			 print_mac(mac, &scan_info->hwinfo->bssid[2]));
+		pr_debug("essid=%s\n", scan_info->hwinfo->essid);
+	}
+}
+#endif
+
+static int gelic_wl_set_auth(struct net_device *netdev,
+			     struct iw_request_info *info,
+			     union iwreq_data *data, char *extra)
+{
+	struct iw_param *param = &data->param;
+	struct gelic_wl_info *wl = port_wl(netdev_port(netdev));
+	unsigned long irqflag;
+	int ret = 0;
+
+	pr_debug("%s: <- %d\n", __func__, param->flags & IW_AUTH_INDEX);
+	spin_lock_irqsave(&wl->lock, irqflag);
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+		if (param->value & IW_AUTH_WPA_VERSION_DISABLED) {
+			pr_debug("%s: NO WPA selected\n", __func__);
+			wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE;
+			wl->group_cipher_method = GELIC_WL_CIPHER_WEP;
+			wl->pairwise_cipher_method = GELIC_WL_CIPHER_WEP;
+		}
+		if (param->value & IW_AUTH_WPA_VERSION_WPA) {
+			pr_debug("%s: WPA version 1 selected\n", __func__);
+			wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA;
+			wl->group_cipher_method = GELIC_WL_CIPHER_TKIP;
+			wl->pairwise_cipher_method = GELIC_WL_CIPHER_TKIP;
+			wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+		}
+		if (param->value & IW_AUTH_WPA_VERSION_WPA2) {
+			/*
+			 * As the hypervisor may not tell the cipher
+			 * information of the AP if it is WPA2,
+			 * you will not decide suitable cipher from
+			 * its beacon.
+			 * You should have knowledge about the AP's
+			 * cipher infomation in other method prior to
+			 * the association.
+			 */
+			if (!precise_ie())
+				pr_info("%s: WPA2 may not work\n", __func__);
+			if (wpa2_capable()) {
+				wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA2;
+				wl->group_cipher_method = GELIC_WL_CIPHER_AES;
+				wl->pairwise_cipher_method =
+					GELIC_WL_CIPHER_AES;
+				wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+			} else
+				ret = -EINVAL;
+		}
+		break;
+
+	case IW_AUTH_CIPHER_PAIRWISE:
+		if (param->value &
+		    (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
+			pr_debug("%s: WEP selected\n", __func__);
+			wl->pairwise_cipher_method = GELIC_WL_CIPHER_WEP;
+		}
+		if (param->value & IW_AUTH_CIPHER_TKIP) {
+			pr_debug("%s: TKIP selected\n", __func__);
+			wl->pairwise_cipher_method = GELIC_WL_CIPHER_TKIP;
+		}
+		if (param->value & IW_AUTH_CIPHER_CCMP) {
+			pr_debug("%s: CCMP selected\n", __func__);
+			wl->pairwise_cipher_method = GELIC_WL_CIPHER_AES;
+		}
+		if (param->value & IW_AUTH_CIPHER_NONE) {
+			pr_debug("%s: no auth selected\n", __func__);
+			wl->pairwise_cipher_method = GELIC_WL_CIPHER_NONE;
+		}
+		break;
+	case IW_AUTH_CIPHER_GROUP:
+		if (param->value &
+		    (IW_AUTH_CIPHER_WEP104 | IW_AUTH_CIPHER_WEP40)) {
+			pr_debug("%s: WEP selected\n", __func__);
+			wl->group_cipher_method = GELIC_WL_CIPHER_WEP;
+		}
+		if (param->value & IW_AUTH_CIPHER_TKIP) {
+			pr_debug("%s: TKIP selected\n", __func__);
+			wl->group_cipher_method = GELIC_WL_CIPHER_TKIP;
+		}
+		if (param->value & IW_AUTH_CIPHER_CCMP) {
+			pr_debug("%s: CCMP selected\n", __func__);
+			wl->group_cipher_method = GELIC_WL_CIPHER_AES;
+		}
+		if (param->value & IW_AUTH_CIPHER_NONE) {
+			pr_debug("%s: no auth selected\n", __func__);
+			wl->group_cipher_method = GELIC_WL_CIPHER_NONE;
+		}
+		break;
+	case IW_AUTH_80211_AUTH_ALG:
+		if (param->value & IW_AUTH_ALG_SHARED_KEY) {
+			pr_debug("%s: shared key specified\n", __func__);
+			wl->auth_method = GELIC_EURUS_AUTH_SHARED;
+		} else if (param->value & IW_AUTH_ALG_OPEN_SYSTEM) {
+			pr_debug("%s: open system specified\n", __func__);
+			wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+		} else
+			ret = -EINVAL;
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		if (param->value) {
+			pr_debug("%s: WPA enabled\n", __func__);
+			wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA;
+		} else {
+			pr_debug("%s: WPA disabled\n", __func__);
+			wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE;
+		}
+		break;
+
+	case IW_AUTH_KEY_MGMT:
+		if (param->value & IW_AUTH_KEY_MGMT_PSK)
+			break;
+		/* intentionally fall through */
+	default:
+		ret = -EOPNOTSUPP;
+		break;
+	};
+
+	if (!ret)
+		set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	pr_debug("%s: -> %d\n", __func__, ret);
+	return ret;
+}
+
+static int gelic_wl_get_auth(struct net_device *netdev,
+			     struct iw_request_info *info,
+			     union iwreq_data *iwreq, char *extra)
+{
+	struct iw_param *param = &iwreq->param;
+	struct gelic_wl_info *wl = port_wl(netdev_port(netdev));
+	unsigned long irqflag;
+	int ret = 0;
+
+	pr_debug("%s: <- %d\n", __func__, param->flags & IW_AUTH_INDEX);
+	spin_lock_irqsave(&wl->lock, irqflag);
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+		switch (wl->wpa_level) {
+		case GELIC_WL_WPA_LEVEL_WPA:
+			param->value |= IW_AUTH_WPA_VERSION_WPA;
+			break;
+		case GELIC_WL_WPA_LEVEL_WPA2:
+			param->value |= IW_AUTH_WPA_VERSION_WPA2;
+			break;
+		default:
+			param->value |= IW_AUTH_WPA_VERSION_DISABLED;
+		}
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+		if (wl->auth_method == GELIC_EURUS_AUTH_SHARED)
+			param->value = IW_AUTH_ALG_SHARED_KEY;
+		else if (wl->auth_method == GELIC_EURUS_AUTH_OPEN)
+			param->value = IW_AUTH_ALG_OPEN_SYSTEM;
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		switch (wl->wpa_level) {
+		case GELIC_WL_WPA_LEVEL_WPA:
+		case GELIC_WL_WPA_LEVEL_WPA2:
+			param->value = 1;
+			break;
+		default:
+			param->value = 0;
+			break;
+		}
+		break;
+	default:
+		ret = -EOPNOTSUPP;
+	}
+
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	pr_debug("%s: -> %d\n", __func__, ret);
+	return ret;
+}
+
+/* SIOC{S,G}IWESSID */
+static int gelic_wl_set_essid(struct net_device *netdev,
+			      struct iw_request_info *info,
+			      union iwreq_data *data, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	unsigned long irqflag;
+
+	pr_debug("%s: <- l=%d f=%d\n", __func__,
+		 data->essid.length, data->essid.flags);
+	if (IW_ESSID_MAX_SIZE < data->essid.length)
+		return -EINVAL;
+
+	spin_lock_irqsave(&wl->lock, irqflag);
+	if (data->essid.flags) {
+		wl->essid_len = data->essid.length;
+		memcpy(wl->essid, extra, wl->essid_len);
+		pr_debug("%s: essid = '%s'\n", __func__, extra);
+		set_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat);
+	} else {
+		pr_debug("%s: ESSID any \n", __func__);
+		clear_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat);
+	}
+	set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+
+
+	gelic_wl_try_associate(netdev); /* FIXME */
+	pr_debug("%s: -> \n", __func__);
+	return 0;
+}
+
+static int gelic_wl_get_essid(struct net_device *netdev,
+			      struct iw_request_info *info,
+			      union iwreq_data *data, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	unsigned long irqflag;
+
+	pr_debug("%s: <- \n", __func__);
+	down(&wl->assoc_stat_lock);
+	spin_lock_irqsave(&wl->lock, irqflag);
+	if (test_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat) ||
+	    wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) {
+		memcpy(extra, wl->essid, wl->essid_len);
+		data->essid.length = wl->essid_len;
+		data->essid.flags = 1;
+	} else
+		data->essid.flags = 0;
+
+	up(&wl->assoc_stat_lock);
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	pr_debug("%s: -> len=%d \n", __func__, data->essid.length);
+
+	return 0;
+}
+
+/* SIO{S,G}IWENCODE */
+static int gelic_wl_set_encode(struct net_device *netdev,
+			       struct iw_request_info *info,
+			       union iwreq_data *data, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	struct iw_point *enc = &data->encoding;
+	__u16 flags;
+	unsigned int irqflag;
+	int key_index, index_specified;
+	int ret = 0;
+
+	pr_debug("%s: <- \n", __func__);
+	flags = enc->flags & IW_ENCODE_FLAGS;
+	key_index = enc->flags & IW_ENCODE_INDEX;
+
+	pr_debug("%s: key_index = %d\n", __func__, key_index);
+	pr_debug("%s: key_len = %d\n", __func__, enc->length);
+	pr_debug("%s: flag=%x\n", __func__, enc->flags & IW_ENCODE_FLAGS);
+
+	if (GELIC_WEP_KEYS < key_index)
+		return -EINVAL;
+
+	spin_lock_irqsave(&wl->lock, irqflag);
+	if (key_index) {
+		index_specified = 1;
+		key_index--;
+	} else {
+		index_specified = 0;
+		key_index = wl->current_key;
+	}
+
+	if (flags & IW_ENCODE_NOKEY) {
+		/* if just IW_ENCODE_NOKEY, change current key index */
+		if (!flags && index_specified) {
+			wl->current_key = key_index;
+			goto done;
+		}
+
+		if (flags & IW_ENCODE_DISABLED) {
+			if (!index_specified) {
+				/* disable encryption */
+				wl->group_cipher_method = GELIC_WL_CIPHER_NONE;
+				wl->pairwise_cipher_method =
+					GELIC_WL_CIPHER_NONE;
+				/* invalidate all key */
+				wl->key_enabled = 0;
+			} else
+				clear_bit(key_index, &wl->key_enabled);
+		}
+
+		if (flags & IW_ENCODE_OPEN)
+			wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+		if (flags & IW_ENCODE_RESTRICTED) {
+			pr_info("%s: shared key mode enabled\n", __func__);
+			wl->auth_method = GELIC_EURUS_AUTH_SHARED;
+		}
+	} else {
+		if (IW_ENCODING_TOKEN_MAX < enc->length) {
+			ret = -EINVAL;
+			goto done;
+		}
+		wl->key_len[key_index] = enc->length;
+		memcpy(wl->key[key_index], extra, enc->length);
+		set_bit(key_index, &wl->key_enabled);
+		wl->pairwise_cipher_method = GELIC_WL_CIPHER_WEP;
+		wl->group_cipher_method = GELIC_WL_CIPHER_WEP;
+	}
+	set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+done:
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	pr_debug("%s: -> \n", __func__);
+	return ret;
+}
+
+static int gelic_wl_get_encode(struct net_device *netdev,
+			       struct iw_request_info *info,
+			       union iwreq_data *data, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	struct iw_point *enc = &data->encoding;
+	unsigned int irqflag;
+	unsigned int key_index, index_specified;
+	int ret = 0;
+
+	pr_debug("%s: <- \n", __func__);
+	key_index = enc->flags & IW_ENCODE_INDEX;
+	pr_debug("%s: flag=%#x point=%p len=%d extra=%p\n", __func__,
+		 enc->flags, enc->pointer, enc->length, extra);
+	if (GELIC_WEP_KEYS < key_index)
+		return -EINVAL;
+
+	spin_lock_irqsave(&wl->lock, irqflag);
+	if (key_index) {
+		index_specified = 1;
+		key_index--;
+	} else {
+		index_specified = 0;
+		key_index = wl->current_key;
+	}
+
+	if (wl->group_cipher_method == GELIC_WL_CIPHER_WEP) {
+		switch (wl->auth_method) {
+		case GELIC_EURUS_AUTH_OPEN:
+			enc->flags = IW_ENCODE_OPEN;
+			break;
+		case GELIC_EURUS_AUTH_SHARED:
+			enc->flags = IW_ENCODE_RESTRICTED;
+			break;
+		}
+	} else
+		enc->flags = IW_ENCODE_DISABLED;
+
+	if (test_bit(key_index, &wl->key_enabled)) {
+		if (enc->length < wl->key_len[key_index]) {
+			ret = -EINVAL;
+			goto done;
+		}
+		enc->length = wl->key_len[key_index];
+		memcpy(extra, wl->key[key_index], wl->key_len[key_index]);
+	} else {
+		enc->length = 0;
+		enc->flags |= IW_ENCODE_NOKEY;
+	}
+	enc->flags |= key_index + 1;
+	pr_debug("%s: -> flag=%x len=%d\n", __func__,
+		 enc->flags, enc->length);
+
+done:
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	return ret;
+}
+
+/* SIOC{S,G}IWAP */
+static int gelic_wl_set_ap(struct net_device *netdev,
+			   struct iw_request_info *info,
+			   union iwreq_data *data, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	unsigned long irqflag;
+
+	pr_debug("%s: <-\n", __func__);
+	if (data->ap_addr.sa_family != ARPHRD_ETHER)
+		return -EINVAL;
+
+	spin_lock_irqsave(&wl->lock, irqflag);
+	if (is_valid_ether_addr(data->ap_addr.sa_data)) {
+		memcpy(wl->bssid, data->ap_addr.sa_data,
+		       ETH_ALEN);
+		set_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat);
+		set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+		pr_debug("%s: bss=%02x:%02x:%02x:%02x:%02x:%02x\n",
+			 __func__,
+			 wl->bssid[0], wl->bssid[1],
+			 wl->bssid[2], wl->bssid[3],
+			 wl->bssid[4], wl->bssid[5]);
+	} else {
+		pr_debug("%s: clear bssid\n", __func__);
+		clear_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat);
+		memset(wl->bssid, 0, ETH_ALEN);
+	}
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	pr_debug("%s: ->\n", __func__);
+	return 0;
+}
+
+static int gelic_wl_get_ap(struct net_device *netdev,
+			   struct iw_request_info *info,
+			   union iwreq_data *data, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	unsigned long irqflag;
+
+	pr_debug("%s: <-\n", __func__);
+	down(&wl->assoc_stat_lock);
+	spin_lock_irqsave(&wl->lock, irqflag);
+	if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED) {
+		data->ap_addr.sa_family = ARPHRD_ETHER;
+		memcpy(data->ap_addr.sa_data, wl->active_bssid,
+		       ETH_ALEN);
+	} else
+		memset(data->ap_addr.sa_data, 0, ETH_ALEN);
+
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	up(&wl->assoc_stat_lock);
+	pr_debug("%s: ->\n", __func__);
+	return 0;
+}
+
+/* SIOC{S,G}IWENCODEEXT */
+static int gelic_wl_set_encodeext(struct net_device *netdev,
+				  struct iw_request_info *info,
+				  union iwreq_data *data, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	struct iw_point *enc = &data->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	__u16 alg;
+	__u16 flags;
+	unsigned int irqflag;
+	int key_index;
+	int ret = 0;
+
+	pr_debug("%s: <- \n", __func__);
+	flags = enc->flags & IW_ENCODE_FLAGS;
+	alg = ext->alg;
+	key_index = enc->flags & IW_ENCODE_INDEX;
+
+	pr_debug("%s: key_index = %d\n", __func__, key_index);
+	pr_debug("%s: key_len = %d\n", __func__, enc->length);
+	pr_debug("%s: flag=%x\n", __func__, enc->flags & IW_ENCODE_FLAGS);
+	pr_debug("%s: ext_flag=%x\n", __func__, ext->ext_flags);
+	pr_debug("%s: ext_key_len=%x\n", __func__, ext->key_len);
+
+	if (GELIC_WEP_KEYS < key_index)
+		return -EINVAL;
+
+	spin_lock_irqsave(&wl->lock, irqflag);
+	if (key_index)
+		key_index--;
+	else
+		key_index = wl->current_key;
+
+	if (!enc->length && (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)) {
+		/* reques to change default key index */
+		pr_debug("%s: request to change default key to %d\n",
+			 __func__, key_index);
+		wl->current_key = key_index;
+		goto done;
+	}
+
+	if (alg == IW_ENCODE_ALG_NONE || (flags & IW_ENCODE_DISABLED)) {
+		pr_debug("%s: alg disabled\n", __func__);
+		wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE;
+		wl->group_cipher_method = GELIC_WL_CIPHER_NONE;
+		wl->pairwise_cipher_method = GELIC_WL_CIPHER_NONE;
+		wl->auth_method = GELIC_EURUS_AUTH_OPEN; /* should be open */
+	} else if (alg == IW_ENCODE_ALG_WEP) {
+		pr_debug("%s: WEP requested\n", __func__);
+		if (flags & IW_ENCODE_OPEN) {
+			pr_debug("%s: open key mode\n", __func__);
+			wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+		}
+		if (flags & IW_ENCODE_RESTRICTED) {
+			pr_debug("%s: shared key mode\n", __func__);
+			wl->auth_method = GELIC_EURUS_AUTH_SHARED;
+		}
+		if (IW_ENCODING_TOKEN_MAX < ext->key_len) {
+			pr_info("%s: key is too long %d\n", __func__,
+				ext->key_len);
+			ret = -EINVAL;
+			goto done;
+		}
+		/* OK, update the key */
+		wl->key_len[key_index] = ext->key_len;
+		memset(wl->key[key_index], 0, IW_ENCODING_TOKEN_MAX);
+		memcpy(wl->key[key_index], ext->key, ext->key_len);
+		set_bit(key_index, &wl->key_enabled);
+		/* remember wep info changed */
+		set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+	} else if ((alg == IW_ENCODE_ALG_TKIP) || (alg == IW_ENCODE_ALG_CCMP)) {
+		pr_debug("%s: TKIP/CCMP requested alg=%d\n", __func__, alg);
+		/* check key length */
+		if (IW_ENCODING_TOKEN_MAX < ext->key_len) {
+			pr_info("%s: key is too long %d\n", __func__,
+				ext->key_len);
+			ret = -EINVAL;
+			goto done;
+		}
+		if (alg == IW_ENCODE_ALG_CCMP) {
+			pr_debug("%s: AES selected\n", __func__);
+			wl->group_cipher_method = GELIC_WL_CIPHER_AES;
+			wl->pairwise_cipher_method = GELIC_WL_CIPHER_AES;
+			wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA2;
+		} else {
+			pr_debug("%s: TKIP selected, WPA forced\n", __func__);
+			wl->group_cipher_method = GELIC_WL_CIPHER_TKIP;
+			wl->pairwise_cipher_method = GELIC_WL_CIPHER_TKIP;
+			/* FIXME: how do we do if WPA2 + TKIP? */
+			wl->wpa_level = GELIC_WL_WPA_LEVEL_WPA;
+		}
+		if (flags & IW_ENCODE_RESTRICTED)
+			BUG();
+		wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+		/* We should use same key for both and unicast */
+		if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+			pr_debug("%s: group key \n", __func__);
+		else
+			pr_debug("%s: unicast key \n", __func__);
+		/* OK, update the key */
+		wl->key_len[key_index] = ext->key_len;
+		memset(wl->key[key_index], 0, IW_ENCODING_TOKEN_MAX);
+		memcpy(wl->key[key_index], ext->key, ext->key_len);
+		set_bit(key_index, &wl->key_enabled);
+		/* remember info changed */
+		set_bit(GELIC_WL_STAT_CONFIGURED, &wl->stat);
+	}
+done:
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	pr_debug("%s: -> \n", __func__);
+	return ret;
+}
+
+static int gelic_wl_get_encodeext(struct net_device *netdev,
+				  struct iw_request_info *info,
+				  union iwreq_data *data, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	struct iw_point *enc = &data->encoding;
+	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
+	unsigned int irqflag;
+	int key_index;
+	int ret = 0;
+	int max_key_len;
+
+	pr_debug("%s: <- \n", __func__);
+
+	max_key_len = enc->length - sizeof(struct iw_encode_ext);
+	if (max_key_len < 0)
+		return -EINVAL;
+	key_index = enc->flags & IW_ENCODE_INDEX;
+
+	pr_debug("%s: key_index = %d\n", __func__, key_index);
+	pr_debug("%s: key_len = %d\n", __func__, enc->length);
+	pr_debug("%s: flag=%x\n", __func__, enc->flags & IW_ENCODE_FLAGS);
+
+	if (GELIC_WEP_KEYS < key_index)
+		return -EINVAL;
+
+	spin_lock_irqsave(&wl->lock, irqflag);
+	if (key_index)
+		key_index--;
+	else
+		key_index = wl->current_key;
+
+	memset(ext, 0, sizeof(struct iw_encode_ext));
+	switch (wl->group_cipher_method) {
+	case GELIC_WL_CIPHER_WEP:
+		ext->alg = IW_ENCODE_ALG_WEP;
+		enc->flags |= IW_ENCODE_ENABLED;
+		break;
+	case GELIC_WL_CIPHER_TKIP:
+		ext->alg = IW_ENCODE_ALG_TKIP;
+		enc->flags |= IW_ENCODE_ENABLED;
+		break;
+	case GELIC_WL_CIPHER_AES:
+		ext->alg = IW_ENCODE_ALG_CCMP;
+		enc->flags |= IW_ENCODE_ENABLED;
+		break;
+	case GELIC_WL_CIPHER_NONE:
+	default:
+		ext->alg = IW_ENCODE_ALG_NONE;
+		enc->flags |= IW_ENCODE_NOKEY;
+		break;
+	}
+
+	if (!(enc->flags & IW_ENCODE_NOKEY)) {
+		if (max_key_len < wl->key_len[key_index]) {
+			ret = -E2BIG;
+			goto out;
+		}
+		if (test_bit(key_index, &wl->key_enabled))
+			memcpy(ext->key, wl->key[key_index],
+			       wl->key_len[key_index]);
+		else
+			pr_debug("%s: disabled key requested ix=%d\n",
+				 __func__, key_index);
+	}
+out:
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	pr_debug("%s: -> \n", __func__);
+	return ret;
+}
+/* SIOC{S,G}IWMODE */
+static int gelic_wl_set_mode(struct net_device *netdev,
+			     struct iw_request_info *info,
+			     union iwreq_data *data, char *extra)
+{
+	__u32 mode = data->mode;
+	int ret;
+
+	pr_debug("%s: <- \n", __func__);
+	if (mode == IW_MODE_INFRA)
+		ret = 0;
+	else
+		ret = -EOPNOTSUPP;
+	pr_debug("%s: -> %d\n", __func__, ret);
+	return ret;
+}
+
+static int gelic_wl_get_mode(struct net_device *netdev,
+			     struct iw_request_info *info,
+			     union iwreq_data *data, char *extra)
+{
+	__u32 *mode = &data->mode;
+	pr_debug("%s: <- \n", __func__);
+	*mode = IW_MODE_INFRA;
+	pr_debug("%s: ->\n", __func__);
+	return 0;
+}
+
+/* SIOCIWFIRSTPRIV */
+static int hex2bin(u8 *str, u8 *bin, unsigned int len)
+{
+	unsigned int i;
+	static unsigned char *hex = "0123456789ABCDEF";
+	unsigned char *p, *q;
+	u8 tmp;
+
+	if (len != WPA_PSK_LEN * 2)
+		return -EINVAL;
+
+	for (i = 0; i < WPA_PSK_LEN * 2; i += 2) {
+		p = strchr(hex, toupper(str[i]));
+		q = strchr(hex, toupper(str[i + 1]));
+		if (!p || !q) {
+			pr_info("%s: unconvertible PSK digit=%d\n",
+				__func__, i);
+			return -EINVAL;
+		}
+		tmp = ((p - hex) << 4) + (q - hex);
+		*bin++ = tmp;
+	}
+	return 0;
+};
+
+static int gelic_wl_priv_set_psk(struct net_device *net_dev,
+				 struct iw_request_info *info,
+				 union iwreq_data *data, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));
+	unsigned int len;
+	unsigned int irqflag;
+	int ret = 0;
+
+	pr_debug("%s:<- len=%d\n", __func__, data->data.length);
+	len = data->data.length - 1;
+	if (len <= 2)
+		return -EINVAL;
+
+	spin_lock_irqsave(&wl->lock, irqflag);
+	if (extra[0] == '"' && extra[len - 1] == '"') {
+		pr_debug("%s: passphrase mode\n", __func__);
+		/* pass phrase */
+		if (GELIC_WL_EURUS_PSK_MAX_LEN < (len - 2)) {
+			pr_info("%s: passphrase too long\n", __func__);
+			ret = -E2BIG;
+			goto out;
+		}
+		memset(wl->psk, 0, sizeof(wl->psk));
+		wl->psk_len = len - 2;
+		memcpy(wl->psk, &(extra[1]), wl->psk_len);
+		wl->psk_type = GELIC_EURUS_WPA_PSK_PASSPHRASE;
+	} else {
+		ret = hex2bin(extra, wl->psk, len);
+		if (ret)
+			goto out;
+		wl->psk_len = WPA_PSK_LEN;
+		wl->psk_type = GELIC_EURUS_WPA_PSK_BIN;
+	}
+	set_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat);
+out:
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	pr_debug("%s:->\n", __func__);
+	return ret;
+}
+
+static int gelic_wl_priv_get_psk(struct net_device *net_dev,
+				 struct iw_request_info *info,
+				 union iwreq_data *data, char *extra)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));
+	char *p;
+	unsigned int irqflag;
+	unsigned int i;
+
+	pr_debug("%s:<-\n", __func__);
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	spin_lock_irqsave(&wl->lock, irqflag);
+	p = extra;
+	if (test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat)) {
+		if (wl->psk_type == GELIC_EURUS_WPA_PSK_BIN) {
+			for (i = 0; i < wl->psk_len; i++) {
+				sprintf(p, "%02xu", wl->psk[i]);
+				p += 2;
+			}
+			*p = '\0';
+			data->data.length = wl->psk_len * 2;
+		} else {
+			*p++ = '"';
+			memcpy(p, wl->psk, wl->psk_len);
+			p += wl->psk_len;
+			*p++ = '"';
+			*p = '\0';
+			data->data.length = wl->psk_len + 2;
+		}
+	} else
+		/* no psk set */
+		data->data.length = 0;
+	spin_unlock_irqrestore(&wl->lock, irqflag);
+	pr_debug("%s:-> %d\n", __func__, data->data.length);
+	return 0;
+}
+
+/* SIOCGIWNICKN */
+static int gelic_wl_get_nick(struct net_device *net_dev,
+				  struct iw_request_info *info,
+				  union iwreq_data *data, char *extra)
+{
+	strcpy(extra, "gelic_wl");
+	data->data.length = strlen(extra);
+	data->data.flags = 1;
+	return 0;
+}
+
+
+/* --- */
+
+static struct iw_statistics *gelic_wl_get_wireless_stats(
+	struct net_device *netdev)
+{
+
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	struct gelic_eurus_cmd *cmd;
+	struct iw_statistics *is;
+	struct gelic_eurus_rssi_info *rssi;
+
+	pr_debug("%s: <-\n", __func__);
+
+	is = &wl->iwstat;
+	memset(is, 0, sizeof(*is));
+	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_GET_RSSI_CFG,
+				   wl->buf, sizeof(*rssi));
+	if (cmd && !cmd->status && !cmd->cmd_status) {
+		rssi = wl->buf;
+		is->qual.level = be16_to_cpu(rssi->rssi);
+		is->qual.updated = IW_QUAL_LEVEL_UPDATED |
+			IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
+	} else
+		/* not associated */
+		is->qual.updated = IW_QUAL_ALL_INVALID;
+
+	kfree(cmd);
+	pr_debug("%s: ->\n", __func__);
+	return is;
+}
+
+/*
+ *  scanning helpers
+ */
+static int gelic_wl_start_scan(struct gelic_wl_info *wl, int always_scan)
+{
+	struct gelic_eurus_cmd *cmd;
+	int ret = 0;
+
+	pr_debug("%s: <- always=%d\n", __func__, always_scan);
+	if (down_interruptible(&wl->scan_lock))
+		return -ERESTARTSYS;
+
+	/*
+	 * If already a scan in progress, do not trigger more
+	 */
+	if (wl->scan_stat == GELIC_WL_SCAN_STAT_SCANNING) {
+		pr_debug("%s: scanning now\n", __func__);
+		goto out;
+	}
+
+	init_completion(&wl->scan_done);
+	/*
+	 * If we have already a bss list, don't try to get new
+	 */
+	if (!always_scan && wl->scan_stat == GELIC_WL_SCAN_STAT_GOT_LIST) {
+		pr_debug("%s: already has the list\n", __func__);
+		complete(&wl->scan_done);
+		goto out;
+	}
+	/*
+	 * issue start scan request
+	 */
+	wl->scan_stat = GELIC_WL_SCAN_STAT_SCANNING;
+	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_START_SCAN,
+				   NULL, 0);
+	if (!cmd || cmd->status || cmd->cmd_status) {
+		wl->scan_stat = GELIC_WL_SCAN_STAT_INIT;
+		complete(&wl->scan_done);
+		ret = -ENOMEM;
+		goto out;
+	}
+	kfree(cmd);
+out:
+	up(&wl->scan_lock);
+	pr_debug("%s: ->\n", __func__);
+	return ret;
+}
+
+/*
+ * retrieve scan result from the chip (hypervisor)
+ * this function is invoked by schedule work.
+ */
+static void gelic_wl_scan_complete_event(struct gelic_wl_info *wl)
+{
+	struct gelic_eurus_cmd *cmd = NULL;
+	struct gelic_wl_scan_info *target, *tmp;
+	struct gelic_wl_scan_info *oldest = NULL;
+	struct gelic_eurus_scan_info *scan_info;
+	unsigned int scan_info_size;
+	union iwreq_data data;
+	unsigned long this_time = jiffies;
+	unsigned int data_len, i, found, r;
+	DECLARE_MAC_BUF(mac);
+
+	pr_debug("%s:start\n", __func__);
+	down(&wl->scan_lock);
+
+	if (wl->scan_stat != GELIC_WL_SCAN_STAT_SCANNING) {
+		/*
+		 * stop() may be called while scanning, ignore result
+		 */
+		pr_debug("%s: scan complete when stat != scanning(%d)\n",
+			 __func__, wl->scan_stat);
+		goto out;
+	}
+
+	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_GET_SCAN,
+				   wl->buf, PAGE_SIZE);
+	if (!cmd || cmd->status || cmd->cmd_status) {
+		wl->scan_stat = GELIC_WL_SCAN_STAT_INIT;
+		pr_info("%s:cmd failed\n", __func__);
+		kfree(cmd);
+		goto out;
+	}
+	data_len = cmd->size;
+	pr_debug("%s: data_len = %d\n", __func__, data_len);
+	kfree(cmd);
+
+	/* OK, bss list retrieved */
+	wl->scan_stat = GELIC_WL_SCAN_STAT_GOT_LIST;
+
+	/* mark all entries are old */
+	list_for_each_entry_safe(target, tmp, &wl->network_list, list) {
+		target->valid = 0;
+		/* expire too old entries */
+		if (time_before(target->last_scanned + wl->scan_age,
+				this_time)) {
+			kfree(target->hwinfo);
+			target->hwinfo = NULL;
+			list_move_tail(&target->list, &wl->network_free_list);
+		}
+	}
+
+	/* put them in the newtork_list */
+	scan_info = wl->buf;
+	scan_info_size = 0;
+	i = 0;
+	while (scan_info_size < data_len) {
+		pr_debug("%s:size=%d bssid=%s scan_info=%p\n", __func__,
+			 be16_to_cpu(scan_info->size),
+			 print_mac(mac, &scan_info->bssid[2]), scan_info);
+		found = 0;
+		oldest = NULL;
+		list_for_each_entry(target, &wl->network_list, list) {
+			if (!compare_ether_addr(&target->hwinfo->bssid[2],
+						&scan_info->bssid[2])) {
+				found = 1;
+				pr_debug("%s: same BBS found scanned list\n",
+					 __func__);
+				break;
+			}
+			if (!oldest ||
+			    (target->last_scanned < oldest->last_scanned))
+				oldest = target;
+		}
+
+		if (!found) {
+			/* not found in the list */
+			if (list_empty(&wl->network_free_list)) {
+				/* expire oldest */
+				target = oldest;
+			} else {
+				target = list_entry(wl->network_free_list.next,
+						    struct gelic_wl_scan_info,
+						    list);
+			}
+		}
+
+		/* update the item */
+		target->last_scanned = this_time;
+		target->valid = 1;
+		target->eurus_index = i;
+		kfree(target->hwinfo);
+		target->hwinfo = kzalloc(be16_to_cpu(scan_info->size),
+					 GFP_KERNEL);
+		if (!target->hwinfo) {
+			pr_info("%s: kzalloc failed\n", __func__);
+			i++;
+			scan_info_size += be16_to_cpu(scan_info->size);
+			scan_info = (void *)scan_info +
+				be16_to_cpu(scan_info->size);
+			continue;
+		}
+		/* copy hw scan info */
+		memcpy(target->hwinfo, scan_info, scan_info->size);
+		target->essid_len = strnlen(scan_info->essid,
+					    sizeof(scan_info->essid));
+		target->rate_len = 0;
+		for (r = 0; r < MAX_RATES_LENGTH; r++)
+			if (scan_info->rate[r])
+				target->rate_len++;
+		if (8 < target->rate_len)
+			pr_info("%s: AP returns %d rates\n", __func__,
+				target->rate_len);
+		target->rate_ext_len = 0;
+		for (r = 0; r < MAX_RATES_EX_LENGTH; r++)
+			if (scan_info->ext_rate[r])
+				target->rate_ext_len++;
+		list_move_tail(&target->list, &wl->network_list);
+		/* bump pointer */
+		i++;
+		scan_info_size += be16_to_cpu(scan_info->size);
+		scan_info = (void *)scan_info + be16_to_cpu(scan_info->size);
+	}
+	memset(&data, 0, sizeof(data));
+	wireless_send_event(port_to_netdev(wl_port(wl)), SIOCGIWSCAN, &data,
+			    NULL);
+out:
+	complete(&wl->scan_done);
+	up(&wl->scan_lock);
+	pr_debug("%s:end\n", __func__);
+}
+
+/*
+ * Select an appropriate bss from current scan list regarding
+ * current settings from userspace.
+ * The caller must hold wl->scan_lock,
+ * and on the state of wl->scan_state == GELIC_WL_SCAN_GOT_LIST
+ */
+static void update_best(struct gelic_wl_scan_info **best,
+			struct gelic_wl_scan_info *candid,
+			int *best_weight,
+			int *weight)
+{
+	if (*best_weight < ++(*weight)) {
+		*best_weight = *weight;
+		*best = candid;
+	}
+}
+
+static
+struct gelic_wl_scan_info *gelic_wl_find_best_bss(struct gelic_wl_info *wl)
+{
+	struct gelic_wl_scan_info *scan_info;
+	struct gelic_wl_scan_info *best_bss;
+	int weight, best_weight;
+	u16 security;
+	DECLARE_MAC_BUF(mac);
+
+	pr_debug("%s: <-\n", __func__);
+
+	best_bss = NULL;
+	best_weight = 0;
+
+	list_for_each_entry(scan_info, &wl->network_list, list) {
+		pr_debug("%s: station %p\n", __func__, scan_info);
+
+		if (!scan_info->valid) {
+			pr_debug("%s: station invalid\n", __func__);
+			continue;
+		}
+
+		/* If bss specified, check it only */
+		if (test_bit(GELIC_WL_STAT_BSSID_SET, &wl->stat)) {
+			if (!compare_ether_addr(&scan_info->hwinfo->bssid[2],
+						wl->bssid)) {
+				best_bss = scan_info;
+				pr_debug("%s: bssid matched\n", __func__);
+				break;
+			} else {
+				pr_debug("%s: bssid unmached\n", __func__);
+				continue;
+			}
+		}
+
+		weight = 0;
+
+		/* security */
+		security = be16_to_cpu(scan_info->hwinfo->security) &
+			GELIC_EURUS_SCAN_SEC_MASK;
+		if (wl->wpa_level == GELIC_WL_WPA_LEVEL_WPA2) {
+			if (security == GELIC_EURUS_SCAN_SEC_WPA2)
+				update_best(&best_bss, scan_info,
+					    &best_weight, &weight);
+			else
+				continue;
+		} else if (wl->wpa_level == GELIC_WL_WPA_LEVEL_WPA) {
+			if (security == GELIC_EURUS_SCAN_SEC_WPA)
+				update_best(&best_bss, scan_info,
+					    &best_weight, &weight);
+			else
+				continue;
+		} else if (wl->wpa_level == GELIC_WL_WPA_LEVEL_NONE &&
+			   wl->group_cipher_method == GELIC_WL_CIPHER_WEP) {
+			if (security == GELIC_EURUS_SCAN_SEC_WEP)
+				update_best(&best_bss, scan_info,
+					    &best_weight, &weight);
+			else
+				continue;
+		}
+
+		/* If ESSID is set, check it */
+		if (test_bit(GELIC_WL_STAT_ESSID_SET, &wl->stat)) {
+			if ((scan_info->essid_len == wl->essid_len) &&
+			    !strncmp(wl->essid,
+				     scan_info->hwinfo->essid,
+				     scan_info->essid_len))
+				update_best(&best_bss, scan_info,
+					    &best_weight, &weight);
+			else
+				continue;
+		}
+	}
+
+#ifdef DEBUG
+	pr_debug("%s: -> bss=%p\n", __func__, best_bss);
+	if (best_bss) {
+		pr_debug("%s:addr=%s\n", __func__,
+			 print_mac(mac, &best_bss->hwinfo->bssid[2]));
+	}
+#endif
+	return best_bss;
+}
+
+/*
+ * Setup WEP configuration to the chip
+ * The caller must hold wl->scan_lock,
+ * and on the state of wl->scan_state == GELIC_WL_SCAN_GOT_LIST
+ */
+static int gelic_wl_do_wep_setup(struct gelic_wl_info *wl)
+{
+	unsigned int i;
+	struct gelic_eurus_wep_cfg *wep;
+	struct gelic_eurus_cmd *cmd;
+	int wep104 = 0;
+	int have_key = 0;
+	int ret = 0;
+
+	pr_debug("%s: <-\n", __func__);
+	/* we can assume no one should uses the buffer */
+	wep = wl->buf;
+	memset(wep, 0, sizeof(*wep));
+
+	if (wl->group_cipher_method == GELIC_WL_CIPHER_WEP) {
+		pr_debug("%s: WEP mode\n", __func__);
+		for (i = 0; i < GELIC_WEP_KEYS; i++) {
+			if (!test_bit(i, &wl->key_enabled))
+				continue;
+
+			pr_debug("%s: key#%d enabled\n", __func__, i);
+			have_key = 1;
+			if (wl->key_len[i] == 13)
+				wep104 = 1;
+			else if (wl->key_len[i] != 5) {
+				pr_info("%s: wrong wep key[%d]=%d\n",
+					__func__, i, wl->key_len[i]);
+				ret = -EINVAL;
+				goto out;
+			}
+			memcpy(wep->key[i], wl->key[i], wl->key_len[i]);
+		}
+
+		if (!have_key) {
+			pr_info("%s: all wep key disabled\n", __func__);
+			ret = -EINVAL;
+			goto out;
+		}
+
+		if (wep104) {
+			pr_debug("%s: 104bit key\n", __func__);
+			wep->security = cpu_to_be16(GELIC_EURUS_WEP_SEC_104BIT);
+		} else {
+			pr_debug("%s: 40bit key\n", __func__);
+			wep->security = cpu_to_be16(GELIC_EURUS_WEP_SEC_40BIT);
+		}
+	} else {
+		pr_debug("%s: NO encryption\n", __func__);
+		wep->security = cpu_to_be16(GELIC_EURUS_WEP_SEC_NONE);
+	}
+
+	/* issue wep setup */
+	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_SET_WEP_CFG,
+				   wep, sizeof(*wep));
+	if (!cmd)
+		ret = -ENOMEM;
+	else if (cmd->status || cmd->cmd_status)
+		ret = -ENXIO;
+
+	kfree(cmd);
+out:
+	pr_debug("%s: ->\n", __func__);
+	return ret;
+}
+
+#ifdef DEBUG
+static const char *wpasecstr(enum gelic_eurus_wpa_security sec)
+{
+	switch (sec) {
+	case GELIC_EURUS_WPA_SEC_NONE:
+		return "NONE";
+		break;
+	case GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP:
+		return "WPA_TKIP_TKIP";
+		break;
+	case GELIC_EURUS_WPA_SEC_WPA_TKIP_AES:
+		return "WPA_TKIP_AES";
+		break;
+	case GELIC_EURUS_WPA_SEC_WPA_AES_AES:
+		return "WPA_AES_AES";
+		break;
+	case GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP:
+		return "WPA2_TKIP_TKIP";
+		break;
+	case GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES:
+		return "WPA2_TKIP_AES";
+		break;
+	case GELIC_EURUS_WPA_SEC_WPA2_AES_AES:
+		return "WPA2_AES_AES";
+		break;
+	}
+	return "";
+};
+#endif
+
+static int gelic_wl_do_wpa_setup(struct gelic_wl_info *wl)
+{
+	struct gelic_eurus_wpa_cfg *wpa;
+	struct gelic_eurus_cmd *cmd;
+	u16 security;
+	int ret = 0;
+
+	pr_debug("%s: <-\n", __func__);
+	/* we can assume no one should uses the buffer */
+	wpa = wl->buf;
+	memset(wpa, 0, sizeof(*wpa));
+
+	if (!test_bit(GELIC_WL_STAT_WPA_PSK_SET, &wl->stat))
+		pr_info("%s: PSK not configured yet\n", __func__);
+
+	/* copy key */
+	memcpy(wpa->psk, wl->psk, wl->psk_len);
+
+	/* set security level */
+	if (wl->wpa_level == GELIC_WL_WPA_LEVEL_WPA2) {
+		if (wl->group_cipher_method == GELIC_WL_CIPHER_AES) {
+			security = GELIC_EURUS_WPA_SEC_WPA2_AES_AES;
+		} else {
+			if (wl->pairwise_cipher_method == GELIC_WL_CIPHER_AES &&
+			    precise_ie())
+				security = GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES;
+			else
+				security = GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP;
+		}
+	} else {
+		if (wl->group_cipher_method == GELIC_WL_CIPHER_AES) {
+			security = GELIC_EURUS_WPA_SEC_WPA_AES_AES;
+		} else {
+			if (wl->pairwise_cipher_method == GELIC_WL_CIPHER_AES &&
+			    precise_ie())
+				security = GELIC_EURUS_WPA_SEC_WPA_TKIP_AES;
+			else
+				security = GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP;
+		}
+	}
+	wpa->security = cpu_to_be16(security);
+
+	/* PSK type */
+	wpa->psk_type = cpu_to_be16(wl->psk_type);
+#ifdef DEBUG
+	pr_debug("%s: sec=%s psktype=%s\nn", __func__,
+		 wpasecstr(wpa->security),
+		 (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ?
+		 "BIN" : "passphrase");
+#if 0
+	/*
+	 * don't enable here if you plan to submit
+	 * the debug log because this dumps your precious
+	 * passphrase/key.
+	 */
+	pr_debug("%s: psk=%s\n",
+		 (wpa->psk_type == GELIC_EURUS_WPA_PSK_BIN) ?
+		 (char *)"N/A" : (char *)wpa->psk);
+#endif
+#endif
+	/* issue wpa setup */
+	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_SET_WPA_CFG,
+				   wpa, sizeof(*wpa));
+	if (!cmd)
+		ret = -ENOMEM;
+	else if (cmd->status || cmd->cmd_status)
+		ret = -ENXIO;
+	kfree(cmd);
+	pr_debug("%s: --> %d\n", __func__, ret);
+	return ret;
+}
+
+/*
+ * Start association. caller must hold assoc_stat_lock
+ */
+static int gelic_wl_associate_bss(struct gelic_wl_info *wl,
+				  struct gelic_wl_scan_info *bss)
+{
+	struct gelic_eurus_cmd *cmd;
+	struct gelic_eurus_common_cfg *common;
+	int ret = 0;
+	unsigned long rc;
+
+	pr_debug("%s: <-\n", __func__);
+
+	/* do common config */
+	common = wl->buf;
+	memset(common, 0, sizeof(*common));
+	common->bss_type = cpu_to_be16(GELIC_EURUS_BSS_INFRA);
+	common->op_mode = cpu_to_be16(GELIC_EURUS_OPMODE_11BG);
+
+	common->scan_index = cpu_to_be16(bss->eurus_index);
+	switch (wl->auth_method) {
+	case GELIC_EURUS_AUTH_OPEN:
+		common->auth_method = cpu_to_be16(GELIC_EURUS_AUTH_OPEN);
+		break;
+	case GELIC_EURUS_AUTH_SHARED:
+		common->auth_method = cpu_to_be16(GELIC_EURUS_AUTH_SHARED);
+		break;
+	}
+
+#ifdef DEBUG
+	scan_list_dump(wl);
+#endif
+	pr_debug("%s: common cfg index=%d bsstype=%d auth=%d\n", __func__,
+		 be16_to_cpu(common->scan_index),
+		 be16_to_cpu(common->bss_type),
+		 be16_to_cpu(common->auth_method));
+
+	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_SET_COMMON_CFG,
+				   common, sizeof(*common));
+	if (!cmd || cmd->status || cmd->cmd_status) {
+		ret = -ENOMEM;
+		kfree(cmd);
+		goto out;
+	}
+	kfree(cmd);
+
+	/* WEP/WPA */
+	switch (wl->wpa_level) {
+	case GELIC_WL_WPA_LEVEL_NONE:
+		/* If WEP or no security, setup WEP config */
+		ret = gelic_wl_do_wep_setup(wl);
+		break;
+	case GELIC_WL_WPA_LEVEL_WPA:
+	case GELIC_WL_WPA_LEVEL_WPA2:
+		ret = gelic_wl_do_wpa_setup(wl);
+		break;
+	};
+
+	if (ret) {
+		pr_debug("%s: WEP/WPA setup failed %d\n", __func__,
+			 ret);
+	}
+
+	/* start association */
+	init_completion(&wl->assoc_done);
+	wl->assoc_stat = GELIC_WL_ASSOC_STAT_ASSOCIATING;
+	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_ASSOC,
+				   NULL, 0);
+	if (!cmd || cmd->status || cmd->cmd_status) {
+		pr_debug("%s: assoc request failed\n", __func__);
+		wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN;
+		kfree(cmd);
+		ret = -ENOMEM;
+		gelic_wl_send_iwap_event(wl, NULL);
+		goto out;
+	}
+	kfree(cmd);
+
+	/* wait for connected event */
+	rc = wait_for_completion_timeout(&wl->assoc_done, HZ * 4);/*FIXME*/
+
+	if (!rc) {
+		/* timeouted.  Maybe key or cyrpt mode is wrong */
+		pr_info("%s: connect timeout \n", __func__);
+		cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_DISASSOC,
+					   NULL, 0);
+		kfree(cmd);
+		wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN;
+		gelic_wl_send_iwap_event(wl, NULL);
+		ret = -ENXIO;
+	} else {
+		wl->assoc_stat = GELIC_WL_ASSOC_STAT_ASSOCIATED;
+		/* copy bssid */
+		memcpy(wl->active_bssid, &bss->hwinfo->bssid[2], ETH_ALEN);
+
+		/* send connect event */
+		gelic_wl_send_iwap_event(wl, wl->active_bssid);
+		pr_info("%s: connected\n", __func__);
+	}
+out:
+	pr_debug("%s: ->\n", __func__);
+	return ret;
+}
+
+/*
+ * connected event
+ */
+static void gelic_wl_connected_event(struct gelic_wl_info *wl,
+				     u64 event)
+{
+	u64 desired_event = 0;
+
+	switch (wl->wpa_level) {
+	case GELIC_WL_WPA_LEVEL_NONE:
+		desired_event = GELIC_LV1_WL_EVENT_CONNECTED;
+		break;
+	case GELIC_WL_WPA_LEVEL_WPA:
+	case GELIC_WL_WPA_LEVEL_WPA2:
+		desired_event = GELIC_LV1_WL_EVENT_WPA_CONNECTED;
+		break;
+	}
+
+	if (desired_event == event) {
+		pr_debug("%s: completed \n", __func__);
+		complete(&wl->assoc_done);
+		netif_carrier_on(port_to_netdev(wl_port(wl)));
+	} else
+		pr_debug("%s: event %#lx under wpa\n",
+				 __func__, event);
+}
+
+/*
+ * disconnect event
+ */
+static void gelic_wl_disconnect_event(struct gelic_wl_info *wl,
+				      u64 event)
+{
+	struct gelic_eurus_cmd *cmd;
+	int lock;
+
+	/*
+	 * If we fall here in the middle of association,
+	 * associate_bss() should be waiting for complation of
+	 * wl->assoc_done.
+	 * As it waits with timeout, just leave assoc_done
+	 * uncompleted, then it terminates with timeout
+	 */
+	if (down_trylock(&wl->assoc_stat_lock)) {
+		pr_debug("%s: already locked\n", __func__);
+		lock = 0;
+	} else {
+		pr_debug("%s: obtain lock\n", __func__);
+		lock = 1;
+	}
+
+	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_DISASSOC, NULL, 0);
+	kfree(cmd);
+
+	/* send disconnected event to the supplicant */
+	if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED)
+		gelic_wl_send_iwap_event(wl, NULL);
+
+	wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN;
+	netif_carrier_off(port_to_netdev(wl_port(wl)));
+
+	if (lock)
+		up(&wl->assoc_stat_lock);
+}
+/*
+ * event worker
+ */
+#ifdef DEBUG
+static const char *eventstr(enum gelic_lv1_wl_event event)
+{
+	static char buf[32];
+	char *ret;
+	if (event & GELIC_LV1_WL_EVENT_DEVICE_READY)
+		ret = "EURUS_READY";
+	else if (event & GELIC_LV1_WL_EVENT_SCAN_COMPLETED)
+		ret = "SCAN_COMPLETED";
+	else if (event & GELIC_LV1_WL_EVENT_DEAUTH)
+		ret = "DEAUTH";
+	else if (event & GELIC_LV1_WL_EVENT_BEACON_LOST)
+		ret = "BEACON_LOST";
+	else if (event & GELIC_LV1_WL_EVENT_CONNECTED)
+		ret = "CONNECTED";
+	else if (event & GELIC_LV1_WL_EVENT_WPA_CONNECTED)
+		ret = "WPA_CONNECTED";
+	else if (event & GELIC_LV1_WL_EVENT_WPA_ERROR)
+		ret = "WPA_ERROR";
+	else {
+		sprintf(buf, "Unknown(%#x)", event);
+		ret = buf;
+	}
+	return ret;
+}
+#else
+static const char *eventstr(enum gelic_lv1_wl_event event)
+{
+	return NULL;
+}
+#endif
+static void gelic_wl_event_worker(struct work_struct *work)
+{
+	struct gelic_wl_info *wl;
+	struct gelic_port *port;
+	u64 event, tmp;
+	int status;
+
+	pr_debug("%s:start\n", __func__);
+	wl = container_of(work, struct gelic_wl_info, event_work.work);
+	port = wl_port(wl);
+	while (1) {
+		status = lv1_net_control(bus_id(port->card), dev_id(port->card),
+					 GELIC_LV1_GET_WLAN_EVENT, 0, 0, 0,
+					 &event, &tmp);
+		if (status) {
+			if (status != LV1_NO_ENTRY)
+				pr_debug("%s:wlan event failed %d\n",
+					 __func__, status);
+			/* got all events */
+			pr_debug("%s:end\n", __func__);
+			return;
+		}
+		pr_debug("%s: event=%s\n", __func__, eventstr(event));
+		switch (event) {
+		case GELIC_LV1_WL_EVENT_SCAN_COMPLETED:
+			gelic_wl_scan_complete_event(wl);
+			break;
+		case GELIC_LV1_WL_EVENT_BEACON_LOST:
+		case GELIC_LV1_WL_EVENT_DEAUTH:
+			gelic_wl_disconnect_event(wl, event);
+			break;
+		case GELIC_LV1_WL_EVENT_CONNECTED:
+		case GELIC_LV1_WL_EVENT_WPA_CONNECTED:
+			gelic_wl_connected_event(wl, event);
+			break;
+		default:
+			break;
+		}
+	} /* while */
+}
+/*
+ * association worker
+ */
+static void gelic_wl_assoc_worker(struct work_struct *work)
+{
+	struct gelic_wl_info *wl;
+
+	struct gelic_wl_scan_info *best_bss;
+	int ret;
+
+	wl = container_of(work, struct gelic_wl_info, assoc_work.work);
+
+	down(&wl->assoc_stat_lock);
+
+	if (wl->assoc_stat != GELIC_WL_ASSOC_STAT_DISCONN)
+		goto out;
+
+	ret = gelic_wl_start_scan(wl, 0);
+	if (ret == -ERESTARTSYS) {
+		pr_debug("%s: scan start failed association\n", __func__);
+		schedule_delayed_work(&wl->assoc_work, HZ/10); /*FIXME*/
+		goto out;
+	} else if (ret) {
+		pr_info("%s: scan prerequisite failed\n", __func__);
+		goto out;
+	}
+
+	/*
+	 * Wait for bss scan completion
+	 * If we have scan list already, gelic_wl_start_scan()
+	 * returns OK and raises the complete.  Thus,
+	 * it's ok to wait unconditionally here
+	 */
+	wait_for_completion(&wl->scan_done);
+
+	pr_debug("%s: scan done\n", __func__);
+	down(&wl->scan_lock);
+	if (wl->scan_stat != GELIC_WL_SCAN_STAT_GOT_LIST) {
+		gelic_wl_send_iwap_event(wl, NULL);
+		pr_info("%s: no scan list. association failed\n", __func__);
+		goto scan_lock_out;
+	}
+
+	/* find best matching bss */
+	best_bss = gelic_wl_find_best_bss(wl);
+	if (!best_bss) {
+		gelic_wl_send_iwap_event(wl, NULL);
+		pr_info("%s: no bss matched. association failed\n", __func__);
+		goto scan_lock_out;
+	}
+
+	/* ok, do association */
+	ret = gelic_wl_associate_bss(wl, best_bss);
+	if (ret)
+		pr_info("%s: association failed %d\n", __func__, ret);
+scan_lock_out:
+	up(&wl->scan_lock);
+out:
+	up(&wl->assoc_stat_lock);
+}
+/*
+ * Interrupt handler
+ * Called from the ethernet interrupt handler
+ * Processes wireless specific virtual interrupts only
+ */
+void gelic_wl_interrupt(struct net_device *netdev, u64 status)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+
+	if (status & GELIC_CARD_WLAN_COMMAND_COMPLETED) {
+		pr_debug("%s:cmd complete\n", __func__);
+		complete(&wl->cmd_done_intr);
+	}
+
+	if (status & GELIC_CARD_WLAN_EVENT_RECEIVED) {
+		pr_debug("%s:event received\n", __func__);
+		queue_delayed_work(wl->event_queue, &wl->event_work, 0);
+	}
+}
+
+/*
+ * driver helpers
+ */
+#define IW_IOCTL(n) [(n) - SIOCSIWCOMMIT]
+static const iw_handler gelic_wl_wext_handler[] =
+{
+	IW_IOCTL(SIOCGIWNAME)		= gelic_wl_get_name,
+	IW_IOCTL(SIOCGIWRANGE)		= gelic_wl_get_range,
+	IW_IOCTL(SIOCSIWSCAN)		= gelic_wl_set_scan,
+	IW_IOCTL(SIOCGIWSCAN)		= gelic_wl_get_scan,
+	IW_IOCTL(SIOCSIWAUTH)		= gelic_wl_set_auth,
+	IW_IOCTL(SIOCGIWAUTH)		= gelic_wl_get_auth,
+	IW_IOCTL(SIOCSIWESSID)		= gelic_wl_set_essid,
+	IW_IOCTL(SIOCGIWESSID)		= gelic_wl_get_essid,
+	IW_IOCTL(SIOCSIWENCODE)		= gelic_wl_set_encode,
+	IW_IOCTL(SIOCGIWENCODE)		= gelic_wl_get_encode,
+	IW_IOCTL(SIOCSIWAP)		= gelic_wl_set_ap,
+	IW_IOCTL(SIOCGIWAP)		= gelic_wl_get_ap,
+	IW_IOCTL(SIOCSIWENCODEEXT)	= gelic_wl_set_encodeext,
+	IW_IOCTL(SIOCGIWENCODEEXT)	= gelic_wl_get_encodeext,
+	IW_IOCTL(SIOCSIWMODE)		= gelic_wl_set_mode,
+	IW_IOCTL(SIOCGIWMODE)		= gelic_wl_get_mode,
+	IW_IOCTL(SIOCGIWNICKN)		= gelic_wl_get_nick,
+};
+
+static struct iw_priv_args gelic_wl_private_args[] =
+{
+	{
+		.cmd = GELIC_WL_PRIV_SET_PSK,
+		.set_args = IW_PRIV_TYPE_CHAR |
+		(GELIC_WL_EURUS_PSK_MAX_LEN + 2),
+		.name = "set_psk"
+	},
+	{
+		.cmd = GELIC_WL_PRIV_GET_PSK,
+		.get_args = IW_PRIV_TYPE_CHAR |
+		(GELIC_WL_EURUS_PSK_MAX_LEN + 2),
+		.name = "get_psk"
+	}
+};
+
+static const iw_handler gelic_wl_private_handler[] =
+{
+	gelic_wl_priv_set_psk,
+	gelic_wl_priv_get_psk,
+};
+
+static const struct iw_handler_def gelic_wl_wext_handler_def = {
+	.num_standard		= ARRAY_SIZE(gelic_wl_wext_handler),
+	.standard		= gelic_wl_wext_handler,
+	.get_wireless_stats	= gelic_wl_get_wireless_stats,
+	.num_private		= ARRAY_SIZE(gelic_wl_private_handler),
+	.num_private_args	= ARRAY_SIZE(gelic_wl_private_args),
+	.private		= gelic_wl_private_handler,
+	.private_args		= gelic_wl_private_args,
+};
+
+static struct net_device *gelic_wl_alloc(struct gelic_card *card)
+{
+	struct net_device *netdev;
+	struct gelic_port *port;
+	struct gelic_wl_info *wl;
+	unsigned int i;
+
+	pr_debug("%s:start\n", __func__);
+	netdev = alloc_etherdev(sizeof(struct gelic_port) +
+				sizeof(struct gelic_wl_info));
+	pr_debug("%s: netdev =%p card=%p \np", __func__, netdev, card);
+	if (!netdev)
+		return NULL;
+
+	port = netdev_priv(netdev);
+	port->netdev = netdev;
+	port->card = card;
+	port->type = GELIC_PORT_WIRELESS;
+
+	wl = port_wl(port);
+	pr_debug("%s: wl=%p port=%p\n", __func__, wl, port);
+
+	/* allocate scan list */
+	wl->networks = kzalloc(sizeof(struct gelic_wl_scan_info) *
+			       GELIC_WL_BSS_MAX_ENT, GFP_KERNEL);
+
+	if (!wl->networks)
+		goto fail_bss;
+
+	wl->eurus_cmd_queue = create_singlethread_workqueue("gelic_cmd");
+	if (!wl->eurus_cmd_queue)
+		goto fail_cmd_workqueue;
+
+	wl->event_queue = create_singlethread_workqueue("gelic_event");
+	if (!wl->event_queue)
+		goto fail_event_workqueue;
+
+	INIT_LIST_HEAD(&wl->network_free_list);
+	INIT_LIST_HEAD(&wl->network_list);
+	for (i = 0; i < GELIC_WL_BSS_MAX_ENT; i++)
+		list_add_tail(&wl->networks[i].list,
+			      &wl->network_free_list);
+	init_completion(&wl->cmd_done_intr);
+
+	INIT_DELAYED_WORK(&wl->event_work, gelic_wl_event_worker);
+	INIT_DELAYED_WORK(&wl->assoc_work, gelic_wl_assoc_worker);
+	init_MUTEX(&wl->scan_lock);
+	init_MUTEX(&wl->assoc_stat_lock);
+
+	init_completion(&wl->scan_done);
+	/* for the case that no scan request is issued and stop() is called */
+	complete(&wl->scan_done);
+
+	spin_lock_init(&wl->lock);
+
+	wl->scan_age = 5*HZ; /* FIXME */
+
+	/* buffer for receiving scanned list etc */
+	BUILD_BUG_ON(PAGE_SIZE <
+		     sizeof(struct gelic_eurus_scan_info) *
+		     GELIC_EURUS_MAX_SCAN);
+	wl->buf = (void *)get_zeroed_page(GFP_KERNEL);
+	if (!wl->buf) {
+		pr_info("%s:buffer allocation failed\n", __func__);
+		goto fail_getpage;
+	}
+	pr_debug("%s:end\n", __func__);
+	return netdev;
+
+fail_getpage:
+	destroy_workqueue(wl->event_queue);
+fail_event_workqueue:
+	destroy_workqueue(wl->eurus_cmd_queue);
+fail_cmd_workqueue:
+	kfree(wl->networks);
+fail_bss:
+	free_netdev(netdev);
+	pr_debug("%s:end error\n", __func__);
+	return NULL;
+
+}
+
+static void gelic_wl_free(struct gelic_wl_info *wl)
+{
+	struct gelic_wl_scan_info *scan_info;
+	unsigned int i;
+
+	pr_debug("%s: <-\n", __func__);
+
+	pr_debug("%s: destroy queues\n", __func__);
+	destroy_workqueue(wl->eurus_cmd_queue);
+	destroy_workqueue(wl->event_queue);
+
+	scan_info = wl->networks;
+	for (i = 0; i < GELIC_WL_BSS_MAX_ENT; i++, scan_info++)
+		kfree(scan_info->hwinfo);
+	kfree(wl->networks);
+
+	free_netdev(port_to_netdev(wl_port(wl)));
+
+	pr_debug("%s: ->\n", __func__);
+}
+
+static int gelic_wl_try_associate(struct net_device *netdev)
+{
+	struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));
+	int ret = -1;
+	unsigned int i;
+
+	pr_debug("%s: <-\n", __func__);
+
+	/* check constraits for start association */
+	/* for no access restriction AP */
+	if (wl->group_cipher_method == GELIC_WL_CIPHER_NONE) {
+		if (test_bit(GELIC_WL_STAT_CONFIGURED,
+			     &wl->stat))
+			goto do_associate;
+		else {
+			pr_debug("%s: no wep, not configured\n", __func__);
+			return ret;
+		}
+	}
+
+	/* for WEP, one of four keys should be set */
+	if (wl->group_cipher_method == GELIC_WL_CIPHER_WEP) {
+		/* one of keys set */
+		for (i = 0; i < GELIC_WEP_KEYS; i++) {
+			if (test_bit(i, &wl->key_enabled))
+			    goto do_associate;
+		}
+		pr_debug("%s: WEP, but no key specified\n", __func__);
+		return ret;
+	}
+
+	/* for WPA[2], psk should be set */
+	if ((wl->group_cipher_method == GELIC_WL_CIPHER_TKIP) ||
+	    (wl->group_cipher_method == GELIC_WL_CIPHER_AES)) {
+		if (test_bit(GELIC_WL_STAT_WPA_PSK_SET,
+			     &wl->stat))
+			goto do_associate;
+		else {
+			pr_debug("%s: AES/TKIP, but PSK not configured\n",
+				 __func__);
+			return ret;
+		}
+	}
+
+do_associate:
+	ret = schedule_delayed_work(&wl->assoc_work, 0);
+	pr_debug("%s: start association work %d\n", __func__, ret);
+	return ret;
+}
+
+/*
+ * netdev handlers
+ */
+static int gelic_wl_open(struct net_device *netdev)
+{
+	struct gelic_card *card = netdev_card(netdev);
+
+	pr_debug("%s:->%p\n", __func__, netdev);
+
+	gelic_card_up(card);
+
+	/* try to associate */
+	gelic_wl_try_associate(netdev);
+
+	netif_start_queue(netdev);
+
+	pr_debug("%s:<-\n", __func__);
+	return 0;
+}
+
+/*
+ * reset state machine
+ */
+static int gelic_wl_reset_state(struct gelic_wl_info *wl)
+{
+	struct gelic_wl_scan_info *target;
+	struct gelic_wl_scan_info *tmp;
+
+	/* empty scan list */
+	list_for_each_entry_safe(target, tmp, &wl->network_list, list) {
+		list_move_tail(&target->list, &wl->network_free_list);
+	}
+	wl->scan_stat = GELIC_WL_SCAN_STAT_INIT;
+
+	/* clear configuration */
+	wl->auth_method = GELIC_EURUS_AUTH_OPEN;
+	wl->group_cipher_method = GELIC_WL_CIPHER_NONE;
+	wl->pairwise_cipher_method = GELIC_WL_CIPHER_NONE;
+	wl->wpa_level = GELIC_WL_WPA_LEVEL_NONE;
+
+	wl->key_enabled = 0;
+	wl->current_key = 0;
+
+	wl->psk_type = GELIC_EURUS_WPA_PSK_PASSPHRASE;
+	wl->psk_len = 0;
+
+	wl->essid_len = 0;
+	memset(wl->essid, 0, sizeof(wl->essid));
+	memset(wl->bssid, 0, sizeof(wl->bssid));
+	memset(wl->active_bssid, 0, sizeof(wl->active_bssid));
+
+	wl->assoc_stat = GELIC_WL_ASSOC_STAT_DISCONN;
+
+	memset(&wl->iwstat, 0, sizeof(wl->iwstat));
+	/* all status bit clear */
+	wl->stat = 0;
+	return 0;
+}
+
+/*
+ * Tell eurus to terminate association
+ */
+static void gelic_wl_disconnect(struct net_device *netdev)
+{
+	struct gelic_port *port = netdev_priv(netdev);
+	struct gelic_wl_info *wl = port_wl(port);
+	struct gelic_eurus_cmd *cmd;
+
+	/*
+	 * If scann process is running on chip,
+	 * further requests will be rejected
+	 */
+	if (wl->scan_stat == GELIC_WL_SCAN_STAT_SCANNING)
+		wait_for_completion_timeout(&wl->scan_done, HZ);
+
+	cmd = gelic_eurus_sync_cmd(wl, GELIC_EURUS_CMD_DISASSOC, NULL, 0);
+	kfree(cmd);
+	gelic_wl_send_iwap_event(wl, NULL);
+};
+
+static int gelic_wl_stop(struct net_device *netdev)
+{
+	struct gelic_port *port = netdev_priv(netdev);
+	struct gelic_wl_info *wl = port_wl(port);
+	struct gelic_card *card = netdev_card(netdev);
+
+	pr_debug("%s:<-\n", __func__);
+
+	/*
+	 * Cancel pending association work.
+	 * event work can run after netdev down
+	 */
+	cancel_delayed_work(&wl->assoc_work);
+
+	if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED)
+		gelic_wl_disconnect(netdev);
+
+	/* reset our state machine */
+	gelic_wl_reset_state(wl);
+
+	netif_stop_queue(netdev);
+
+	gelic_card_down(card);
+
+	pr_debug("%s:->\n", __func__);
+	return 0;
+}
+
+/* -- */
+
+static struct ethtool_ops gelic_wl_ethtool_ops = {
+	.get_drvinfo	= gelic_net_get_drvinfo,
+	.get_link	= gelic_wl_get_link,
+	.get_tx_csum	= ethtool_op_get_tx_csum,
+	.set_tx_csum	= ethtool_op_set_tx_csum,
+	.get_rx_csum	= gelic_net_get_rx_csum,
+	.set_rx_csum	= gelic_net_set_rx_csum,
+};
+
+static void gelic_wl_setup_netdev_ops(struct net_device *netdev)
+{
+	struct gelic_wl_info *wl;
+	wl = port_wl(netdev_priv(netdev));
+	BUG_ON(!wl);
+	netdev->open = &gelic_wl_open;
+	netdev->stop = &gelic_wl_stop;
+	netdev->hard_start_xmit = &gelic_net_xmit;
+	netdev->set_multicast_list = &gelic_net_set_multi;
+	netdev->change_mtu = &gelic_net_change_mtu;
+	netdev->wireless_data = &wl->wireless_data;
+	netdev->wireless_handlers = &gelic_wl_wext_handler_def;
+	/* tx watchdog */
+	netdev->tx_timeout = &gelic_net_tx_timeout;
+	netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
+
+	netdev->ethtool_ops = &gelic_wl_ethtool_ops;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	netdev->poll_controller = gelic_net_poll_controller;
+#endif
+}
+
+/*
+ * driver probe/remove
+ */
+int gelic_wl_driver_probe(struct gelic_card *card)
+{
+	int ret;
+	struct net_device *netdev;
+
+	pr_debug("%s:start\n", __func__);
+
+	if (ps3_compare_firmware_version(1, 6, 0) < 0)
+		return 0;
+	if (!card->vlan[GELIC_PORT_WIRELESS].tx)
+		return 0;
+
+	/* alloc netdevice for wireless */
+	netdev = gelic_wl_alloc(card);
+	if (!netdev)
+		return -ENOMEM;
+
+	/* setup net_device structure */
+	gelic_wl_setup_netdev_ops(netdev);
+
+	/* setup some of net_device and register it */
+	ret = gelic_net_setup_netdev(netdev, card);
+	if (ret)
+		goto fail_setup;
+	card->netdev[GELIC_PORT_WIRELESS] = netdev;
+
+	/* add enable wireless interrupt */
+	card->irq_mask |= GELIC_CARD_WLAN_EVENT_RECEIVED |
+		GELIC_CARD_WLAN_COMMAND_COMPLETED;
+	/* to allow wireless commands while both interfaces are down */
+	gelic_card_set_irq_mask(card, GELIC_CARD_WLAN_EVENT_RECEIVED |
+				GELIC_CARD_WLAN_COMMAND_COMPLETED);
+	pr_debug("%s:end\n", __func__);
+	return 0;
+
+fail_setup:
+	gelic_wl_free(port_wl(netdev_port(netdev)));
+
+	return ret;
+}
+
+int gelic_wl_driver_remove(struct gelic_card *card)
+{
+	struct gelic_wl_info *wl;
+	struct net_device *netdev;
+
+	pr_debug("%s:start\n", __func__);
+
+	if (ps3_compare_firmware_version(1, 6, 0) < 0)
+		return 0;
+	if (!card->vlan[GELIC_PORT_WIRELESS].tx)
+		return 0;
+
+	netdev = card->netdev[GELIC_PORT_WIRELESS];
+	wl = port_wl(netdev_priv(netdev));
+
+	/* if the interface was not up, but associated */
+	if (wl->assoc_stat == GELIC_WL_ASSOC_STAT_ASSOCIATED)
+		gelic_wl_disconnect(netdev);
+
+	complete(&wl->cmd_done_intr);
+
+	/* cancel all work queue */
+	cancel_delayed_work(&wl->assoc_work);
+	cancel_delayed_work(&wl->event_work);
+	flush_workqueue(wl->eurus_cmd_queue);
+	flush_workqueue(wl->event_queue);
+
+	unregister_netdev(netdev);
+
+	/* disable wireless interrupt */
+	pr_debug("%s: disable intr\n", __func__);
+	card->irq_mask &= ~(GELIC_CARD_WLAN_EVENT_RECEIVED |
+			    GELIC_CARD_WLAN_COMMAND_COMPLETED);
+	/* free bss list, netdev*/
+	gelic_wl_free(wl);
+	pr_debug("%s:end\n", __func__);
+	return 0;
+}
diff --git a/drivers/net/ps3_gelic_wireless.h b/drivers/net/ps3_gelic_wireless.h
new file mode 100644
index 0000000..1036971
--- /dev/null
+++ b/drivers/net/ps3_gelic_wireless.h
@@ -0,0 +1,329 @@
+/*
+ *  PS3 gelic network driver.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2007 Sony Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation version 2.
+ *
+ * This program is distributed in the hope that 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _GELIC_WIRELESS_H
+#define _GELIC_WIRELESS_H
+
+#include <linux/wireless.h>
+#include <net/iw_handler.h>
+
+
+/* return value from  GELIC_LV1_GET_WLAN_EVENT netcontrol */
+enum gelic_lv1_wl_event {
+	GELIC_LV1_WL_EVENT_DEVICE_READY   = 0x01, /* Eurus ready */
+	GELIC_LV1_WL_EVENT_SCAN_COMPLETED = 0x02, /* Scan has completed */
+	GELIC_LV1_WL_EVENT_DEAUTH         = 0x04, /* Deauthed by the AP */
+	GELIC_LV1_WL_EVENT_BEACON_LOST    = 0x08, /* Beacon lost detected */
+	GELIC_LV1_WL_EVENT_CONNECTED      = 0x10, /* Connected to AP */
+	GELIC_LV1_WL_EVENT_WPA_CONNECTED  = 0x20, /* WPA connection */
+	GELIC_LV1_WL_EVENT_WPA_ERROR      = 0x40, /* MIC error */
+};
+
+/* arguments for GELIC_LV1_POST_WLAN_COMMAND netcontrol */
+enum gelic_eurus_command {
+	GELIC_EURUS_CMD_ASSOC		=  1, /* association start */
+	GELIC_EURUS_CMD_DISASSOC	=  2, /* disassociate      */
+	GELIC_EURUS_CMD_START_SCAN	=  3, /* scan start        */
+	GELIC_EURUS_CMD_GET_SCAN	=  4, /* get scan result   */
+	GELIC_EURUS_CMD_SET_COMMON_CFG	=  5, /* set common config */
+	GELIC_EURUS_CMD_GET_COMMON_CFG	=  6, /* set common config */
+	GELIC_EURUS_CMD_SET_WEP_CFG	=  7, /* set WEP config    */
+	GELIC_EURUS_CMD_GET_WEP_CFG	=  8, /* get WEP config    */
+	GELIC_EURUS_CMD_SET_WPA_CFG	=  9, /* set WPA config    */
+	GELIC_EURUS_CMD_GET_WPA_CFG	= 10, /* get WPA config    */
+	GELIC_EURUS_CMD_GET_RSSI_CFG	= 11, /* get RSSI info.    */
+	GELIC_EURUS_CMD_MAX_INDEX
+};
+
+/* for GELIC_EURUS_CMD_COMMON_CFG */
+enum gelic_eurus_bss_type {
+	GELIC_EURUS_BSS_INFRA = 0,
+	GELIC_EURUS_BSS_ADHOC = 1, /* not supported */
+};
+
+enum gelic_eurus_auth_method {
+	GELIC_EURUS_AUTH_OPEN = 0, /* FIXME: WLAN_AUTH_OPEN */
+	GELIC_EURUS_AUTH_SHARED = 1, /* not supported */
+};
+
+enum gelic_eurus_opmode {
+	GELIC_EURUS_OPMODE_11BG = 0, /* 802.11b/g */
+	GELIC_EURUS_OPMODE_11B = 1, /* 802.11b only */
+	GELIC_EURUS_OPMODE_11G = 2, /* 802.11g only */
+};
+
+struct gelic_eurus_common_cfg {
+	/* all fields are big endian */
+	u16 scan_index;
+	u16 bss_type;    /* infra or adhoc */
+	u16 auth_method; /* shared key or open */
+	u16 op_mode; /* B/G */
+} __attribute__((packed));
+
+
+/* for GELIC_EURUS_CMD_WEP_CFG */
+enum gelic_eurus_wep_security {
+	GELIC_EURUS_WEP_SEC_NONE	= 0,
+	GELIC_EURUS_WEP_SEC_40BIT	= 1,
+	GELIC_EURUS_WEP_SEC_104BIT	= 2,
+};
+
+struct gelic_eurus_wep_cfg {
+	/* all fields are big endian */
+	u16 security;
+	u8 key[4][16];
+} __attribute__((packed));
+
+/* for GELIC_EURUS_CMD_WPA_CFG */
+enum gelic_eurus_wpa_security {
+	GELIC_EURUS_WPA_SEC_NONE		= 0x0000,
+	/* group=TKIP, pairwise=TKIP */
+	GELIC_EURUS_WPA_SEC_WPA_TKIP_TKIP	= 0x0001,
+	/* group=AES, pairwise=AES */
+	GELIC_EURUS_WPA_SEC_WPA_AES_AES		= 0x0002,
+	/* group=TKIP, pairwise=TKIP */
+	GELIC_EURUS_WPA_SEC_WPA2_TKIP_TKIP	= 0x0004,
+	/* group=AES, pairwise=AES */
+	GELIC_EURUS_WPA_SEC_WPA2_AES_AES	= 0x0008,
+	/* group=TKIP, pairwise=AES */
+	GELIC_EURUS_WPA_SEC_WPA_TKIP_AES	= 0x0010,
+	/* group=TKIP, pairwise=AES */
+	GELIC_EURUS_WPA_SEC_WPA2_TKIP_AES	= 0x0020,
+};
+
+enum gelic_eurus_wpa_psk_type {
+	GELIC_EURUS_WPA_PSK_PASSPHRASE	= 0, /* passphrase string   */
+	GELIC_EURUS_WPA_PSK_BIN		= 1, /* 32 bytes binary key */
+};
+
+#define GELIC_WL_EURUS_PSK_MAX_LEN	64
+#define WPA_PSK_LEN			32 /* WPA spec says 256bit */
+
+struct gelic_eurus_wpa_cfg {
+	/* all fields are big endian */
+	u16 security;
+	u16 psk_type; /* psk key encoding type */
+	u8 psk[GELIC_WL_EURUS_PSK_MAX_LEN]; /* psk key; hex or passphrase */
+} __attribute__((packed));
+
+/* for GELIC_EURUS_CMD_{START,GET}_SCAN */
+enum gelic_eurus_scan_capability {
+	GELIC_EURUS_SCAN_CAP_ADHOC	= 0x0000,
+	GELIC_EURUS_SCAN_CAP_INFRA	= 0x0001,
+	GELIC_EURUS_SCAN_CAP_MASK	= 0x0001,
+};
+
+enum gelic_eurus_scan_sec_type {
+	GELIC_EURUS_SCAN_SEC_NONE	= 0x0000,
+	GELIC_EURUS_SCAN_SEC_WEP	= 0x0100,
+	GELIC_EURUS_SCAN_SEC_WPA	= 0x0200,
+	GELIC_EURUS_SCAN_SEC_WPA2	= 0x0400,
+	GELIC_EURUS_SCAN_SEC_MASK	= 0x0f00,
+};
+
+enum gelic_eurus_scan_sec_wep_type {
+	GELIC_EURUS_SCAN_SEC_WEP_UNKNOWN	= 0x0000,
+	GELIC_EURUS_SCAN_SEC_WEP_40		= 0x0001,
+	GELIC_EURUS_SCAN_SEC_WEP_104		= 0x0002,
+	GELIC_EURUS_SCAN_SEC_WEP_MASK		= 0x0003,
+};
+
+enum gelic_eurus_scan_sec_wpa_type {
+	GELIC_EURUS_SCAN_SEC_WPA_UNKNOWN	= 0x0000,
+	GELIC_EURUS_SCAN_SEC_WPA_TKIP		= 0x0001,
+	GELIC_EURUS_SCAN_SEC_WPA_AES		= 0x0002,
+	GELIC_EURUS_SCAN_SEC_WPA_MASK		= 0x0003,
+};
+
+/*
+ * hw BSS information structure returned from GELIC_EURUS_CMD_GET_SCAN
+ */
+struct gelic_eurus_scan_info {
+	/* all fields are big endian */
+	__be16 size;
+	__be16 rssi; /* percentage */
+	__be16 channel; /* channel number */
+	__be16 beacon_period; /* FIXME: in msec unit */
+	__be16 capability;
+	__be16 security;
+	u8  bssid[8]; /* last ETH_ALEN are valid. bssid[0],[1] are unused */
+	u8  essid[32]; /* IW_ESSID_MAX_SIZE */
+	u8  rate[16]; /* first MAX_RATES_LENGTH(12) are valid */
+	u8  ext_rate[16]; /* first MAX_RATES_EX_LENGTH(16) are valid */
+	__be32 reserved1;
+	__be32 reserved2;
+	__be32 reserved3;
+	__be32 reserved4;
+	u8 elements[0]; /* ie */
+} __attribute__ ((packed));
+
+/* the hypervisor returns bbs up to 16 */
+#define GELIC_EURUS_MAX_SCAN  (16)
+struct gelic_wl_scan_info {
+	struct list_head list;
+	struct gelic_eurus_scan_info *hwinfo;
+
+	int valid; /* set 1 if this entry was in latest scanned list
+		     * from Eurus */
+	unsigned int eurus_index; /* index in the Eurus list */
+	unsigned long last_scanned; /* acquired time */
+
+	unsigned int rate_len;
+	unsigned int rate_ext_len;
+	unsigned int essid_len;
+};
+
+/* for GELIC_EURUS_CMD_GET_RSSI */
+struct gelic_eurus_rssi_info {
+	/* big endian */
+	__be16 rssi;
+} __attribute__ ((packed));
+
+
+/* for 'stat' member of gelic_wl_info */
+enum gelic_wl_info_status_bit {
+	GELIC_WL_STAT_CONFIGURED,
+	GELIC_WL_STAT_CH_INFO,   /* ch info aquired */
+	GELIC_WL_STAT_ESSID_SET, /* ESSID specified by userspace */
+	GELIC_WL_STAT_BSSID_SET, /* BSSID specified by userspace */
+	GELIC_WL_STAT_WPA_PSK_SET, /* PMK specified by userspace */
+	GELIC_WL_STAT_WPA_LEVEL_SET, /* WEP or WPA[2] selected */
+};
+
+/* for 'scan_stat' member of gelic_wl_info */
+enum gelic_wl_scan_state {
+	/* just initialized or get last scan result failed */
+	GELIC_WL_SCAN_STAT_INIT,
+	/* scan request issued, accepted or chip is scanning */
+	GELIC_WL_SCAN_STAT_SCANNING,
+	/* scan results retrieved */
+	GELIC_WL_SCAN_STAT_GOT_LIST,
+};
+
+/* for 'cipher_method' */
+enum gelic_wl_cipher_method {
+	GELIC_WL_CIPHER_NONE,
+	GELIC_WL_CIPHER_WEP,
+	GELIC_WL_CIPHER_TKIP,
+	GELIC_WL_CIPHER_AES,
+};
+
+/* for 'wpa_level' */
+enum gelic_wl_wpa_level {
+	GELIC_WL_WPA_LEVEL_NONE,
+	GELIC_WL_WPA_LEVEL_WPA,
+	GELIC_WL_WPA_LEVEL_WPA2,
+};
+
+/* for 'assoc_stat' */
+enum gelic_wl_assoc_state {
+	GELIC_WL_ASSOC_STAT_DISCONN,
+	GELIC_WL_ASSOC_STAT_ASSOCIATING,
+	GELIC_WL_ASSOC_STAT_ASSOCIATED,
+};
+/* part of private data alloc_etherdev() allocated */
+#define GELIC_WEP_KEYS 4
+struct gelic_wl_info {
+	/* bss list */
+	struct semaphore scan_lock;
+	struct list_head network_list;
+	struct list_head network_free_list;
+	struct gelic_wl_scan_info *networks;
+
+	unsigned long scan_age; /* last scanned time */
+	enum gelic_wl_scan_state scan_stat;
+	struct completion scan_done;
+
+	/* eurus command queue */
+	struct workqueue_struct *eurus_cmd_queue;
+	struct completion cmd_done_intr;
+
+	/* eurus event handling */
+	struct workqueue_struct *event_queue;
+	struct delayed_work event_work;
+
+	/* wl status bits */
+	unsigned long stat;
+	enum gelic_eurus_auth_method auth_method; /* open/shared */
+	enum gelic_wl_cipher_method group_cipher_method;
+	enum gelic_wl_cipher_method pairwise_cipher_method;
+	enum gelic_wl_wpa_level wpa_level; /* wpa/wpa2 */
+
+	/* association handling */
+	struct semaphore assoc_stat_lock;
+	struct delayed_work assoc_work;
+	enum gelic_wl_assoc_state assoc_stat;
+	struct completion assoc_done;
+
+	spinlock_t lock;
+	u16 ch_info; /* available channels. bit0 = ch1 */
+	/* WEP keys */
+	u8 key[GELIC_WEP_KEYS][IW_ENCODING_TOKEN_MAX];
+	unsigned long key_enabled;
+	unsigned int key_len[GELIC_WEP_KEYS];
+	unsigned int current_key;
+	/* WWPA PSK */
+	u8 psk[GELIC_WL_EURUS_PSK_MAX_LEN];
+	enum gelic_eurus_wpa_psk_type psk_type;
+	unsigned int psk_len;
+
+	u8 essid[IW_ESSID_MAX_SIZE];
+	u8 bssid[ETH_ALEN]; /* userland requested */
+	u8 active_bssid[ETH_ALEN]; /* associated bssid */
+	unsigned int essid_len;
+
+	/* buffer for hypervisor IO */
+	void *buf;
+
+	struct iw_public_data wireless_data;
+	struct iw_statistics iwstat;
+};
+
+#define GELIC_WL_BSS_MAX_ENT 32
+#define GELIC_WL_ASSOC_RETRY 50
+static inline struct gelic_port *wl_port(struct gelic_wl_info *wl)
+{
+	return container_of((void *)wl, struct gelic_port, priv);
+}
+static inline struct gelic_wl_info *port_wl(struct gelic_port *port)
+{
+	return port_priv(port);
+}
+
+struct gelic_eurus_cmd {
+	struct work_struct work;
+	struct gelic_wl_info *wl;
+	unsigned int cmd; /* command code */
+	u64 tag;
+	u64 size;
+	void *buffer;
+	unsigned int buf_size;
+	struct completion done;
+	int status;
+	u64 cmd_status;
+};
+
+/* private ioctls to pass PSK */
+#define GELIC_WL_PRIV_SET_PSK		(SIOCIWFIRSTPRIV + 0)
+#define GELIC_WL_PRIV_GET_PSK		(SIOCIWFIRSTPRIV + 1)
+
+extern int gelic_wl_driver_probe(struct gelic_card *card);
+extern int gelic_wl_driver_remove(struct gelic_card *card);
+extern void gelic_wl_interrupt(struct net_device *netdev, u64 status);
+#endif /* _GELIC_WIRELESS_H */
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index 2334f4e..19184e4 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -61,7 +61,6 @@
 
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT	(6000 * HZ / 1000)
-#define TIMER_WUT	(jiffies + HZ * 1)/* timer wakeup time : 1 second */
 
 /* RDC MAC I/O Size */
 #define R6040_IO_SIZE	256
@@ -174,8 +173,6 @@ struct r6040_private {
 	struct net_device *dev;
 	struct mii_if_info mii_if;
 	struct napi_struct napi;
-	struct net_device_stats stats;
-	u16	napi_rx_running;
 	void __iomem *base;
 };
 
@@ -235,17 +232,53 @@ static void mdio_write(struct net_device *dev, int mii_id, int reg, int val)
 	phy_write(ioaddr, lp->phy_addr, reg, val);
 }
 
-static void r6040_tx_timeout(struct net_device *dev)
+static void r6040_free_txbufs(struct net_device *dev)
 {
-	struct r6040_private *priv = netdev_priv(dev);
+	struct r6040_private *lp = netdev_priv(dev);
+	int i;
 
-	disable_irq(dev->irq);
-	napi_disable(&priv->napi);
-	spin_lock(&priv->lock);
-	dev->stats.tx_errors++;
-	spin_unlock(&priv->lock);
+	for (i = 0; i < TX_DCNT; i++) {
+		if (lp->tx_insert_ptr->skb_ptr) {
+			pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf,
+				MAX_BUF_SIZE, PCI_DMA_TODEVICE);
+			dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
+			lp->rx_insert_ptr->skb_ptr = NULL;
+		}
+		lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp;
+	}
+}
 
-	netif_stop_queue(dev);
+static void r6040_free_rxbufs(struct net_device *dev)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	int i;
+
+	for (i = 0; i < RX_DCNT; i++) {
+		if (lp->rx_insert_ptr->skb_ptr) {
+			pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf,
+				MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
+			dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
+			lp->rx_insert_ptr->skb_ptr = NULL;
+		}
+		lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp;
+	}
+}
+
+static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring,
+				 dma_addr_t desc_dma, int size)
+{
+	struct r6040_descriptor *desc = desc_ring;
+	dma_addr_t mapping = desc_dma;
+
+	while (size-- > 0) {
+		mapping += sizeof(sizeof(*desc));
+		desc->ndesc = cpu_to_le32(mapping);
+		desc->vndescp = desc + 1;
+		desc++;
+	}
+	desc--;
+	desc->ndesc = cpu_to_le32(desc_dma);
+	desc->vndescp = desc_ring;
 }
 
 /* Allocate skb buffer for rx descriptor */
@@ -256,7 +289,7 @@ static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
 
 	descptr = lp->rx_insert_ptr;
 	while (lp->rx_free_desc < RX_DCNT) {
-		descptr->skb_ptr = dev_alloc_skb(MAX_BUF_SIZE);
+		descptr->skb_ptr = netdev_alloc_skb(dev, MAX_BUF_SIZE);
 
 		if (!descptr->skb_ptr)
 			break;
@@ -272,6 +305,63 @@ static void rx_buf_alloc(struct r6040_private *lp, struct net_device *dev)
 	lp->rx_insert_ptr = descptr;
 }
 
+static void r6040_alloc_txbufs(struct net_device *dev)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+
+	lp->tx_free_desc = TX_DCNT;
+
+	lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring;
+	r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT);
+
+	iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0);
+	iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1);
+}
+
+static void r6040_alloc_rxbufs(struct net_device *dev)
+{
+	struct r6040_private *lp = netdev_priv(dev);
+	void __iomem *ioaddr = lp->base;
+
+	lp->rx_free_desc = 0;
+
+	lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring;
+	r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT);
+
+	rx_buf_alloc(lp, dev);
+
+	iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0);
+	iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1);
+}
+
+static void r6040_tx_timeout(struct net_device *dev)
+{
+	struct r6040_private *priv = netdev_priv(dev);
+	void __iomem *ioaddr = priv->base;
+
+	printk(KERN_WARNING "%s: transmit timed out, status %4.4x, PHY status "
+		"%4.4x\n",
+		dev->name, ioread16(ioaddr + MIER),
+		mdio_read(dev, priv->mii_if.phy_id, MII_BMSR));
+
+	disable_irq(dev->irq);
+	napi_disable(&priv->napi);
+	spin_lock(&priv->lock);
+	/* Clear all descriptors */
+	r6040_free_txbufs(dev);
+	r6040_free_rxbufs(dev);
+	r6040_alloc_txbufs(dev);
+	r6040_alloc_rxbufs(dev);
+
+	/* Reset MAC */
+	iowrite16(MAC_RST, ioaddr + MCR1);
+	spin_unlock(&priv->lock);
+	enable_irq(dev->irq);
+
+	dev->stats.tx_errors++;
+	netif_wake_queue(dev);
+}
 
 static struct net_device_stats *r6040_get_stats(struct net_device *dev)
 {
@@ -280,11 +370,11 @@ static struct net_device_stats *r6040_get_stats(struct net_device *dev)
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->lock, flags);
-	priv->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1);
-	priv->stats.multicast += ioread8(ioaddr + ME_CNT0);
+	dev->stats.rx_crc_errors += ioread8(ioaddr + ME_CNT1);
+	dev->stats.multicast += ioread8(ioaddr + ME_CNT0);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	return &priv->stats;
+	return &dev->stats;
 }
 
 /* Stop RDC MAC and Free the allocated resource */
@@ -293,7 +383,6 @@ static void r6040_down(struct net_device *dev)
 	struct r6040_private *lp = netdev_priv(dev);
 	void __iomem *ioaddr = lp->base;
 	struct pci_dev *pdev = lp->pdev;
-	int i;
 	int limit = 2048;
 	u16 *adrp;
 	u16 cmd;
@@ -313,27 +402,12 @@ static void r6040_down(struct net_device *dev)
 	iowrite16(adrp[1], ioaddr + MID_0M);
 	iowrite16(adrp[2], ioaddr + MID_0H);
 	free_irq(dev->irq, dev);
+
 	/* Free RX buffer */
-	for (i = 0; i < RX_DCNT; i++) {
-		if (lp->rx_insert_ptr->skb_ptr) {
-			pci_unmap_single(lp->pdev, lp->rx_insert_ptr->buf,
-				MAX_BUF_SIZE, PCI_DMA_FROMDEVICE);
-			dev_kfree_skb(lp->rx_insert_ptr->skb_ptr);
-			lp->rx_insert_ptr->skb_ptr = NULL;
-		}
-		lp->rx_insert_ptr = lp->rx_insert_ptr->vndescp;
-	}
+	r6040_free_rxbufs(dev);
 
 	/* Free TX buffer */
-	for (i = 0; i < TX_DCNT; i++) {
-		if (lp->tx_insert_ptr->skb_ptr) {
-			pci_unmap_single(lp->pdev, lp->tx_insert_ptr->buf,
-				MAX_BUF_SIZE, PCI_DMA_TODEVICE);
-			dev_kfree_skb(lp->tx_insert_ptr->skb_ptr);
-			lp->rx_insert_ptr->skb_ptr = NULL;
-		}
-		lp->tx_insert_ptr = lp->tx_insert_ptr->vndescp;
-	}
+	r6040_free_txbufs(dev);
 
 	/* Free Descriptor memory */
 	pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
@@ -432,19 +506,24 @@ static int r6040_rx(struct net_device *dev, int limit)
 
 		/* Check for errors */
 		err = ioread16(ioaddr + MLSR);
-		if (err & 0x0400) priv->stats.rx_errors++;
+		if (err & 0x0400)
+			dev->stats.rx_errors++;
 		/* RX FIFO over-run */
-		if (err & 0x8000) priv->stats.rx_fifo_errors++;
+		if (err & 0x8000)
+			dev->stats.rx_fifo_errors++;
 		/* RX descriptor unavailable */
-		if (err & 0x0080) priv->stats.rx_frame_errors++;
+		if (err & 0x0080)
+			dev->stats.rx_frame_errors++;
 		/* Received packet with length over buffer lenght */
-		if (err & 0x0020) priv->stats.rx_over_errors++;
+		if (err & 0x0020)
+			dev->stats.rx_over_errors++;
 		/* Received packet with too long or short */
-		if (err & (0x0010|0x0008)) priv->stats.rx_length_errors++;
+		if (err & (0x0010 | 0x0008))
+			dev->stats.rx_length_errors++;
 		/* Received packet with CRC errors */
 		if (err & 0x0004) {
 			spin_lock(&priv->lock);
-			priv->stats.rx_crc_errors++;
+			dev->stats.rx_crc_errors++;
 			spin_unlock(&priv->lock);
 		}
 
@@ -469,8 +548,8 @@ static int r6040_rx(struct net_device *dev, int limit)
 			/* Send to upper layer */
 			netif_receive_skb(skb_ptr);
 			dev->last_rx = jiffies;
-			priv->dev->stats.rx_packets++;
-			priv->dev->stats.rx_bytes += descptr->len;
+			dev->stats.rx_packets++;
+			dev->stats.rx_bytes += descptr->len;
 			/* To next descriptor */
 			descptr = descptr->vndescp;
 			priv->rx_free_desc--;
@@ -498,11 +577,13 @@ static void r6040_tx(struct net_device *dev)
 		/* Check for errors */
 		err = ioread16(ioaddr + MLSR);
 
-		if (err & 0x0200) priv->stats.rx_fifo_errors++;
-		if (err & (0x2000 | 0x4000)) priv->stats.tx_carrier_errors++;
+		if (err & 0x0200)
+			dev->stats.rx_fifo_errors++;
+		if (err & (0x2000 | 0x4000))
+			dev->stats.tx_carrier_errors++;
 
 		if (descptr->status & 0x8000)
-			break; /* Not complte */
+			break; /* Not complete */
 		skb_ptr = descptr->skb_ptr;
 		pci_unmap_single(priv->pdev, descptr->buf,
 			skb_ptr->len, PCI_DMA_TODEVICE);
@@ -545,7 +626,6 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
 	struct r6040_private *lp = netdev_priv(dev);
 	void __iomem *ioaddr = lp->base;
 	u16 status;
-	int handled = 1;
 
 	/* Mask off RDC MAC interrupt */
 	iowrite16(MSK_INT, ioaddr + MIER);
@@ -565,7 +645,7 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id)
 	if (status & 0x10)
 		r6040_tx(dev);
 
-	return IRQ_RETVAL(handled);
+	return IRQ_HANDLED;
 }
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
@@ -577,53 +657,15 @@ static void r6040_poll_controller(struct net_device *dev)
 }
 #endif
 
-static void r6040_init_ring_desc(struct r6040_descriptor *desc_ring,
-				 dma_addr_t desc_dma, int size)
-{
-	struct r6040_descriptor *desc = desc_ring;
-	dma_addr_t mapping = desc_dma;
-
-	while (size-- > 0) {
-		mapping += sizeof(sizeof(*desc));
-		desc->ndesc = cpu_to_le32(mapping);
-		desc->vndescp = desc + 1;
-		desc++;
-	}
-	desc--;
-	desc->ndesc = cpu_to_le32(desc_dma);
-	desc->vndescp = desc_ring;
-}
-
 /* Init RDC MAC */
 static void r6040_up(struct net_device *dev)
 {
 	struct r6040_private *lp = netdev_priv(dev);
 	void __iomem *ioaddr = lp->base;
 
-	/* Initialize */
-	lp->tx_free_desc = TX_DCNT;
-	lp->rx_free_desc = 0;
-	/* Init descriptor */
-	lp->tx_remove_ptr = lp->tx_insert_ptr = lp->tx_ring;
-	lp->rx_remove_ptr = lp->rx_insert_ptr = lp->rx_ring;
-	/* Init TX descriptor */
-	r6040_init_ring_desc(lp->tx_ring, lp->tx_ring_dma, TX_DCNT);
-
-	/* Init RX descriptor */
-	r6040_init_ring_desc(lp->rx_ring, lp->rx_ring_dma, RX_DCNT);
-
-	/* Allocate buffer for RX descriptor */
-	rx_buf_alloc(lp, dev);
-
-	/*
-	 * TX and RX descriptor start registers.
-	 * Lower 16-bits to MxD_SA0. Higher 16-bits to MxD_SA1.
-	 */
-	iowrite16(lp->tx_ring_dma, ioaddr + MTD_SA0);
-	iowrite16(lp->tx_ring_dma >> 16, ioaddr + MTD_SA1);
-
-	iowrite16(lp->rx_ring_dma, ioaddr + MRD_SA0);
-	iowrite16(lp->rx_ring_dma >> 16, ioaddr + MRD_SA1);
+	/* Initialise and alloc RX/TX buffers */
+	r6040_alloc_txbufs(dev);
+	r6040_alloc_rxbufs(dev);
 
 	/* Buffer Size Register */
 	iowrite16(MAX_BUF_SIZE, ioaddr + MR_BSR);
@@ -689,8 +731,7 @@ static void r6040_timer(unsigned long data)
 	}
 
 	/* Timer active again */
-	lp->timer.expires = TIMER_WUT;
-	add_timer(&lp->timer);
+	mod_timer(&lp->timer, jiffies + round_jiffies(HZ));
 }
 
 /* Read/set MAC address routines */
@@ -746,14 +787,10 @@ static int r6040_open(struct net_device *dev)
 	napi_enable(&lp->napi);
 	netif_start_queue(dev);
 
-	if (lp->switch_sig != ICPLUS_PHY_ID) {
-		/* set and active a timer process */
-		init_timer(&lp->timer);
-		lp->timer.expires = TIMER_WUT;
-		lp->timer.data = (unsigned long)dev;
-		lp->timer.function = &r6040_timer;
-		add_timer(&lp->timer);
-	}
+	/* set and active a timer process */
+	setup_timer(&lp->timer, r6040_timer, (unsigned long) dev);
+	if (lp->switch_sig != ICPLUS_PHY_ID)
+		mod_timer(&lp->timer, jiffies + HZ);
 	return 0;
 }
 
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 2e9e88b..202fdf3 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1630,7 +1630,8 @@ static inline void sis190_init_rxfilter(struct net_device *dev)
 	SIS_PCI_COMMIT();
 }
 
-static int sis190_get_mac_addr(struct pci_dev *pdev, struct net_device *dev)
+static int __devinit sis190_get_mac_addr(struct pci_dev *pdev, 
+					 struct net_device *dev)
 {
 	u8 from;
 
diff --git a/drivers/s390/net/claw.h b/drivers/s390/net/claw.h
index 1ee9a6f..1a89d98 100644
--- a/drivers/s390/net/claw.h
+++ b/drivers/s390/net/claw.h
@@ -114,11 +114,20 @@ do { \
 	debug_event(claw_dbf_##name,level,(void*)(addr),len); \
 } while (0)
 
+/* Allow to sort out low debug levels early to avoid wasted sprints */
+static inline int claw_dbf_passes(debug_info_t *dbf_grp, int level)
+{
+	return (level <= dbf_grp->level);
+}
+
 #define CLAW_DBF_TEXT_(level,name,text...) \
-do {                                       \
-	sprintf(debug_buffer, text);  \
-		debug_text_event(claw_dbf_##name,level, debug_buffer);\
-} while (0)
+	do { \
+		if (claw_dbf_passes(claw_dbf_##name, level)) { \
+			sprintf(debug_buffer, text); \
+			debug_text_event(claw_dbf_##name, level, \
+						debug_buffer); \
+		} \
+	} while (0)
 
 /*******************************************************
 *  Define Control Blocks                               *
@@ -278,8 +287,6 @@ struct claw_env {
         __u16                   write_size;     /* write buffer size */
         __u16                   dev_id;         /* device ident */
 	__u8			packing;	/* are we packing? */
-	volatile __u8		queme_switch;   /* gate for imed packing  */
-	volatile unsigned long	pk_delay;	/* Delay for adaptive packing */
         __u8                    in_use;         /* device active flag */
         struct net_device       *ndev;    	/* backward ptr to the net dev*/
 };
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 7bfe8d7..f51ed99 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -94,7 +94,7 @@ static int
 lcs_register_debug_facility(void)
 {
 	lcs_dbf_setup = debug_register("lcs_setup", 2, 1, 8);
-	lcs_dbf_trace = debug_register("lcs_trace", 2, 2, 8);
+	lcs_dbf_trace = debug_register("lcs_trace", 4, 1, 8);
 	if (lcs_dbf_setup == NULL || lcs_dbf_trace == NULL) {
 		PRINT_ERR("Not enough memory for debug facility.\n");
 		lcs_unregister_debug_facility();
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index 8976fb0..d58fea5 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -16,11 +16,19 @@ do { \
 	debug_event(lcs_dbf_##name,level,(void*)(addr),len); \
 } while (0)
 
+/* Allow to sort out low debug levels early to avoid wasted sprints */
+static inline int lcs_dbf_passes(debug_info_t *dbf_grp, int level)
+{
+	return (level <= dbf_grp->level);
+}
+
 #define LCS_DBF_TEXT_(level,name,text...) \
-do {                                       \
-	sprintf(debug_buffer, text);  \
-		debug_text_event(lcs_dbf_##name,level, debug_buffer);\
-} while (0)
+	do { \
+		if (lcs_dbf_passes(lcs_dbf_##name, level)) { \
+			sprintf(debug_buffer, text); \
+			debug_text_event(lcs_dbf_##name, level, debug_buffer); \
+		} \
+	} while (0)
 
 /**
  *	sysfs related stuff
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index f3d893c..874a199 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -97,12 +97,22 @@ MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
 
 DECLARE_PER_CPU(char[256], iucv_dbf_txt_buf);
 
-#define IUCV_DBF_TEXT_(name,level,text...)				\
-	do {								\
-		char* iucv_dbf_txt_buf = get_cpu_var(iucv_dbf_txt_buf);	\
-		sprintf(iucv_dbf_txt_buf, text);			\
-		debug_text_event(iucv_dbf_##name,level,iucv_dbf_txt_buf); \
-		put_cpu_var(iucv_dbf_txt_buf);				\
+/* Allow to sort out low debug levels early to avoid wasted sprints */
+static inline int iucv_dbf_passes(debug_info_t *dbf_grp, int level)
+{
+	return (level <= dbf_grp->level);
+}
+
+#define IUCV_DBF_TEXT_(name, level, text...) \
+	do { \
+		if (iucv_dbf_passes(iucv_dbf_##name, level)) { \
+			char* iucv_dbf_txt_buf = \
+					get_cpu_var(iucv_dbf_txt_buf); \
+			sprintf(iucv_dbf_txt_buf, text); \
+			debug_text_event(iucv_dbf_##name, level, \
+						iucv_dbf_txt_buf); \
+			put_cpu_var(iucv_dbf_txt_buf); \
+		} \
 	} while (0)
 
 #define IUCV_DBF_SPRINTF(name,level,text...) \
@@ -137,6 +147,7 @@ PRINT_##importance(header "%02x %02x %02x %02x  %02x %02x %02x %02x  " \
 #define PRINTK_HEADER " iucv: "       /* for debugging */
 
 static struct device_driver netiucv_driver = {
+	.owner = THIS_MODULE,
 	.name = "netiucv",
 	.bus  = &iucv_bus,
 };
@@ -572,9 +583,9 @@ static void netiucv_callback_connres(struct iucv_path *path, u8 ipuser[16])
 }
 
 /**
- * Dummy NOP action for all statemachines
+ * NOP action for statemachines
  */
-static void fsm_action_nop(fsm_instance *fi, int event, void *arg)
+static void netiucv_action_nop(fsm_instance *fi, int event, void *arg)
 {
 }
 
@@ -1110,7 +1121,7 @@ static const fsm_node dev_fsm[] = {
 
 	{ DEV_STATE_RUNNING,    DEV_EVENT_STOP,    dev_action_stop     },
 	{ DEV_STATE_RUNNING,    DEV_EVENT_CONDOWN, dev_action_conndown },
-	{ DEV_STATE_RUNNING,    DEV_EVENT_CONUP,   fsm_action_nop      },
+	{ DEV_STATE_RUNNING,    DEV_EVENT_CONUP,   netiucv_action_nop  },
 };
 
 static const int DEV_FSM_LEN = sizeof(dev_fsm) / sizeof(fsm_node);
diff --git a/include/linux/dm9000.h b/include/linux/dm9000.h
index 0008e2a..a375046 100644
--- a/include/linux/dm9000.h
+++ b/include/linux/dm9000.h
@@ -19,6 +19,8 @@
 #define DM9000_PLATF_8BITONLY	(0x0001)
 #define DM9000_PLATF_16BITONLY	(0x0002)
 #define DM9000_PLATF_32BITONLY	(0x0004)
+#define DM9000_PLATF_EXT_PHY	(0x0008)
+#define DM9000_PLATF_NO_EEPROM	(0x0010)
 
 /* platfrom data for platfrom device structure's platfrom_data field */
 

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2008-02-06 11:49 Jeff Garzik
@ 2008-02-06 11:52 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2008-02-06 11:52 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Wed, 6 Feb 2008 06:49:50 -0500

> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem
> 
> to receive the following updates:

Pulled, thanks Jeff.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2008-02-06 11:49 Jeff Garzik
  2008-02-06 11:52 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2008-02-06 11:49 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


Please pull from 'upstream-davem' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

to receive the following updates:

 drivers/net/forcedeth.c           |   49 +++++-
 drivers/net/gianfar_mii.c         |    4 +-
 drivers/net/iseries_veth.c        |    2 +-
 drivers/net/ixgbe/ixgbe.h         |    4 +-
 drivers/net/ixgbe/ixgbe_ethtool.c |   91 +++++++-----
 drivers/net/ixgbe/ixgbe_main.c    |  305 ++++++++++++++++++++++++------------
 drivers/net/mv643xx_eth.c         |   11 +-
 drivers/net/sky2.c                |   17 +--
 drivers/net/sky2.h                |    2 +-
 drivers/net/tlan.c                |   25 +++-
 drivers/net/tulip/xircom_cb.c     |    2 +-
 drivers/net/ucc_geth_mii.c        |    4 +-
 drivers/net/virtio_net.c          |   10 +-
 drivers/net/wan/hdlc.c            |   24 +--
 drivers/net/wan/hdlc_cisco.c      |    5 +-
 drivers/net/wan/hdlc_fr.c         |   53 +++----
 drivers/net/wan/hdlc_ppp.c        |    2 +-
 drivers/net/wan/hdlc_raw.c        |    2 +-
 drivers/net/wan/hdlc_raw_eth.c    |    6 +-
 drivers/net/wan/hdlc_x25.c        |   10 +-
 include/linux/hdlc.h              |   25 +---
 21 files changed, 398 insertions(+), 255 deletions(-)

Andy Fleming (1):
      Fix PHY Lib support for gianfar and ucc_geth

Ayaz Abdulla (3):
      forcedeth: restart tx/rx
      forcedeth: phy status fix
      forcedeth: preserve registers

Ayyappan Veeraiyan (8):
      ixgbe: remove obsolete irq_sem, add driver state checking code
      ixbge: remove TX lock and redo TX accounting.
      ixbge: Make ethtool code account for media types
      ixgbe: Fix pause code for ethtool
      ixgbe: Fix FW init/release, make this code a function
      ixgbe: properly return CHECKSUM_NONE, cleanup csum code
      ixgbe: fix several counter register errata
      ixgbe: add real-time traffic counters

Byron Bradley (1):
      mv643xx_eth: fix byte order when checksum offload is enabled

Christian Borntraeger (1):
      virtio net: fix oops on interface-up

Erik Mouw (1):
      xircom_cb should return NETDEV_TX_BUSY when no descriptors available

Krzysztof Halasa (3):
      Generic HDLC - fix kernel panic
      Generic HDLC - remove now unneeded hdlc_device_desc
      Generic HDLC - use random_ether_addr()

Leonardo Potenza (1):
      drivers/net/tlan.c: compilation warning fix

Stephen Hemminger (1):
      sky2: fix for Yukon FE (regression in 2.6.25)

Stephen Rothwell (1):
      iSeries: fix section mismatch in iseries_veth

diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 3634223..d4843d0 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -323,8 +323,8 @@ enum {
 	NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR		0x0001
 #define NVREG_MIISTAT_LINKCHANGE	0x0008
-#define NVREG_MIISTAT_MASK		0x000f
-#define NVREG_MIISTAT_MASK2		0x000f
+#define NVREG_MIISTAT_MASK_RW		0x0007
+#define NVREG_MIISTAT_MASK_ALL		0x000f
 	NvRegMIIMask = 0x184,
 #define NVREG_MII_LINKCHANGE		0x0008
 
@@ -624,6 +624,9 @@ union ring_type {
 #define NV_MSI_X_VECTOR_TX    0x1
 #define NV_MSI_X_VECTOR_OTHER 0x2
 
+#define NV_RESTART_TX         0x1
+#define NV_RESTART_RX         0x2
+
 /* statistics */
 struct nv_ethtool_str {
 	char name[ETH_GSTRING_LEN];
@@ -1061,7 +1064,7 @@ static int mii_rw(struct net_device *dev, int addr, int miireg, int value)
 	u32 reg;
 	int retval;
 
-	writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
+	writel(NVREG_MIISTAT_MASK_RW, base + NvRegMIIStatus);
 
 	reg = readl(base + NvRegMIIControl);
 	if (reg & NVREG_MIICTL_INUSE) {
@@ -1432,16 +1435,30 @@ static void nv_mac_reset(struct net_device *dev)
 {
 	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
+	u32 temp1, temp2, temp3;
 
 	dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name);
+
 	writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
 	pci_push(base);
+
+	/* save registers since they will be cleared on reset */
+	temp1 = readl(base + NvRegMacAddrA);
+	temp2 = readl(base + NvRegMacAddrB);
+	temp3 = readl(base + NvRegTransmitPoll);
+
 	writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset);
 	pci_push(base);
 	udelay(NV_MAC_RESET_DELAY);
 	writel(0, base + NvRegMacReset);
 	pci_push(base);
 	udelay(NV_MAC_RESET_DELAY);
+
+	/* restore saved registers */
+	writel(temp1, base + NvRegMacAddrA);
+	writel(temp2, base + NvRegMacAddrB);
+	writel(temp3, base + NvRegTransmitPoll);
+
 	writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
 	pci_push(base);
 }
@@ -2767,6 +2784,7 @@ static int nv_update_linkspeed(struct net_device *dev)
 	int mii_status;
 	int retval = 0;
 	u32 control_1000, status_1000, phyreg, pause_flags, txreg;
+	u32 txrxFlags = 0;
 
 	/* BMSR_LSTATUS is latched, read it twice:
 	 * we want the current value.
@@ -2862,6 +2880,16 @@ set_speed:
 	np->duplex = newdup;
 	np->linkspeed = newls;
 
+	/* The transmitter and receiver must be restarted for safe update */
+	if (readl(base + NvRegTransmitterControl) & NVREG_XMITCTL_START) {
+		txrxFlags |= NV_RESTART_TX;
+		nv_stop_tx(dev);
+	}
+	if (readl(base + NvRegReceiverControl) & NVREG_RCVCTL_START) {
+		txrxFlags |= NV_RESTART_RX;
+		nv_stop_rx(dev);
+	}
+
 	if (np->gigabit == PHY_GIGABIT) {
 		phyreg = readl(base + NvRegRandomSeed);
 		phyreg &= ~(0x3FF00);
@@ -2950,6 +2978,11 @@ set_speed:
 	}
 	nv_update_pause(dev, pause_flags);
 
+	if (txrxFlags & NV_RESTART_TX)
+		nv_start_tx(dev);
+	if (txrxFlags & NV_RESTART_RX)
+		nv_start_rx(dev);
+
 	return retval;
 }
 
@@ -2976,7 +3009,7 @@ static void nv_link_irq(struct net_device *dev)
 	u32 miistat;
 
 	miistat = readl(base + NvRegMIIStatus);
-	writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
+	writel(NVREG_MIISTAT_LINKCHANGE, base + NvRegMIIStatus);
 	dprintk(KERN_INFO "%s: link change irq, status 0x%x.\n", dev->name, miistat);
 
 	if (miistat & (NVREG_MIISTAT_LINKCHANGE))
@@ -4851,7 +4884,7 @@ static int nv_open(struct net_device *dev)
 
 	writel(0, base + NvRegMIIMask);
 	writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
-	writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
+	writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
 
 	writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1);
 	writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus);
@@ -4889,7 +4922,7 @@ static int nv_open(struct net_device *dev)
 
 	nv_disable_hw_interrupts(dev, np->irqmask);
 	pci_push(base);
-	writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
+	writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
 	writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
 	pci_push(base);
 
@@ -4912,7 +4945,7 @@ static int nv_open(struct net_device *dev)
 	{
 		u32 miistat;
 		miistat = readl(base + NvRegMIIStatus);
-		writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
+		writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
 		dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat);
 	}
 	/* set linkspeed to invalid value, thus force nv_update_linkspeed
@@ -5280,7 +5313,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 		phystate &= ~NVREG_ADAPTCTL_RUNNING;
 		writel(phystate, base + NvRegAdapterControl);
 	}
-	writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus);
+	writel(NVREG_MIISTAT_MASK_ALL, base + NvRegMIIStatus);
 
 	if (id->driver_data & DEV_HAS_MGMT_UNIT) {
 		/* management unit running on the mac? */
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 100bf41..6a647d9 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -127,7 +127,7 @@ int gfar_mdio_reset(struct mii_bus *bus)
 	struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
 	unsigned int timeout = PHY_INIT_TIMEOUT;
 
-	spin_lock_bh(&bus->mdio_lock);
+	mutex_lock(&bus->mdio_lock);
 
 	/* Reset the management interface */
 	gfar_write(&regs->miimcfg, MIIMCFG_RESET);
@@ -140,7 +140,7 @@ int gfar_mdio_reset(struct mii_bus *bus)
 			timeout--)
 		cpu_relax();
 
-	spin_unlock_bh(&bus->mdio_lock);
+	mutex_unlock(&bus->mdio_lock);
 
 	if(timeout <= 0) {
 		printk(KERN_ERR "%s: The MII Bus is stuck!\n",
diff --git a/drivers/net/iseries_veth.c b/drivers/net/iseries_veth.c
index 419861c..58d3bb6 100644
--- a/drivers/net/iseries_veth.c
+++ b/drivers/net/iseries_veth.c
@@ -1020,7 +1020,7 @@ static const struct ethtool_ops ops = {
 	.get_link = veth_get_link,
 };
 
-static struct net_device * __init veth_probe_one(int vlan,
+static struct net_device *veth_probe_one(int vlan,
 		struct vio_dev *vio_dev)
 {
 	struct net_device *dev;
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index a021a6e..d0bf206 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -136,8 +136,6 @@ struct ixgbe_ring {
 	u16 head;
 	u16 tail;
 
-	/* To protect race between sender and clean_tx_irq */
-	spinlock_t tx_lock;
 
 	struct ixgbe_queue_stats stats;
 
@@ -174,7 +172,6 @@ struct ixgbe_adapter {
 	struct vlan_group *vlgrp;
 	u16 bd_number;
 	u16 rx_buf_len;
-	atomic_t irq_sem;
 	struct work_struct reset_task;
 
 	/* TX */
@@ -244,6 +241,7 @@ extern const char ixgbe_driver_version[];
 
 extern int ixgbe_up(struct ixgbe_adapter *adapter);
 extern void ixgbe_down(struct ixgbe_adapter *adapter);
+extern void ixgbe_reinit_locked(struct ixgbe_adapter *adapter);
 extern void ixgbe_reset(struct ixgbe_adapter *adapter);
 extern void ixgbe_update_stats(struct ixgbe_adapter *adapter);
 extern void ixgbe_set_ethtool_ops(struct net_device *netdev);
diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 3635344..a119cbd 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -103,21 +103,41 @@ static int ixgbe_get_settings(struct net_device *netdev,
 			      struct ethtool_cmd *ecmd)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
+	u32 link_speed = 0;
+	bool link_up;
 
-	ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
-	ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
-	ecmd->port = PORT_FIBRE;
+	ecmd->supported = SUPPORTED_10000baseT_Full;
+	ecmd->autoneg = AUTONEG_ENABLE;
 	ecmd->transceiver = XCVR_EXTERNAL;
+	if (hw->phy.media_type == ixgbe_media_type_copper) {
+		ecmd->supported |= (SUPPORTED_1000baseT_Full |
+				    SUPPORTED_TP | SUPPORTED_Autoneg);
+
+		ecmd->advertising = (ADVERTISED_TP | ADVERTISED_Autoneg);
+		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
+			ecmd->advertising |= ADVERTISED_10000baseT_Full;
+		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
+			ecmd->advertising |= ADVERTISED_1000baseT_Full;
+
+		ecmd->port = PORT_TP;
+	} else {
+		ecmd->supported |= SUPPORTED_FIBRE;
+		ecmd->advertising = (ADVERTISED_10000baseT_Full |
+				     ADVERTISED_FIBRE);
+		ecmd->port = PORT_FIBRE;
+	}
 
-	if (netif_carrier_ok(adapter->netdev)) {
-		ecmd->speed = SPEED_10000;
+	adapter->hw.mac.ops.check_link(hw, &(link_speed), &link_up);
+	if (link_up) {
+		ecmd->speed = (link_speed == IXGBE_LINK_SPEED_10GB_FULL) ?
+				SPEED_10000 : SPEED_1000;
 		ecmd->duplex = DUPLEX_FULL;
 	} else {
 		ecmd->speed = -1;
 		ecmd->duplex = -1;
 	}
 
-	ecmd->autoneg = AUTONEG_DISABLE;
 	return 0;
 }
 
@@ -125,17 +145,17 @@ static int ixgbe_set_settings(struct net_device *netdev,
 			      struct ethtool_cmd *ecmd)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+	struct ixgbe_hw *hw = &adapter->hw;
 
-	if (ecmd->autoneg == AUTONEG_ENABLE ||
-	    ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL)
-		return -EINVAL;
-
-	if (netif_running(adapter->netdev)) {
-		ixgbe_down(adapter);
-		ixgbe_reset(adapter);
-		ixgbe_up(adapter);
-	} else {
-		ixgbe_reset(adapter);
+	switch (hw->phy.media_type) {
+	case ixgbe_media_type_fiber:
+		if ((ecmd->autoneg == AUTONEG_ENABLE) ||
+		    (ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
+			return -EINVAL;
+		/* in this case we currently only support 10Gb/FULL */
+		break;
+	default:
+		break;
 	}
 
 	return 0;
@@ -147,7 +167,7 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 
-	pause->autoneg = AUTONEG_DISABLE;
+	pause->autoneg = (hw->fc.type == ixgbe_fc_full ? 1 : 0);
 
 	if (hw->fc.type == ixgbe_fc_rx_pause) {
 		pause->rx_pause = 1;
@@ -165,10 +185,8 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	struct ixgbe_hw *hw = &adapter->hw;
 
-	if (pause->autoneg == AUTONEG_ENABLE)
-		return -EINVAL;
-
-	if (pause->rx_pause && pause->tx_pause)
+	if ((pause->autoneg == AUTONEG_ENABLE) ||
+	    (pause->rx_pause && pause->tx_pause))
 		hw->fc.type = ixgbe_fc_full;
 	else if (pause->rx_pause && !pause->tx_pause)
 		hw->fc.type = ixgbe_fc_rx_pause;
@@ -176,15 +194,15 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
 		hw->fc.type = ixgbe_fc_tx_pause;
 	else if (!pause->rx_pause && !pause->tx_pause)
 		hw->fc.type = ixgbe_fc_none;
+	else
+		return -EINVAL;
 
 	hw->fc.original_type = hw->fc.type;
 
-	if (netif_running(adapter->netdev)) {
-		ixgbe_down(adapter);
-		ixgbe_up(adapter);
-	} else {
+	if (netif_running(netdev))
+		ixgbe_reinit_locked(adapter);
+	else
 		ixgbe_reset(adapter);
-	}
 
 	return 0;
 }
@@ -203,12 +221,10 @@ static int ixgbe_set_rx_csum(struct net_device *netdev, u32 data)
 	else
 		adapter->flags &= ~IXGBE_FLAG_RX_CSUM_ENABLED;
 
-	if (netif_running(netdev)) {
-		ixgbe_down(adapter);
-		ixgbe_up(adapter);
-	} else {
+	if (netif_running(netdev))
+		ixgbe_reinit_locked(adapter);
+	else
 		ixgbe_reset(adapter);
-	}
 
 	return 0;
 }
@@ -662,7 +678,10 @@ static int ixgbe_set_ringparam(struct net_device *netdev,
 		return 0;
 	}
 
-	if (netif_running(adapter->netdev))
+	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
+		msleep(1);
+
+	if (netif_running(netdev))
 		ixgbe_down(adapter);
 
 	/*
@@ -733,6 +752,7 @@ err_setup:
 	if (netif_running(adapter->netdev))
 		ixgbe_up(adapter);
 
+	clear_bit(__IXGBE_RESETTING, &adapter->state);
 	return err;
 }
 
@@ -820,11 +840,8 @@ static int ixgbe_nway_reset(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
-	if (netif_running(netdev)) {
-		ixgbe_down(adapter);
-		ixgbe_reset(adapter);
-		ixgbe_up(adapter);
-	}
+	if (netif_running(netdev))
+		ixgbe_reinit_locked(adapter);
 
 	return 0;
 }
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 3732dd6..ead49e5 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -87,6 +87,25 @@ MODULE_VERSION(DRV_VERSION);
 
 #define DEFAULT_DEBUG_LEVEL_SHIFT 3
 
+static void ixgbe_release_hw_control(struct ixgbe_adapter *adapter)
+{
+	u32 ctrl_ext;
+
+	/* Let firmware take over control of h/w */
+	ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
+			ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
+}
+
+static void ixgbe_get_hw_control(struct ixgbe_adapter *adapter)
+{
+	u32 ctrl_ext;
+
+	/* Let firmware know the driver has taken over */
+	ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
+			ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
+}
 
 #ifdef DEBUG
 /**
@@ -165,6 +184,15 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
 	return false;
 }
 
+#define IXGBE_MAX_TXD_PWR	14
+#define IXGBE_MAX_DATA_PER_TXD	(1 << IXGBE_MAX_TXD_PWR)
+
+/* Tx Descriptors needed, worst case */
+#define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \
+			 (((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
+#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
+	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1)	/* for context */
+
 /**
  * ixgbe_clean_tx_irq - Reclaim resources after transmit completes
  * @adapter: board private structure
@@ -177,18 +205,34 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
 	struct ixgbe_tx_buffer *tx_buffer_info;
 	unsigned int i, eop;
 	bool cleaned = false;
-	int count = 0;
+	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
 
 	i = tx_ring->next_to_clean;
 	eop = tx_ring->tx_buffer_info[i].next_to_watch;
 	eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
 	while (eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) {
-		for (cleaned = false; !cleaned;) {
+		cleaned = false;
+		while (!cleaned) {
 			tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
 			tx_buffer_info = &tx_ring->tx_buffer_info[i];
 			cleaned = (i == eop);
 
 			tx_ring->stats.bytes += tx_buffer_info->length;
+			if (cleaned) {
+				struct sk_buff *skb = tx_buffer_info->skb;
+#ifdef NETIF_F_TSO
+				unsigned int segs, bytecount;
+				segs = skb_shinfo(skb)->gso_segs ?: 1;
+				/* multiply data chunks by size of headers */
+				bytecount = ((segs - 1) * skb_headlen(skb)) +
+					    skb->len;
+				total_tx_packets += segs;
+				total_tx_bytes += bytecount;
+#else
+				total_tx_packets++;
+				total_tx_bytes += skb->len;
+#endif
+			}
 			ixgbe_unmap_and_free_tx_resource(adapter,
 							 tx_buffer_info);
 			tx_desc->wb.status = 0;
@@ -204,29 +248,36 @@ static bool ixgbe_clean_tx_irq(struct ixgbe_adapter *adapter,
 		eop_desc = IXGBE_TX_DESC_ADV(*tx_ring, eop);
 
 		/* weight of a sort for tx, avoid endless transmit cleanup */
-		if (count++ >= tx_ring->work_limit)
+		if (total_tx_packets >= tx_ring->work_limit)
 			break;
 	}
 
 	tx_ring->next_to_clean = i;
 
-#define TX_WAKE_THRESHOLD 32
-	spin_lock(&tx_ring->tx_lock);
-
-	if (cleaned && netif_carrier_ok(netdev) &&
-	    (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD) &&
-	    !test_bit(__IXGBE_DOWN, &adapter->state))
-		netif_wake_queue(netdev);
-
-	spin_unlock(&tx_ring->tx_lock);
+#define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
+	if (total_tx_packets && netif_carrier_ok(netdev) &&
+	    (IXGBE_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) {
+		/* Make sure that anybody stopping the queue after this
+		 * sees the new next_to_clean.
+		 */
+		smp_mb();
+		if (netif_queue_stopped(netdev) &&
+		    !test_bit(__IXGBE_DOWN, &adapter->state)) {
+			netif_wake_queue(netdev);
+			adapter->restart_queue++;
+		}
+	}
 
 	if (adapter->detect_tx_hung)
 		if (ixgbe_check_tx_hang(adapter, tx_ring, eop, eop_desc))
 			netif_stop_queue(netdev);
 
-	if (count >= tx_ring->work_limit)
+	if (total_tx_packets >= tx_ring->work_limit)
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EICS, tx_ring->eims_value);
 
+	adapter->net_stats.tx_bytes += total_tx_bytes;
+	adapter->net_stats.tx_packets += total_tx_packets;
+	cleaned = total_tx_packets ? true : false;
 	return cleaned;
 }
 
@@ -255,25 +306,40 @@ static void ixgbe_receive_skb(struct ixgbe_adapter *adapter,
 	}
 }
 
+/**
+ * ixgbe_rx_checksum - indicate in skb if hw indicated a good cksum
+ * @adapter: address of board private structure
+ * @status_err: hardware indication of status of receive
+ * @skb: skb currently being received and modified
+ **/
 static inline void ixgbe_rx_checksum(struct ixgbe_adapter *adapter,
 					 u32 status_err,
 					 struct sk_buff *skb)
 {
 	skb->ip_summed = CHECKSUM_NONE;
 
-	/* Ignore Checksum bit is set */
+	/* Ignore Checksum bit is set, or rx csum disabled */
 	if ((status_err & IXGBE_RXD_STAT_IXSM) ||
-		     !(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
+	    !(adapter->flags & IXGBE_FLAG_RX_CSUM_ENABLED))
 		return;
-	/* TCP/UDP checksum error bit is set */
-	if (status_err & (IXGBE_RXDADV_ERR_TCPE | IXGBE_RXDADV_ERR_IPE)) {
-		/* let the stack verify checksum errors */
+
+	/* if IP and error */
+	if ((status_err & IXGBE_RXD_STAT_IPCS) &&
+	    (status_err & IXGBE_RXDADV_ERR_IPE)) {
 		adapter->hw_csum_rx_error++;
 		return;
 	}
+
+	if (!(status_err & IXGBE_RXD_STAT_L4CS))
+		return;
+
+	if (status_err & IXGBE_RXDADV_ERR_TCPE) {
+		adapter->hw_csum_rx_error++;
+		return;
+	}
+
 	/* It must be a TCP or UDP packet with a valid checksum */
-	if (status_err & (IXGBE_RXD_STAT_L4CS | IXGBE_RXD_STAT_UDPCS))
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
+	skb->ip_summed = CHECKSUM_UNNECESSARY;
 	adapter->hw_csum_rx_good++;
 }
 
@@ -379,6 +445,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
 	u16 hdr_info, vlan_tag;
 	bool is_vlan, cleaned = false;
 	int cleaned_count = 0;
+	unsigned int total_rx_bytes = 0, total_rx_packets = 0;
 
 	i = rx_ring->next_to_clean;
 	upper_len = 0;
@@ -458,6 +525,11 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_adapter *adapter,
 		}
 
 		ixgbe_rx_checksum(adapter, staterr, skb);
+
+		/* probably a little skewed due to removing CRC */
+		total_rx_bytes += skb->len;
+		total_rx_packets++;
+
 		skb->protocol = eth_type_trans(skb, netdev);
 		ixgbe_receive_skb(adapter, skb, is_vlan, vlan_tag);
 		netdev->last_rx = jiffies;
@@ -486,6 +558,9 @@ next_desc:
 	if (cleaned_count)
 		ixgbe_alloc_rx_buffers(adapter, rx_ring, cleaned_count);
 
+	adapter->net_stats.rx_bytes += total_rx_bytes;
+	adapter->net_stats.rx_packets += total_rx_packets;
+
 	return cleaned;
 }
 
@@ -535,7 +610,9 @@ static irqreturn_t ixgbe_msix_lsc(int irq, void *data)
 		if (!test_bit(__IXGBE_DOWN, &adapter->state))
 			mod_timer(&adapter->watchdog_timer, jiffies);
 	}
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
+
+	if (!test_bit(__IXGBE_DOWN, &adapter->state))
+		IXGBE_WRITE_REG(hw, IXGBE_EIMS, IXGBE_EIMS_OTHER);
 
 	return IRQ_HANDLED;
 }
@@ -713,7 +790,6 @@ static irqreturn_t ixgbe_intr(int irq, void *data)
 	if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
 		/* Disable interrupts and register for poll. The flush of the
 		 * posted write is intentionally left out. */
-		atomic_inc(&adapter->irq_sem);
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
 		__netif_rx_schedule(netdev, &adapter->napi);
 	}
@@ -801,7 +877,6 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
  **/
 static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
 {
-	atomic_inc(&adapter->irq_sem);
 	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMC, ~0);
 	IXGBE_WRITE_FLUSH(&adapter->hw);
 	synchronize_irq(adapter->pdev->irq);
@@ -813,15 +888,13 @@ static inline void ixgbe_irq_disable(struct ixgbe_adapter *adapter)
  **/
 static inline void ixgbe_irq_enable(struct ixgbe_adapter *adapter)
 {
-	if (atomic_dec_and_test(&adapter->irq_sem)) {
-		if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
-			IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC,
-					(IXGBE_EIMS_ENABLE_MASK &
-					 ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC)));
-		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS,
-				IXGBE_EIMS_ENABLE_MASK);
-		IXGBE_WRITE_FLUSH(&adapter->hw);
-	}
+	if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED)
+		IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIAC,
+				(IXGBE_EIMS_ENABLE_MASK &
+				 ~(IXGBE_EIMS_OTHER | IXGBE_EIMS_LSC)));
+	IXGBE_WRITE_REG(&adapter->hw, IXGBE_EIMS,
+			IXGBE_EIMS_ENABLE_MASK);
+	IXGBE_WRITE_FLUSH(&adapter->hw);
 }
 
 /**
@@ -1040,7 +1113,8 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	u32 ctrl;
 
-	ixgbe_irq_disable(adapter);
+	if (!test_bit(__IXGBE_DOWN, &adapter->state))
+		ixgbe_irq_disable(adapter);
 	adapter->vlgrp = grp;
 
 	if (grp) {
@@ -1051,7 +1125,8 @@ static void ixgbe_vlan_rx_register(struct net_device *netdev,
 		IXGBE_WRITE_REG(&adapter->hw, IXGBE_VLNCTRL, ctrl);
 	}
 
-	ixgbe_irq_enable(adapter);
+	if (!test_bit(__IXGBE_DOWN, &adapter->state))
+		ixgbe_irq_enable(adapter);
 }
 
 static void ixgbe_vlan_rx_add_vid(struct net_device *netdev, u16 vid)
@@ -1066,9 +1141,13 @@ static void ixgbe_vlan_rx_kill_vid(struct net_device *netdev, u16 vid)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 
-	ixgbe_irq_disable(adapter);
+	if (!test_bit(__IXGBE_DOWN, &adapter->state))
+		ixgbe_irq_disable(adapter);
+
 	vlan_group_set_device(adapter->vlgrp, vid, NULL);
-	ixgbe_irq_enable(adapter);
+
+	if (!test_bit(__IXGBE_DOWN, &adapter->state))
+		ixgbe_irq_enable(adapter);
 
 	/* remove VID from filter table */
 	ixgbe_set_vfta(&adapter->hw, vid, 0, false);
@@ -1170,6 +1249,8 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
 	u32 txdctl, rxdctl, mhadd;
 	int max_frame = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
 
+	ixgbe_get_hw_control(adapter);
+
 	if (adapter->flags & (IXGBE_FLAG_MSIX_ENABLED |
 			      IXGBE_FLAG_MSI_ENABLED)) {
 		if (adapter->flags & IXGBE_FLAG_MSIX_ENABLED) {
@@ -1224,6 +1305,16 @@ static int ixgbe_up_complete(struct ixgbe_adapter *adapter)
 	return 0;
 }
 
+void ixgbe_reinit_locked(struct ixgbe_adapter *adapter)
+{
+	WARN_ON(in_interrupt());
+	while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
+		msleep(1);
+	ixgbe_down(adapter);
+	ixgbe_up(adapter);
+	clear_bit(__IXGBE_RESETTING, &adapter->state);
+}
+
 int ixgbe_up(struct ixgbe_adapter *adapter)
 {
 	/* hardware has been reset, we need to reload some things */
@@ -1408,7 +1499,6 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
 	msleep(10);
 
 	napi_disable(&adapter->napi);
-	atomic_set(&adapter->irq_sem, 0);
 
 	ixgbe_irq_disable(adapter);
 
@@ -1447,6 +1537,8 @@ static int ixgbe_suspend(struct pci_dev *pdev, pm_message_t state)
 	pci_enable_wake(pdev, PCI_D3hot, 0);
 	pci_enable_wake(pdev, PCI_D3cold, 0);
 
+	ixgbe_release_hw_control(adapter);
+
 	pci_disable_device(pdev);
 
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
@@ -1481,7 +1573,8 @@ static int ixgbe_clean(struct napi_struct *napi, int budget)
 	/* If budget not fully consumed, exit the polling mode */
 	if (work_done < budget) {
 		netif_rx_complete(netdev, napi);
-		ixgbe_irq_enable(adapter);
+		if (!test_bit(__IXGBE_DOWN, &adapter->state))
+			ixgbe_irq_enable(adapter);
 	}
 
 	return work_done;
@@ -1506,8 +1599,7 @@ static void ixgbe_reset_task(struct work_struct *work)
 
 	adapter->tx_timeout_count++;
 
-	ixgbe_down(adapter);
-	ixgbe_up(adapter);
+	ixgbe_reinit_locked(adapter);
 }
 
 /**
@@ -1590,7 +1682,6 @@ static int __devinit ixgbe_sw_init(struct ixgbe_adapter *adapter)
 		return -ENOMEM;
 	}
 
-	atomic_set(&adapter->irq_sem, 1);
 	set_bit(__IXGBE_DOWN, &adapter->state);
 
 	return 0;
@@ -1634,7 +1725,6 @@ int ixgbe_setup_tx_resources(struct ixgbe_adapter *adapter,
 	txdr->next_to_use = 0;
 	txdr->next_to_clean = 0;
 	txdr->work_limit = txdr->count;
-	spin_lock_init(&txdr->tx_lock);
 
 	return 0;
 }
@@ -1828,10 +1918,8 @@ static int ixgbe_change_mtu(struct net_device *netdev, int new_mtu)
 
 	netdev->mtu = new_mtu;
 
-	if (netif_running(netdev)) {
-		ixgbe_down(adapter);
-		ixgbe_up(adapter);
-	}
+	if (netif_running(netdev))
+		ixgbe_reinit_locked(adapter);
 
 	return 0;
 }
@@ -1852,14 +1940,8 @@ static int ixgbe_open(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
 	int err;
-	u32 ctrl_ext;
 	u32 num_rx_queues = adapter->num_rx_queues;
 
-	/* Let firmware know the driver has taken over */
-	ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
-			ctrl_ext | IXGBE_CTRL_EXT_DRV_LOAD);
-
 try_intr_reinit:
 	/* allocate transmit descriptors */
 	err = ixgbe_setup_all_tx_resources(adapter);
@@ -1910,6 +1992,7 @@ try_intr_reinit:
 	return 0;
 
 err_up:
+	ixgbe_release_hw_control(adapter);
 	ixgbe_free_irq(adapter);
 err_req_irq:
 	ixgbe_free_all_rx_resources(adapter);
@@ -1935,7 +2018,6 @@ err_setup_tx:
 static int ixgbe_close(struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
-	u32 ctrl_ext;
 
 	ixgbe_down(adapter);
 	ixgbe_free_irq(adapter);
@@ -1943,9 +2025,7 @@ static int ixgbe_close(struct net_device *netdev)
 	ixgbe_free_all_tx_resources(adapter);
 	ixgbe_free_all_rx_resources(adapter);
 
-	ctrl_ext = IXGBE_READ_REG(&adapter->hw, IXGBE_CTRL_EXT);
-	IXGBE_WRITE_REG(&adapter->hw, IXGBE_CTRL_EXT,
-			ctrl_ext & ~IXGBE_CTRL_EXT_DRV_LOAD);
+	ixgbe_release_hw_control(adapter);
 
 	return 0;
 }
@@ -1957,22 +2037,26 @@ static int ixgbe_close(struct net_device *netdev)
 void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
-	u64 good_rx, missed_rx, bprc;
+	u64 total_mpc = 0;
+	u32 i, missed_rx = 0, mpc, bprc, lxon, lxoff, xon_off_tot;
 
 	adapter->stats.crcerrs += IXGBE_READ_REG(hw, IXGBE_CRCERRS);
-	good_rx = IXGBE_READ_REG(hw, IXGBE_GPRC);
-	missed_rx = IXGBE_READ_REG(hw, IXGBE_MPC(0));
-	missed_rx += IXGBE_READ_REG(hw, IXGBE_MPC(1));
-	missed_rx += IXGBE_READ_REG(hw, IXGBE_MPC(2));
-	missed_rx += IXGBE_READ_REG(hw, IXGBE_MPC(3));
-	missed_rx += IXGBE_READ_REG(hw, IXGBE_MPC(4));
-	missed_rx += IXGBE_READ_REG(hw, IXGBE_MPC(5));
-	missed_rx += IXGBE_READ_REG(hw, IXGBE_MPC(6));
-	missed_rx += IXGBE_READ_REG(hw, IXGBE_MPC(7));
-	adapter->stats.gprc += (good_rx - missed_rx);
-
-	adapter->stats.mpc[0] += missed_rx;
+	for (i = 0; i < 8; i++) {
+		/* for packet buffers not used, the register should read 0 */
+		mpc = IXGBE_READ_REG(hw, IXGBE_MPC(i));
+		missed_rx += mpc;
+		adapter->stats.mpc[i] += mpc;
+		total_mpc += adapter->stats.mpc[i];
+		adapter->stats.rnbc[i] += IXGBE_READ_REG(hw, IXGBE_RNBC(i));
+	}
+	adapter->stats.gprc += IXGBE_READ_REG(hw, IXGBE_GPRC);
+	/* work around hardware counting issue */
+	adapter->stats.gprc -= missed_rx;
+
+	/* 82598 hardware only has a 32 bit counter in the high register */
 	adapter->stats.gorc += IXGBE_READ_REG(hw, IXGBE_GORCH);
+	adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
+	adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH);
 	bprc = IXGBE_READ_REG(hw, IXGBE_BPRC);
 	adapter->stats.bprc += bprc;
 	adapter->stats.mprc += IXGBE_READ_REG(hw, IXGBE_MPRC);
@@ -1984,35 +2068,37 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 	adapter->stats.prc511 += IXGBE_READ_REG(hw, IXGBE_PRC511);
 	adapter->stats.prc1023 += IXGBE_READ_REG(hw, IXGBE_PRC1023);
 	adapter->stats.prc1522 += IXGBE_READ_REG(hw, IXGBE_PRC1522);
-
 	adapter->stats.rlec += IXGBE_READ_REG(hw, IXGBE_RLEC);
 	adapter->stats.lxonrxc += IXGBE_READ_REG(hw, IXGBE_LXONRXC);
-	adapter->stats.lxontxc += IXGBE_READ_REG(hw, IXGBE_LXONTXC);
 	adapter->stats.lxoffrxc += IXGBE_READ_REG(hw, IXGBE_LXOFFRXC);
-	adapter->stats.lxofftxc += IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
+	lxon = IXGBE_READ_REG(hw, IXGBE_LXONTXC);
+	adapter->stats.lxontxc += lxon;
+	lxoff = IXGBE_READ_REG(hw, IXGBE_LXOFFTXC);
+	adapter->stats.lxofftxc += lxoff;
 	adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
 	adapter->stats.gptc += IXGBE_READ_REG(hw, IXGBE_GPTC);
-	adapter->stats.gotc += IXGBE_READ_REG(hw, IXGBE_GOTCH);
-	adapter->stats.rnbc[0] += IXGBE_READ_REG(hw, IXGBE_RNBC(0));
+	adapter->stats.mptc += IXGBE_READ_REG(hw, IXGBE_MPTC);
+	/*
+	 * 82598 errata - tx of flow control packets is included in tx counters
+	 */
+	xon_off_tot = lxon + lxoff;
+	adapter->stats.gptc -= xon_off_tot;
+	adapter->stats.mptc -= xon_off_tot;
+	adapter->stats.gotc -= (xon_off_tot * (ETH_ZLEN + ETH_FCS_LEN));
 	adapter->stats.ruc += IXGBE_READ_REG(hw, IXGBE_RUC);
 	adapter->stats.rfc += IXGBE_READ_REG(hw, IXGBE_RFC);
 	adapter->stats.rjc += IXGBE_READ_REG(hw, IXGBE_RJC);
-	adapter->stats.tor += IXGBE_READ_REG(hw, IXGBE_TORH);
 	adapter->stats.tpr += IXGBE_READ_REG(hw, IXGBE_TPR);
 	adapter->stats.ptc64 += IXGBE_READ_REG(hw, IXGBE_PTC64);
+	adapter->stats.ptc64 -= xon_off_tot;
 	adapter->stats.ptc127 += IXGBE_READ_REG(hw, IXGBE_PTC127);
 	adapter->stats.ptc255 += IXGBE_READ_REG(hw, IXGBE_PTC255);
 	adapter->stats.ptc511 += IXGBE_READ_REG(hw, IXGBE_PTC511);
 	adapter->stats.ptc1023 += IXGBE_READ_REG(hw, IXGBE_PTC1023);
 	adapter->stats.ptc1522 += IXGBE_READ_REG(hw, IXGBE_PTC1522);
-	adapter->stats.mptc += IXGBE_READ_REG(hw, IXGBE_MPTC);
 	adapter->stats.bptc += IXGBE_READ_REG(hw, IXGBE_BPTC);
 
 	/* Fill out the OS statistics structure */
-	adapter->net_stats.rx_packets = adapter->stats.gprc;
-	adapter->net_stats.tx_packets = adapter->stats.gptc;
-	adapter->net_stats.rx_bytes = adapter->stats.gorc;
-	adapter->net_stats.tx_bytes = adapter->stats.gotc;
 	adapter->net_stats.multicast = adapter->stats.mprc;
 
 	/* Rx Errors */
@@ -2021,8 +2107,7 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter)
 	adapter->net_stats.rx_dropped = 0;
 	adapter->net_stats.rx_length_errors = adapter->stats.rlec;
 	adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs;
-	adapter->net_stats.rx_missed_errors = adapter->stats.mpc[0];
-
+	adapter->net_stats.rx_missed_errors = total_mpc;
 }
 
 /**
@@ -2076,15 +2161,6 @@ static void ixgbe_watchdog(unsigned long data)
 			  round_jiffies(jiffies + 2 * HZ));
 }
 
-#define IXGBE_MAX_TXD_PWR	14
-#define IXGBE_MAX_DATA_PER_TXD	(1 << IXGBE_MAX_TXD_PWR)
-
-/* Tx Descriptors needed, worst case */
-#define TXD_USE_COUNT(S) (((S) >> IXGBE_MAX_TXD_PWR) + \
-			 (((S) & (IXGBE_MAX_DATA_PER_TXD - 1)) ? 1 : 0))
-#define DESC_NEEDED (TXD_USE_COUNT(IXGBE_MAX_DATA_PER_TXD) /* skb->data */ + \
-	MAX_SKB_FRAGS * TXD_USE_COUNT(PAGE_SIZE) + 1)	/* for context */
-
 static int ixgbe_tso(struct ixgbe_adapter *adapter,
 			 struct ixgbe_ring *tx_ring, struct sk_buff *skb,
 			 u32 tx_flags, u8 *hdr_len)
@@ -2356,6 +2432,37 @@ static void ixgbe_tx_queue(struct ixgbe_adapter *adapter,
 	writel(i, adapter->hw.hw_addr + tx_ring->tail);
 }
 
+static int __ixgbe_maybe_stop_tx(struct net_device *netdev,
+				 struct ixgbe_ring *tx_ring, int size)
+{
+	struct ixgbe_adapter *adapter = netdev_priv(netdev);
+
+	netif_stop_queue(netdev);
+	/* Herbert's original patch had:
+	 *  smp_mb__after_netif_stop_queue();
+	 * but since that doesn't exist yet, just open code it. */
+	smp_mb();
+
+	/* We need to check again in a case another CPU has just
+	 * made room available. */
+	if (likely(IXGBE_DESC_UNUSED(tx_ring) < size))
+		return -EBUSY;
+
+	/* A reprieve! - use start_queue because it doesn't call schedule */
+	netif_wake_queue(netdev);
+	++adapter->restart_queue;
+	return 0;
+}
+
+static int ixgbe_maybe_stop_tx(struct net_device *netdev,
+			       struct ixgbe_ring *tx_ring, int size)
+{
+	if (likely(IXGBE_DESC_UNUSED(tx_ring) >= size))
+		return 0;
+	return __ixgbe_maybe_stop_tx(netdev, tx_ring, size);
+}
+
+
 static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -2363,7 +2470,6 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	unsigned int len = skb->len;
 	unsigned int first;
 	unsigned int tx_flags = 0;
-	unsigned long flags = 0;
 	u8 hdr_len;
 	int tso;
 	unsigned int mss = 0;
@@ -2389,14 +2495,10 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	for (f = 0; f < nr_frags; f++)
 		count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
 
-	spin_lock_irqsave(&tx_ring->tx_lock, flags);
-	if (IXGBE_DESC_UNUSED(tx_ring) < (count + 2)) {
+	if (ixgbe_maybe_stop_tx(netdev, tx_ring, count)) {
 		adapter->tx_busy++;
-		netif_stop_queue(netdev);
-		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 		return NETDEV_TX_BUSY;
 	}
-	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 	if (adapter->vlgrp && vlan_tx_tag_present(skb)) {
 		tx_flags |= IXGBE_TX_FLAGS_VLAN;
 		tx_flags |= (vlan_tx_tag_get(skb) << IXGBE_TX_FLAGS_VLAN_SHIFT);
@@ -2423,11 +2525,7 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 
 	netdev->trans_start = jiffies;
 
-	spin_lock_irqsave(&tx_ring->tx_lock, flags);
-	/* Make sure there is space in the ring for the next send. */
-	if (IXGBE_DESC_UNUSED(tx_ring) < DESC_NEEDED)
-		netif_stop_queue(netdev);
-	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+	ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
 
 	return NETDEV_TX_OK;
 }
@@ -2697,6 +2795,7 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
 	return 0;
 
 err_register:
+	ixgbe_release_hw_control(adapter);
 err_hw_init:
 err_sw_init:
 err_eeprom:
@@ -2732,6 +2831,8 @@ static void __devexit ixgbe_remove(struct pci_dev *pdev)
 
 	unregister_netdev(netdev);
 
+	ixgbe_release_hw_control(adapter);
+
 	kfree(adapter->tx_ring);
 	kfree(adapter->rx_ring);
 
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 651c269..b528ce7 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1652,6 +1652,11 @@ static void eth_tx_fill_frag_descs(struct mv643xx_private *mp,
 	}
 }
 
+static inline __be16 sum16_as_be(__sum16 sum)
+{
+	return (__force __be16)sum;
+}
+
 /**
  * eth_tx_submit_descs_for_skb - submit data from an skb to the tx hw
  *
@@ -1689,7 +1694,7 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
 	desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
 
 	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		BUG_ON(skb->protocol != ETH_P_IP);
+		BUG_ON(skb->protocol != htons(ETH_P_IP));
 
 		cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM |
 			   ETH_GEN_IP_V_4_CHECKSUM  |
@@ -1698,10 +1703,10 @@ static void eth_tx_submit_descs_for_skb(struct mv643xx_private *mp,
 		switch (ip_hdr(skb)->protocol) {
 		case IPPROTO_UDP:
 			cmd_sts |= ETH_UDP_FRAME;
-			desc->l4i_chk = udp_hdr(skb)->check;
+			desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));
 			break;
 		case IPPROTO_TCP:
-			desc->l4i_chk = tcp_hdr(skb)->check;
+			desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));
 			break;
 		default:
 			BUG();
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index dc06236..9a62959 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -857,7 +857,7 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port)
 	sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
 
 	/* On chips without ram buffer, pause is controled by MAC level */
-	if (sky2_read8(hw, B2_E_0) == 0) {
+	if (!(hw->flags & SKY2_HW_RAM_BUFFER)) {
 		sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
 		sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
 
@@ -1194,7 +1194,7 @@ static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2)
 	struct sk_buff *skb;
 	int i;
 
-	if (sky2->hw->flags & SKY2_HW_FIFO_HANG_CHECK) {
+	if (sky2->hw->flags & SKY2_HW_RAM_BUFFER) {
 		unsigned char *start;
 		/*
 		 * Workaround for a bug in FIFO that cause hang
@@ -1387,6 +1387,7 @@ static int sky2_up(struct net_device *dev)
 	if (ramsize > 0) {
 		u32 rxspace;
 
+		hw->flags |= SKY2_HW_RAM_BUFFER;
 		pr_debug(PFX "%s: ram buffer %dK\n", dev->name, ramsize);
 		if (ramsize < 16)
 			rxspace = ramsize / 2;
@@ -2026,7 +2027,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu)
 
 	synchronize_irq(hw->pdev->irq);
 
-	if (sky2_read8(hw, B2_E_0) == 0)
+	if (!(hw->flags & SKY2_HW_RAM_BUFFER))
 		sky2_set_tx_stfwd(hw, port);
 
 	ctl = gma_read16(hw, port, GM_GP_CTRL);
@@ -2566,7 +2567,7 @@ static void sky2_watchdog(unsigned long arg)
 			++active;
 
 			/* For chips with Rx FIFO, check if stuck */
-			if ((hw->flags & SKY2_HW_FIFO_HANG_CHECK) &&
+			if ((hw->flags & SKY2_HW_RAM_BUFFER) &&
 			     sky2_rx_hung(dev)) {
 				pr_info(PFX "%s: receiver hang detected\n",
 					dev->name);
@@ -2722,11 +2723,7 @@ static int __devinit sky2_init(struct sky2_hw *hw)
 
 	switch(hw->chip_id) {
 	case CHIP_ID_YUKON_XL:
-		hw->flags = SKY2_HW_GIGABIT
-			| SKY2_HW_NEWER_PHY;
-		if (hw->chip_rev < 3)
-			hw->flags |= SKY2_HW_FIFO_HANG_CHECK;
-
+		hw->flags = SKY2_HW_GIGABIT | SKY2_HW_NEWER_PHY;
 		break;
 
 	case CHIP_ID_YUKON_EC_U:
@@ -2752,7 +2749,7 @@ static int __devinit sky2_init(struct sky2_hw *hw)
 			dev_err(&hw->pdev->dev, "unsupported revision Yukon-EC rev A1\n");
 			return -EOPNOTSUPP;
 		}
-		hw->flags = SKY2_HW_GIGABIT | SKY2_HW_FIFO_HANG_CHECK;
+		hw->flags = SKY2_HW_GIGABIT;
 		break;
 
 	case CHIP_ID_YUKON_FE:
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 2bced1a..5ab5c1c 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -2045,7 +2045,7 @@ struct sky2_hw {
 #define SKY2_HW_FIBRE_PHY	0x00000002
 #define SKY2_HW_GIGABIT		0x00000004
 #define SKY2_HW_NEWER_PHY	0x00000008
-#define SKY2_HW_FIFO_HANG_CHECK	0x00000010
+#define SKY2_HW_RAM_BUFFER	0x00000010
 #define SKY2_HW_NEW_LE		0x00000020	/* new LSOv2 format */
 #define SKY2_HW_AUTO_TX_SUM	0x00000040	/* new IP decode for Tx */
 #define SKY2_HW_ADV_POWER_CTL	0x00000080	/* additional PHY power regs */
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index c99ce74..3af5b92 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -465,7 +465,7 @@ static struct pci_driver tlan_driver = {
 
 static int __init tlan_probe(void)
 {
-	static int	pad_allocated;
+	int rc = -ENODEV;
 
 	printk(KERN_INFO "%s", tlan_banner);
 
@@ -473,17 +473,22 @@ static int __init tlan_probe(void)
 
 	if (TLanPadBuffer == NULL) {
 		printk(KERN_ERR "TLAN: Could not allocate memory for pad buffer.\n");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto err_out;
 	}
 
 	memset(TLanPadBuffer, 0, TLAN_MIN_FRAME_SIZE);
-	pad_allocated = 1;
 
 	TLAN_DBG(TLAN_DEBUG_PROBE, "Starting PCI Probe....\n");
 
 	/* Use new style PCI probing. Now the kernel will
 	   do most of this for us */
-	pci_register_driver(&tlan_driver);
+	rc = pci_register_driver(&tlan_driver);
+
+	if (rc != 0) {
+		printk(KERN_ERR "TLAN: Could not register pci driver.\n");
+		goto err_out_pci_free;
+	}
 
 	TLAN_DBG(TLAN_DEBUG_PROBE, "Starting EISA Probe....\n");
 	TLan_EisaProbe();
@@ -493,11 +498,17 @@ static int __init tlan_probe(void)
 		 tlan_have_pci, tlan_have_eisa);
 
 	if (TLanDevicesInstalled == 0) {
-		pci_unregister_driver(&tlan_driver);
-		pci_free_consistent(NULL, TLAN_MIN_FRAME_SIZE, TLanPadBuffer, TLanPadBufferDMA);
-		return -ENODEV;
+		rc = -ENODEV;
+		goto  err_out_pci_unreg;
 	}
 	return 0;
+
+err_out_pci_unreg:
+	pci_unregister_driver(&tlan_driver);
+err_out_pci_free:
+	pci_free_consistent(NULL, TLAN_MIN_FRAME_SIZE, TLanPadBuffer, TLanPadBufferDMA);
+err_out:
+	return rc;
 }
 
 
diff --git a/drivers/net/tulip/xircom_cb.c b/drivers/net/tulip/xircom_cb.c
index 8fc7274..6b93d01 100644
--- a/drivers/net/tulip/xircom_cb.c
+++ b/drivers/net/tulip/xircom_cb.c
@@ -441,7 +441,7 @@ static int xircom_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	spin_unlock_irqrestore(&card->lock,flags);
 	trigger_transmit(card);
 
-	return -EIO;
+	return NETDEV_TX_BUSY;
 }
 
 
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index e3ba14a..c69e654 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -109,7 +109,7 @@ int uec_mdio_reset(struct mii_bus *bus)
 	struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
 	unsigned int timeout = PHY_INIT_TIMEOUT;
 
-	spin_lock_bh(&bus->mdio_lock);
+	mutex_lock(&bus->mdio_lock);
 
 	/* Reset the management interface */
 	out_be32(&regs->miimcfg, MIIMCFG_RESET_MANAGEMENT);
@@ -121,7 +121,7 @@ int uec_mdio_reset(struct mii_bus *bus)
 	while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--)
 		cpu_relax();
 
-	spin_unlock_bh(&bus->mdio_lock);
+	mutex_unlock(&bus->mdio_lock);
 
 	if (timeout <= 0) {
 		printk(KERN_ERR "%s: The MII Bus is stuck!\n", bus->name);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index e66de0c..fdc2367 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -302,10 +302,12 @@ static int virtnet_open(struct net_device *dev)
 
 	/* If all buffers were filled by other side before we napi_enabled, we
 	 * won't get another interrupt, so process any outstanding packets
-	 * now.  virtnet_poll wants re-enable the queue, so we disable here. */
-	vi->rvq->vq_ops->disable_cb(vi->rvq);
-	netif_rx_schedule(vi->dev, &vi->napi);
-
+	 * now.  virtnet_poll wants re-enable the queue, so we disable here.
+	 * We synchronize against interrupts via NAPI_STATE_SCHED */
+	if (netif_rx_schedule_prep(dev, &vi->napi)) {
+		vi->rvq->vq_ops->disable_cb(vi->rvq);
+		__netif_rx_schedule(dev, &vi->napi);
+	}
 	return 0;
 }
 
diff --git a/drivers/net/wan/hdlc.c b/drivers/net/wan/hdlc.c
index d553e6f..39951d0 100644
--- a/drivers/net/wan/hdlc.c
+++ b/drivers/net/wan/hdlc.c
@@ -1,7 +1,7 @@
 /*
  * Generic HDLC support routines for Linux
  *
- * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
+ * Copyright (C) 1999 - 2008 Krzysztof Halasa <khc@pm.waw.pl>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -39,7 +39,7 @@
 #include <net/net_namespace.h>
 
 
-static const char* version = "HDLC support module revision 1.21";
+static const char* version = "HDLC support module revision 1.22";
 
 #undef DEBUG_LINK
 
@@ -66,19 +66,15 @@ static struct net_device_stats *hdlc_get_stats(struct net_device *dev)
 static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
 		    struct packet_type *p, struct net_device *orig_dev)
 {
-	struct hdlc_device_desc *desc = dev_to_desc(dev);
+	struct hdlc_device *hdlc = dev_to_hdlc(dev);
 
 	if (dev->nd_net != &init_net) {
 		kfree_skb(skb);
 		return 0;
 	}
 
-	if (desc->netif_rx)
-		return desc->netif_rx(skb);
-
-	desc->stats.rx_dropped++; /* Shouldn't happen */
-	dev_kfree_skb(skb);
-	return NET_RX_DROP;
+	BUG_ON(!hdlc->proto->netif_rx);
+	return hdlc->proto->netif_rx(skb);
 }
 
 
@@ -87,7 +83,7 @@ static inline void hdlc_proto_start(struct net_device *dev)
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	if (hdlc->proto->start)
-		return hdlc->proto->start(dev);
+		hdlc->proto->start(dev);
 }
 
 
@@ -96,7 +92,7 @@ static inline void hdlc_proto_stop(struct net_device *dev)
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	if (hdlc->proto->stop)
-		return hdlc->proto->stop(dev);
+		hdlc->proto->stop(dev);
 }
 
 
@@ -263,8 +259,7 @@ static void hdlc_setup(struct net_device *dev)
 struct net_device *alloc_hdlcdev(void *priv)
 {
 	struct net_device *dev;
-	dev = alloc_netdev(sizeof(struct hdlc_device_desc) +
-			   sizeof(hdlc_device), "hdlc%d", hdlc_setup);
+	dev = alloc_netdev(sizeof(struct hdlc_device), "hdlc%d", hdlc_setup);
 	if (dev)
 		dev_to_hdlc(dev)->priv = priv;
 	return dev;
@@ -281,7 +276,7 @@ void unregister_hdlc_device(struct net_device *dev)
 
 
 int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
-			 int (*rx)(struct sk_buff *skb), size_t size)
+			 size_t size)
 {
 	detach_hdlc_protocol(dev);
 
@@ -297,7 +292,6 @@ int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
 			return -ENOBUFS;
 		}
 	dev_to_hdlc(dev)->proto = proto;
-	dev_to_desc(dev)->netif_rx = rx;
 	return 0;
 }
 
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index 038a6e7..7133c68 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -250,7 +250,7 @@ static int cisco_rx(struct sk_buff *skb)
 	return NET_RX_DROP;
 
  rx_error:
-	dev_to_desc(dev)->stats.rx_errors++; /* Mark error */
+	dev_to_hdlc(dev)->stats.rx_errors++; /* Mark error */
 	dev_kfree_skb_any(skb);
 	return NET_RX_DROP;
 }
@@ -314,6 +314,7 @@ static struct hdlc_proto proto = {
 	.stop		= cisco_stop,
 	.type_trans	= cisco_type_trans,
 	.ioctl		= cisco_ioctl,
+	.netif_rx	= cisco_rx,
 	.module		= THIS_MODULE,
 };
 
@@ -360,7 +361,7 @@ static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
 		if (result)
 			return result;
 
-		result = attach_hdlc_protocol(dev, &proto, cisco_rx,
+		result = attach_hdlc_protocol(dev, &proto,
 					      sizeof(struct cisco_state));
 		if (result)
 			return result;
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 071a64c..c4ab032 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -42,7 +42,6 @@
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/pkt_sched.h>
-#include <linux/random.h>
 #include <linux/inetdevice.h>
 #include <linux/lapb.h>
 #include <linux/rtnetlink.h>
@@ -136,6 +135,10 @@ typedef struct pvc_device_struct {
 	}state;
 }pvc_device;
 
+struct pvc_desc {
+	struct net_device_stats stats;
+	pvc_device *pvc;
+};
 
 struct frad_state {
 	fr_proto settings;
@@ -171,17 +174,20 @@ static inline void dlci_to_q922(u8 *hdr, u16 dlci)
 }
 
 
-static inline struct frad_state * state(hdlc_device *hdlc)
+static inline struct frad_state* state(hdlc_device *hdlc)
 {
 	return(struct frad_state *)(hdlc->state);
 }
 
-
-static __inline__ pvc_device* dev_to_pvc(struct net_device *dev)
+static inline struct pvc_desc* pvcdev_to_desc(struct net_device *dev)
 {
 	return dev->priv;
 }
 
+static inline struct net_device_stats* pvc_get_stats(struct net_device *dev)
+{
+	return &pvcdev_to_desc(dev)->stats;
+}
 
 static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci)
 {
@@ -351,7 +357,7 @@ static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
 
 static int pvc_open(struct net_device *dev)
 {
-	pvc_device *pvc = dev_to_pvc(dev);
+	pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
 
 	if ((pvc->frad->flags & IFF_UP) == 0)
 		return -EIO;  /* Frad must be UP in order to activate PVC */
@@ -371,7 +377,7 @@ static int pvc_open(struct net_device *dev)
 
 static int pvc_close(struct net_device *dev)
 {
-	pvc_device *pvc = dev_to_pvc(dev);
+	pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
 
 	if (--pvc->open_count == 0) {
 		hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
@@ -390,7 +396,7 @@ static int pvc_close(struct net_device *dev)
 
 static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
-	pvc_device *pvc = dev_to_pvc(dev);
+	pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
 	fr_proto_pvc_info info;
 
 	if (ifr->ifr_settings.type == IF_GET_PROTO) {
@@ -416,17 +422,9 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 	return -EINVAL;
 }
 
-
-static inline struct net_device_stats *pvc_get_stats(struct net_device *dev)
-{
-	return &dev_to_desc(dev)->stats;
-}
-
-
-
 static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	pvc_device *pvc = dev_to_pvc(dev);
+	pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
 	struct net_device_stats *stats = pvc_get_stats(dev);
 
 	if (pvc->state.active) {
@@ -957,7 +955,7 @@ static int fr_rx(struct sk_buff *skb)
 
 
 	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
-		dev_to_desc(frad)->stats.rx_dropped++;
+		dev_to_hdlc(frad)->stats.rx_dropped++;
 		return NET_RX_DROP;
 	}
 
@@ -1018,7 +1016,7 @@ static int fr_rx(struct sk_buff *skb)
 	}
 
  rx_error:
-	dev_to_desc(frad)->stats.rx_errors++; /* Mark error */
+	dev_to_hdlc(frad)->stats.rx_errors++; /* Mark error */
 	dev_kfree_skb_any(skb);
 	return NET_RX_DROP;
 }
@@ -1109,11 +1107,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
 	used = pvc_is_used(pvc);
 
 	if (type == ARPHRD_ETHER)
-		dev = alloc_netdev(sizeof(struct net_device_stats),
-				   "pvceth%d", ether_setup);
+		dev = alloc_netdev(sizeof(struct pvc_desc), "pvceth%d",
+				   ether_setup);
 	else
-		dev = alloc_netdev(sizeof(struct net_device_stats),
-				   "pvc%d", pvc_setup);
+		dev = alloc_netdev(sizeof(struct pvc_desc), "pvc%d", pvc_setup);
 
 	if (!dev) {
 		printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
@@ -1122,10 +1119,9 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
 		return -ENOBUFS;
 	}
 
-	if (type == ARPHRD_ETHER) {
-		memcpy(dev->dev_addr, "\x00\x01", 2);
-                get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2);
-	} else {
+	if (type == ARPHRD_ETHER)
+		random_ether_addr(dev->dev_addr);
+	else {
 		*(__be16*)dev->dev_addr = htons(dlci);
 		dlci_to_q922(dev->broadcast, dlci);
 	}
@@ -1137,7 +1133,7 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
 	dev->change_mtu = pvc_change_mtu;
 	dev->mtu = HDLC_MAX_MTU;
 	dev->tx_queue_len = 0;
-	dev->priv = pvc;
+	pvcdev_to_desc(dev)->pvc = pvc;
 
 	result = dev_alloc_name(dev, dev->name);
 	if (result < 0) {
@@ -1219,6 +1215,7 @@ static struct hdlc_proto proto = {
 	.stop		= fr_stop,
 	.detach		= fr_destroy,
 	.ioctl		= fr_ioctl,
+	.netif_rx	= fr_rx,
 	.module		= THIS_MODULE,
 };
 
@@ -1277,7 +1274,7 @@ static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
 			return result;
 
 		if (dev_to_hdlc(dev)->proto != &proto) { /* Different proto */
-			result = attach_hdlc_protocol(dev, &proto, fr_rx,
+			result = attach_hdlc_protocol(dev, &proto,
 						      sizeof(struct frad_state));
 			if (result)
 				return result;
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index 519e155..10396d9 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -122,7 +122,7 @@ static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
 		if (result)
 			return result;
 
-		result = attach_hdlc_protocol(dev, &proto, NULL,
+		result = attach_hdlc_protocol(dev, &proto,
 					      sizeof(struct ppp_state));
 		if (result)
 			return result;
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index e23bc66..bbbb819 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -82,7 +82,7 @@ static int raw_ioctl(struct net_device *dev, struct ifreq *ifr)
 		if (result)
 			return result;
 
-		result = attach_hdlc_protocol(dev, &proto, NULL,
+		result = attach_hdlc_protocol(dev, &proto,
 					      sizeof(raw_hdlc_proto));
 		if (result)
 			return result;
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index 8895394..d20c685 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -18,7 +18,6 @@
 #include <linux/init.h>
 #include <linux/skbuff.h>
 #include <linux/pkt_sched.h>
-#include <linux/random.h>
 #include <linux/inetdevice.h>
 #include <linux/lapb.h>
 #include <linux/rtnetlink.h>
@@ -96,7 +95,7 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
 		if (result)
 			return result;
 
-		result = attach_hdlc_protocol(dev, &proto, NULL,
+		result = attach_hdlc_protocol(dev, &proto,
 					      sizeof(raw_hdlc_proto));
 		if (result)
 			return result;
@@ -107,8 +106,7 @@ static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
 		ether_setup(dev);
 		dev->change_mtu = old_ch_mtu;
 		dev->tx_queue_len = old_qlen;
-		memcpy(dev->dev_addr, "\x00\x01", 2);
-                get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2);
+		random_ether_addr(dev->dev_addr);
 		netif_dormant_off(dev);
 		return 0;
 	}
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index cd7b22f..c15cc11 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -164,17 +164,17 @@ static void x25_close(struct net_device *dev)
 
 static int x25_rx(struct sk_buff *skb)
 {
-	struct hdlc_device_desc *desc = dev_to_desc(skb->dev);
+	struct hdlc_device *hdlc = dev_to_hdlc(skb->dev);
 
 	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
-		desc->stats.rx_dropped++;
+		hdlc->stats.rx_dropped++;
 		return NET_RX_DROP;
 	}
 
 	if (lapb_data_received(skb->dev, skb) == LAPB_OK)
 		return NET_RX_SUCCESS;
 
-	desc->stats.rx_errors++;
+	hdlc->stats.rx_errors++;
 	dev_kfree_skb_any(skb);
 	return NET_RX_DROP;
 }
@@ -184,6 +184,7 @@ static struct hdlc_proto proto = {
 	.open		= x25_open,
 	.close		= x25_close,
 	.ioctl		= x25_ioctl,
+	.netif_rx	= x25_rx,
 	.module		= THIS_MODULE,
 };
 
@@ -211,8 +212,7 @@ static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
 		if (result)
 			return result;
 
-		if ((result = attach_hdlc_protocol(dev, &proto,
-						   x25_rx, 0)) != 0)
+		if ((result = attach_hdlc_protocol(dev, &proto, 0)))
 			return result;
 		dev->hard_start_xmit = x25_xmit;
 		dev->type = ARPHRD_X25;
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h
index db390c5..6115545 100644
--- a/include/linux/hdlc.h
+++ b/include/linux/hdlc.h
@@ -26,13 +26,6 @@
 #include <linux/netdevice.h>
 #include <linux/hdlc/ioctl.h>
 
-
-/* Used by all network devices here, pointed to by netdev_priv(dev) */
-struct hdlc_device_desc {
-	int (*netif_rx)(struct sk_buff *skb);
-	struct net_device_stats stats;
-};
-
 /* This structure is a private property of HDLC protocols.
    Hardware drivers have no interest here */
 
@@ -44,12 +37,15 @@ struct hdlc_proto {
 	void (*detach)(struct net_device *dev);
 	int (*ioctl)(struct net_device *dev, struct ifreq *ifr);
 	__be16 (*type_trans)(struct sk_buff *skb, struct net_device *dev);
+	int (*netif_rx)(struct sk_buff *skb);
 	struct module *module;
 	struct hdlc_proto *next; /* next protocol in the list */
 };
 
 
+/* Pointed to by dev->priv */
 typedef struct hdlc_device {
+	struct net_device_stats stats;
 	/* used by HDLC layer to take control over HDLC device from hw driver*/
 	int (*attach)(struct net_device *dev,
 		      unsigned short encoding, unsigned short parity);
@@ -83,18 +79,11 @@ void unregister_hdlc_protocol(struct hdlc_proto *proto);
 
 struct net_device *alloc_hdlcdev(void *priv);
 
-
-static __inline__ struct hdlc_device_desc* dev_to_desc(struct net_device *dev)
-{
-	return netdev_priv(dev);
-}
-
-static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev)
+static inline struct hdlc_device* dev_to_hdlc(struct net_device *dev)
 {
-	return netdev_priv(dev) + sizeof(struct hdlc_device_desc);
+	return dev->priv;
 }
 
-
 static __inline__ void debug_frame(const struct sk_buff *skb)
 {
 	int i;
@@ -116,13 +105,13 @@ int hdlc_open(struct net_device *dev);
 void hdlc_close(struct net_device *dev);
 
 int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
-			 int (*rx)(struct sk_buff *skb), size_t size);
+			 size_t size);
 /* May be used by hardware driver to gain control over HDLC device */
 void detach_hdlc_protocol(struct net_device *dev);
 
 static __inline__ struct net_device_stats *hdlc_stats(struct net_device *dev)
 {
-	return &dev_to_desc(dev)->stats;
+	return &dev_to_hdlc(dev)->stats;
 }
 
 

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
       [not found] <20080122110231.GA18441@havoc.gtf.org>
@ 2008-01-22 14:20 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2008-01-22 14:20 UTC (permalink / raw)
  To: jeff; +Cc: netdev

From: Jeff Garzik <jeff@garzik.org>
Date: Tue, 22 Jan 2008 06:02:31 -0500

> NOTE:  This is the igb as Auke submitted it.  It still needs a review
> against ultra-recent Intel driver work.
> 
> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

Pulled and pushed out, I'll try to take a stare at IGB
after getting some sleep.

Thanks!

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-10-25  7:49 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2007-10-25  7:49 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML


Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 Documentation/networking/00-INDEX        |    2 -
 Documentation/networking/net-modules.txt |  315 ------------------------------
 drivers/net/bonding/bond_main.c          |    5 +-
 drivers/net/bonding/bonding.h            |    1 -
 drivers/net/cpmac.c                      |  145 ++++++++------
 drivers/net/ehea/ehea.h                  |    2 +-
 drivers/net/ehea/ehea_main.c             |    7 +-
 drivers/net/forcedeth.c                  |   16 ++
 drivers/net/ipg.c                        |   22 ++-
 drivers/net/ipg.h                        |   20 --
 drivers/net/natsemi.c                    |    1 +
 drivers/net/usb/rndis_host.c             |   18 ++-
 include/linux/pci_ids.h                  |    4 +
 13 files changed, 149 insertions(+), 409 deletions(-)
 delete mode 100644 Documentation/networking/net-modules.txt

Adrian Bunk (4):
      remove Documentation/networking/net-modules.txt
      drivers/net/ipg.c: cleanups
      make bonding/bond_main.c:bond_deinit() static
      bonding/bond_main.c: fix cut'n'paste error

Ayaz Abdulla (1):
      [netdrvr] forcedeth: add MCP77 device IDs

Eugene Konev (3):
      cpmac: use print_mac() instead of MAC_FMT
      cpmac: convert to napi_struct interface
      cpmac: update to new fixed phy driver interface

Ingo Molnar (1):
      natsemi: fix oops, link back netdevice from private-struct

Jan-Bernd Themann (1):
      ehea: fix port_napi_disable/enable

Thomas Sailer (1):
      rndis_host: reduce MTU instead of refusing to talk to devices with low max packet size

diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX
index 153d84d..f5a5e6d 100644
--- a/Documentation/networking/00-INDEX
+++ b/Documentation/networking/00-INDEX
@@ -80,8 +80,6 @@ multicast.txt
 	- Behaviour of cards under Multicast
 ncsa-telnet
 	- notes on how NCSA telnet (DOS) breaks with MTU discovery enabled.
-net-modules.txt
-	- info and "insmod" parameters for all network driver modules.
 netdevices.txt
 	- info on network device driver functions exported to the kernel.
 olympic.txt
diff --git a/Documentation/networking/net-modules.txt b/Documentation/networking/net-modules.txt
deleted file mode 100644
index 98c4392..0000000
--- a/Documentation/networking/net-modules.txt
+++ /dev/null
@@ -1,315 +0,0 @@
-Wed 2-Aug-95  <matti.aarnio@utu.fi>
-
-		Linux network driver modules
-
-	Do not mistake this for "README.modules" at the top-level
-	directory!  That document tells about modules in general, while
-	this one tells only about network device driver modules.
-
-	This is a potpourri of INSMOD-time(*) configuration options
-	(if such exists) and their default values of various modules
-	in the Linux network drivers collection.
-
-	Some modules have also hidden (= non-documented) tunable values.
-	The choice of not documenting them is based on general belief, that
-	the less the user needs to know, the better.  (There are things that
-	driver developers can use, others should not confuse themselves.)
-
-	In many cases it is highly preferred that insmod:ing is done
-	ONLY with defining an explicit address for the card, AND BY
-	NOT USING AUTO-PROBING!
-
-	Now most cards have some explicitly defined base address that they
-	are compiled with (to avoid auto-probing, among other things).
-	If that compiled value does not match your actual configuration,
-	do use the "io=0xXXX" -parameter for the insmod, and give there
-	a value matching your environment.
-
-	If you are adventurous, you can ask the driver to autoprobe
-	by using the "io=0" parameter, however it is a potentially dangerous
-	thing to do in a live system.  (If you don't know where the
-	card is located, you can try autoprobing, and after possible
-	crash recovery, insmod with proper IO-address..)
-
-	--------------------------
-	(*)	"INSMOD-time" means when you load module with
-		/sbin/insmod  you can feed it optional parameters.
-		See "man insmod".
-	--------------------------
-
-
-	8390 based Network Modules		(Paul Gortmaker, Nov 12, 1995)
-	--------------------------
-
-(Includes: smc-ultra, ne, wd, 3c503, hp, hp-plus, e2100 and ac3200)
-
-The 8390 series of network drivers now support multiple card systems without 
-reloading the same module multiple times (memory efficient!) This is done by 
-specifying multiple comma separated values, such as:
-
-	insmod 3c503.o io=0x280,0x300,0x330,0x350  xcvr=0,1,0,1
-
-The above would have the one module controlling four 3c503 cards, with card 2
-and 4 using external transceivers. The "insmod" manual describes the usage
-of comma separated value lists.
-
-It is *STRONGLY RECOMMENDED* that you supply "io=" instead of autoprobing.
-If an "io=" argument is not supplied, then the ISA drivers will complain
-about autoprobing being not recommended, and begrudgingly autoprobe for
-a *SINGLE CARD ONLY* -- if you want to use multiple cards you *have* to 
-supply an "io=0xNNN,0xQQQ,..." argument.
-
-The ne module is an exception to the above. A NE2000 is essentially an
-8390 chip, some bus glue and some RAM. Because of this, the ne probe is
-more invasive than the rest, and so at boot we make sure the ne probe is 
-done last of all the 8390 cards (so that it won't trip over other 8390 based
-cards) With modules we can't ensure that all other non-ne 8390 cards have
-already been found. Because of this, the ne module REQUIRES an "io=0xNNN" 
-argument passed in via insmod. It will refuse to autoprobe.
-
-It is also worth noting that auto-IRQ probably isn't as reliable during 
-the flurry of interrupt activity on a running machine. Cards such as the 
-ne2000 that can't get the IRQ setting from an EEPROM or configuration
-register are probably best supplied with an "irq=M" argument as well.
-
-
-----------------------------------------------------------------------
-Card/Module List - Configurable Parameters and Default Values
-----------------------------------------------------------------------
-
-3c501.c:
-	io  = 0x280	IO base address
-	irq = 5		IRQ
-	(Probes ports:	0x280, 0x300)
-
-3c503.c:
-	io = 0		(It will complain if you don't supply an "io=0xNNN")
-	irq = 0		(IRQ software selected by driver using autoIRQ)
-	xcvr = 0	(Use xcvr=1 to select external transceiver.)
-	(Probes ports: 0x300, 0x310, 0x330, 0x350, 0x250, 0x280, 0x2A0, 0x2E0)
-
-3c505.c:
-	io = 0
-	irq = 0
-	dma = 6         (not autoprobed)
-	(Probes ports: 0x300, 0x280, 0x310)
-
-3c507.c:
-	io = 0x300
-	irq = 0
-	(Probes ports: 0x300, 0x320, 0x340, 0x280)
-
-3c509.c:
-	io = 0
-	irq = 0
-	( Module load-time probing Works reliably only on EISA, ISA ID-PROBE
-	  IS NOT RELIABLE!  Compile this driver statically into kernel for
-	  now, if you need it auto-probing on an ISA-bus machine. )
-
-8390.c:
-	(No public options, several other modules need this one)
-
-a2065.c:
-	Since this is a Zorro board, it supports full autoprobing, even for
-	multiple boards. (m68k/Amiga)
-
-ac3200.c:
-	io = 0		(Checks 0x1000 to 0x8fff in 0x1000 intervals)
-	irq = 0		(Read from config register)
-	(EISA probing..)
-
-apricot.c:
-	io = 0x300  (Can't be altered!)
-	irq = 10
-
-arcnet.c:
-	io = 0
-	irqnum = 0
-	shmem = 0
-	num = 0
-	DO SET THESE MANUALLY AT INSMOD!
-	(When probing, looks at the following possible addresses:
-	 Suggested ones:
-		0x300, 0x2E0, 0x2F0, 0x2D0
-	 Other ones:
-		0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270,
-		0x280, 0x290, 0x2A0, 0x2B0, 0x2C0,
-		       0x310, 0x320, 0x330, 0x340, 0x350, 0x360, 0x370,
-		0x380, 0x390, 0x3A0,			  0x3E0, 0x3F0  )
-
-ariadne.c:
-	Since this is a Zorro board, it supports full autoprobing, even for
-	multiple boards. (m68k/Amiga)
-
-at1700.c:
-	io = 0x260
-	irq = 0
-	(Probes ports: 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300)
-
-atarilance.c:
-	Supports full autoprobing. (m68k/Atari)
-
-atp.c: *Not modularized*
-	(Probes ports: 0x378, 0x278, 0x3BC;
-	 fixed IRQs: 5 and 7			)
-
-cops.c:
-	io = 0x240
-	irq = 5
-	nodeid = 0	(AutoSelect = 0, NodeID 1-254 is hand selected.)
-	(Probes ports: 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260,
-		       0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360)	
-
-de4x5.c:
-	io = 0x000b
-	irq = 10
-	is_not_dec = 0  -- For non-DEC card using DEC 21040/21041/21140 chip, set this to 1
-	(EISA, and PCI probing)
-
-de600.c:
-	de600_debug = 0
-	(On port 0x378, irq 7 -- lpt1;  compile time configurable)
-
-de620.c:
-	bnc = 0, utp = 0  <-- Force media by setting either.
-	io = 0x378	(also compile-time configurable)
-	irq = 7
-
-depca.c:
-	io = 0x200
-	irq = 7
-	(Probes ports:	ISA:  0x300, 0x200;
-			EISA: 0x0c00		)
-
-dummy.c:
-	No options
-
-e2100.c:
-	io = 0		(It will complain if you don't supply an "io=0xNNN")
-	irq = 0		(IRQ software selected by driver)
-	mem = 0		(Override default shared memory start of 0xd0000)
-	xcvr = 0	(Use xcvr=1 to select external transceiver.)
-	(Probes ports: 0x300, 0x280, 0x380, 0x220)
-
-eepro.c:
-	io = 0x200
-	irq = 0
-	(Probes ports: 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0x360)
-
-eexpress.c:
-	io = 0x300
-	irq = 0		(IRQ value read from EEPROM)
-	(Probes ports: 0x300, 0x270, 0x320, 0x340)
-
-eql.c:
-	(No parameters)
-
-ewrk3.c:
-	io = 0x300
-	irq = 5
-	(With module no autoprobing!
-	 On EISA-bus does EISA probing.
-	 Static linkage probes ports on ISA bus:
-		0x100, 0x120, 0x140, 0x160, 0x180, 0x1A0, 0x1C0,
-		0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
-		0x300,        0x340, 0x360, 0x380, 0x3A0, 0x3C0)
-
-hp-plus.c:
-	io = 0		(It will complain if you don't supply an "io=0xNNN")
-	irq = 0		(IRQ read from configuration register)
-	(Probes ports: 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340)
-
-hp.c:
-	io = 0		(It will complain if you don't supply an "io=0xNNN")
-	irq = 0		(IRQ software selected by driver using autoIRQ)
-	(Probes ports: 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240)
-
-hp100.c:
-	hp100_port = 0 (IO-base address)
-	(Does EISA-probing, if on EISA-slot;
-	 On ISA-bus probes all ports from 0x100 thru to 0x3E0
-	 in increments of 0x020)
-
-hydra.c:
-	Since this is a Zorro board, it supports full autoprobing, even for
-	multiple boards. (m68k/Amiga)
-
-ibmtr.c:
-	io = 0xa20, 0xa24 (autoprobed by default)
-	irq = 0 (driver cannot select irq - read from hardware)
-	mem = 0 (shared memory base set at 0xd0000 and not yet 
-	         able to override thru mem= parameter.)
-
-lance.c: *Not modularized*
-	(PCI, and ISA probing; "CONFIG_PCI" needed for PCI support)
-	(Probes ISA ports: 0x300, 0x320, 0x340, 0x360)
-
-loopback.c: *Static kernel component*
-
-ne.c:
-	io = 0		(Explicitly *requires* an "io=0xNNN" value)
-	irq = 0		(Tries to determine configured IRQ via autoIRQ)
-	(Probes ports: 0x300, 0x280, 0x320, 0x340, 0x360)
-
-net_init.c: *Static kernel component*
-
-ni52.c: *Not modularized*
-	(Probes ports:	0x300, 0x280, 0x360, 0x320, 0x340
-		mems:	0xD0000, 0xD2000, 0xC8000, 0xCA000,
-			0xD4000, 0xD6000, 0xD8000 )
-
-ni65.c: *Not modularized*  **16MB MEMORY BARRIER BUG**
-	(Probes ports:	0x300, 0x320, 0x340, 0x360)
-
-pi2.c:	*Not modularized* (well, NON-STANDARD modularization!)
-	Only one card supported at this time.
-	(Probes ports: 0x380, 0x300, 0x320, 0x340, 0x360, 0x3A0)
-
-plip.c:
-	io = 0
-	irq = 0		(by default, uses IRQ 5 for port at 0x3bc, IRQ 7
-			for port at 0x378, and IRQ 2 for port at 0x278)
-	(Probes ports: 0x278, 0x378, 0x3bc)
-
-ppp.c:
-	No options (ppp-2.2+ has some, this is based on non-dynamic
-	version from ppp-2.1.2d)
-
-seeq8005.c: *Not modularized*
-	(Probes ports: 0x300, 0x320, 0x340, 0x360)
-
-skeleton.c: *Skeleton*
-
-slhc.c:
-	No configuration parameters
-
-slip.c:
-	slip_maxdev = 256 (default value from SL_NRUNIT on slip.h)
-
-
-smc-ultra.c:
-	io = 0		(It will complain if you don't supply an "io=0xNNN")
-	irq = 0		(IRQ val. read from EEPROM)
-	(Probes ports:	0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380)
-
-tulip.c: *Partial modularization*
-	(init-time memory allocation makes problems..)
-
-tunnel.c:
-	No insmod parameters
-
-wavelan.c:
-	io = 0x390	(Settable, but change not recommended)
-	irq = 0		(Not honoured, if changed..)
-
-wd.c:
-	io = 0		(It will complain if you don't supply an "io=0xNNN")
-	irq = 0		(IRQ val. read from EEPROM, ancient cards use autoIRQ)
-	mem = 0		(Force shared-memory on address 0xC8000, or whatever..)
-	mem_end = 0	(Force non-std. mem. size via supplying mem_end val.)
-			(eg. for 32k WD8003EBT, use mem=0xd0000 mem_end=0xd8000)
-	(Probes ports:	0x300, 0x280, 0x380, 0x240)
-
-znet.c: *Not modularized*
-	(Only one device on  Zenith Z-Note (notebook?) systems,
-	 configuration information from (EE)PROM)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6909bec..6937ef0 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -188,6 +188,7 @@ struct bond_parm_tbl arp_validate_tbl[] = {
 /*-------------------------- Forward declarations ---------------------------*/
 
 static void bond_send_gratuitous_arp(struct bonding *bond);
+static void bond_deinit(struct net_device *bond_dev);
 
 /*---------------------------- General routines -----------------------------*/
 
@@ -3681,7 +3682,7 @@ static int bond_open(struct net_device *bond_dev)
 	}
 
 	if (bond->params.mode == BOND_MODE_8023AD) {
-		INIT_DELAYED_WORK(&bond->ad_work, bond_alb_monitor);
+		INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
 		queue_delayed_work(bond->wq, &bond->ad_work, 0);
 		/* register to receive LACPDUs */
 		bond_register_lacpdu(bond);
@@ -4449,7 +4450,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
 /* De-initialize device specific data.
  * Caller must hold rtnl_lock.
  */
-void bond_deinit(struct net_device *bond_dev)
+static void bond_deinit(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
 
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index d1ed14b..61c1b45 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -302,7 +302,6 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_de
 int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
 void bond_destroy(struct bonding *bond);
 int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
-void bond_deinit(struct net_device *bond_dev);
 int bond_create_sysfs(void);
 void bond_destroy_sysfs(void);
 void bond_destroy_sysfs_entry(struct bonding *bond);
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index 57541d2..6fd95a2 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -34,6 +34,7 @@
 #include <linux/skbuff.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
+#include <linux/phy_fixed.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <asm/gpio.h>
@@ -53,12 +54,6 @@ MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable");
 MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
 
 #define CPMAC_VERSION "0.5.0"
-/* stolen from net/ieee80211.h */
-#ifndef MAC_FMT
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0], ((u8*)(x))[1], ((u8*)(x))[2], \
-		   ((u8*)(x))[3], ((u8*)(x))[4], ((u8*)(x))[5]
-#endif
 /* frame size + 802.1q tag */
 #define CPMAC_SKB_SIZE		(ETH_FRAME_LEN + 4)
 #define CPMAC_QUEUES	8
@@ -211,6 +206,7 @@ struct cpmac_priv {
 	struct net_device *dev;
 	struct work_struct reset_work;
 	struct platform_device *pdev;
+	struct napi_struct napi;
 };
 
 static irqreturn_t cpmac_irq(int, void *);
@@ -362,47 +358,48 @@ static void cpmac_set_multicast_list(struct net_device *dev)
 	}
 }
 
-static struct sk_buff *cpmac_rx_one(struct net_device *dev,
-				    struct cpmac_priv *priv,
+static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv,
 				    struct cpmac_desc *desc)
 {
 	struct sk_buff *skb, *result = NULL;
 
 	if (unlikely(netif_msg_hw(priv)))
-		cpmac_dump_desc(dev, desc);
+		cpmac_dump_desc(priv->dev, desc);
 	cpmac_write(priv->regs, CPMAC_RX_ACK(0), (u32)desc->mapping);
 	if (unlikely(!desc->datalen)) {
 		if (netif_msg_rx_err(priv) && net_ratelimit())
 			printk(KERN_WARNING "%s: rx: spurious interrupt\n",
-			       dev->name);
+			       priv->dev->name);
 		return NULL;
 	}
 
-	skb = netdev_alloc_skb(dev, CPMAC_SKB_SIZE);
+	skb = netdev_alloc_skb(priv->dev, CPMAC_SKB_SIZE);
 	if (likely(skb)) {
 		skb_reserve(skb, 2);
 		skb_put(desc->skb, desc->datalen);
-		desc->skb->protocol = eth_type_trans(desc->skb, dev);
+		desc->skb->protocol = eth_type_trans(desc->skb, priv->dev);
 		desc->skb->ip_summed = CHECKSUM_NONE;
-		dev->stats.rx_packets++;
-		dev->stats.rx_bytes += desc->datalen;
+		priv->dev->stats.rx_packets++;
+		priv->dev->stats.rx_bytes += desc->datalen;
 		result = desc->skb;
-		dma_unmap_single(&dev->dev, desc->data_mapping, CPMAC_SKB_SIZE,
-				 DMA_FROM_DEVICE);
+		dma_unmap_single(&priv->dev->dev, desc->data_mapping,
+				 CPMAC_SKB_SIZE, DMA_FROM_DEVICE);
 		desc->skb = skb;
-		desc->data_mapping = dma_map_single(&dev->dev, skb->data,
+		desc->data_mapping = dma_map_single(&priv->dev->dev, skb->data,
 						    CPMAC_SKB_SIZE,
 						    DMA_FROM_DEVICE);
 		desc->hw_data = (u32)desc->data_mapping;
 		if (unlikely(netif_msg_pktdata(priv))) {
-			printk(KERN_DEBUG "%s: received packet:\n", dev->name);
-			cpmac_dump_skb(dev, result);
+			printk(KERN_DEBUG "%s: received packet:\n",
+			       priv->dev->name);
+			cpmac_dump_skb(priv->dev, result);
 		}
 	} else {
 		if (netif_msg_rx_err(priv) && net_ratelimit())
 			printk(KERN_WARNING
-			       "%s: low on skbs, dropping packet\n", dev->name);
-		dev->stats.rx_dropped++;
+			       "%s: low on skbs, dropping packet\n",
+			       priv->dev->name);
+		priv->dev->stats.rx_dropped++;
 	}
 
 	desc->buflen = CPMAC_SKB_SIZE;
@@ -411,25 +408,25 @@ static struct sk_buff *cpmac_rx_one(struct net_device *dev,
 	return result;
 }
 
-static int cpmac_poll(struct net_device *dev, int *budget)
+static int cpmac_poll(struct napi_struct *napi, int budget)
 {
 	struct sk_buff *skb;
 	struct cpmac_desc *desc;
-	int received = 0, quota = min(dev->quota, *budget);
-	struct cpmac_priv *priv = netdev_priv(dev);
+	int received = 0;
+	struct cpmac_priv *priv = container_of(napi, struct cpmac_priv, napi);
 
 	spin_lock(&priv->rx_lock);
 	if (unlikely(!priv->rx_head)) {
 		if (netif_msg_rx_err(priv) && net_ratelimit())
 			printk(KERN_WARNING "%s: rx: polling, but no queue\n",
-			       dev->name);
-		netif_rx_complete(dev);
+			       priv->dev->name);
+		netif_rx_complete(priv->dev, napi);
 		return 0;
 	}
 
 	desc = priv->rx_head;
-	while ((received < quota) && ((desc->dataflags & CPMAC_OWN) == 0)) {
-		skb = cpmac_rx_one(dev, priv, desc);
+	while (((desc->dataflags & CPMAC_OWN) == 0) && (received < budget)) {
+		skb = cpmac_rx_one(priv, desc);
 		if (likely(skb)) {
 			netif_receive_skb(skb);
 			received++;
@@ -439,13 +436,11 @@ static int cpmac_poll(struct net_device *dev, int *budget)
 
 	priv->rx_head = desc;
 	spin_unlock(&priv->rx_lock);
-	*budget -= received;
-	dev->quota -= received;
 	if (unlikely(netif_msg_rx_status(priv)))
-		printk(KERN_DEBUG "%s: poll processed %d packets\n", dev->name,
-		       received);
+		printk(KERN_DEBUG "%s: poll processed %d packets\n",
+		       priv->dev->name, received);
 	if (desc->dataflags & CPMAC_OWN) {
-		netif_rx_complete(dev);
+		netif_rx_complete(priv->dev, napi);
 		cpmac_write(priv->regs, CPMAC_RX_PTR(0), (u32)desc->mapping);
 		cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
 		return 0;
@@ -655,6 +650,7 @@ static void cpmac_hw_error(struct work_struct *work)
 	spin_unlock(&priv->rx_lock);
 	cpmac_clear_tx(priv->dev);
 	cpmac_hw_start(priv->dev);
+	napi_enable(&priv->napi);
 	netif_start_queue(priv->dev);
 }
 
@@ -681,8 +677,10 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
 
 	if (status & MAC_INT_RX) {
 		queue = (status >> 8) & 7;
-		netif_rx_schedule(dev);
-		cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue);
+		if (netif_rx_schedule_prep(dev, &priv->napi)) {
+			cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue);
+			__netif_rx_schedule(dev, &priv->napi);
+		}
 	}
 
 	cpmac_write(priv->regs, CPMAC_MAC_EOI_VECTOR, 0);
@@ -692,6 +690,7 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
 			printk(KERN_ERR "%s: hw error, resetting...\n",
 			       dev->name);
 		netif_stop_queue(dev);
+		napi_disable(&priv->napi);
 		cpmac_hw_stop(dev);
 		schedule_work(&priv->reset_work);
 		if (unlikely(netif_msg_hw(priv)))
@@ -849,6 +848,15 @@ static void cpmac_adjust_link(struct net_device *dev)
 	spin_unlock(&priv->lock);
 }
 
+static int cpmac_link_update(struct net_device *dev,
+			     struct fixed_phy_status *status)
+{
+	status->link = 1;
+	status->speed = 100;
+	status->duplex = 1;
+	return 0;
+}
+
 static int cpmac_open(struct net_device *dev)
 {
 	int i, size, res;
@@ -857,15 +865,6 @@ static int cpmac_open(struct net_device *dev)
 	struct cpmac_desc *desc;
 	struct sk_buff *skb;
 
-	priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link,
-				0, PHY_INTERFACE_MODE_MII);
-	if (IS_ERR(priv->phy)) {
-		if (netif_msg_drv(priv))
-			printk(KERN_ERR "%s: Could not attach to PHY\n",
-			       dev->name);
-		return PTR_ERR(priv->phy);
-	}
-
 	mem = platform_get_resource_byname(priv->pdev, IORESOURCE_MEM, "regs");
 	if (!request_mem_region(mem->start, mem->end - mem->start, dev->name)) {
 		if (netif_msg_drv(priv))
@@ -927,6 +926,7 @@ static int cpmac_open(struct net_device *dev)
 	INIT_WORK(&priv->reset_work, cpmac_hw_error);
 	cpmac_hw_start(dev);
 
+	napi_enable(&priv->napi);
 	priv->phy->state = PHY_CHANGELINK;
 	phy_start(priv->phy);
 
@@ -951,8 +951,6 @@ fail_remap:
 	release_mem_region(mem->start, mem->end - mem->start);
 
 fail_reserve:
-	phy_disconnect(priv->phy);
-
 	return res;
 }
 
@@ -965,9 +963,8 @@ static int cpmac_stop(struct net_device *dev)
 	netif_stop_queue(dev);
 
 	cancel_work_sync(&priv->reset_work);
+	napi_disable(&priv->napi);
 	phy_stop(priv->phy);
-	phy_disconnect(priv->phy);
-	priv->phy = NULL;
 
 	cpmac_hw_stop(dev);
 
@@ -1001,11 +998,13 @@ static int external_switch;
 
 static int __devinit cpmac_probe(struct platform_device *pdev)
 {
-	int rc, phy_id;
+	int rc, phy_id, i;
 	struct resource *mem;
 	struct cpmac_priv *priv;
 	struct net_device *dev;
 	struct plat_cpmac_data *pdata;
+	struct fixed_info *fixed_phy;
+	DECLARE_MAC_BUF(mac);
 
 	pdata = pdev->dev.platform_data;
 
@@ -1053,21 +1052,51 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
 	dev->set_multicast_list = cpmac_set_multicast_list;
 	dev->tx_timeout         = cpmac_tx_timeout;
 	dev->ethtool_ops        = &cpmac_ethtool_ops;
-	dev->poll = cpmac_poll;
-	dev->weight = 64;
 	dev->features |= NETIF_F_MULTI_QUEUE;
 
+	netif_napi_add(dev, &priv->napi, cpmac_poll, 64);
+
 	spin_lock_init(&priv->lock);
 	spin_lock_init(&priv->rx_lock);
 	priv->dev = dev;
 	priv->ring_size = 64;
 	priv->msg_enable = netif_msg_init(debug_level, 0xff);
 	memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
+
 	if (phy_id == 31) {
-		snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT,
-			 cpmac_mii.id, phy_id);
-	} else
-		snprintf(priv->phy_name, BUS_ID_SIZE, "fixed@%d:%d", 100, 1);
+		snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, cpmac_mii.id,
+			 phy_id);
+	} else {
+		/* Let's try to get a free fixed phy... */
+		for (i = 0; i < MAX_PHY_AMNT; i++) {
+			fixed_phy = fixed_mdio_get_phydev(i);
+			if (!fixed_phy)
+				continue;
+			if (!fixed_phy->phydev->attached_dev) {
+				strncpy(priv->phy_name,
+					fixed_phy->phydev->dev.bus_id,
+					BUS_ID_SIZE);
+				fixed_mdio_set_link_update(fixed_phy->phydev,
+							   &cpmac_link_update);
+				goto phy_found;
+			}
+		}
+		if (netif_msg_drv(priv))
+			printk(KERN_ERR "%s: Could not find fixed PHY\n",
+			       dev->name);
+		rc = -ENODEV;
+		goto fail;
+	}
+
+phy_found:
+	priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0,
+				PHY_INTERFACE_MODE_MII);
+	if (IS_ERR(priv->phy)) {
+		if (netif_msg_drv(priv))
+			printk(KERN_ERR "%s: Could not attach to PHY\n",
+			       dev->name);
+		return PTR_ERR(priv->phy);
+	}
 
 	if ((rc = register_netdev(dev))) {
 		printk(KERN_ERR "cpmac: error %i registering device %s\n", rc,
@@ -1077,9 +1106,9 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
 
 	if (netif_msg_probe(priv)) {
 		printk(KERN_INFO
-		       "cpmac: device %s (regs: %p, irq: %d, phy: %s, mac: "
-		       MAC_FMT ")\n", dev->name, (void *)mem->start, dev->irq,
-		       priv->phy_name, MAC_ARG(dev->dev_addr));
+		       "cpmac: device %s (regs: %p, irq: %d, phy: %s, "
+		       "mac: %s)\n", dev->name, (void *)mem->start, dev->irq,
+		       priv->phy_name, print_mac(mac, dev->dev_addr));
 	}
 	return 0;
 
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index b557bb4..4b4b74e 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0078"
+#define DRV_VERSION	"EHEA_0079"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 2809c99..0a7e789 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2329,7 +2329,7 @@ static void port_napi_disable(struct ehea_port *port)
 {
 	int i;
 
-	for (i = 0; i < port->num_def_qps; i++)
+	for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++)
 		napi_disable(&port->port_res[i].napi);
 }
 
@@ -2337,7 +2337,7 @@ static void port_napi_enable(struct ehea_port *port)
 {
 	int i;
 
-	for (i = 0; i < port->num_def_qps; i++)
+	for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++)
 		napi_enable(&port->port_res[i].napi);
 }
 
@@ -2373,8 +2373,6 @@ static int ehea_down(struct net_device *dev)
 	ehea_drop_multicast_list(dev);
 	ehea_free_interrupts(dev);
 
-	port_napi_disable(port);
-
 	port->state = EHEA_PORT_DOWN;
 
 	ret = ehea_clean_all_portres(port);
@@ -2396,6 +2394,7 @@ static int ehea_stop(struct net_device *dev)
 	flush_scheduled_work();
 	down(&port->port_lock);
 	netif_stop_queue(dev);
+	port_napi_disable(port);
 	ret = ehea_down(dev);
 	up(&port->port_lock);
 	return ret;
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 70ddf1a..92ce2e3 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -5597,6 +5597,22 @@ static struct pci_device_id pci_tbl[] = {
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
 		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
 	},
+	{	/* MCP77 Ethernet Controller */
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+	},
+	{	/* MCP77 Ethernet Controller */
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+	},
+	{	/* MCP77 Ethernet Controller */
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+	},
+	{	/* MCP77 Ethernet Controller */
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+	},
 	{0,},
 };
 
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 6888723..dbd23bb 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -55,6 +55,26 @@ MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver "
 		   DrvVer);
 MODULE_LICENSE("GPL");
 
+//variable record -- index by leading revision/length
+//Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
+static unsigned short DefaultPhyParam[] = {
+	// 11/12/03 IP1000A v1-3 rev=0x40
+	/*--------------------------------------------------------------------------
+	(0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2,
+				 27, 0x0c10, 28, 0x0c10, 29, 0x2c10, 31, 0x0003, 23, 0x92f6,
+				 31, 0x0000, 23, 0x003d, 30, 0x00de, 20, 0x20e7,  9, 0x0700,
+	  --------------------------------------------------------------------------*/
+	// 12/17/03 IP1000A v1-4 rev=0x40
+	(0x4000 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
+	    0x0000,
+	30, 0x005e, 9, 0x0700,
+	// 01/09/04 IP1000A v1-5 rev=0x41
+	(0x4100 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
+	    0x0000,
+	30, 0x005e, 9, 0x0700,
+	0x0000
+};
+
 static const char *ipg_brand_name[] = {
 	"IC PLUS IP1000 1000/100/10 based NIC",
 	"Sundance Technology ST2021 based NIC",
@@ -990,7 +1010,7 @@ static void ipg_nic_txcleanup(struct net_device *dev)
 }
 
 /* Provides statistical information about the IPG NIC. */
-struct net_device_stats *ipg_nic_get_stats(struct net_device *dev)
+static struct net_device_stats *ipg_nic_get_stats(struct net_device *dev)
 {
 	struct ipg_nic_private *sp = netdev_priv(dev);
 	void __iomem *ioaddr = sp->ioaddr;
diff --git a/drivers/net/ipg.h b/drivers/net/ipg.h
index e418b90..d5d092c 100644
--- a/drivers/net/ipg.h
+++ b/drivers/net/ipg.h
@@ -833,24 +833,4 @@ struct ipg_nic_private {
 	struct delayed_work task;
 };
 
-//variable record -- index by leading revision/length
-//Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
-unsigned short DefaultPhyParam[] = {
-	// 11/12/03 IP1000A v1-3 rev=0x40
-	/*--------------------------------------------------------------------------
-	(0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2,
-				 27, 0x0c10, 28, 0x0c10, 29, 0x2c10, 31, 0x0003, 23, 0x92f6,
-				 31, 0x0000, 23, 0x003d, 30, 0x00de, 20, 0x20e7,  9, 0x0700,
-	  --------------------------------------------------------------------------*/
-	// 12/17/03 IP1000A v1-4 rev=0x40
-	(0x4000 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
-	    0x0000,
-	30, 0x005e, 9, 0x0700,
-	// 01/09/04 IP1000A v1-5 rev=0x41
-	(0x4100 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
-	    0x0000,
-	30, 0x005e, 9, 0x0700,
-	0x0000
-};
-
 #endif				/* __LINUX_IPG_H */
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 9531171..87cde06 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -864,6 +864,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 
 	np = netdev_priv(dev);
 	netif_napi_add(dev, &np->napi, natsemi_poll, 64);
+	np->dev = dev;
 
 	np->pci_dev = pdev;
 	pci_set_drvdata(pdev, dev);
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index cd991a0..1ebe325 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -512,11 +512,19 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
 	}
 	tmp = le32_to_cpu(u.init_c->max_transfer_size);
 	if (tmp < dev->hard_mtu) {
-		dev_err(&intf->dev,
-			"dev can't take %u byte packets (max %u)\n",
-			dev->hard_mtu, tmp);
-		retval = -EINVAL;
-		goto fail_and_release;
+		if (tmp <= net->hard_header_len) {
+			dev_err(&intf->dev,
+				"dev can't take %u byte packets (max %u)\n",
+				dev->hard_mtu, tmp);
+			retval = -EINVAL;
+			goto fail_and_release;
+		}
+		dev->hard_mtu = tmp;
+		net->mtu = dev->hard_mtu - net->hard_header_len;
+		dev_warn(&intf->dev,
+			 "dev can't take %u byte packets (max %u), "
+			 "adjusting MTU to %u\n",
+			 dev->hard_mtu, tmp, net->mtu);
 	}
 
 	/* REVISIT:  peripheral "alignment" request is ignored ... */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 4e10a07..e44aac8 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1236,6 +1236,10 @@
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE       0x0560
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE       0x056C
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE       0x0759
+#define PCI_DEVICE_ID_NVIDIA_NVENET_32              0x0760
+#define PCI_DEVICE_ID_NVIDIA_NVENET_33              0x0761
+#define PCI_DEVICE_ID_NVIDIA_NVENET_34              0x0762
+#define PCI_DEVICE_ID_NVIDIA_NVENET_35              0x0763
 
 #define PCI_VENDOR_ID_IMS		0x10e0
 #define PCI_DEVICE_ID_IMS_TT128		0x9128

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-10-24  1:30 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2007-10-24  1:30 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML


Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 MAINTAINERS                      |   31 +--
 drivers/net/Kconfig              |   13 +-
 drivers/net/bonding/bond_3ad.c   |    6 +-
 drivers/net/bonding/bond_3ad.h   |    2 +-
 drivers/net/bonding/bond_alb.c   |  110 ++++--
 drivers/net/bonding/bond_alb.h   |    2 +-
 drivers/net/bonding/bond_main.c  |  330 ++++++++++------
 drivers/net/bonding/bond_sysfs.c |   79 ++---
 drivers/net/bonding/bonding.h    |   14 +-
 drivers/net/cpmac.c              |   31 +-
 drivers/net/defxx.c              |    2 +-
 drivers/net/mipsnet.c            |   44 +--
 drivers/net/mv643xx_eth.c        |  807 +++++++++++++++++++++++++++++++-------
 drivers/net/mv643xx_eth.h        |  370 -----------------
 drivers/net/pasemi_mac.c         |    2 +-
 drivers/net/r8169.c              |  406 +++++++++++++-------
 drivers/net/sky2.c               |    4 +-
 include/linux/mv643xx.h          |  328 +---------------
 include/linux/mv643xx_eth.h      |   31 ++
 include/linux/netdevice.h        |    2 +-
 20 files changed, 1330 insertions(+), 1284 deletions(-)
 delete mode 100644 drivers/net/mv643xx_eth.h
 create mode 100644 include/linux/mv643xx_eth.h

Dale Farnsworth (2):
      mv643xx_eth: Remove obsolete checksum offload comment
      mv643xx_eth: Hook up mv643xx_get_sset_count

Francois Romieu (11):
      r8169: convert bitfield to plain enum mask
      r8169: MSI support
      r8169: remove private net_device_stats structure
      r8169: use the existing symbolic name of vendor PCI ID 0x1259
      r8169: add MAC identifiers
      r8169: remove dead wood
      r8169: make room for more phy init changes
      r8169: phy init for the 8168
      r8169: phy init cleanup
      r8169: update the phy init for the 8168C
      r8169: more phy init for the 8168

Jay Vosburgh (6):
      Convert bonding timers to workqueues
      bonding: Convert balance-rr transmit to new locking
      bonding: Convert miimon to new locking
      bonding: Convert locks to _bh, rework alb locking for new locking
      bonding: Convert more locks to _bh, acquire rtnl, for new locking
      bonding: Acquire correct locks in alb for promisc change

Jeff Garzik (2):
      Update MAINTAINERS to reflect my (jgarzik's) current efforts.
      Remove Andrew Morton from list of net driver maintainers.

Joe Perches (2):
      r8169: add KERN_DEBUG to dprintk (trivial)
      r8169: KERN_XXX vs PFX (trivial)

Lennert Buytenhek (9):
      mv643xx_eth: Split off mv643xx_eth platform device data
      mv643xx_eth: Move ethernet register definitions into private header
      mv643xx_eth: Disable RX/TX byte swapping on little-endian systems
      mv643xx_eth: Enable use on Orion platforms
      mv643xx_eth: Remove SHARED_REGS register address bias
      mv643xx_eth: Remove MV643XX_ETH_ register prefix
      mv643xx_eth: Clean up mv643xx_eth.h
      mv643xx_eth: Remove unused register defines
      mv643xx_eth: Merge drivers/net/mv643xx_eth.h into mv643xx_eth.c

Maciej W. Rozycki (1):
      defxx.c: dfx_bus_init() is __devexit not __devinit

Matteo Croce (1):
      AR7 ethernet: small post-merge cleanups and fixes

Olof Johansson (1):
      pasemi_mac: fix typo

Ralf Baechle (1):
      MIPSnet: Delete all the useless debugging printks.

Stephen Hemminger (1):
      sky2: crash on remove

Ursula Braun (2):
      remove header_ops bug in qeth driver
      s390 MAINTAINERS

diff --git a/MAINTAINERS b/MAINTAINERS
index 40245af..9d0ae8d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -136,17 +136,6 @@ M:	ajk@iehk.rwth-aachen.de
 L:	linux-hams@vger.kernel.org
 S:	Maintained
 
-8139CP 10/100 FAST ETHERNET DRIVER
-P:	Jeff Garzik
-M:	jgarzik@pobox.com
-S:	Maintained
-
-8139TOO 10/100 FAST ETHERNET DRIVER
-P:	Jeff Garzik
-M:	jgarzik@pobox.com
-W:	http://sourceforge.net/projects/gkernel/
-S:	Maintained
-
 8169 10/100/1000 GIGABIT ETHERNET DRIVER
 P:	Francois Romieu
 M:	romieu@fr.zoreil.com
@@ -1037,12 +1026,6 @@ M:	kernel@wantstofly.org
 L:	netdev@vger.kernel.org
 S:	Maintained
 
-CIRRUS LOGIC GENERIC FBDEV DRIVER
-P:	Jeff Garzik
-M:	jgarzik@pobox.com
-L:	linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
-S:	Odd Fixes
-
 CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER
 P:	Lennert Buytenhek
 M:	kernel@wantstofly.org
@@ -1963,12 +1946,6 @@ M:	adaplas@gmail.com
 L:	linux-fbdev-devel@lists.sourceforge.net (subscribers-only)
 S:	Maintained
 
-INTEL I8XX RANDOM NUMBER GENERATOR SUPPORT
-P:	Jeff Garzik
-M:	jgarzik@pobox.com
-W:	http://sourceforge.net/projects/gkernel/
-S:	Maintained
-
 INTEL IA32 MICROCODE UPDATE SUPPORT
 P:	Tigran Aivazian
 M:	tigran@aivazian.fsnet.co.uk
@@ -2695,8 +2672,6 @@ M:	Paul.Clements@steeleye.com
 S:	Maintained
 
 NETWORK DEVICE DRIVERS
-P:	Andrew Morton
-M:	akpm@linux-foundation.org
 P:	Jeff Garzik
 M:	jgarzik@pobox.com
 L:	netdev@vger.kernel.org
@@ -3248,6 +3223,8 @@ S:	Supported
 S390 NETWORK DRIVERS
 P:	Ursula Braun
 M:	ubraun@linux.vnet.ibm.com
+P:	Frank Blaschka
+M:	blaschka@linux.vnet.ibm.com
 M:	linux390@de.ibm.com
 L:	linux-s390@vger.kernel.org
 W:	http://www.ibm.com/developerworks/linux/linux390/
@@ -4103,10 +4080,6 @@ M:	hirofumi@mail.parknet.co.jp
 L:	linux-kernel@vger.kernel.org
 S:	Maintained
 
-VIA 82Cxxx AUDIO DRIVER (old OSS driver)
-P:	Jeff Garzik
-S:	Odd fixes
-
 VIA RHINE NETWORK DRIVER
 P:	Roger Luethi
 M:	rl@hellgate.ch
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2538816..86b8641 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2371,13 +2371,16 @@ config UGETH_TX_ON_DEMAND
 	depends on UCC_GETH
 
 config MV643XX_ETH
-	tristate "MV-643XX Ethernet support"
-	depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32)
+	tristate "Marvell Discovery (643XX) and Orion ethernet support"
+	depends on MV64360 || MV64X60 || (PPC_MULTIPLATFORM && PPC32) || ARCH_ORION
 	select MII
 	help
-	  This driver supports the gigabit Ethernet on the Marvell MV643XX
-	  chipset which is used in the Momenco Ocelot C and Jaguar ATX and
-	  Pegasos II, amongst other PPC and MIPS boards.
+	  This driver supports the gigabit ethernet MACs in the
+	  Marvell Discovery PPC/MIPS chipset family (MV643XX) and
+	  in the Marvell Orion ARM SoC family.
+
+	  Some boards that use the Discovery chipset are the Momenco
+	  Ocelot C and Jaguar ATX and Pegasos II.
 
 config QLA3XXX
 	tristate "QLogic QLA3XXX Network Driver Support"
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index 084f029..cb3c6fa 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2076,8 +2076,10 @@ void bond_3ad_unbind_slave(struct slave *slave)
  * times out, and it selects an aggregator for the ports that are yet not
  * related to any aggregator, and selects the active aggregator for a bond.
  */
-void bond_3ad_state_machine_handler(struct bonding *bond)
+void bond_3ad_state_machine_handler(struct work_struct *work)
 {
+	struct bonding *bond = container_of(work, struct bonding,
+					    ad_work.work);
 	struct port *port;
 	struct aggregator *aggregator;
 
@@ -2128,7 +2130,7 @@ void bond_3ad_state_machine_handler(struct bonding *bond)
 	}
 
 re_arm:
-	mod_timer(&(BOND_AD_INFO(bond).ad_timer), jiffies + ad_delta_in_ticks);
+	queue_delayed_work(bond->wq, &bond->ad_work, ad_delta_in_ticks);
 out:
 	read_unlock(&bond->lock);
 }
diff --git a/drivers/net/bonding/bond_3ad.h b/drivers/net/bonding/bond_3ad.h
index f165572..b5ee45f 100644
--- a/drivers/net/bonding/bond_3ad.h
+++ b/drivers/net/bonding/bond_3ad.h
@@ -276,7 +276,7 @@ struct ad_slave_info {
 void bond_3ad_initialize(struct bonding *bond, u16 tick_resolution, int lacp_fast);
 int  bond_3ad_bind_slave(struct slave *slave);
 void bond_3ad_unbind_slave(struct slave *slave);
-void bond_3ad_state_machine_handler(struct bonding *bond);
+void bond_3ad_state_machine_handler(struct work_struct *);
 void bond_3ad_adapter_speed_changed(struct slave *slave);
 void bond_3ad_adapter_duplex_changed(struct slave *slave);
 void bond_3ad_handle_link_change(struct slave *slave, char link);
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index aea2217..25b8dbf 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -128,12 +128,12 @@ static inline u8 _simple_hash(const u8 *hash_start, int hash_size)
 
 static inline void _lock_tx_hashtbl(struct bonding *bond)
 {
-	spin_lock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
+	spin_lock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
 }
 
 static inline void _unlock_tx_hashtbl(struct bonding *bond)
 {
-	spin_unlock(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
+	spin_unlock_bh(&(BOND_ALB_INFO(bond).tx_hashtbl_lock));
 }
 
 /* Caller must hold tx_hashtbl lock */
@@ -305,12 +305,12 @@ static struct slave *tlb_choose_channel(struct bonding *bond, u32 hash_index, u3
 /*********************** rlb specific functions ***************************/
 static inline void _lock_rx_hashtbl(struct bonding *bond)
 {
-	spin_lock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+	spin_lock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
 }
 
 static inline void _unlock_rx_hashtbl(struct bonding *bond)
 {
-	spin_unlock(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
+	spin_unlock_bh(&(BOND_ALB_INFO(bond).rx_hashtbl_lock));
 }
 
 /* when an ARP REPLY is received from a client update its info
@@ -472,13 +472,13 @@ static void rlb_clear_slave(struct bonding *bond, struct slave *slave)
 
 	_unlock_rx_hashtbl(bond);
 
-	write_lock(&bond->curr_slave_lock);
+	write_lock_bh(&bond->curr_slave_lock);
 
 	if (slave != bond->curr_active_slave) {
 		rlb_teach_disabled_mac_on_primary(bond, slave->dev->dev_addr);
 	}
 
-	write_unlock(&bond->curr_slave_lock);
+	write_unlock_bh(&bond->curr_slave_lock);
 }
 
 static void rlb_update_client(struct rlb_client_info *client_info)
@@ -959,19 +959,34 @@ static int alb_set_slave_mac_addr(struct slave *slave, u8 addr[], int hw)
 	return 0;
 }
 
-/* Caller must hold bond lock for write or curr_slave_lock for write*/
+/*
+ * Swap MAC addresses between two slaves.
+ *
+ * Called with RTNL held, and no other locks.
+ *
+ */
+
 static void alb_swap_mac_addr(struct bonding *bond, struct slave *slave1, struct slave *slave2)
 {
-	struct slave *disabled_slave = NULL;
 	u8 tmp_mac_addr[ETH_ALEN];
-	int slaves_state_differ;
-
-	slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
 
 	memcpy(tmp_mac_addr, slave1->dev->dev_addr, ETH_ALEN);
 	alb_set_slave_mac_addr(slave1, slave2->dev->dev_addr, bond->alb_info.rlb_enabled);
 	alb_set_slave_mac_addr(slave2, tmp_mac_addr, bond->alb_info.rlb_enabled);
 
+}
+
+/*
+ * Send learning packets after MAC address swap.
+ *
+ * Called with RTNL and bond->lock held for read.
+ */
+static void alb_fasten_mac_swap(struct bonding *bond, struct slave *slave1,
+				struct slave *slave2)
+{
+	int slaves_state_differ = (SLAVE_IS_OK(slave1) != SLAVE_IS_OK(slave2));
+	struct slave *disabled_slave = NULL;
+
 	/* fasten the change in the switch */
 	if (SLAVE_IS_OK(slave1)) {
 		alb_send_learning_packets(slave1, slave1->dev->dev_addr);
@@ -1044,7 +1059,9 @@ static void alb_change_hw_addr_on_detach(struct bonding *bond, struct slave *sla
 		}
 
 		if (found) {
+			/* locking: needs RTNL and nothing else */
 			alb_swap_mac_addr(bond, slave, tmp_slave);
+			alb_fasten_mac_swap(bond, slave, tmp_slave);
 		}
 	}
 }
@@ -1375,8 +1392,10 @@ out:
 	return 0;
 }
 
-void bond_alb_monitor(struct bonding *bond)
+void bond_alb_monitor(struct work_struct *work)
 {
+	struct bonding *bond = container_of(work, struct bonding,
+					    alb_work.work);
 	struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
 	struct slave *slave;
 	int i;
@@ -1436,16 +1455,16 @@ void bond_alb_monitor(struct bonding *bond)
 
 	/* handle rlb stuff */
 	if (bond_info->rlb_enabled) {
-		/* the following code changes the promiscuity of the
-		 * the curr_active_slave. It needs to be locked with a
-		 * write lock to protect from other code that also
-		 * sets the promiscuity.
-		 */
-		write_lock_bh(&bond->curr_slave_lock);
-
 		if (bond_info->primary_is_promisc &&
 		    (++bond_info->rlb_promisc_timeout_counter >= RLB_PROMISC_TIMEOUT)) {
 
+			/*
+			 * dev_set_promiscuity requires rtnl and
+			 * nothing else.
+			 */
+			read_unlock(&bond->lock);
+			rtnl_lock();
+
 			bond_info->rlb_promisc_timeout_counter = 0;
 
 			/* If the primary was set to promiscuous mode
@@ -1454,9 +1473,10 @@ void bond_alb_monitor(struct bonding *bond)
 			 */
 			dev_set_promiscuity(bond->curr_active_slave->dev, -1);
 			bond_info->primary_is_promisc = 0;
-		}
 
-		write_unlock_bh(&bond->curr_slave_lock);
+			rtnl_unlock();
+			read_lock(&bond->lock);
+		}
 
 		if (bond_info->rlb_rebalance) {
 			bond_info->rlb_rebalance = 0;
@@ -1479,7 +1499,7 @@ void bond_alb_monitor(struct bonding *bond)
 	}
 
 re_arm:
-	mod_timer(&(bond_info->alb_timer), jiffies + alb_delta_in_ticks);
+	queue_delayed_work(bond->wq, &bond->alb_work, alb_delta_in_ticks);
 out:
 	read_unlock(&bond->lock);
 }
@@ -1500,11 +1520,11 @@ int bond_alb_init_slave(struct bonding *bond, struct slave *slave)
 	/* caller must hold the bond lock for write since the mac addresses
 	 * are compared and may be swapped.
 	 */
-	write_lock_bh(&bond->lock);
+	read_lock(&bond->lock);
 
 	res = alb_handle_addr_collision_on_attach(bond, slave);
 
-	write_unlock_bh(&bond->lock);
+	read_unlock(&bond->lock);
 
 	if (res) {
 		return res;
@@ -1569,13 +1589,21 @@ void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char
  * Set the bond->curr_active_slave to @new_slave and handle
  * mac address swapping and promiscuity changes as needed.
  *
- * Caller must hold bond curr_slave_lock for write (or bond lock for write)
+ * If new_slave is NULL, caller must hold curr_slave_lock or
+ * bond->lock for write.
+ *
+ * If new_slave is not NULL, caller must hold RTNL, bond->lock for
+ * read and curr_slave_lock for write.  Processing here may sleep, so
+ * no other locks may be held.
  */
 void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave)
 {
 	struct slave *swap_slave;
 	int i;
 
+	if (new_slave)
+		ASSERT_RTNL();
+
 	if (bond->curr_active_slave == new_slave) {
 		return;
 	}
@@ -1608,6 +1636,19 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
 		}
 	}
 
+	/*
+	 * Arrange for swap_slave and new_slave to temporarily be
+	 * ignored so we can mess with their MAC addresses without
+	 * fear of interference from transmit activity.
+	 */
+	if (swap_slave) {
+		tlb_clear_slave(bond, swap_slave, 1);
+	}
+	tlb_clear_slave(bond, new_slave, 1);
+
+	write_unlock_bh(&bond->curr_slave_lock);
+	read_unlock(&bond->lock);
+
 	/* curr_active_slave must be set before calling alb_swap_mac_addr */
 	if (swap_slave) {
 		/* swap mac address */
@@ -1616,11 +1657,23 @@ void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave
 		/* set the new_slave to the bond mac address */
 		alb_set_slave_mac_addr(new_slave, bond->dev->dev_addr,
 				       bond->alb_info.rlb_enabled);
+	}
+
+	read_lock(&bond->lock);
+
+	if (swap_slave) {
+		alb_fasten_mac_swap(bond, swap_slave, new_slave);
+	} else {
 		/* fasten bond mac on new current slave */
 		alb_send_learning_packets(new_slave, bond->dev->dev_addr);
 	}
+
+	write_lock_bh(&bond->curr_slave_lock);
 }
 
+/*
+ * Called with RTNL
+ */
 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
 {
 	struct bonding *bond = bond_dev->priv;
@@ -1657,8 +1710,12 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
 		}
 	}
 
+	write_unlock_bh(&bond->curr_slave_lock);
+	read_unlock(&bond->lock);
+
 	if (swap_slave) {
 		alb_swap_mac_addr(bond, swap_slave, bond->curr_active_slave);
+		alb_fasten_mac_swap(bond, swap_slave, bond->curr_active_slave);
 	} else {
 		alb_set_slave_mac_addr(bond->curr_active_slave, bond_dev->dev_addr,
 				       bond->alb_info.rlb_enabled);
@@ -1670,6 +1727,9 @@ int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr)
 		}
 	}
 
+	read_lock(&bond->lock);
+	write_lock_bh(&bond->curr_slave_lock);
+
 	return 0;
 }
 
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index fd87264..50968f8 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -125,7 +125,7 @@ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave);
 void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
 void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
 int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
-void bond_alb_monitor(struct bonding *bond);
+void bond_alb_monitor(struct work_struct *);
 int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
 void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
 #endif /* __BOND_ALB_H__ */
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6f85cc3..6909bec 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1590,15 +1590,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 	case BOND_MODE_TLB:
 	case BOND_MODE_ALB:
 		new_slave->state = BOND_STATE_ACTIVE;
-		if ((!bond->curr_active_slave) &&
-		    (new_slave->link != BOND_LINK_DOWN)) {
-			/* first slave or no active slave yet, and this link
-			 * is OK, so make this interface the active one
-			 */
-			bond_change_active_slave(bond, new_slave);
-		} else {
-			bond_set_slave_inactive_flags(new_slave);
-		}
+		bond_set_slave_inactive_flags(new_slave);
 		break;
 	default:
 		dprintk("This slave is always active in trunk mode\n");
@@ -1754,9 +1746,23 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 		bond_alb_deinit_slave(bond, slave);
 	}
 
-	if (oldcurrent == slave)
+	if (oldcurrent == slave) {
+		/*
+		 * Note that we hold RTNL over this sequence, so there
+		 * is no concern that another slave add/remove event
+		 * will interfere.
+		 */
+		write_unlock_bh(&bond->lock);
+		read_lock(&bond->lock);
+		write_lock_bh(&bond->curr_slave_lock);
+
 		bond_select_active_slave(bond);
 
+		write_unlock_bh(&bond->curr_slave_lock);
+		read_unlock(&bond->lock);
+		write_lock_bh(&bond->lock);
+	}
+
 	if (bond->slave_cnt == 0) {
 		bond_set_carrier(bond);
 
@@ -1840,9 +1846,9 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 */
 void bond_destroy(struct bonding *bond)
 {
+	unregister_netdevice(bond->dev);
 	bond_deinit(bond->dev);
 	bond_destroy_sysfs_entry(bond);
-	unregister_netdevice(bond->dev);
 }
 
 /*
@@ -2012,16 +2018,19 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
 		return -EINVAL;
 	}
 
-	write_lock_bh(&bond->lock);
+	read_lock(&bond->lock);
 
+	read_lock(&bond->curr_slave_lock);
 	old_active = bond->curr_active_slave;
+	read_unlock(&bond->curr_slave_lock);
+
 	new_active = bond_get_slave_by_dev(bond, slave_dev);
 
 	/*
 	 * Changing to the current active: do nothing; return success.
 	 */
 	if (new_active && (new_active == old_active)) {
-		write_unlock_bh(&bond->lock);
+		read_unlock(&bond->lock);
 		return 0;
 	}
 
@@ -2029,12 +2038,14 @@ static int bond_ioctl_change_active(struct net_device *bond_dev, struct net_devi
 	    (old_active) &&
 	    (new_active->link == BOND_LINK_UP) &&
 	    IS_UP(new_active->dev)) {
+		write_lock_bh(&bond->curr_slave_lock);
 		bond_change_active_slave(bond, new_active);
+		write_unlock_bh(&bond->curr_slave_lock);
 	} else {
 		res = -EINVAL;
 	}
 
-	write_unlock_bh(&bond->lock);
+	read_unlock(&bond->lock);
 
 	return res;
 }
@@ -2046,9 +2057,9 @@ static int bond_info_query(struct net_device *bond_dev, struct ifbond *info)
 	info->bond_mode = bond->params.mode;
 	info->miimon = bond->params.miimon;
 
-	read_lock_bh(&bond->lock);
+	read_lock(&bond->lock);
 	info->num_slaves = bond->slave_cnt;
-	read_unlock_bh(&bond->lock);
+	read_unlock(&bond->lock);
 
 	return 0;
 }
@@ -2063,7 +2074,7 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
 		return -ENODEV;
 	}
 
-	read_lock_bh(&bond->lock);
+	read_lock(&bond->lock);
 
 	bond_for_each_slave(bond, slave, i) {
 		if (i == (int)info->slave_id) {
@@ -2072,7 +2083,7 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
 		}
 	}
 
-	read_unlock_bh(&bond->lock);
+	read_unlock(&bond->lock);
 
 	if (found) {
 		strcpy(info->slave_name, slave->dev->name);
@@ -2088,26 +2099,25 @@ static int bond_slave_info_query(struct net_device *bond_dev, struct ifslave *in
 
 /*-------------------------------- Monitoring -------------------------------*/
 
-/* this function is called regularly to monitor each slave's link. */
-void bond_mii_monitor(struct net_device *bond_dev)
+/*
+ * if !have_locks, return nonzero if a failover is necessary.  if
+ * have_locks, do whatever failover activities are needed.
+ *
+ * This is to separate the inspection and failover steps for locking
+ * purposes; failover requires rtnl, but acquiring it for every
+ * inspection is undesirable, so a wrapper first does inspection, and
+ * the acquires the necessary locks and calls again to perform
+ * failover if needed.  Since all locks are dropped, a complete
+ * restart is needed between calls.
+ */
+static int __bond_mii_monitor(struct bonding *bond, int have_locks)
 {
-	struct bonding *bond = bond_dev->priv;
 	struct slave *slave, *oldcurrent;
 	int do_failover = 0;
-	int delta_in_ticks;
 	int i;
 
-	read_lock(&bond->lock);
-
-	delta_in_ticks = (bond->params.miimon * HZ) / 1000;
-
-	if (bond->kill_timers) {
+	if (bond->slave_cnt == 0)
 		goto out;
-	}
-
-	if (bond->slave_cnt == 0) {
-		goto re_arm;
-	}
 
 	/* we will try to read the link status of each of our slaves, and
 	 * set their IFF_RUNNING flag appropriately. For each slave not
@@ -2141,7 +2151,11 @@ void bond_mii_monitor(struct net_device *bond_dev)
 		switch (slave->link) {
 		case BOND_LINK_UP:	/* the link was up */
 			if (link_state == BMSR_LSTATUS) {
-				/* link stays up, nothing more to do */
+				if (!oldcurrent) {
+					if (!have_locks)
+						return 1;
+					do_failover = 1;
+				}
 				break;
 			} else { /* link going down */
 				slave->link  = BOND_LINK_FAIL;
@@ -2156,7 +2170,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
 					       ": %s: link status down for %s "
 					       "interface %s, disabling it in "
 					       "%d ms.\n",
-					       bond_dev->name,
+					       bond->dev->name,
 					       IS_UP(slave_dev)
 					       ? ((bond->params.mode == BOND_MODE_ACTIVEBACKUP)
 						  ? ((slave == oldcurrent)
@@ -2174,6 +2188,9 @@ void bond_mii_monitor(struct net_device *bond_dev)
 			if (link_state != BMSR_LSTATUS) {
 				/* link stays down */
 				if (slave->delay <= 0) {
+					if (!have_locks)
+						return 1;
+
 					/* link down for too long time */
 					slave->link = BOND_LINK_DOWN;
 
@@ -2189,7 +2206,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
 					       ": %s: link status definitely "
 					       "down for interface %s, "
 					       "disabling it\n",
-					       bond_dev->name,
+					       bond->dev->name,
 					       slave_dev->name);
 
 					/* notify ad that the link status has changed */
@@ -2215,7 +2232,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
 				printk(KERN_INFO DRV_NAME
 				       ": %s: link status up again after %d "
 				       "ms for interface %s.\n",
-				       bond_dev->name,
+				       bond->dev->name,
 				       (bond->params.downdelay - slave->delay) * bond->params.miimon,
 				       slave_dev->name);
 			}
@@ -2235,7 +2252,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
 					       ": %s: link status up for "
 					       "interface %s, enabling it "
 					       "in %d ms.\n",
-					       bond_dev->name,
+					       bond->dev->name,
 					       slave_dev->name,
 					       bond->params.updelay * bond->params.miimon);
 				}
@@ -2251,12 +2268,15 @@ void bond_mii_monitor(struct net_device *bond_dev)
 				printk(KERN_INFO DRV_NAME
 				       ": %s: link status down again after %d "
 				       "ms for interface %s.\n",
-				       bond_dev->name,
+				       bond->dev->name,
 				       (bond->params.updelay - slave->delay) * bond->params.miimon,
 				       slave_dev->name);
 			} else {
 				/* link stays up */
 				if (slave->delay == 0) {
+					if (!have_locks)
+						return 1;
+
 					/* now the link has been up for long time enough */
 					slave->link = BOND_LINK_UP;
 					slave->jiffies = jiffies;
@@ -2275,7 +2295,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
 					printk(KERN_INFO DRV_NAME
 					       ": %s: link status definitely "
 					       "up for interface %s.\n",
-					       bond_dev->name,
+					       bond->dev->name,
 					       slave_dev->name);
 
 					/* notify ad that the link status has changed */
@@ -2301,7 +2321,7 @@ void bond_mii_monitor(struct net_device *bond_dev)
 			/* Should not happen */
 			printk(KERN_ERR DRV_NAME
 			       ": %s: Error: %s Illegal value (link=%d)\n",
-			       bond_dev->name,
+			       bond->dev->name,
 			       slave->dev->name,
 			       slave->link);
 			goto out;
@@ -2322,22 +2342,52 @@ void bond_mii_monitor(struct net_device *bond_dev)
 	} /* end of for */
 
 	if (do_failover) {
-		write_lock(&bond->curr_slave_lock);
+		ASSERT_RTNL();
+
+		write_lock_bh(&bond->curr_slave_lock);
 
 		bond_select_active_slave(bond);
 
-		write_unlock(&bond->curr_slave_lock);
+		write_unlock_bh(&bond->curr_slave_lock);
+
 	} else
 		bond_set_carrier(bond);
 
-re_arm:
-	if (bond->params.miimon) {
-		mod_timer(&bond->mii_timer, jiffies + delta_in_ticks);
-	}
 out:
-	read_unlock(&bond->lock);
+	return 0;
 }
 
+/*
+ * bond_mii_monitor
+ *
+ * Really a wrapper that splits the mii monitor into two phases: an
+ * inspection, then (if inspection indicates something needs to be
+ * done) an acquisition of appropriate locks followed by another pass
+ * to implement whatever link state changes are indicated.
+ */
+void bond_mii_monitor(struct work_struct *work)
+{
+	struct bonding *bond = container_of(work, struct bonding,
+					    mii_work.work);
+	unsigned long delay;
+
+	read_lock(&bond->lock);
+	if (bond->kill_timers) {
+		read_unlock(&bond->lock);
+		return;
+	}
+	if (__bond_mii_monitor(bond, 0)) {
+		read_unlock(&bond->lock);
+		rtnl_lock();
+		read_lock(&bond->lock);
+		__bond_mii_monitor(bond, 1);
+		rtnl_unlock();
+	}
+
+	delay = ((bond->params.miimon * HZ) / 1000) ? : 1;
+	read_unlock(&bond->lock);
+	queue_delayed_work(bond->wq, &bond->mii_work, delay);
+}
 
 static __be32 bond_glean_dev_ip(struct net_device *dev)
 {
@@ -2636,9 +2686,10 @@ out:
  * arp is transmitted to generate traffic. see activebackup_arp_monitor for
  * arp monitoring in active backup mode.
  */
-void bond_loadbalance_arp_mon(struct net_device *bond_dev)
+void bond_loadbalance_arp_mon(struct work_struct *work)
 {
-	struct bonding *bond = bond_dev->priv;
+	struct bonding *bond = container_of(work, struct bonding,
+					    arp_work.work);
 	struct slave *slave, *oldcurrent;
 	int do_failover = 0;
 	int delta_in_ticks;
@@ -2685,13 +2736,13 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev)
 					printk(KERN_INFO DRV_NAME
 					       ": %s: link status definitely "
 					       "up for interface %s, ",
-					       bond_dev->name,
+					       bond->dev->name,
 					       slave->dev->name);
 					do_failover = 1;
 				} else {
 					printk(KERN_INFO DRV_NAME
 					       ": %s: interface %s is now up\n",
-					       bond_dev->name,
+					       bond->dev->name,
 					       slave->dev->name);
 				}
 			}
@@ -2715,7 +2766,7 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev)
 
 				printk(KERN_INFO DRV_NAME
 				       ": %s: interface %s is now down.\n",
-				       bond_dev->name,
+				       bond->dev->name,
 				       slave->dev->name);
 
 				if (slave == oldcurrent) {
@@ -2737,17 +2788,19 @@ void bond_loadbalance_arp_mon(struct net_device *bond_dev)
 	}
 
 	if (do_failover) {
-		write_lock(&bond->curr_slave_lock);
+		rtnl_lock();
+		write_lock_bh(&bond->curr_slave_lock);
 
 		bond_select_active_slave(bond);
 
-		write_unlock(&bond->curr_slave_lock);
+		write_unlock_bh(&bond->curr_slave_lock);
+		rtnl_unlock();
+
 	}
 
 re_arm:
-	if (bond->params.arp_interval) {
-		mod_timer(&bond->arp_timer, jiffies + delta_in_ticks);
-	}
+	if (bond->params.arp_interval)
+		queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
 out:
 	read_unlock(&bond->lock);
 }
@@ -2767,9 +2820,10 @@ out:
  * may have received.
  * see loadbalance_arp_monitor for arp monitoring in load balancing mode
  */
-void bond_activebackup_arp_mon(struct net_device *bond_dev)
+void bond_activebackup_arp_mon(struct work_struct *work)
 {
-	struct bonding *bond = bond_dev->priv;
+	struct bonding *bond = container_of(work, struct bonding,
+					    arp_work.work);
 	struct slave *slave;
 	int delta_in_ticks;
 	int i;
@@ -2798,7 +2852,9 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
 
 				slave->link = BOND_LINK_UP;
 
-				write_lock(&bond->curr_slave_lock);
+				rtnl_lock();
+
+				write_lock_bh(&bond->curr_slave_lock);
 
 				if ((!bond->curr_active_slave) &&
 				    ((jiffies - slave->dev->trans_start) <= delta_in_ticks)) {
@@ -2821,18 +2877,19 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
 					printk(KERN_INFO DRV_NAME
 					       ": %s: %s is up and now the "
 					       "active interface\n",
-					       bond_dev->name,
+					       bond->dev->name,
 					       slave->dev->name);
 					netif_carrier_on(bond->dev);
 				} else {
 					printk(KERN_INFO DRV_NAME
 					       ": %s: backup interface %s is "
 					       "now up\n",
-					       bond_dev->name,
+					       bond->dev->name,
 					       slave->dev->name);
 				}
 
-				write_unlock(&bond->curr_slave_lock);
+				write_unlock_bh(&bond->curr_slave_lock);
+				rtnl_unlock();
 			}
 		} else {
 			read_lock(&bond->curr_slave_lock);
@@ -2864,7 +2921,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
 
 				printk(KERN_INFO DRV_NAME
 				       ": %s: backup interface %s is now down\n",
-				       bond_dev->name,
+				       bond->dev->name,
 				       slave->dev->name);
 			} else {
 				read_unlock(&bond->curr_slave_lock);
@@ -2899,15 +2956,18 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
 			printk(KERN_INFO DRV_NAME
 			       ": %s: link status down for active interface "
 			       "%s, disabling it\n",
-			       bond_dev->name,
+			       bond->dev->name,
 			       slave->dev->name);
 
-			write_lock(&bond->curr_slave_lock);
+			rtnl_lock();
+			write_lock_bh(&bond->curr_slave_lock);
 
 			bond_select_active_slave(bond);
 			slave = bond->curr_active_slave;
 
-			write_unlock(&bond->curr_slave_lock);
+			write_unlock_bh(&bond->curr_slave_lock);
+
+			rtnl_unlock();
 
 			bond->current_arp_slave = slave;
 
@@ -2921,14 +2981,17 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
 			printk(KERN_INFO DRV_NAME
 			       ": %s: changing from interface %s to primary "
 			       "interface %s\n",
-			       bond_dev->name,
+			       bond->dev->name,
 			       slave->dev->name,
 			       bond->primary_slave->dev->name);
 
 			/* primary is up so switch to it */
-			write_lock(&bond->curr_slave_lock);
+			rtnl_lock();
+			write_lock_bh(&bond->curr_slave_lock);
 			bond_change_active_slave(bond, bond->primary_slave);
-			write_unlock(&bond->curr_slave_lock);
+			write_unlock_bh(&bond->curr_slave_lock);
+
+			rtnl_unlock();
 
 			slave = bond->primary_slave;
 			slave->jiffies = jiffies;
@@ -2985,7 +3048,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
 					printk(KERN_INFO DRV_NAME
 					       ": %s: backup interface %s is "
 					       "now down.\n",
-					       bond_dev->name,
+					       bond->dev->name,
 					       slave->dev->name);
 				}
 			}
@@ -2994,7 +3057,7 @@ void bond_activebackup_arp_mon(struct net_device *bond_dev)
 
 re_arm:
 	if (bond->params.arp_interval) {
-		mod_timer(&bond->arp_timer, jiffies + delta_in_ticks);
+		queue_delayed_work(bond->wq, &bond->arp_work, delta_in_ticks);
 	}
 out:
 	read_unlock(&bond->lock);
@@ -3015,7 +3078,7 @@ static void *bond_info_seq_start(struct seq_file *seq, loff_t *pos)
 
 	/* make sure the bond won't be taken away */
 	read_lock(&dev_base_lock);
-	read_lock_bh(&bond->lock);
+	read_lock(&bond->lock);
 
 	if (*pos == 0) {
 		return SEQ_START_TOKEN;
@@ -3049,7 +3112,7 @@ static void bond_info_seq_stop(struct seq_file *seq, void *v)
 {
 	struct bonding *bond = seq->private;
 
-	read_unlock_bh(&bond->lock);
+	read_unlock(&bond->lock);
 	read_unlock(&dev_base_lock);
 }
 
@@ -3582,15 +3645,11 @@ static int bond_xmit_hash_policy_l2(struct sk_buff *skb,
 static int bond_open(struct net_device *bond_dev)
 {
 	struct bonding *bond = bond_dev->priv;
-	struct timer_list *mii_timer = &bond->mii_timer;
-	struct timer_list *arp_timer = &bond->arp_timer;
 
 	bond->kill_timers = 0;
 
 	if ((bond->params.mode == BOND_MODE_TLB) ||
 	    (bond->params.mode == BOND_MODE_ALB)) {
-		struct timer_list *alb_timer = &(BOND_ALB_INFO(bond).alb_timer);
-
 		/* bond_alb_initialize must be called before the timer
 		 * is started.
 		 */
@@ -3599,44 +3658,31 @@ static int bond_open(struct net_device *bond_dev)
 			return -1;
 		}
 
-		init_timer(alb_timer);
-		alb_timer->expires  = jiffies + 1;
-		alb_timer->data     = (unsigned long)bond;
-		alb_timer->function = (void *)&bond_alb_monitor;
-		add_timer(alb_timer);
+		INIT_DELAYED_WORK(&bond->alb_work, bond_alb_monitor);
+		queue_delayed_work(bond->wq, &bond->alb_work, 0);
 	}
 
 	if (bond->params.miimon) {  /* link check interval, in milliseconds. */
-		init_timer(mii_timer);
-		mii_timer->expires  = jiffies + 1;
-		mii_timer->data     = (unsigned long)bond_dev;
-		mii_timer->function = (void *)&bond_mii_monitor;
-		add_timer(mii_timer);
+		INIT_DELAYED_WORK(&bond->mii_work, bond_mii_monitor);
+		queue_delayed_work(bond->wq, &bond->mii_work, 0);
 	}
 
 	if (bond->params.arp_interval) {  /* arp interval, in milliseconds. */
-		init_timer(arp_timer);
-		arp_timer->expires  = jiffies + 1;
-		arp_timer->data     = (unsigned long)bond_dev;
-		if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
-			arp_timer->function = (void *)&bond_activebackup_arp_mon;
-		} else {
-			arp_timer->function = (void *)&bond_loadbalance_arp_mon;
-		}
+		if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+			INIT_DELAYED_WORK(&bond->arp_work,
+					  bond_activebackup_arp_mon);
+		else
+			INIT_DELAYED_WORK(&bond->arp_work,
+					  bond_loadbalance_arp_mon);
+
+		queue_delayed_work(bond->wq, &bond->arp_work, 0);
 		if (bond->params.arp_validate)
 			bond_register_arp(bond);
-
-		add_timer(arp_timer);
 	}
 
 	if (bond->params.mode == BOND_MODE_8023AD) {
-		struct timer_list *ad_timer = &(BOND_AD_INFO(bond).ad_timer);
-		init_timer(ad_timer);
-		ad_timer->expires  = jiffies + 1;
-		ad_timer->data     = (unsigned long)bond;
-		ad_timer->function = (void *)&bond_3ad_state_machine_handler;
-		add_timer(ad_timer);
-
+		INIT_DELAYED_WORK(&bond->ad_work, bond_alb_monitor);
+		queue_delayed_work(bond->wq, &bond->ad_work, 0);
 		/* register to receive LACPDUs */
 		bond_register_lacpdu(bond);
 	}
@@ -3664,25 +3710,21 @@ static int bond_close(struct net_device *bond_dev)
 
 	write_unlock_bh(&bond->lock);
 
-	/* del_timer_sync must run without holding the bond->lock
-	 * because a running timer might be trying to hold it too
-	 */
-
 	if (bond->params.miimon) {  /* link check interval, in milliseconds. */
-		del_timer_sync(&bond->mii_timer);
+		cancel_delayed_work(&bond->mii_work);
 	}
 
 	if (bond->params.arp_interval) {  /* arp interval, in milliseconds. */
-		del_timer_sync(&bond->arp_timer);
+		cancel_delayed_work(&bond->arp_work);
 	}
 
 	switch (bond->params.mode) {
 	case BOND_MODE_8023AD:
-		del_timer_sync(&(BOND_AD_INFO(bond).ad_timer));
+		cancel_delayed_work(&bond->ad_work);
 		break;
 	case BOND_MODE_TLB:
 	case BOND_MODE_ALB:
-		del_timer_sync(&(BOND_ALB_INFO(bond).alb_timer));
+		cancel_delayed_work(&bond->alb_work);
 		break;
 	default:
 		break;
@@ -3779,13 +3821,13 @@ static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd
 		if (mii->reg_num == 1) {
 			struct bonding *bond = bond_dev->priv;
 			mii->val_out = 0;
-			read_lock_bh(&bond->lock);
+			read_lock(&bond->lock);
 			read_lock(&bond->curr_slave_lock);
 			if (netif_carrier_ok(bond->dev)) {
 				mii->val_out = BMSR_LSTATUS;
 			}
 			read_unlock(&bond->curr_slave_lock);
-			read_unlock_bh(&bond->lock);
+			read_unlock(&bond->lock);
 		}
 
 		return 0;
@@ -4077,8 +4119,7 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
 {
 	struct bonding *bond = bond_dev->priv;
 	struct slave *slave, *start_at;
-	int i;
-	int res = 1;
+	int i, slave_no, res = 1;
 
 	read_lock(&bond->lock);
 
@@ -4086,29 +4127,29 @@ static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev
 		goto out;
 	}
 
-	read_lock(&bond->curr_slave_lock);
-	slave = start_at = bond->curr_active_slave;
-	read_unlock(&bond->curr_slave_lock);
+	/*
+	 * Concurrent TX may collide on rr_tx_counter; we accept that
+	 * as being rare enough not to justify using an atomic op here
+	 */
+	slave_no = bond->rr_tx_counter++ % bond->slave_cnt;
 
-	if (!slave) {
-		goto out;
+	bond_for_each_slave(bond, slave, i) {
+		slave_no--;
+		if (slave_no < 0) {
+			break;
+		}
 	}
 
+	start_at = slave;
 	bond_for_each_slave_from(bond, slave, i, start_at) {
 		if (IS_UP(slave->dev) &&
 		    (slave->link == BOND_LINK_UP) &&
 		    (slave->state == BOND_STATE_ACTIVE)) {
 			res = bond_dev_queue_xmit(bond, skb, slave->dev);
-
-			write_lock(&bond->curr_slave_lock);
-			bond->curr_active_slave = slave->next;
-			write_unlock(&bond->curr_slave_lock);
-
 			break;
 		}
 	}
 
-
 out:
 	if (res) {
 		/* no suitable interface, frame not sent */
@@ -4340,6 +4381,10 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
 
 	bond->params = *params; /* copy params struct */
 
+	bond->wq = create_singlethread_workqueue(bond_dev->name);
+	if (!bond->wq)
+		return -ENOMEM;
+
 	/* Initialize pointers */
 	bond->first_slave = NULL;
 	bond->curr_active_slave = NULL;
@@ -4428,8 +4473,8 @@ static void bond_free_all(void)
 		bond_mc_list_destroy(bond);
 		/* Release the bonded slaves */
 		bond_release_all(bond_dev);
-		bond_deinit(bond_dev);
 		unregister_netdevice(bond_dev);
+		bond_deinit(bond_dev);
 	}
 
 #ifdef CONFIG_PROC_FS
@@ -4826,10 +4871,32 @@ out_rtnl:
 	return res;
 }
 
+static void bond_work_cancel_all(struct bonding *bond)
+{
+	write_lock_bh(&bond->lock);
+	bond->kill_timers = 1;
+	write_unlock_bh(&bond->lock);
+
+	if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
+		cancel_delayed_work(&bond->mii_work);
+
+	if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
+		cancel_delayed_work(&bond->arp_work);
+
+	if (bond->params.mode == BOND_MODE_ALB &&
+	    delayed_work_pending(&bond->alb_work))
+		cancel_delayed_work(&bond->alb_work);
+
+	if (bond->params.mode == BOND_MODE_8023AD &&
+	    delayed_work_pending(&bond->ad_work))
+		cancel_delayed_work(&bond->ad_work);
+}
+
 static int __init bonding_init(void)
 {
 	int i;
 	int res;
+	struct bonding *bond, *nxt;
 
 	printk(KERN_INFO "%s", version);
 
@@ -4856,6 +4923,11 @@ static int __init bonding_init(void)
 
 	goto out;
 err:
+	list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
+		bond_work_cancel_all(bond);
+		destroy_workqueue(bond->wq);
+	}
+
 	rtnl_lock();
 	bond_free_all();
 	bond_destroy_sysfs();
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 855dc10..7a06ade 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -229,7 +229,7 @@ static ssize_t bonding_show_slaves(struct device *d,
 	int i, res = 0;
 	struct bonding *bond = to_bond(d);
 
-	read_lock_bh(&bond->lock);
+	read_lock(&bond->lock);
 	bond_for_each_slave(bond, slave, i) {
 		if (res > (PAGE_SIZE - IFNAMSIZ)) {
 			/* not enough space for another interface name */
@@ -240,7 +240,7 @@ static ssize_t bonding_show_slaves(struct device *d,
 		}
 		res += sprintf(buf + res, "%s ", slave->dev->name);
 	}
-	read_unlock_bh(&bond->lock);
+	read_unlock(&bond->lock);
 	res += sprintf(buf + res, "\n");
 	res++;
 	return res;
@@ -282,18 +282,18 @@ static ssize_t bonding_store_slaves(struct device *d,
 
 		/* Got a slave name in ifname.  Is it already in the list? */
 		found = 0;
-		read_lock_bh(&bond->lock);
+		read_lock(&bond->lock);
 		bond_for_each_slave(bond, slave, i)
 			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
 				printk(KERN_ERR DRV_NAME
 				       ": %s: Interface %s is already enslaved!\n",
 				       bond->dev->name, ifname);
 				ret = -EPERM;
-				read_unlock_bh(&bond->lock);
+				read_unlock(&bond->lock);
 				goto out;
 			}
 
-		read_unlock_bh(&bond->lock);
+		read_unlock(&bond->lock);
 		printk(KERN_INFO DRV_NAME ": %s: Adding slave %s.\n",
 		       bond->dev->name, ifname);
 		dev = dev_get_by_name(&init_net, ifname);
@@ -662,12 +662,9 @@ static ssize_t bonding_store_arp_interval(struct device *d,
 		       "%s Disabling MII monitoring.\n",
 		       bond->dev->name, bond->dev->name);
 		bond->params.miimon = 0;
-		/* Kill MII timer, else it brings bond's link down */
-		if (bond->arp_timer.function) {
-			printk(KERN_INFO DRV_NAME
-			": %s: Kill MII timer, else it brings bond's link down...\n",
-		       bond->dev->name);
-			del_timer_sync(&bond->mii_timer);
+		if (delayed_work_pending(&bond->mii_work)) {
+			cancel_delayed_work(&bond->mii_work);
+			flush_workqueue(bond->wq);
 		}
 	}
 	if (!bond->params.arp_targets[0]) {
@@ -682,25 +679,15 @@ static ssize_t bonding_store_arp_interval(struct device *d,
 		 * timer will get fired off when the open function
 		 * is called.
 		 */
-		if (bond->arp_timer.function) {
-			/* The timer's already set up, so fire it off */
-			mod_timer(&bond->arp_timer, jiffies + 1);
-		} else {
-			/* Set up the timer. */
-			init_timer(&bond->arp_timer);
-			bond->arp_timer.expires = jiffies + 1;
-			bond->arp_timer.data =
-				(unsigned long) bond->dev;
-			if (bond->params.mode == BOND_MODE_ACTIVEBACKUP) {
-				bond->arp_timer.function =
-					(void *)
-					&bond_activebackup_arp_mon;
-			} else {
-				bond->arp_timer.function =
-					(void *)
-					&bond_loadbalance_arp_mon;
-			}
-			add_timer(&bond->arp_timer);
+		if (!delayed_work_pending(&bond->arp_work)) {
+			if (bond->params.mode == BOND_MODE_ACTIVEBACKUP)
+				INIT_DELAYED_WORK(&bond->arp_work,
+						  bond_activebackup_arp_mon);
+			else
+				INIT_DELAYED_WORK(&bond->arp_work,
+						  bond_loadbalance_arp_mon);
+
+			queue_delayed_work(bond->wq, &bond->arp_work, 0);
 		}
 	}
 
@@ -1056,12 +1043,9 @@ static ssize_t bonding_store_miimon(struct device *d,
 				bond->params.arp_validate =
 					BOND_ARP_VALIDATE_NONE;
 			}
-			/* Kill ARP timer, else it brings bond's link down */
-			if (bond->mii_timer.function) {
-				printk(KERN_INFO DRV_NAME
-				": %s: Kill ARP timer, else it brings bond's link down...\n",
-			       bond->dev->name);
-				del_timer_sync(&bond->arp_timer);
+			if (delayed_work_pending(&bond->arp_work)) {
+				cancel_delayed_work(&bond->arp_work);
+				flush_workqueue(bond->wq);
 			}
 		}
 
@@ -1071,18 +1055,11 @@ static ssize_t bonding_store_miimon(struct device *d,
 			 * timer will get fired off when the open function
 			 * is called.
 			 */
-			if (bond->mii_timer.function) {
-				/* The timer's already set up, so fire it off */
-				mod_timer(&bond->mii_timer, jiffies + 1);
-			} else {
-				/* Set up the timer. */
-				init_timer(&bond->mii_timer);
-				bond->mii_timer.expires = jiffies + 1;
-				bond->mii_timer.data =
-					(unsigned long) bond->dev;
-				bond->mii_timer.function =
-					(void *) &bond_mii_monitor;
-				add_timer(&bond->mii_timer);
+			if (!delayed_work_pending(&bond->mii_work)) {
+				INIT_DELAYED_WORK(&bond->mii_work,
+						  bond_mii_monitor);
+				queue_delayed_work(bond->wq,
+						   &bond->mii_work, 0);
 			}
 		}
 	}
@@ -1156,6 +1133,9 @@ static ssize_t bonding_store_primary(struct device *d,
 	}
 out:
 	write_unlock_bh(&bond->lock);
+
+	rtnl_unlock();
+
 	return count;
 }
 static DEVICE_ATTR(primary, S_IRUGO | S_IWUSR, bonding_show_primary, bonding_store_primary);
@@ -1213,6 +1193,7 @@ static ssize_t bonding_show_active_slave(struct device *d,
 	struct bonding *bond = to_bond(d);
 	int count;
 
+	rtnl_lock();
 
 	read_lock(&bond->curr_slave_lock);
 	curr = bond->curr_active_slave;
@@ -1292,6 +1273,8 @@ static ssize_t bonding_store_active_slave(struct device *d,
 	}
 out:
 	write_unlock_bh(&bond->lock);
+	rtnl_unlock();
+
 	return count;
 
 }
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index b818060..d1ed14b 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -184,8 +184,6 @@ struct bonding {
 	s32      slave_cnt; /* never change this value outside the attach/detach wrappers */
 	rwlock_t lock;
 	rwlock_t curr_slave_lock;
-	struct   timer_list mii_timer;
-	struct   timer_list arp_timer;
 	s8       kill_timers;
 	s8	 send_grat_arp;
 	s8	 setup_by_slave;
@@ -199,12 +197,18 @@ struct bonding {
 	int      (*xmit_hash_policy)(struct sk_buff *, struct net_device *, int);
 	__be32   master_ip;
 	u16      flags;
+	u16      rr_tx_counter;
 	struct   ad_bond_info ad_info;
 	struct   alb_bond_info alb_info;
 	struct   bond_params params;
 	struct   list_head vlan_list;
 	struct   vlan_group *vlgrp;
 	struct   packet_type arp_mon_pt;
+	struct   workqueue_struct *wq;
+	struct   delayed_work mii_work;
+	struct   delayed_work arp_work;
+	struct   delayed_work alb_work;
+	struct   delayed_work ad_work;
 };
 
 /**
@@ -307,9 +311,9 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla
 void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
 int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
 int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
-void bond_mii_monitor(struct net_device *bond_dev);
-void bond_loadbalance_arp_mon(struct net_device *bond_dev);
-void bond_activebackup_arp_mon(struct net_device *bond_dev);
+void bond_mii_monitor(struct work_struct *);
+void bond_loadbalance_arp_mon(struct work_struct *);
+void bond_activebackup_arp_mon(struct work_struct *);
 void bond_set_mode_ops(struct bonding *bond, int mode);
 int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
 void bond_select_active_slave(struct bonding *bond);
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
index ae41973..57541d2 100644
--- a/drivers/net/cpmac.c
+++ b/drivers/net/cpmac.c
@@ -460,18 +460,11 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	struct cpmac_desc *desc;
 	struct cpmac_priv *priv = netdev_priv(dev);
 
-	if (unlikely(skb_padto(skb, ETH_ZLEN))) {
-		if (netif_msg_tx_err(priv) && net_ratelimit())
-			printk(KERN_WARNING
-			       "%s: tx: padding failed, dropping\n", dev->name);
-		spin_lock(&priv->lock);
-		dev->stats.tx_dropped++;
-		spin_unlock(&priv->lock);
-		return -ENOMEM;
-	}
+	if (unlikely(skb_padto(skb, ETH_ZLEN)))
+		return NETDEV_TX_OK;
 
 	len = max(skb->len, ETH_ZLEN);
-	queue = skb_get_queue_mapping(skb);
+	queue = skb->queue_mapping;
 #ifdef CONFIG_NETDEVICES_MULTIQUEUE
 	netif_stop_subqueue(dev, queue);
 #else
@@ -481,13 +474,9 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	desc = &priv->desc_ring[queue];
 	if (unlikely(desc->dataflags & CPMAC_OWN)) {
 		if (netif_msg_tx_err(priv) && net_ratelimit())
-			printk(KERN_WARNING "%s: tx dma ring full, dropping\n",
+			printk(KERN_WARNING "%s: tx dma ring full\n",
 			       dev->name);
-		spin_lock(&priv->lock);
-		dev->stats.tx_dropped++;
-		spin_unlock(&priv->lock);
-		dev_kfree_skb_any(skb);
-		return -ENOMEM;
+		return NETDEV_TX_BUSY;
 	}
 
 	spin_lock(&priv->lock);
@@ -509,7 +498,7 @@ static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		cpmac_dump_skb(dev, skb);
 	cpmac_write(priv->regs, CPMAC_TX_PTR(queue), (u32)desc->mapping);
 
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 static void cpmac_end_xmit(struct net_device *dev, int queue)
@@ -646,12 +635,14 @@ static void cpmac_clear_tx(struct net_device *dev)
 	int i;
 	if (unlikely(!priv->desc_ring))
 		return;
-	for (i = 0; i < CPMAC_QUEUES; i++)
+	for (i = 0; i < CPMAC_QUEUES; i++) {
+		priv->desc_ring[i].dataflags = 0;
 		if (priv->desc_ring[i].skb) {
 			dev_kfree_skb_any(priv->desc_ring[i].skb);
 			if (netif_subqueue_stopped(dev, i))
 			    netif_wake_subqueue(dev, i);
 		}
+	}
 }
 
 static void cpmac_hw_error(struct work_struct *work)
@@ -727,11 +718,13 @@ static void cpmac_tx_timeout(struct net_device *dev)
 #ifdef CONFIG_NETDEVICES_MULTIQUEUE
 	for (i = 0; i < CPMAC_QUEUES; i++)
 		if (priv->desc_ring[i].skb) {
+			priv->desc_ring[i].dataflags = 0;
 			dev_kfree_skb_any(priv->desc_ring[i].skb);
 			netif_wake_subqueue(dev, i);
 			break;
 		}
 #else
+	priv->desc_ring[0].dataflags = 0;
 	if (priv->desc_ring[0].skb)
 		dev_kfree_skb_any(priv->desc_ring[0].skb);
 	netif_wake_queue(dev);
@@ -794,7 +787,7 @@ static int cpmac_set_ringparam(struct net_device *dev, struct ethtool_ringparam*
 {
 	struct cpmac_priv *priv = netdev_priv(dev);
 
-	if (dev->flags && IFF_UP)
+	if (netif_running(dev))
 		return -EBUSY;
 	priv->ring_size = ring->rx_pending;
 	return 0;
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index b07613e..ddc30c4 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -805,7 +805,7 @@ static void __devinit dfx_bus_init(struct net_device *dev)
  *   Interrupts are disabled at the adapter bus-specific logic.
  */
 
-static void __devinit dfx_bus_uninit(struct net_device *dev)
+static void __devexit dfx_bus_uninit(struct net_device *dev)
 {
 	DFX_board_t *bp = netdev_priv(dev);
 	struct device *bdev = bp->bus_dev;
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index 37707a0..aafc3ce 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -30,6 +30,7 @@ static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
 			int len)
 {
 	uint32_t available_len = inl(mipsnet_reg_address(dev, rxDataCount));
+
 	if (available_len < len)
 		return -EFAULT;
 
@@ -45,14 +46,8 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
 	int count_to_go = skb->len;
 	char *buf_ptr = skb->data;
 
-	pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n",
-		 dev->name, __FUNCTION__, skb->len);
-
 	outl(skb->len, mipsnet_reg_address(dev, txDataCount));
 
-	pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n",
-		 dev->name, __FUNCTION__, skb->len);
-
 	for (; count_to_go; buf_ptr++, count_to_go--)
 		outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer));
 
@@ -64,10 +59,8 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
 
 static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	pr_debug("%s:%s(): transmitting %d bytes\n",
-		 dev->name, __FUNCTION__, skb->len);
-
-	/* Only one packet at a time. Once TXDONE interrupt is serviced, the
+	/*
+	 * Only one packet at a time. Once TXDONE interrupt is serviced, the
 	 * queue will be restarted.
 	 */
 	netif_stop_queue(dev);
@@ -94,8 +87,6 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
 	skb->protocol = eth_type_trans(skb, dev);
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-	pr_debug("%s:%s(): pushing RXed data to kernel\n",
-		 dev->name, __FUNCTION__);
 	netif_rx(skb);
 
 	dev->stats.rx_packets++;
@@ -112,44 +103,29 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
 	uint64_t interruptFlags;
 
 	if (irq == dev->irq) {
-		pr_debug("%s:%s(): irq %d for device\n",
-			 dev->name, __FUNCTION__, irq);
-
 		retval = IRQ_HANDLED;
 
 		interruptFlags =
 		    inl(mipsnet_reg_address(dev, interruptControl));
-		pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
-			 __FUNCTION__, interruptFlags);
 
 		if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
-			pr_debug("%s:%s(): got TXDone\n",
-				 dev->name, __FUNCTION__);
 			outl(MIPSNET_INTCTL_TXDONE,
 			     mipsnet_reg_address(dev, interruptControl));
 			/* only one packet at a time, we are done. */
 			netif_wake_queue(dev);
 		} else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
-			pr_debug("%s:%s(): got RX data\n",
-				 dev->name, __FUNCTION__);
 			mipsnet_get_fromdev(dev,
 				    inl(mipsnet_reg_address(dev, rxDataCount)));
-			pr_debug("%s:%s(): clearing RX int\n",
-				 dev->name, __FUNCTION__);
 			outl(MIPSNET_INTCTL_RXDONE,
 			     mipsnet_reg_address(dev, interruptControl));
 
 		} else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
-			pr_debug("%s:%s(): got test interrupt\n",
-				 dev->name, __FUNCTION__);
 			/*
 			 * TESTBIT is cleared on read.
 			 * And takes effect after a write with 0
 			 */
 			outl(0, mipsnet_reg_address(dev, interruptControl));
 		} else {
-			pr_debug("%s:%s(): no valid fags 0x%016llx\n",
-				 dev->name, __FUNCTION__, interruptFlags);
 			/* Maybe shared IRQ, just ignore, no clearing. */
 			retval = IRQ_NONE;
 		}
@@ -165,22 +141,15 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
 static int mipsnet_open(struct net_device *dev)
 {
 	int err;
-	pr_debug("%s: mipsnet_open\n", dev->name);
 
 	err = request_irq(dev->irq, &mipsnet_interrupt,
 			  IRQF_SHARED, dev->name, (void *) dev);
 
 	if (err) {
-		pr_debug("%s: %s(): can't get irq %d\n",
-			 dev->name, __FUNCTION__, dev->irq);
 		release_region(dev->base_addr, MIPSNET_IO_EXTENT);
 		return err;
 	}
 
-	pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n",
-		 dev->name, __FUNCTION__, dev->base_addr, dev->irq);
-
-
 	netif_start_queue(dev);
 
 	/* test interrupt handler */
@@ -193,8 +162,8 @@ static int mipsnet_open(struct net_device *dev)
 
 static int mipsnet_close(struct net_device *dev)
 {
-	pr_debug("%s: %s()\n", dev->name, __FUNCTION__);
 	netif_stop_queue(dev);
+
 	return 0;
 }
 
@@ -229,9 +198,6 @@ static int __init mipsnet_probe(struct device *dev)
 
 	/* Get the io region now, get irq on open() */
 	if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) {
-		pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} "
-			 "for dev is not availble.\n", netdev->name,
-			 __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
 		err = -EBUSY;
 		goto out_free_netdev;
 	}
@@ -295,8 +261,6 @@ static int __init mipsnet_init_module(void)
 
 static void __exit mipsnet_exit_module(void)
 {
-	pr_debug("MIPSNet Ethernet driver exiting\n");
-
 	driver_unregister(&mipsnet_driver);
 }
 
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 84f2d63..651c269 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1,5 +1,5 @@
 /*
- * drivers/net/mv643xx_eth.c - Driver for MV643XX ethernet ports
+ * Driver for Marvell Discovery (MV643XX) and Marvell Orion ethernet ports
  * Copyright (C) 2002 Matthew Dharm <mdharm@momenco.com>
  *
  * Based on the 64360 driver from:
@@ -43,14 +43,567 @@
 #include <linux/ethtool.h>
 #include <linux/platform_device.h>
 
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/mii.h>
+
+#include <linux/mv643xx_eth.h>
+
 #include <asm/io.h>
 #include <asm/types.h>
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/delay.h>
-#include "mv643xx_eth.h"
+#include <asm/dma-mapping.h>
+
+#define MV643XX_CHECKSUM_OFFLOAD_TX
+#define MV643XX_NAPI
+#define MV643XX_TX_FAST_REFILL
+#undef	MV643XX_COAL
+
+/*
+ * Number of RX / TX descriptors on RX / TX rings.
+ * Note that allocating RX descriptors is done by allocating the RX
+ * ring AND a preallocated RX buffers (skb's) for each descriptor.
+ * The TX descriptors only allocates the TX descriptors ring,
+ * with no pre allocated TX buffers (skb's are allocated by higher layers.
+ */
+
+/* Default TX ring size is 1000 descriptors */
+#define MV643XX_DEFAULT_TX_QUEUE_SIZE 1000
+
+/* Default RX ring size is 400 descriptors */
+#define MV643XX_DEFAULT_RX_QUEUE_SIZE 400
+
+#define MV643XX_TX_COAL 100
+#ifdef MV643XX_COAL
+#define MV643XX_RX_COAL 100
+#endif
+
+#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
+#define MAX_DESCS_PER_SKB	(MAX_SKB_FRAGS + 1)
+#else
+#define MAX_DESCS_PER_SKB	1
+#endif
+
+#define ETH_VLAN_HLEN		4
+#define ETH_FCS_LEN		4
+#define ETH_HW_IP_ALIGN		2		/* hw aligns IP header */
+#define ETH_WRAPPER_LEN		(ETH_HW_IP_ALIGN + ETH_HLEN + \
+					ETH_VLAN_HLEN + ETH_FCS_LEN)
+#define ETH_RX_SKB_SIZE		(dev->mtu + ETH_WRAPPER_LEN + \
+					dma_get_cache_alignment())
+
+/*
+ * Registers shared between all ports.
+ */
+#define PHY_ADDR_REG				0x0000
+#define SMI_REG					0x0004
+
+/*
+ * Per-port registers.
+ */
+#define PORT_CONFIG_REG(p)				(0x0400 + ((p) << 10))
+#define PORT_CONFIG_EXTEND_REG(p)			(0x0404 + ((p) << 10))
+#define MAC_ADDR_LOW(p)					(0x0414 + ((p) << 10))
+#define MAC_ADDR_HIGH(p)				(0x0418 + ((p) << 10))
+#define SDMA_CONFIG_REG(p)				(0x041c + ((p) << 10))
+#define PORT_SERIAL_CONTROL_REG(p)			(0x043c + ((p) << 10))
+#define PORT_STATUS_REG(p)				(0x0444 + ((p) << 10))
+#define TRANSMIT_QUEUE_COMMAND_REG(p)			(0x0448 + ((p) << 10))
+#define MAXIMUM_TRANSMIT_UNIT(p)			(0x0458 + ((p) << 10))
+#define INTERRUPT_CAUSE_REG(p)				(0x0460 + ((p) << 10))
+#define INTERRUPT_CAUSE_EXTEND_REG(p)			(0x0464 + ((p) << 10))
+#define INTERRUPT_MASK_REG(p)				(0x0468 + ((p) << 10))
+#define INTERRUPT_EXTEND_MASK_REG(p)			(0x046c + ((p) << 10))
+#define TX_FIFO_URGENT_THRESHOLD_REG(p)			(0x0474 + ((p) << 10))
+#define RX_CURRENT_QUEUE_DESC_PTR_0(p)			(0x060c + ((p) << 10))
+#define RECEIVE_QUEUE_COMMAND_REG(p)			(0x0680 + ((p) << 10))
+#define TX_CURRENT_QUEUE_DESC_PTR_0(p)			(0x06c0 + ((p) << 10))
+#define MIB_COUNTERS_BASE(p)				(0x1000 + ((p) << 7))
+#define DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(p)	(0x1400 + ((p) << 10))
+#define DA_FILTER_OTHER_MULTICAST_TABLE_BASE(p)		(0x1500 + ((p) << 10))
+#define DA_FILTER_UNICAST_TABLE_BASE(p)			(0x1600 + ((p) << 10))
+
+/* These macros describe Ethernet Port configuration reg (Px_cR) bits */
+#define UNICAST_NORMAL_MODE		(0 << 0)
+#define UNICAST_PROMISCUOUS_MODE	(1 << 0)
+#define DEFAULT_RX_QUEUE(queue)		((queue) << 1)
+#define DEFAULT_RX_ARP_QUEUE(queue)	((queue) << 4)
+#define RECEIVE_BC_IF_NOT_IP_OR_ARP	(0 << 7)
+#define REJECT_BC_IF_NOT_IP_OR_ARP	(1 << 7)
+#define RECEIVE_BC_IF_IP		(0 << 8)
+#define REJECT_BC_IF_IP			(1 << 8)
+#define RECEIVE_BC_IF_ARP		(0 << 9)
+#define REJECT_BC_IF_ARP		(1 << 9)
+#define TX_AM_NO_UPDATE_ERROR_SUMMARY	(1 << 12)
+#define CAPTURE_TCP_FRAMES_DIS		(0 << 14)
+#define CAPTURE_TCP_FRAMES_EN		(1 << 14)
+#define CAPTURE_UDP_FRAMES_DIS		(0 << 15)
+#define CAPTURE_UDP_FRAMES_EN		(1 << 15)
+#define DEFAULT_RX_TCP_QUEUE(queue)	((queue) << 16)
+#define DEFAULT_RX_UDP_QUEUE(queue)	((queue) << 19)
+#define DEFAULT_RX_BPDU_QUEUE(queue)	((queue) << 22)
+
+#define PORT_CONFIG_DEFAULT_VALUE			\
+		UNICAST_NORMAL_MODE		|	\
+		DEFAULT_RX_QUEUE(0)		|	\
+		DEFAULT_RX_ARP_QUEUE(0)		|	\
+		RECEIVE_BC_IF_NOT_IP_OR_ARP	|	\
+		RECEIVE_BC_IF_IP		|	\
+		RECEIVE_BC_IF_ARP		|	\
+		CAPTURE_TCP_FRAMES_DIS		|	\
+		CAPTURE_UDP_FRAMES_DIS		|	\
+		DEFAULT_RX_TCP_QUEUE(0)		|	\
+		DEFAULT_RX_UDP_QUEUE(0)		|	\
+		DEFAULT_RX_BPDU_QUEUE(0)
+
+/* These macros describe Ethernet Port configuration extend reg (Px_cXR) bits*/
+#define CLASSIFY_EN				(1 << 0)
+#define SPAN_BPDU_PACKETS_AS_NORMAL		(0 << 1)
+#define SPAN_BPDU_PACKETS_TO_RX_QUEUE_7		(1 << 1)
+#define PARTITION_DISABLE			(0 << 2)
+#define PARTITION_ENABLE			(1 << 2)
+
+#define PORT_CONFIG_EXTEND_DEFAULT_VALUE		\
+		SPAN_BPDU_PACKETS_AS_NORMAL	|	\
+		PARTITION_DISABLE
+
+/* These macros describe Ethernet Port Sdma configuration reg (SDCR) bits */
+#define RIFB				(1 << 0)
+#define RX_BURST_SIZE_1_64BIT		(0 << 1)
+#define RX_BURST_SIZE_2_64BIT		(1 << 1)
+#define RX_BURST_SIZE_4_64BIT		(2 << 1)
+#define RX_BURST_SIZE_8_64BIT		(3 << 1)
+#define RX_BURST_SIZE_16_64BIT		(4 << 1)
+#define BLM_RX_NO_SWAP			(1 << 4)
+#define BLM_RX_BYTE_SWAP		(0 << 4)
+#define BLM_TX_NO_SWAP			(1 << 5)
+#define BLM_TX_BYTE_SWAP		(0 << 5)
+#define DESCRIPTORS_BYTE_SWAP		(1 << 6)
+#define DESCRIPTORS_NO_SWAP		(0 << 6)
+#define IPG_INT_RX(value)		(((value) & 0x3fff) << 8)
+#define TX_BURST_SIZE_1_64BIT		(0 << 22)
+#define TX_BURST_SIZE_2_64BIT		(1 << 22)
+#define TX_BURST_SIZE_4_64BIT		(2 << 22)
+#define TX_BURST_SIZE_8_64BIT		(3 << 22)
+#define TX_BURST_SIZE_16_64BIT		(4 << 22)
+
+#if defined(__BIG_ENDIAN)
+#define PORT_SDMA_CONFIG_DEFAULT_VALUE		\
+		RX_BURST_SIZE_4_64BIT	|	\
+		IPG_INT_RX(0)		|	\
+		TX_BURST_SIZE_4_64BIT
+#elif defined(__LITTLE_ENDIAN)
+#define PORT_SDMA_CONFIG_DEFAULT_VALUE		\
+		RX_BURST_SIZE_4_64BIT	|	\
+		BLM_RX_NO_SWAP		|	\
+		BLM_TX_NO_SWAP		|	\
+		IPG_INT_RX(0)		|	\
+		TX_BURST_SIZE_4_64BIT
+#else
+#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
+#endif
+
+/* These macros describe Ethernet Port serial control reg (PSCR) bits */
+#define SERIAL_PORT_DISABLE			(0 << 0)
+#define SERIAL_PORT_ENABLE			(1 << 0)
+#define DO_NOT_FORCE_LINK_PASS			(0 << 1)
+#define FORCE_LINK_PASS				(1 << 1)
+#define ENABLE_AUTO_NEG_FOR_DUPLX		(0 << 2)
+#define DISABLE_AUTO_NEG_FOR_DUPLX		(1 << 2)
+#define ENABLE_AUTO_NEG_FOR_FLOW_CTRL		(0 << 3)
+#define DISABLE_AUTO_NEG_FOR_FLOW_CTRL		(1 << 3)
+#define ADV_NO_FLOW_CTRL			(0 << 4)
+#define ADV_SYMMETRIC_FLOW_CTRL			(1 << 4)
+#define FORCE_FC_MODE_NO_PAUSE_DIS_TX		(0 << 5)
+#define FORCE_FC_MODE_TX_PAUSE_DIS		(1 << 5)
+#define FORCE_BP_MODE_NO_JAM			(0 << 7)
+#define FORCE_BP_MODE_JAM_TX			(1 << 7)
+#define FORCE_BP_MODE_JAM_TX_ON_RX_ERR		(2 << 7)
+#define SERIAL_PORT_CONTROL_RESERVED		(1 << 9)
+#define FORCE_LINK_FAIL				(0 << 10)
+#define DO_NOT_FORCE_LINK_FAIL			(1 << 10)
+#define RETRANSMIT_16_ATTEMPTS			(0 << 11)
+#define RETRANSMIT_FOREVER			(1 << 11)
+#define ENABLE_AUTO_NEG_SPEED_GMII		(0 << 13)
+#define DISABLE_AUTO_NEG_SPEED_GMII		(1 << 13)
+#define DTE_ADV_0				(0 << 14)
+#define DTE_ADV_1				(1 << 14)
+#define DISABLE_AUTO_NEG_BYPASS			(0 << 15)
+#define ENABLE_AUTO_NEG_BYPASS			(1 << 15)
+#define AUTO_NEG_NO_CHANGE			(0 << 16)
+#define RESTART_AUTO_NEG			(1 << 16)
+#define MAX_RX_PACKET_1518BYTE			(0 << 17)
+#define MAX_RX_PACKET_1522BYTE			(1 << 17)
+#define MAX_RX_PACKET_1552BYTE			(2 << 17)
+#define MAX_RX_PACKET_9022BYTE			(3 << 17)
+#define MAX_RX_PACKET_9192BYTE			(4 << 17)
+#define MAX_RX_PACKET_9700BYTE			(5 << 17)
+#define MAX_RX_PACKET_MASK			(7 << 17)
+#define CLR_EXT_LOOPBACK			(0 << 20)
+#define SET_EXT_LOOPBACK			(1 << 20)
+#define SET_HALF_DUPLEX_MODE			(0 << 21)
+#define SET_FULL_DUPLEX_MODE			(1 << 21)
+#define DISABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX	(0 << 22)
+#define ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX	(1 << 22)
+#define SET_GMII_SPEED_TO_10_100		(0 << 23)
+#define SET_GMII_SPEED_TO_1000			(1 << 23)
+#define SET_MII_SPEED_TO_10			(0 << 24)
+#define SET_MII_SPEED_TO_100			(1 << 24)
+
+#define PORT_SERIAL_CONTROL_DEFAULT_VALUE		\
+		DO_NOT_FORCE_LINK_PASS		|	\
+		ENABLE_AUTO_NEG_FOR_DUPLX	|	\
+		DISABLE_AUTO_NEG_FOR_FLOW_CTRL	|	\
+		ADV_SYMMETRIC_FLOW_CTRL		|	\
+		FORCE_FC_MODE_NO_PAUSE_DIS_TX	|	\
+		FORCE_BP_MODE_NO_JAM		|	\
+		(1 << 9) /* reserved */		|	\
+		DO_NOT_FORCE_LINK_FAIL		|	\
+		RETRANSMIT_16_ATTEMPTS		|	\
+		ENABLE_AUTO_NEG_SPEED_GMII	|	\
+		DTE_ADV_0			|	\
+		DISABLE_AUTO_NEG_BYPASS		|	\
+		AUTO_NEG_NO_CHANGE		|	\
+		MAX_RX_PACKET_9700BYTE		|	\
+		CLR_EXT_LOOPBACK		|	\
+		SET_FULL_DUPLEX_MODE		|	\
+		ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX
+
+/* These macros describe Ethernet Serial Status reg (PSR) bits */
+#define PORT_STATUS_MODE_10_BIT		(1 << 0)
+#define PORT_STATUS_LINK_UP		(1 << 1)
+#define PORT_STATUS_FULL_DUPLEX		(1 << 2)
+#define PORT_STATUS_FLOW_CONTROL	(1 << 3)
+#define PORT_STATUS_GMII_1000		(1 << 4)
+#define PORT_STATUS_MII_100		(1 << 5)
+/* PSR bit 6 is undocumented */
+#define PORT_STATUS_TX_IN_PROGRESS	(1 << 7)
+#define PORT_STATUS_AUTONEG_BYPASSED	(1 << 8)
+#define PORT_STATUS_PARTITION		(1 << 9)
+#define PORT_STATUS_TX_FIFO_EMPTY	(1 << 10)
+/* PSR bits 11-31 are reserved */
+
+#define PORT_DEFAULT_TRANSMIT_QUEUE_SIZE	800
+#define PORT_DEFAULT_RECEIVE_QUEUE_SIZE		400
+
+#define DESC_SIZE				64
+
+#define ETH_RX_QUEUES_ENABLED	(1 << 0)	/* use only Q0 for receive */
+#define ETH_TX_QUEUES_ENABLED	(1 << 0)	/* use only Q0 for transmit */
+
+#define ETH_INT_CAUSE_RX_DONE	(ETH_RX_QUEUES_ENABLED << 2)
+#define ETH_INT_CAUSE_RX_ERROR	(ETH_RX_QUEUES_ENABLED << 9)
+#define ETH_INT_CAUSE_RX	(ETH_INT_CAUSE_RX_DONE | ETH_INT_CAUSE_RX_ERROR)
+#define ETH_INT_CAUSE_EXT	0x00000002
+#define ETH_INT_UNMASK_ALL	(ETH_INT_CAUSE_RX | ETH_INT_CAUSE_EXT)
+
+#define ETH_INT_CAUSE_TX_DONE	(ETH_TX_QUEUES_ENABLED << 0)
+#define ETH_INT_CAUSE_TX_ERROR	(ETH_TX_QUEUES_ENABLED << 8)
+#define ETH_INT_CAUSE_TX	(ETH_INT_CAUSE_TX_DONE | ETH_INT_CAUSE_TX_ERROR)
+#define ETH_INT_CAUSE_PHY	0x00010000
+#define ETH_INT_CAUSE_STATE	0x00100000
+#define ETH_INT_UNMASK_ALL_EXT	(ETH_INT_CAUSE_TX | ETH_INT_CAUSE_PHY | \
+					ETH_INT_CAUSE_STATE)
+
+#define ETH_INT_MASK_ALL	0x00000000
+#define ETH_INT_MASK_ALL_EXT	0x00000000
+
+#define PHY_WAIT_ITERATIONS	1000	/* 1000 iterations * 10uS = 10mS max */
+#define PHY_WAIT_MICRO_SECONDS	10
+
+/* Buffer offset from buffer pointer */
+#define RX_BUF_OFFSET				0x2
+
+/* Gigabit Ethernet Unit Global Registers */
+
+/* MIB Counters register definitions */
+#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW	0x0
+#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH	0x4
+#define ETH_MIB_BAD_OCTETS_RECEIVED		0x8
+#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR	0xc
+#define ETH_MIB_GOOD_FRAMES_RECEIVED		0x10
+#define ETH_MIB_BAD_FRAMES_RECEIVED		0x14
+#define ETH_MIB_BROADCAST_FRAMES_RECEIVED	0x18
+#define ETH_MIB_MULTICAST_FRAMES_RECEIVED	0x1c
+#define ETH_MIB_FRAMES_64_OCTETS		0x20
+#define ETH_MIB_FRAMES_65_TO_127_OCTETS		0x24
+#define ETH_MIB_FRAMES_128_TO_255_OCTETS	0x28
+#define ETH_MIB_FRAMES_256_TO_511_OCTETS	0x2c
+#define ETH_MIB_FRAMES_512_TO_1023_OCTETS	0x30
+#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS	0x34
+#define ETH_MIB_GOOD_OCTETS_SENT_LOW		0x38
+#define ETH_MIB_GOOD_OCTETS_SENT_HIGH		0x3c
+#define ETH_MIB_GOOD_FRAMES_SENT		0x40
+#define ETH_MIB_EXCESSIVE_COLLISION		0x44
+#define ETH_MIB_MULTICAST_FRAMES_SENT		0x48
+#define ETH_MIB_BROADCAST_FRAMES_SENT		0x4c
+#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED	0x50
+#define ETH_MIB_FC_SENT				0x54
+#define ETH_MIB_GOOD_FC_RECEIVED		0x58
+#define ETH_MIB_BAD_FC_RECEIVED			0x5c
+#define ETH_MIB_UNDERSIZE_RECEIVED		0x60
+#define ETH_MIB_FRAGMENTS_RECEIVED		0x64
+#define ETH_MIB_OVERSIZE_RECEIVED		0x68
+#define ETH_MIB_JABBER_RECEIVED			0x6c
+#define ETH_MIB_MAC_RECEIVE_ERROR		0x70
+#define ETH_MIB_BAD_CRC_EVENT			0x74
+#define ETH_MIB_COLLISION			0x78
+#define ETH_MIB_LATE_COLLISION			0x7c
+
+/* Port serial status reg (PSR) */
+#define ETH_INTERFACE_PCM			0x00000001
+#define ETH_LINK_IS_UP				0x00000002
+#define ETH_PORT_AT_FULL_DUPLEX			0x00000004
+#define ETH_RX_FLOW_CTRL_ENABLED		0x00000008
+#define ETH_GMII_SPEED_1000			0x00000010
+#define ETH_MII_SPEED_100			0x00000020
+#define ETH_TX_IN_PROGRESS			0x00000080
+#define ETH_BYPASS_ACTIVE			0x00000100
+#define ETH_PORT_AT_PARTITION_STATE		0x00000200
+#define ETH_PORT_TX_FIFO_EMPTY			0x00000400
+
+/* SMI reg */
+#define ETH_SMI_BUSY		0x10000000	/* 0 - Write, 1 - Read	*/
+#define ETH_SMI_READ_VALID	0x08000000	/* 0 - Write, 1 - Read	*/
+#define ETH_SMI_OPCODE_WRITE	0		/* Completion of Read	*/
+#define ETH_SMI_OPCODE_READ	0x04000000	/* Operation is in progress */
+
+/* Interrupt Cause Register Bit Definitions */
+
+/* SDMA command status fields macros */
+
+/* Tx & Rx descriptors status */
+#define ETH_ERROR_SUMMARY			0x00000001
+
+/* Tx & Rx descriptors command */
+#define ETH_BUFFER_OWNED_BY_DMA			0x80000000
+
+/* Tx descriptors status */
+#define ETH_LC_ERROR				0
+#define ETH_UR_ERROR				0x00000002
+#define ETH_RL_ERROR				0x00000004
+#define ETH_LLC_SNAP_FORMAT			0x00000200
+
+/* Rx descriptors status */
+#define ETH_OVERRUN_ERROR			0x00000002
+#define ETH_MAX_FRAME_LENGTH_ERROR		0x00000004
+#define ETH_RESOURCE_ERROR			0x00000006
+#define ETH_VLAN_TAGGED				0x00080000
+#define ETH_BPDU_FRAME				0x00100000
+#define ETH_UDP_FRAME_OVER_IP_V_4		0x00200000
+#define ETH_OTHER_FRAME_TYPE			0x00400000
+#define ETH_LAYER_2_IS_ETH_V_2			0x00800000
+#define ETH_FRAME_TYPE_IP_V_4			0x01000000
+#define ETH_FRAME_HEADER_OK			0x02000000
+#define ETH_RX_LAST_DESC			0x04000000
+#define ETH_RX_FIRST_DESC			0x08000000
+#define ETH_UNKNOWN_DESTINATION_ADDR		0x10000000
+#define ETH_RX_ENABLE_INTERRUPT			0x20000000
+#define ETH_LAYER_4_CHECKSUM_OK			0x40000000
+
+/* Rx descriptors byte count */
+#define ETH_FRAME_FRAGMENTED			0x00000004
+
+/* Tx descriptors command */
+#define ETH_LAYER_4_CHECKSUM_FIRST_DESC		0x00000400
+#define ETH_FRAME_SET_TO_VLAN			0x00008000
+#define ETH_UDP_FRAME				0x00010000
+#define ETH_GEN_TCP_UDP_CHECKSUM		0x00020000
+#define ETH_GEN_IP_V_4_CHECKSUM			0x00040000
+#define ETH_ZERO_PADDING			0x00080000
+#define ETH_TX_LAST_DESC			0x00100000
+#define ETH_TX_FIRST_DESC			0x00200000
+#define ETH_GEN_CRC				0x00400000
+#define ETH_TX_ENABLE_INTERRUPT			0x00800000
+#define ETH_AUTO_MODE				0x40000000
+
+#define ETH_TX_IHL_SHIFT			11
+
+/* typedefs */
+
+typedef enum _eth_func_ret_status {
+	ETH_OK,			/* Returned as expected.		*/
+	ETH_ERROR,		/* Fundamental error.			*/
+	ETH_RETRY,		/* Could not process request. Try later.*/
+	ETH_END_OF_JOB,		/* Ring has nothing to process.		*/
+	ETH_QUEUE_FULL,		/* Ring resource error.			*/
+	ETH_QUEUE_LAST_RESOURCE	/* Ring resources about to exhaust.	*/
+} ETH_FUNC_RET_STATUS;
+
+typedef enum _eth_target {
+	ETH_TARGET_DRAM,
+	ETH_TARGET_DEVICE,
+	ETH_TARGET_CBS,
+	ETH_TARGET_PCI0,
+	ETH_TARGET_PCI1
+} ETH_TARGET;
+
+/* These are for big-endian machines.  Little endian needs different
+ * definitions.
+ */
+#if defined(__BIG_ENDIAN)
+struct eth_rx_desc {
+	u16 byte_cnt;		/* Descriptor buffer byte count		*/
+	u16 buf_size;		/* Buffer size				*/
+	u32 cmd_sts;		/* Descriptor command status		*/
+	u32 next_desc_ptr;	/* Next descriptor pointer		*/
+	u32 buf_ptr;		/* Descriptor buffer pointer		*/
+};
+
+struct eth_tx_desc {
+	u16 byte_cnt;		/* buffer byte count			*/
+	u16 l4i_chk;		/* CPU provided TCP checksum		*/
+	u32 cmd_sts;		/* Command/status field			*/
+	u32 next_desc_ptr;	/* Pointer to next descriptor		*/
+	u32 buf_ptr;		/* pointer to buffer for this descriptor*/
+};
+#elif defined(__LITTLE_ENDIAN)
+struct eth_rx_desc {
+	u32 cmd_sts;		/* Descriptor command status		*/
+	u16 buf_size;		/* Buffer size				*/
+	u16 byte_cnt;		/* Descriptor buffer byte count		*/
+	u32 buf_ptr;		/* Descriptor buffer pointer		*/
+	u32 next_desc_ptr;	/* Next descriptor pointer		*/
+};
+
+struct eth_tx_desc {
+	u32 cmd_sts;		/* Command/status field			*/
+	u16 l4i_chk;		/* CPU provided TCP checksum		*/
+	u16 byte_cnt;		/* buffer byte count			*/
+	u32 buf_ptr;		/* pointer to buffer for this descriptor*/
+	u32 next_desc_ptr;	/* Pointer to next descriptor		*/
+};
+#else
+#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
+#endif
+
+/* Unified struct for Rx and Tx operations. The user is not required to	*/
+/* be familier with neither Tx nor Rx descriptors.			*/
+struct pkt_info {
+	unsigned short byte_cnt;	/* Descriptor buffer byte count	*/
+	unsigned short l4i_chk;		/* Tx CPU provided TCP Checksum	*/
+	unsigned int cmd_sts;		/* Descriptor command status	*/
+	dma_addr_t buf_ptr;		/* Descriptor buffer pointer	*/
+	struct sk_buff *return_info;	/* User resource return information */
+};
+
+/* Ethernet port specific information */
+struct mv643xx_mib_counters {
+	u64 good_octets_received;
+	u32 bad_octets_received;
+	u32 internal_mac_transmit_err;
+	u32 good_frames_received;
+	u32 bad_frames_received;
+	u32 broadcast_frames_received;
+	u32 multicast_frames_received;
+	u32 frames_64_octets;
+	u32 frames_65_to_127_octets;
+	u32 frames_128_to_255_octets;
+	u32 frames_256_to_511_octets;
+	u32 frames_512_to_1023_octets;
+	u32 frames_1024_to_max_octets;
+	u64 good_octets_sent;
+	u32 good_frames_sent;
+	u32 excessive_collision;
+	u32 multicast_frames_sent;
+	u32 broadcast_frames_sent;
+	u32 unrec_mac_control_received;
+	u32 fc_sent;
+	u32 good_fc_received;
+	u32 bad_fc_received;
+	u32 undersize_received;
+	u32 fragments_received;
+	u32 oversize_received;
+	u32 jabber_received;
+	u32 mac_receive_error;
+	u32 bad_crc_event;
+	u32 collision;
+	u32 late_collision;
+};
+
+struct mv643xx_private {
+	int port_num;			/* User Ethernet port number	*/
+
+	u32 rx_sram_addr;		/* Base address of rx sram area */
+	u32 rx_sram_size;		/* Size of rx sram area		*/
+	u32 tx_sram_addr;		/* Base address of tx sram area */
+	u32 tx_sram_size;		/* Size of tx sram area		*/
+
+	int rx_resource_err;		/* Rx ring resource error flag */
+
+	/* Tx/Rx rings managment indexes fields. For driver use */
+
+	/* Next available and first returning Rx resource */
+	int rx_curr_desc_q, rx_used_desc_q;
+
+	/* Next available and first returning Tx resource */
+	int tx_curr_desc_q, tx_used_desc_q;
+
+#ifdef MV643XX_TX_FAST_REFILL
+	u32 tx_clean_threshold;
+#endif
+
+	struct eth_rx_desc *p_rx_desc_area;
+	dma_addr_t rx_desc_dma;
+	int rx_desc_area_size;
+	struct sk_buff **rx_skb;
+
+	struct eth_tx_desc *p_tx_desc_area;
+	dma_addr_t tx_desc_dma;
+	int tx_desc_area_size;
+	struct sk_buff **tx_skb;
+
+	struct work_struct tx_timeout_task;
+
+	struct net_device *dev;
+	struct napi_struct napi;
+	struct net_device_stats stats;
+	struct mv643xx_mib_counters mib_counters;
+	spinlock_t lock;
+	/* Size of Tx Ring per queue */
+	int tx_ring_size;
+	/* Number of tx descriptors in use */
+	int tx_desc_count;
+	/* Size of Rx Ring per queue */
+	int rx_ring_size;
+	/* Number of rx descriptors in use */
+	int rx_desc_count;
+
+	/*
+	 * Used in case RX Ring is empty, which can be caused when
+	 * system does not have resources (skb's)
+	 */
+	struct timer_list timeout;
+
+	u32 rx_int_coal;
+	u32 tx_int_coal;
+	struct mii_if_info mii;
+};
 
 /* Static function declarations */
+static void eth_port_init(struct mv643xx_private *mp);
+static void eth_port_reset(unsigned int eth_port_num);
+static void eth_port_start(struct net_device *dev);
+
+static void ethernet_phy_reset(unsigned int eth_port_num);
+
+static void eth_port_write_smi_reg(unsigned int eth_port_num,
+				   unsigned int phy_reg, unsigned int value);
+
+static void eth_port_read_smi_reg(unsigned int eth_port_num,
+				  unsigned int phy_reg, unsigned int *value);
+
+static void eth_clear_mib_counters(unsigned int eth_port_num);
+
+static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp,
+					    struct pkt_info *p_pkt_info);
+static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp,
+					      struct pkt_info *p_pkt_info);
+
 static void eth_port_uc_addr_get(unsigned int port_num, unsigned char *p_addr);
 static void eth_port_uc_addr_set(unsigned int port_num, unsigned char *p_addr);
 static void eth_port_set_multicast_list(struct net_device *);
@@ -78,26 +631,19 @@ static const struct ethtool_ops mv643xx_ethtool_ops;
 static char mv643xx_driver_name[] = "mv643xx_eth";
 static char mv643xx_driver_version[] = "1.0";
 
-static void __iomem *mv643xx_eth_shared_base;
+static void __iomem *mv643xx_eth_base;
 
-/* used to protect MV643XX_ETH_SMI_REG, which is shared across ports */
+/* used to protect SMI_REG, which is shared across ports */
 static DEFINE_SPINLOCK(mv643xx_eth_phy_lock);
 
 static inline u32 mv_read(int offset)
 {
-	void __iomem *reg_base;
-
-	reg_base = mv643xx_eth_shared_base - MV643XX_ETH_SHARED_REGS;
-
-	return readl(reg_base + offset);
+	return readl(mv643xx_eth_base + offset);
 }
 
 static inline void mv_write(int offset, u32 data)
 {
-	void __iomem *reg_base;
-
-	reg_base = mv643xx_eth_shared_base - MV643XX_ETH_SHARED_REGS;
-	writel(data, reg_base + offset);
+	writel(data, mv643xx_eth_base + offset);
 }
 
 /*
@@ -221,12 +767,12 @@ static void mv643xx_eth_set_rx_mode(struct net_device *dev)
 	struct mv643xx_private *mp = netdev_priv(dev);
 	u32 config_reg;
 
-	config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num));
+	config_reg = mv_read(PORT_CONFIG_REG(mp->port_num));
 	if (dev->flags & IFF_PROMISC)
-		config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
+		config_reg |= (u32) UNICAST_PROMISCUOUS_MODE;
 	else
-		config_reg &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
-	mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), config_reg);
+		config_reg &= ~(u32) UNICAST_PROMISCUOUS_MODE;
+	mv_write(PORT_CONFIG_REG(mp->port_num), config_reg);
 
 	eth_port_set_multicast_list(dev);
 }
@@ -462,41 +1008,37 @@ static void mv643xx_eth_update_pscr(struct net_device *dev,
 	u32 o_pscr, n_pscr;
 	unsigned int queues;
 
-	o_pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
+	o_pscr = mv_read(PORT_SERIAL_CONTROL_REG(port_num));
 	n_pscr = o_pscr;
 
 	/* clear speed, duplex and rx buffer size fields */
-	n_pscr &= ~(MV643XX_ETH_SET_MII_SPEED_TO_100  |
-		   MV643XX_ETH_SET_GMII_SPEED_TO_1000 |
-		   MV643XX_ETH_SET_FULL_DUPLEX_MODE   |
-		   MV643XX_ETH_MAX_RX_PACKET_MASK);
+	n_pscr &= ~(SET_MII_SPEED_TO_100  |
+		   SET_GMII_SPEED_TO_1000 |
+		   SET_FULL_DUPLEX_MODE   |
+		   MAX_RX_PACKET_MASK);
 
 	if (ecmd->duplex == DUPLEX_FULL)
-		n_pscr |= MV643XX_ETH_SET_FULL_DUPLEX_MODE;
+		n_pscr |= SET_FULL_DUPLEX_MODE;
 
 	if (ecmd->speed == SPEED_1000)
-		n_pscr |= MV643XX_ETH_SET_GMII_SPEED_TO_1000 |
-			  MV643XX_ETH_MAX_RX_PACKET_9700BYTE;
+		n_pscr |= SET_GMII_SPEED_TO_1000 |
+			  MAX_RX_PACKET_9700BYTE;
 	else {
 		if (ecmd->speed == SPEED_100)
-			n_pscr |= MV643XX_ETH_SET_MII_SPEED_TO_100;
-		n_pscr |= MV643XX_ETH_MAX_RX_PACKET_1522BYTE;
+			n_pscr |= SET_MII_SPEED_TO_100;
+		n_pscr |= MAX_RX_PACKET_1522BYTE;
 	}
 
 	if (n_pscr != o_pscr) {
-		if ((o_pscr & MV643XX_ETH_SERIAL_PORT_ENABLE) == 0)
-			mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
-								n_pscr);
+		if ((o_pscr & SERIAL_PORT_ENABLE) == 0)
+			mv_write(PORT_SERIAL_CONTROL_REG(port_num), n_pscr);
 		else {
 			queues = mv643xx_eth_port_disable_tx(port_num);
 
-			o_pscr &= ~MV643XX_ETH_SERIAL_PORT_ENABLE;
-			mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
-								o_pscr);
-			mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
-								n_pscr);
-			mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num),
-								n_pscr);
+			o_pscr &= ~SERIAL_PORT_ENABLE;
+			mv_write(PORT_SERIAL_CONTROL_REG(port_num), o_pscr);
+			mv_write(PORT_SERIAL_CONTROL_REG(port_num), n_pscr);
+			mv_write(PORT_SERIAL_CONTROL_REG(port_num), n_pscr);
 			if (queues)
 				mv643xx_eth_port_enable_tx(port_num, queues);
 		}
@@ -522,13 +1064,13 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id)
 	unsigned int port_num = mp->port_num;
 
 	/* Read interrupt cause registers */
-	eth_int_cause = mv_read(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num)) &
+	eth_int_cause = mv_read(INTERRUPT_CAUSE_REG(port_num)) &
 						ETH_INT_UNMASK_ALL;
 	if (eth_int_cause & ETH_INT_CAUSE_EXT) {
 		eth_int_cause_ext = mv_read(
-			MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) &
+			INTERRUPT_CAUSE_EXTEND_REG(port_num)) &
 						ETH_INT_UNMASK_ALL_EXT;
-		mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num),
+		mv_write(INTERRUPT_CAUSE_EXTEND_REG(port_num),
 							~eth_int_cause_ext);
 	}
 
@@ -556,10 +1098,10 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id)
 #ifdef MV643XX_NAPI
 	if (eth_int_cause & ETH_INT_CAUSE_RX) {
 		/* schedule the NAPI poll routine to maintain port */
-		mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-							ETH_INT_MASK_ALL);
+		mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
+
 		/* wait for previous write to complete */
-		mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
+		mv_read(INTERRUPT_MASK_REG(port_num));
 
 		netif_rx_schedule(dev, &mp->napi);
 	}
@@ -611,9 +1153,9 @@ static unsigned int eth_port_set_rx_coal(unsigned int eth_port_num,
 	unsigned int coal = ((t_clk / 1000000) * delay) / 64;
 
 	/* Set RX Coalescing mechanism */
-	mv_write(MV643XX_ETH_SDMA_CONFIG_REG(eth_port_num),
+	mv_write(SDMA_CONFIG_REG(eth_port_num),
 		((coal & 0x3fff) << 8) |
-		(mv_read(MV643XX_ETH_SDMA_CONFIG_REG(eth_port_num))
+		(mv_read(SDMA_CONFIG_REG(eth_port_num))
 			& 0xffc000ff));
 
 	return coal;
@@ -649,8 +1191,7 @@ static unsigned int eth_port_set_tx_coal(unsigned int eth_port_num,
 	unsigned int coal;
 	coal = ((t_clk / 1000000) * delay) / 64;
 	/* Set TX Coalescing mechanism */
-	mv_write(MV643XX_ETH_TX_FIFO_URGENT_THRESHOLD_REG(eth_port_num),
-								coal << 4);
+	mv_write(TX_FIFO_URGENT_THRESHOLD_REG(eth_port_num), coal << 4);
 	return coal;
 }
 
@@ -786,10 +1327,10 @@ static int mv643xx_eth_open(struct net_device *dev)
 	int err;
 
 	/* Clear any pending ethernet port interrupts */
-	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-	mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+	mv_write(INTERRUPT_CAUSE_REG(port_num), 0);
+	mv_write(INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
 	/* wait for previous write to complete */
-	mv_read (MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num));
+	mv_read (INTERRUPT_CAUSE_EXTEND_REG(port_num));
 
 	err = request_irq(dev->irq, mv643xx_eth_int_handler,
 			IRQF_SHARED | IRQF_SAMPLE_RANDOM, dev->name, dev);
@@ -896,11 +1437,10 @@ static int mv643xx_eth_open(struct net_device *dev)
 		eth_port_set_tx_coal(port_num, 133000000, MV643XX_TX_COAL);
 
 	/* Unmask phy and link status changes interrupts */
-	mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
-						ETH_INT_UNMASK_ALL_EXT);
+	mv_write(INTERRUPT_EXTEND_MASK_REG(port_num), ETH_INT_UNMASK_ALL_EXT);
 
 	/* Unmask RX buffer and TX end interrupt */
-	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
+	mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
 
 	return 0;
 
@@ -980,9 +1520,9 @@ static int mv643xx_eth_stop(struct net_device *dev)
 	unsigned int port_num = mp->port_num;
 
 	/* Mask all interrupts on ethernet port */
-	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
+	mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
 	/* wait for previous write to complete */
-	mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
+	mv_read(INTERRUPT_MASK_REG(port_num));
 
 #ifdef MV643XX_NAPI
 	napi_disable(&mp->napi);
@@ -1021,16 +1561,15 @@ static int mv643xx_poll(struct napi_struct *napi, int budget)
 #endif
 
 	work_done = 0;
-	if ((mv_read(MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port_num)))
+	if ((mv_read(RX_CURRENT_QUEUE_DESC_PTR_0(port_num)))
 	    != (u32) mp->rx_used_desc_q)
 		work_done = mv643xx_eth_receive_queue(dev, budget);
 
 	if (work_done < budget) {
 		netif_rx_complete(dev, napi);
-		mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0);
-		mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
-		mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
-						ETH_INT_UNMASK_ALL);
+		mv_write(INTERRUPT_CAUSE_REG(port_num), 0);
+		mv_write(INTERRUPT_CAUSE_EXTEND_REG(port_num), 0);
+		mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
 	}
 
 	return work_done;
@@ -1233,13 +1772,13 @@ static void mv643xx_netpoll(struct net_device *netdev)
 	struct mv643xx_private *mp = netdev_priv(netdev);
 	int port_num = mp->port_num;
 
-	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
+	mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_MASK_ALL);
 	/* wait for previous write to complete */
-	mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
+	mv_read(INTERRUPT_MASK_REG(port_num));
 
 	mv643xx_eth_int_handler(netdev->irq, netdev);
 
-	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
+	mv_write(INTERRUPT_MASK_REG(port_num), ETH_INT_UNMASK_ALL);
 }
 #endif
 
@@ -1357,8 +1896,8 @@ static int mv643xx_eth_probe(struct platform_device *pdev)
 
 	/* set default config values */
 	eth_port_uc_addr_get(port_num, dev->dev_addr);
-	mp->rx_ring_size = MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE;
-	mp->tx_ring_size = MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE;
+	mp->rx_ring_size = PORT_DEFAULT_RECEIVE_QUEUE_SIZE;
+	mp->tx_ring_size = PORT_DEFAULT_TRANSMIT_QUEUE_SIZE;
 
 	if (is_valid_ether_addr(pd->mac_addr))
 		memcpy(dev->dev_addr, pd->mac_addr, 6);
@@ -1470,9 +2009,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 	if (res == NULL)
 		return -ENODEV;
 
-	mv643xx_eth_shared_base = ioremap(res->start,
-						MV643XX_ETH_SHARED_REGS_SIZE);
-	if (mv643xx_eth_shared_base == NULL)
+	mv643xx_eth_base = ioremap(res->start, res->end - res->start + 1);
+	if (mv643xx_eth_base == NULL)
 		return -ENOMEM;
 
 	return 0;
@@ -1481,8 +2019,8 @@ static int mv643xx_eth_shared_probe(struct platform_device *pdev)
 
 static int mv643xx_eth_shared_remove(struct platform_device *pdev)
 {
-	iounmap(mv643xx_eth_shared_base);
-	mv643xx_eth_shared_base = NULL;
+	iounmap(mv643xx_eth_base);
+	mv643xx_eth_base = NULL;
 
 	return 0;
 }
@@ -1494,8 +2032,8 @@ static void mv643xx_eth_shutdown(struct platform_device *pdev)
 	unsigned int port_num = mp->port_num;
 
 	/* Mask all interrupts on ethernet port */
-	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0);
-	mv_read (MV643XX_ETH_INTERRUPT_MASK_REG(port_num));
+	mv_write(INTERRUPT_MASK_REG(port_num), 0);
+	mv_read (INTERRUPT_MASK_REG(port_num));
 
 	eth_port_reset(port_num);
 }
@@ -1762,49 +2300,49 @@ static void eth_port_start(struct net_device *dev)
 
 	/* Assignment of Tx CTRP of given queue */
 	tx_curr_desc = mp->tx_curr_desc_q;
-	mv_write(MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(port_num),
+	mv_write(TX_CURRENT_QUEUE_DESC_PTR_0(port_num),
 		(u32)((struct eth_tx_desc *)mp->tx_desc_dma + tx_curr_desc));
 
 	/* Assignment of Rx CRDP of given queue */
 	rx_curr_desc = mp->rx_curr_desc_q;
-	mv_write(MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port_num),
+	mv_write(RX_CURRENT_QUEUE_DESC_PTR_0(port_num),
 		(u32)((struct eth_rx_desc *)mp->rx_desc_dma + rx_curr_desc));
 
 	/* Add the assigned Ethernet address to the port's address table */
 	eth_port_uc_addr_set(port_num, dev->dev_addr);
 
 	/* Assign port configuration and command. */
-	mv_write(MV643XX_ETH_PORT_CONFIG_REG(port_num),
-			  MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE);
+	mv_write(PORT_CONFIG_REG(port_num),
+			  PORT_CONFIG_DEFAULT_VALUE);
 
-	mv_write(MV643XX_ETH_PORT_CONFIG_EXTEND_REG(port_num),
-			  MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE);
+	mv_write(PORT_CONFIG_EXTEND_REG(port_num),
+			  PORT_CONFIG_EXTEND_DEFAULT_VALUE);
 
-	pscr = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
+	pscr = mv_read(PORT_SERIAL_CONTROL_REG(port_num));
 
-	pscr &= ~(MV643XX_ETH_SERIAL_PORT_ENABLE | MV643XX_ETH_FORCE_LINK_PASS);
-	mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
+	pscr &= ~(SERIAL_PORT_ENABLE | FORCE_LINK_PASS);
+	mv_write(PORT_SERIAL_CONTROL_REG(port_num), pscr);
 
-	pscr |= MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
-		MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII    |
-		MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX     |
-		MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL	   |
-		MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED;
+	pscr |= DISABLE_AUTO_NEG_FOR_FLOW_CTRL |
+		DISABLE_AUTO_NEG_SPEED_GMII    |
+		DISABLE_AUTO_NEG_FOR_DUPLX     |
+		DO_NOT_FORCE_LINK_FAIL	   |
+		SERIAL_PORT_CONTROL_RESERVED;
 
-	mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
+	mv_write(PORT_SERIAL_CONTROL_REG(port_num), pscr);
 
-	pscr |= MV643XX_ETH_SERIAL_PORT_ENABLE;
-	mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), pscr);
+	pscr |= SERIAL_PORT_ENABLE;
+	mv_write(PORT_SERIAL_CONTROL_REG(port_num), pscr);
 
 	/* Assign port SDMA configuration */
-	mv_write(MV643XX_ETH_SDMA_CONFIG_REG(port_num),
-			  MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE);
+	mv_write(SDMA_CONFIG_REG(port_num),
+			  PORT_SDMA_CONFIG_DEFAULT_VALUE);
 
 	/* Enable port Rx. */
 	mv643xx_eth_port_enable_rx(port_num, ETH_RX_QUEUES_ENABLED);
 
 	/* Disable port bandwidth limits by clearing MTU register */
-	mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0);
+	mv_write(MAXIMUM_TRANSMIT_UNIT(port_num), 0);
 
 	/* save phy settings across reset */
 	mv643xx_get_settings(dev, &ethtool_cmd);
@@ -1825,11 +2363,11 @@ static void eth_port_uc_addr_set(unsigned int port_num, unsigned char *p_addr)
 	mac_h = (p_addr[0] << 24) | (p_addr[1] << 16) | (p_addr[2] << 8) |
 							(p_addr[3] << 0);
 
-	mv_write(MV643XX_ETH_MAC_ADDR_LOW(port_num), mac_l);
-	mv_write(MV643XX_ETH_MAC_ADDR_HIGH(port_num), mac_h);
+	mv_write(MAC_ADDR_LOW(port_num), mac_l);
+	mv_write(MAC_ADDR_HIGH(port_num), mac_h);
 
 	/* Accept frames with this address */
-	table = MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE(port_num);
+	table = DA_FILTER_UNICAST_TABLE_BASE(port_num);
 	eth_port_set_filter_table_entry(table, p_addr[5] & 0x0f);
 }
 
@@ -1841,8 +2379,8 @@ static void eth_port_uc_addr_get(unsigned int port_num, unsigned char *p_addr)
 	unsigned int mac_h;
 	unsigned int mac_l;
 
-	mac_h = mv_read(MV643XX_ETH_MAC_ADDR_HIGH(port_num));
-	mac_l = mv_read(MV643XX_ETH_MAC_ADDR_LOW(port_num));
+	mac_h = mv_read(MAC_ADDR_HIGH(port_num));
+	mac_l = mv_read(MAC_ADDR_LOW(port_num));
 
 	p_addr[0] = (mac_h >> 24) & 0xff;
 	p_addr[1] = (mac_h >> 16) & 0xff;
@@ -1902,7 +2440,7 @@ static void eth_port_mc_addr(unsigned int eth_port_num, unsigned char *p_addr)
 
 	if ((p_addr[0] == 0x01) && (p_addr[1] == 0x00) &&
 	    (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) {
-		table = MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+		table = DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
 					(eth_port_num);
 		eth_port_set_filter_table_entry(table, p_addr[5]);
 		return;
@@ -1976,7 +2514,7 @@ static void eth_port_mc_addr(unsigned int eth_port_num, unsigned char *p_addr)
 	for (i = 0; i < 8; i++)
 		crc_result = crc_result | (crc[i] << i);
 
-	table = MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num);
+	table = DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num);
 	eth_port_set_filter_table_entry(table, crc_result);
 }
 
@@ -2006,7 +2544,7 @@ static void eth_port_set_multicast_list(struct net_device *dev)
 			 * 3-1  Queue	 ETH_Q0=0
 			 * 7-4  Reserved = 0;
 			 */
-			mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+			mv_write(DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
 
 			/* Set all entries in DA filter other multicast
 			 * table (Ex_dFOMT)
@@ -2016,7 +2554,7 @@ static void eth_port_set_multicast_list(struct net_device *dev)
 			 * 3-1  Queue	 ETH_Q0=0
 			 * 7-4  Reserved = 0;
 			 */
-			mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
+			mv_write(DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101);
 		}
 		return;
 	}
@@ -2026,11 +2564,11 @@ static void eth_port_set_multicast_list(struct net_device *dev)
 	 */
 	for (table_index = 0; table_index <= 0xFC; table_index += 4) {
 		/* Clear DA filter special multicast table (Ex_dFSMT) */
-		mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+		mv_write(DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
 				(eth_port_num) + table_index, 0);
 
 		/* Clear DA filter other multicast table (Ex_dFOMT) */
-		mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE
+		mv_write(DA_FILTER_OTHER_MULTICAST_TABLE_BASE
 				(eth_port_num) + table_index, 0);
 	}
 
@@ -2064,15 +2602,15 @@ static void eth_port_init_mac_tables(unsigned int eth_port_num)
 
 	/* Clear DA filter unicast table (Ex_dFUT) */
 	for (table_index = 0; table_index <= 0xC; table_index += 4)
-		mv_write(MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE
+		mv_write(DA_FILTER_UNICAST_TABLE_BASE
 					(eth_port_num) + table_index, 0);
 
 	for (table_index = 0; table_index <= 0xFC; table_index += 4) {
 		/* Clear DA filter special multicast table (Ex_dFSMT) */
-		mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
+		mv_write(DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE
 					(eth_port_num) + table_index, 0);
 		/* Clear DA filter other multicast table (Ex_dFOMT) */
-		mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE
+		mv_write(DA_FILTER_OTHER_MULTICAST_TABLE_BASE
 					(eth_port_num) + table_index, 0);
 	}
 }
@@ -2101,12 +2639,12 @@ static void eth_clear_mib_counters(unsigned int eth_port_num)
 	/* Perform dummy reads from MIB counters */
 	for (i = ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i < ETH_MIB_LATE_COLLISION;
 									i += 4)
-		mv_read(MV643XX_ETH_MIB_COUNTERS_BASE(eth_port_num) + i);
+		mv_read(MIB_COUNTERS_BASE(eth_port_num) + i);
 }
 
 static inline u32 read_mib(struct mv643xx_private *mp, int offset)
 {
-	return mv_read(MV643XX_ETH_MIB_COUNTERS_BASE(mp->port_num) + offset);
+	return mv_read(MIB_COUNTERS_BASE(mp->port_num) + offset);
 }
 
 static void eth_update_mib_counters(struct mv643xx_private *mp)
@@ -2191,7 +2729,7 @@ static int ethernet_phy_get(unsigned int eth_port_num)
 {
 	unsigned int reg_data;
 
-	reg_data = mv_read(MV643XX_ETH_PHY_ADDR_REG);
+	reg_data = mv_read(PHY_ADDR_REG);
 
 	return ((reg_data >> (5 * eth_port_num)) & 0x1f);
 }
@@ -2218,10 +2756,10 @@ static void ethernet_phy_set(unsigned int eth_port_num, int phy_addr)
 	u32 reg_data;
 	int addr_shift = 5 * eth_port_num;
 
-	reg_data = mv_read(MV643XX_ETH_PHY_ADDR_REG);
+	reg_data = mv_read(PHY_ADDR_REG);
 	reg_data &= ~(0x1f << addr_shift);
 	reg_data |= (phy_addr & 0x1f) << addr_shift;
-	mv_write(MV643XX_ETH_PHY_ADDR_REG, reg_data);
+	mv_write(PHY_ADDR_REG, reg_data);
 }
 
 /*
@@ -2259,13 +2797,13 @@ static void ethernet_phy_reset(unsigned int eth_port_num)
 static void mv643xx_eth_port_enable_tx(unsigned int port_num,
 					unsigned int queues)
 {
-	mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), queues);
+	mv_write(TRANSMIT_QUEUE_COMMAND_REG(port_num), queues);
 }
 
 static void mv643xx_eth_port_enable_rx(unsigned int port_num,
 					unsigned int queues)
 {
-	mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), queues);
+	mv_write(RECEIVE_QUEUE_COMMAND_REG(port_num), queues);
 }
 
 static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num)
@@ -2273,21 +2811,18 @@ static unsigned int mv643xx_eth_port_disable_tx(unsigned int port_num)
 	u32 queues;
 
 	/* Stop Tx port activity. Check port Tx activity. */
-	queues = mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num))
-							& 0xFF;
+	queues = mv_read(TRANSMIT_QUEUE_COMMAND_REG(port_num)) & 0xFF;
 	if (queues) {
 		/* Issue stop command for active queues only */
-		mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num),
-							(queues << 8));
+		mv_write(TRANSMIT_QUEUE_COMMAND_REG(port_num), (queues << 8));
 
 		/* Wait for all Tx activity to terminate. */
 		/* Check port cause register that all Tx queues are stopped */
-		while (mv_read(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num))
-							& 0xFF)
+		while (mv_read(TRANSMIT_QUEUE_COMMAND_REG(port_num)) & 0xFF)
 			udelay(PHY_WAIT_MICRO_SECONDS);
 
 		/* Wait for Tx FIFO to empty */
-		while (mv_read(MV643XX_ETH_PORT_STATUS_REG(port_num)) &
+		while (mv_read(PORT_STATUS_REG(port_num)) &
 							ETH_PORT_TX_FIFO_EMPTY)
 			udelay(PHY_WAIT_MICRO_SECONDS);
 	}
@@ -2300,17 +2835,14 @@ static unsigned int mv643xx_eth_port_disable_rx(unsigned int port_num)
 	u32 queues;
 
 	/* Stop Rx port activity. Check port Rx activity. */
-	queues = mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num))
-							& 0xFF;
+	queues = mv_read(RECEIVE_QUEUE_COMMAND_REG(port_num)) & 0xFF;
 	if (queues) {
 		/* Issue stop command for active queues only */
-		mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
-							(queues << 8));
+		mv_write(RECEIVE_QUEUE_COMMAND_REG(port_num), (queues << 8));
 
 		/* Wait for all Rx activity to terminate. */
 		/* Check port cause register that all Rx queues are stopped */
-		while (mv_read(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num))
-							& 0xFF)
+		while (mv_read(RECEIVE_QUEUE_COMMAND_REG(port_num)) & 0xFF)
 			udelay(PHY_WAIT_MICRO_SECONDS);
 	}
 
@@ -2346,11 +2878,11 @@ static void eth_port_reset(unsigned int port_num)
 	eth_clear_mib_counters(port_num);
 
 	/* Reset the Enable bit in the Configuration Register */
-	reg_data = mv_read(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num));
-	reg_data &= ~(MV643XX_ETH_SERIAL_PORT_ENABLE		|
-			MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL	|
-			MV643XX_ETH_FORCE_LINK_PASS);
-	mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data);
+	reg_data = mv_read(PORT_SERIAL_CONTROL_REG(port_num));
+	reg_data &= ~(SERIAL_PORT_ENABLE		|
+			DO_NOT_FORCE_LINK_FAIL	|
+			FORCE_LINK_PASS);
+	mv_write(PORT_SERIAL_CONTROL_REG(port_num), reg_data);
 }
 
 
@@ -2385,7 +2917,7 @@ static void eth_port_read_smi_reg(unsigned int port_num,
 	spin_lock_irqsave(&mv643xx_eth_phy_lock, flags);
 
 	/* wait for the SMI register to become available */
-	for (i = 0; mv_read(MV643XX_ETH_SMI_REG) & ETH_SMI_BUSY; i++) {
+	for (i = 0; mv_read(SMI_REG) & ETH_SMI_BUSY; i++) {
 		if (i == PHY_WAIT_ITERATIONS) {
 			printk("mv643xx PHY busy timeout, port %d\n", port_num);
 			goto out;
@@ -2393,11 +2925,11 @@ static void eth_port_read_smi_reg(unsigned int port_num,
 		udelay(PHY_WAIT_MICRO_SECONDS);
 	}
 
-	mv_write(MV643XX_ETH_SMI_REG,
+	mv_write(SMI_REG,
 		(phy_addr << 16) | (phy_reg << 21) | ETH_SMI_OPCODE_READ);
 
 	/* now wait for the data to be valid */
-	for (i = 0; !(mv_read(MV643XX_ETH_SMI_REG) & ETH_SMI_READ_VALID); i++) {
+	for (i = 0; !(mv_read(SMI_REG) & ETH_SMI_READ_VALID); i++) {
 		if (i == PHY_WAIT_ITERATIONS) {
 			printk("mv643xx PHY read timeout, port %d\n", port_num);
 			goto out;
@@ -2405,7 +2937,7 @@ static void eth_port_read_smi_reg(unsigned int port_num,
 		udelay(PHY_WAIT_MICRO_SECONDS);
 	}
 
-	*value = mv_read(MV643XX_ETH_SMI_REG) & 0xffff;
+	*value = mv_read(SMI_REG) & 0xffff;
 out:
 	spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
 }
@@ -2443,7 +2975,7 @@ static void eth_port_write_smi_reg(unsigned int eth_port_num,
 	spin_lock_irqsave(&mv643xx_eth_phy_lock, flags);
 
 	/* wait for the SMI register to become available */
-	for (i = 0; mv_read(MV643XX_ETH_SMI_REG) & ETH_SMI_BUSY; i++) {
+	for (i = 0; mv_read(SMI_REG) & ETH_SMI_BUSY; i++) {
 		if (i == PHY_WAIT_ITERATIONS) {
 			printk("mv643xx PHY busy timeout, port %d\n",
 								eth_port_num);
@@ -2452,7 +2984,7 @@ static void eth_port_write_smi_reg(unsigned int eth_port_num,
 		udelay(PHY_WAIT_MICRO_SECONDS);
 	}
 
-	mv_write(MV643XX_ETH_SMI_REG, (phy_addr << 16) | (phy_reg << 21) |
+	mv_write(SMI_REG, (phy_addr << 16) | (phy_reg << 21) |
 				ETH_SMI_OPCODE_WRITE | (value & 0xffff));
 out:
 	spin_unlock_irqrestore(&mv643xx_eth_phy_lock, flags);
@@ -2742,6 +3274,7 @@ static const struct ethtool_ops mv643xx_ethtool_ops = {
 	.get_drvinfo            = mv643xx_get_drvinfo,
 	.get_link               = mv643xx_eth_get_link,
 	.set_sg			= ethtool_op_set_sg,
+	.get_sset_count		= mv643xx_get_sset_count,
 	.get_ethtool_stats      = mv643xx_get_ethtool_stats,
 	.get_strings            = mv643xx_get_strings,
 	.nway_reset		= mv643xx_eth_nway_restart,
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
deleted file mode 100644
index be669eb..0000000
--- a/drivers/net/mv643xx_eth.h
+++ /dev/null
@@ -1,370 +0,0 @@
-#ifndef __MV643XX_ETH_H__
-#define __MV643XX_ETH_H__
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/workqueue.h>
-#include <linux/mii.h>
-
-#include <linux/mv643xx.h>
-
-#include <asm/dma-mapping.h>
-
-/* Checksum offload for Tx works for most packets, but
- * fails if previous packet sent did not use hw csum
- */
-#define	MV643XX_CHECKSUM_OFFLOAD_TX
-#define	MV643XX_NAPI
-#define	MV643XX_TX_FAST_REFILL
-#undef	MV643XX_COAL
-
-/*
- * Number of RX / TX descriptors on RX / TX rings.
- * Note that allocating RX descriptors is done by allocating the RX
- * ring AND a preallocated RX buffers (skb's) for each descriptor.
- * The TX descriptors only allocates the TX descriptors ring,
- * with no pre allocated TX buffers (skb's are allocated by higher layers.
- */
-
-/* Default TX ring size is 1000 descriptors */
-#define MV643XX_DEFAULT_TX_QUEUE_SIZE 1000
-
-/* Default RX ring size is 400 descriptors */
-#define MV643XX_DEFAULT_RX_QUEUE_SIZE 400
-
-#define MV643XX_TX_COAL 100
-#ifdef MV643XX_COAL
-#define MV643XX_RX_COAL 100
-#endif
-
-#ifdef MV643XX_CHECKSUM_OFFLOAD_TX
-#define MAX_DESCS_PER_SKB	(MAX_SKB_FRAGS + 1)
-#else
-#define MAX_DESCS_PER_SKB	1
-#endif
-
-#define ETH_VLAN_HLEN		4
-#define ETH_FCS_LEN		4
-#define ETH_HW_IP_ALIGN		2		/* hw aligns IP header */
-#define ETH_WRAPPER_LEN		(ETH_HW_IP_ALIGN + ETH_HLEN + \
-					ETH_VLAN_HLEN + ETH_FCS_LEN)
-#define ETH_RX_SKB_SIZE		(dev->mtu + ETH_WRAPPER_LEN + dma_get_cache_alignment())
-
-#define ETH_RX_QUEUES_ENABLED	(1 << 0)	/* use only Q0 for receive */
-#define ETH_TX_QUEUES_ENABLED	(1 << 0)	/* use only Q0 for transmit */
-
-#define ETH_INT_CAUSE_RX_DONE	(ETH_RX_QUEUES_ENABLED << 2)
-#define ETH_INT_CAUSE_RX_ERROR	(ETH_RX_QUEUES_ENABLED << 9)
-#define ETH_INT_CAUSE_RX	(ETH_INT_CAUSE_RX_DONE | ETH_INT_CAUSE_RX_ERROR)
-#define ETH_INT_CAUSE_EXT	0x00000002
-#define ETH_INT_UNMASK_ALL	(ETH_INT_CAUSE_RX | ETH_INT_CAUSE_EXT)
-
-#define ETH_INT_CAUSE_TX_DONE	(ETH_TX_QUEUES_ENABLED << 0)
-#define ETH_INT_CAUSE_TX_ERROR	(ETH_TX_QUEUES_ENABLED << 8)
-#define ETH_INT_CAUSE_TX	(ETH_INT_CAUSE_TX_DONE | ETH_INT_CAUSE_TX_ERROR)
-#define ETH_INT_CAUSE_PHY	0x00010000
-#define ETH_INT_CAUSE_STATE	0x00100000
-#define ETH_INT_UNMASK_ALL_EXT	(ETH_INT_CAUSE_TX | ETH_INT_CAUSE_PHY | \
-					ETH_INT_CAUSE_STATE)
-
-#define ETH_INT_MASK_ALL	0x00000000
-#define ETH_INT_MASK_ALL_EXT	0x00000000
-
-#define PHY_WAIT_ITERATIONS	1000	/* 1000 iterations * 10uS = 10mS max */
-#define PHY_WAIT_MICRO_SECONDS	10
-
-/* Buffer offset from buffer pointer */
-#define RX_BUF_OFFSET				0x2
-
-/* Gigabit Ethernet Unit Global Registers */
-
-/* MIB Counters register definitions */
-#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW	0x0
-#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH	0x4
-#define ETH_MIB_BAD_OCTETS_RECEIVED		0x8
-#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR	0xc
-#define ETH_MIB_GOOD_FRAMES_RECEIVED		0x10
-#define ETH_MIB_BAD_FRAMES_RECEIVED		0x14
-#define ETH_MIB_BROADCAST_FRAMES_RECEIVED	0x18
-#define ETH_MIB_MULTICAST_FRAMES_RECEIVED	0x1c
-#define ETH_MIB_FRAMES_64_OCTETS		0x20
-#define ETH_MIB_FRAMES_65_TO_127_OCTETS		0x24
-#define ETH_MIB_FRAMES_128_TO_255_OCTETS	0x28
-#define ETH_MIB_FRAMES_256_TO_511_OCTETS	0x2c
-#define ETH_MIB_FRAMES_512_TO_1023_OCTETS	0x30
-#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS	0x34
-#define ETH_MIB_GOOD_OCTETS_SENT_LOW		0x38
-#define ETH_MIB_GOOD_OCTETS_SENT_HIGH		0x3c
-#define ETH_MIB_GOOD_FRAMES_SENT		0x40
-#define ETH_MIB_EXCESSIVE_COLLISION		0x44
-#define ETH_MIB_MULTICAST_FRAMES_SENT		0x48
-#define ETH_MIB_BROADCAST_FRAMES_SENT		0x4c
-#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED	0x50
-#define ETH_MIB_FC_SENT				0x54
-#define ETH_MIB_GOOD_FC_RECEIVED		0x58
-#define ETH_MIB_BAD_FC_RECEIVED			0x5c
-#define ETH_MIB_UNDERSIZE_RECEIVED		0x60
-#define ETH_MIB_FRAGMENTS_RECEIVED		0x64
-#define ETH_MIB_OVERSIZE_RECEIVED		0x68
-#define ETH_MIB_JABBER_RECEIVED			0x6c
-#define ETH_MIB_MAC_RECEIVE_ERROR		0x70
-#define ETH_MIB_BAD_CRC_EVENT			0x74
-#define ETH_MIB_COLLISION			0x78
-#define ETH_MIB_LATE_COLLISION			0x7c
-
-/* Port serial status reg (PSR) */
-#define ETH_INTERFACE_PCM			0x00000001
-#define ETH_LINK_IS_UP				0x00000002
-#define ETH_PORT_AT_FULL_DUPLEX			0x00000004
-#define ETH_RX_FLOW_CTRL_ENABLED		0x00000008
-#define ETH_GMII_SPEED_1000			0x00000010
-#define ETH_MII_SPEED_100			0x00000020
-#define ETH_TX_IN_PROGRESS			0x00000080
-#define ETH_BYPASS_ACTIVE			0x00000100
-#define ETH_PORT_AT_PARTITION_STATE		0x00000200
-#define ETH_PORT_TX_FIFO_EMPTY			0x00000400
-
-/* SMI reg */
-#define ETH_SMI_BUSY		0x10000000	/* 0 - Write, 1 - Read	*/
-#define ETH_SMI_READ_VALID	0x08000000	/* 0 - Write, 1 - Read	*/
-#define ETH_SMI_OPCODE_WRITE	0		/* Completion of Read	*/
-#define ETH_SMI_OPCODE_READ 	0x04000000	/* Operation is in progress */
-
-/* Interrupt Cause Register Bit Definitions */
-
-/* SDMA command status fields macros */
-
-/* Tx & Rx descriptors status */
-#define ETH_ERROR_SUMMARY			0x00000001
-
-/* Tx & Rx descriptors command */
-#define ETH_BUFFER_OWNED_BY_DMA			0x80000000
-
-/* Tx descriptors status */
-#define ETH_LC_ERROR				0
-#define ETH_UR_ERROR				0x00000002
-#define ETH_RL_ERROR				0x00000004
-#define ETH_LLC_SNAP_FORMAT			0x00000200
-
-/* Rx descriptors status */
-#define ETH_OVERRUN_ERROR			0x00000002
-#define ETH_MAX_FRAME_LENGTH_ERROR		0x00000004
-#define ETH_RESOURCE_ERROR			0x00000006
-#define ETH_VLAN_TAGGED				0x00080000
-#define ETH_BPDU_FRAME				0x00100000
-#define ETH_UDP_FRAME_OVER_IP_V_4		0x00200000
-#define ETH_OTHER_FRAME_TYPE			0x00400000
-#define ETH_LAYER_2_IS_ETH_V_2			0x00800000
-#define ETH_FRAME_TYPE_IP_V_4			0x01000000
-#define ETH_FRAME_HEADER_OK			0x02000000
-#define ETH_RX_LAST_DESC			0x04000000
-#define ETH_RX_FIRST_DESC			0x08000000
-#define ETH_UNKNOWN_DESTINATION_ADDR		0x10000000
-#define ETH_RX_ENABLE_INTERRUPT			0x20000000
-#define ETH_LAYER_4_CHECKSUM_OK			0x40000000
-
-/* Rx descriptors byte count */
-#define ETH_FRAME_FRAGMENTED			0x00000004
-
-/* Tx descriptors command */
-#define ETH_LAYER_4_CHECKSUM_FIRST_DESC		0x00000400
-#define ETH_FRAME_SET_TO_VLAN			0x00008000
-#define ETH_UDP_FRAME				0x00010000
-#define ETH_GEN_TCP_UDP_CHECKSUM		0x00020000
-#define ETH_GEN_IP_V_4_CHECKSUM			0x00040000
-#define ETH_ZERO_PADDING			0x00080000
-#define ETH_TX_LAST_DESC			0x00100000
-#define ETH_TX_FIRST_DESC			0x00200000
-#define ETH_GEN_CRC				0x00400000
-#define ETH_TX_ENABLE_INTERRUPT			0x00800000
-#define ETH_AUTO_MODE				0x40000000
-
-#define ETH_TX_IHL_SHIFT			11
-
-/* typedefs */
-
-typedef enum _eth_func_ret_status {
-	ETH_OK,			/* Returned as expected.		*/
-	ETH_ERROR,		/* Fundamental error.			*/
-	ETH_RETRY,		/* Could not process request. Try later.*/
-	ETH_END_OF_JOB,		/* Ring has nothing to process.		*/
-	ETH_QUEUE_FULL,		/* Ring resource error.			*/
-	ETH_QUEUE_LAST_RESOURCE	/* Ring resources about to exhaust.	*/
-} ETH_FUNC_RET_STATUS;
-
-typedef enum _eth_target {
-	ETH_TARGET_DRAM,
-	ETH_TARGET_DEVICE,
-	ETH_TARGET_CBS,
-	ETH_TARGET_PCI0,
-	ETH_TARGET_PCI1
-} ETH_TARGET;
-
-/* These are for big-endian machines.  Little endian needs different
- * definitions.
- */
-#if defined(__BIG_ENDIAN)
-struct eth_rx_desc {
-	u16 byte_cnt;		/* Descriptor buffer byte count		*/
-	u16 buf_size;		/* Buffer size				*/
-	u32 cmd_sts;		/* Descriptor command status		*/
-	u32 next_desc_ptr;	/* Next descriptor pointer		*/
-	u32 buf_ptr;		/* Descriptor buffer pointer		*/
-};
-
-struct eth_tx_desc {
-	u16 byte_cnt;		/* buffer byte count			*/
-	u16 l4i_chk;		/* CPU provided TCP checksum		*/
-	u32 cmd_sts;		/* Command/status field			*/
-	u32 next_desc_ptr;	/* Pointer to next descriptor		*/
-	u32 buf_ptr;		/* pointer to buffer for this descriptor*/
-};
-
-#elif defined(__LITTLE_ENDIAN)
-struct eth_rx_desc {
-	u32 cmd_sts;		/* Descriptor command status		*/
-	u16 buf_size;		/* Buffer size				*/
-	u16 byte_cnt;		/* Descriptor buffer byte count		*/
-	u32 buf_ptr;		/* Descriptor buffer pointer		*/
-	u32 next_desc_ptr;	/* Next descriptor pointer		*/
-};
-
-struct eth_tx_desc {
-	u32 cmd_sts;		/* Command/status field			*/
-	u16 l4i_chk;		/* CPU provided TCP checksum		*/
-	u16 byte_cnt;		/* buffer byte count			*/
-	u32 buf_ptr;		/* pointer to buffer for this descriptor*/
-	u32 next_desc_ptr;	/* Pointer to next descriptor		*/
-};
-#else
-#error One of __BIG_ENDIAN or __LITTLE_ENDIAN must be defined
-#endif
-
-/* Unified struct for Rx and Tx operations. The user is not required to	*/
-/* be familier with neither Tx nor Rx descriptors.			*/
-struct pkt_info {
-	unsigned short byte_cnt;	/* Descriptor buffer byte count	*/
-	unsigned short l4i_chk;		/* Tx CPU provided TCP Checksum	*/
-	unsigned int cmd_sts;		/* Descriptor command status	*/
-	dma_addr_t buf_ptr;		/* Descriptor buffer pointer	*/
-	struct sk_buff *return_info;	/* User resource return information */
-};
-
-/* Ethernet port specific information */
-
-struct mv643xx_mib_counters {
-	u64 good_octets_received;
-	u32 bad_octets_received;
-	u32 internal_mac_transmit_err;
-	u32 good_frames_received;
-	u32 bad_frames_received;
-	u32 broadcast_frames_received;
-	u32 multicast_frames_received;
-	u32 frames_64_octets;
-	u32 frames_65_to_127_octets;
-	u32 frames_128_to_255_octets;
-	u32 frames_256_to_511_octets;
-	u32 frames_512_to_1023_octets;
-	u32 frames_1024_to_max_octets;
-	u64 good_octets_sent;
-	u32 good_frames_sent;
-	u32 excessive_collision;
-	u32 multicast_frames_sent;
-	u32 broadcast_frames_sent;
-	u32 unrec_mac_control_received;
-	u32 fc_sent;
-	u32 good_fc_received;
-	u32 bad_fc_received;
-	u32 undersize_received;
-	u32 fragments_received;
-	u32 oversize_received;
-	u32 jabber_received;
-	u32 mac_receive_error;
-	u32 bad_crc_event;
-	u32 collision;
-	u32 late_collision;
-};
-
-struct mv643xx_private {
-	int port_num;			/* User Ethernet port number	*/
-
-	u32 rx_sram_addr;		/* Base address of rx sram area */
-	u32 rx_sram_size;		/* Size of rx sram area		*/
-	u32 tx_sram_addr;		/* Base address of tx sram area */
-	u32 tx_sram_size;		/* Size of tx sram area		*/
-
-	int rx_resource_err;		/* Rx ring resource error flag */
-
-	/* Tx/Rx rings managment indexes fields. For driver use */
-
-	/* Next available and first returning Rx resource */
-	int rx_curr_desc_q, rx_used_desc_q;
-
-	/* Next available and first returning Tx resource */
-	int tx_curr_desc_q, tx_used_desc_q;
-
-#ifdef MV643XX_TX_FAST_REFILL
-	u32 tx_clean_threshold;
-#endif
-
-	struct eth_rx_desc *p_rx_desc_area;
-	dma_addr_t rx_desc_dma;
-	int rx_desc_area_size;
-	struct sk_buff **rx_skb;
-
-	struct eth_tx_desc *p_tx_desc_area;
-	dma_addr_t tx_desc_dma;
-	int tx_desc_area_size;
-	struct sk_buff **tx_skb;
-
-	struct work_struct tx_timeout_task;
-
-	struct net_device *dev;
-	struct napi_struct napi;
-	struct net_device_stats stats;
-	struct mv643xx_mib_counters mib_counters;
-	spinlock_t lock;
-	/* Size of Tx Ring per queue */
-	int tx_ring_size;
-	/* Number of tx descriptors in use */
-	int tx_desc_count;
-	/* Size of Rx Ring per queue */
-	int rx_ring_size;
-	/* Number of rx descriptors in use */
-	int rx_desc_count;
-
-	/*
-	 * Used in case RX Ring is empty, which can be caused when
-	 * system does not have resources (skb's)
-	 */
-	struct timer_list timeout;
-
-	u32 rx_int_coal;
-	u32 tx_int_coal;
-	struct mii_if_info mii;
-};
-
-/* Port operation control routines */
-static void eth_port_init(struct mv643xx_private *mp);
-static void eth_port_reset(unsigned int eth_port_num);
-static void eth_port_start(struct net_device *dev);
-
-/* PHY and MIB routines */
-static void ethernet_phy_reset(unsigned int eth_port_num);
-
-static void eth_port_write_smi_reg(unsigned int eth_port_num,
-				   unsigned int phy_reg, unsigned int value);
-
-static void eth_port_read_smi_reg(unsigned int eth_port_num,
-				  unsigned int phy_reg, unsigned int *value);
-
-static void eth_clear_mib_counters(unsigned int eth_port_num);
-
-/* Port data flow control routines */
-static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp,
-					    struct pkt_info *p_pkt_info);
-static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp,
-					      struct pkt_info *p_pkt_info);
-
-#endif				/* __MV643XX_ETH_H__ */
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 9f9a421..ab4d309 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -550,7 +550,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 
 	n = mac->rx->next_to_clean;
 
-	prefetch(RX_RING(mac, n));
+	prefetch(&RX_RING(mac, n));
 
 	for (count = 0; count < limit; count++) {
 		macrx = RX_RING(mac, n);
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 419c00c..e8960f2 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -44,7 +44,8 @@
 		printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
 		#expr,__FILE__,__FUNCTION__,__LINE__);		\
 	}
-#define dprintk(fmt, args...)	do { printk(PFX fmt, ## args); } while (0)
+#define dprintk(fmt, args...) \
+	do { printk(KERN_DEBUG PFX fmt, ## args); } while (0)
 #else
 #define assert(expr) do {} while (0)
 #define dprintk(fmt, args...)	do {} while (0)
@@ -111,19 +112,15 @@ enum mac_version {
 	RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
 	RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
 	RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
-	RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be 8168Bf
-	RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb 8101Ec
-	RTL_GIGA_MAC_VER_14 = 0x0e, // 8101
-	RTL_GIGA_MAC_VER_15 = 0x0f  // 8101
-};
-
-enum phy_version {
-	RTL_GIGA_PHY_VER_C = 0x03, /* PHY Reg 0x03 bit0-3 == 0x0000 */
-	RTL_GIGA_PHY_VER_D = 0x04, /* PHY Reg 0x03 bit0-3 == 0x0000 */
-	RTL_GIGA_PHY_VER_E = 0x05, /* PHY Reg 0x03 bit0-3 == 0x0000 */
-	RTL_GIGA_PHY_VER_F = 0x06, /* PHY Reg 0x03 bit0-3 == 0x0001 */
-	RTL_GIGA_PHY_VER_G = 0x07, /* PHY Reg 0x03 bit0-3 == 0x0002 */
-	RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */
+	RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
+	RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
+	RTL_GIGA_MAC_VER_14 = 0x0e, // 8101 ?
+	RTL_GIGA_MAC_VER_15 = 0x0f, // 8101 ?
+	RTL_GIGA_MAC_VER_16 = 0x11, // 8101Ec
+	RTL_GIGA_MAC_VER_17 = 0x10, // 8168Bf
+	RTL_GIGA_MAC_VER_18 = 0x12, // 8168CP
+	RTL_GIGA_MAC_VER_19 = 0x13, // 8168C
+	RTL_GIGA_MAC_VER_20 = 0x14  // 8168C
 };
 
 #define _R(NAME,MAC,MASK) \
@@ -144,7 +141,12 @@ static const struct {
 	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
 	_R("RTL8101e",		RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
 	_R("RTL8100e",		RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139
-	_R("RTL8100e",		RTL_GIGA_MAC_VER_15, 0xff7e1880)  // PCI-E 8139
+	_R("RTL8100e",		RTL_GIGA_MAC_VER_15, 0xff7e1880), // PCI-E 8139
+	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_17, 0xff7e1880), // PCI-E
+	_R("RTL8101e",		RTL_GIGA_MAC_VER_16, 0xff7e1880), // PCI-E
+	_R("RTL8168cp/8111cp",	RTL_GIGA_MAC_VER_18, 0xff7e1880), // PCI-E
+	_R("RTL8168c/8111c",	RTL_GIGA_MAC_VER_19, 0xff7e1880), // PCI-E
+	_R("RTL8168c/8111c",	RTL_GIGA_MAC_VER_20, 0xff7e1880)  // PCI-E
 };
 #undef _R
 
@@ -165,7 +167,7 @@ static struct pci_device_id rtl8169_pci_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8168), 0, 0, RTL_CFG_1 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), 0, 0, RTL_CFG_0 },
 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), 0, 0, RTL_CFG_0 },
-	{ PCI_DEVICE(0x1259,			0xc107), 0, 0, RTL_CFG_0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_AT,		0xc107), 0, 0, RTL_CFG_0 },
 	{ PCI_DEVICE(0x16ec,			0x0116), 0, 0, RTL_CFG_0 },
 	{ PCI_VENDOR_ID_LINKSYS,		0x1032,
 		PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
@@ -277,6 +279,7 @@ enum rtl_register_content {
 	TxDMAShift = 8,	/* DMA burst value (0-7) is shift this many bits */
 
 	/* Config1 register p.24 */
+	MSIEnable	= (1 << 5),	/* Enable Message Signaled Interrupt */
 	PMEnable	= (1 << 0),	/* Power Management Enable */
 
 	/* Config2 register p. 25 */
@@ -380,17 +383,20 @@ struct ring_info {
 	u8		__pad[sizeof(void *) - sizeof(u32)];
 };
 
+enum features {
+	RTL_FEATURE_WOL	= (1 << 0),
+	RTL_FEATURE_MSI	= (1 << 1),
+};
+
 struct rtl8169_private {
 	void __iomem *mmio_addr;	/* memory map physical address */
 	struct pci_dev *pci_dev;	/* Index of PCI device */
 	struct net_device *dev;
 	struct napi_struct napi;
-	struct net_device_stats stats;	/* statistics of net device */
 	spinlock_t lock;		/* spin lock flag */
 	u32 msg_enable;
 	int chipset;
 	int mac_version;
-	int phy_version;
 	u32 cur_rx; /* Index into the Rx descriptor buffer of next Rx pkt. */
 	u32 cur_tx; /* Index into the Tx descriptor buffer of next Rx pkt. */
 	u32 dirty_rx;
@@ -420,7 +426,7 @@ struct rtl8169_private {
 	unsigned int (*phy_reset_pending)(void __iomem *);
 	unsigned int (*link_ok)(void __iomem *);
 	struct delayed_work task;
-	unsigned wol_enabled : 1;
+	unsigned features;
 };
 
 MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@@ -626,7 +632,10 @@ static int rtl8169_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
-	tp->wol_enabled = (wol->wolopts) ? 1 : 0;
+	if (wol->wolopts)
+		tp->features |= RTL_FEATURE_WOL;
+	else
+		tp->features &= ~RTL_FEATURE_WOL;
 
 	spin_unlock_irq(&tp->lock);
 
@@ -707,7 +716,8 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
 
 		/* This tweak comes straight from Realtek's driver. */
 		if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
-		    (tp->mac_version == RTL_GIGA_MAC_VER_13)) {
+		    ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
+		     (tp->mac_version == RTL_GIGA_MAC_VER_16))) {
 			auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA;
 		}
 	}
@@ -715,7 +725,8 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
 	/* The 8100e/8101e do Fast Ethernet only. */
 	if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
 	    (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_15)) {
+	    (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
 		if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
 		    netif_msg_link(tp)) {
 			printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
@@ -726,7 +737,8 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
 
 	auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
 
-	if (tp->mac_version == RTL_GIGA_MAC_VER_12) {
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_12) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_17)) {
 		/* Vendor specific (0x1f) and reserved (0x0e) MII registers. */
 		mdio_write(ioaddr, 0x1f, 0x0000);
 		mdio_write(ioaddr, 0x0e, 0x0000);
@@ -1104,26 +1116,51 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
 	 */
 	const struct {
 		u32 mask;
+		u32 val;
 		int mac_version;
 	} mac_info[] = {
-		{ 0x38800000,	RTL_GIGA_MAC_VER_15 },
-		{ 0x38000000,	RTL_GIGA_MAC_VER_12 },
-		{ 0x34000000,	RTL_GIGA_MAC_VER_13 },
-		{ 0x30800000,	RTL_GIGA_MAC_VER_14 },
-		{ 0x30000000,	RTL_GIGA_MAC_VER_11 },
-		{ 0x98000000,	RTL_GIGA_MAC_VER_06 },
-		{ 0x18000000,	RTL_GIGA_MAC_VER_05 },
-		{ 0x10000000,	RTL_GIGA_MAC_VER_04 },
-		{ 0x04000000,	RTL_GIGA_MAC_VER_03 },
-		{ 0x00800000,	RTL_GIGA_MAC_VER_02 },
-		{ 0x00000000,	RTL_GIGA_MAC_VER_01 }	/* Catch-all */
+		/* 8168B family. */
+		{ 0x7c800000, 0x3c800000,	RTL_GIGA_MAC_VER_18 },
+		{ 0x7cf00000, 0x3c000000,	RTL_GIGA_MAC_VER_19 },
+		{ 0x7cf00000, 0x3c200000,	RTL_GIGA_MAC_VER_20 },
+		{ 0x7c800000, 0x3c000000,	RTL_GIGA_MAC_VER_20 },
+
+		/* 8168B family. */
+		{ 0x7cf00000, 0x38000000,	RTL_GIGA_MAC_VER_12 },
+		{ 0x7cf00000, 0x38500000,	RTL_GIGA_MAC_VER_17 },
+		{ 0x7c800000, 0x38000000,	RTL_GIGA_MAC_VER_17 },
+		{ 0x7c800000, 0x30000000,	RTL_GIGA_MAC_VER_11 },
+
+		/* 8101 family. */
+		{ 0x7cf00000, 0x34000000,	RTL_GIGA_MAC_VER_13 },
+		{ 0x7cf00000, 0x34200000,	RTL_GIGA_MAC_VER_16 },
+		{ 0x7c800000, 0x34000000,	RTL_GIGA_MAC_VER_16 },
+		/* FIXME: where did these entries come from ? -- FR */
+		{ 0xfc800000, 0x38800000,	RTL_GIGA_MAC_VER_15 },
+		{ 0xfc800000, 0x30800000,	RTL_GIGA_MAC_VER_14 },
+
+		/* 8110 family. */
+		{ 0xfc800000, 0x98000000,	RTL_GIGA_MAC_VER_06 },
+		{ 0xfc800000, 0x18000000,	RTL_GIGA_MAC_VER_05 },
+		{ 0xfc800000, 0x10000000,	RTL_GIGA_MAC_VER_04 },
+		{ 0xfc800000, 0x04000000,	RTL_GIGA_MAC_VER_03 },
+		{ 0xfc800000, 0x00800000,	RTL_GIGA_MAC_VER_02 },
+		{ 0xfc800000, 0x00000000,	RTL_GIGA_MAC_VER_01 },
+
+		{ 0x00000000, 0x00000000,	RTL_GIGA_MAC_VER_01 }	/* Catch-all */
 	}, *p = mac_info;
 	u32 reg;
 
-	reg = RTL_R32(TxConfig) & 0xfc800000;
-	while ((reg & p->mask) != p->mask)
+	reg = RTL_R32(TxConfig);
+	while ((reg & p->mask) != p->val)
 		p++;
 	tp->mac_version = p->mac_version;
+
+	if (p->mask == 0x00000000) {
+		struct pci_dev *pdev = tp->pci_dev;
+
+		dev_info(&pdev->dev, "unknown MAC (%08x)\n", reg);
+	}
 }
 
 static void rtl8169_print_mac_version(struct rtl8169_private *tp)
@@ -1131,54 +1168,21 @@ static void rtl8169_print_mac_version(struct rtl8169_private *tp)
 	dprintk("mac_version = 0x%02x\n", tp->mac_version);
 }
 
-static void rtl8169_get_phy_version(struct rtl8169_private *tp,
-				    void __iomem *ioaddr)
-{
-	const struct {
-		u16 mask;
-		u16 set;
-		int phy_version;
-	} phy_info[] = {
-		{ 0x000f, 0x0002, RTL_GIGA_PHY_VER_G },
-		{ 0x000f, 0x0001, RTL_GIGA_PHY_VER_F },
-		{ 0x000f, 0x0000, RTL_GIGA_PHY_VER_E },
-		{ 0x0000, 0x0000, RTL_GIGA_PHY_VER_D } /* Catch-all */
-	}, *p = phy_info;
+struct phy_reg {
 	u16 reg;
+	u16 val;
+};
 
-	reg = mdio_read(ioaddr, MII_PHYSID2) & 0xffff;
-	while ((reg & p->mask) != p->set)
-		p++;
-	tp->phy_version = p->phy_version;
-}
-
-static void rtl8169_print_phy_version(struct rtl8169_private *tp)
+static void rtl_phy_write(void __iomem *ioaddr, struct phy_reg *regs, int len)
 {
-	struct {
-		int version;
-		char *msg;
-		u32 reg;
-	} phy_print[] = {
-		{ RTL_GIGA_PHY_VER_G, "RTL_GIGA_PHY_VER_G", 0x0002 },
-		{ RTL_GIGA_PHY_VER_F, "RTL_GIGA_PHY_VER_F", 0x0001 },
-		{ RTL_GIGA_PHY_VER_E, "RTL_GIGA_PHY_VER_E", 0x0000 },
-		{ RTL_GIGA_PHY_VER_D, "RTL_GIGA_PHY_VER_D", 0x0000 },
-		{ 0, NULL, 0x0000 }
-	}, *p;
-
-	for (p = phy_print; p->msg; p++) {
-		if (tp->phy_version == p->version) {
-			dprintk("phy_version == %s (%04x)\n", p->msg, p->reg);
-			return;
-		}
+	while (len-- > 0) {
+		mdio_write(ioaddr, regs->reg, regs->val);
+		regs++;
 	}
-	dprintk("phy_version == Unknown\n");
 }
 
-static void rtl8169_hw_phy_config(struct net_device *dev)
+static void rtl8169s_hw_phy_config(void __iomem *ioaddr)
 {
-	struct rtl8169_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
 	struct {
 		u16 regs[5]; /* Beware of bit-sign propagation */
 	} phy_magic[5] = { {
@@ -1211,33 +1215,9 @@ static void rtl8169_hw_phy_config(struct net_device *dev)
 	}, *p = phy_magic;
 	unsigned int i;
 
-	rtl8169_print_mac_version(tp);
-	rtl8169_print_phy_version(tp);
-
-	if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
-		return;
-	if (tp->phy_version >= RTL_GIGA_PHY_VER_H)
-		return;
-
-	dprintk("MAC version != 0 && PHY version == 0 or 1\n");
-	dprintk("Do final_reg2.cfg\n");
-
-	/* Shazam ! */
-
-	if (tp->mac_version == RTL_GIGA_MAC_VER_04) {
-		mdio_write(ioaddr, 31, 0x0002);
-		mdio_write(ioaddr,  1, 0x90d0);
-		mdio_write(ioaddr, 31, 0x0000);
-		return;
-	}
-
-	if ((tp->mac_version != RTL_GIGA_MAC_VER_02) &&
-	    (tp->mac_version != RTL_GIGA_MAC_VER_03))
-		return;
-
-	mdio_write(ioaddr, 31, 0x0001);			//w 31 2 0 1
-	mdio_write(ioaddr, 21, 0x1000);			//w 21 15 0 1000
-	mdio_write(ioaddr, 24, 0x65c7);			//w 24 15 0 65c7
+	mdio_write(ioaddr, 0x1f, 0x0001);		//w 31 2 0 1
+	mdio_write(ioaddr, 0x15, 0x1000);		//w 21 15 0 1000
+	mdio_write(ioaddr, 0x18, 0x65c7);		//w 24 15 0 65c7
 	rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0);	//w 4 11 11 0
 
 	for (i = 0; i < ARRAY_SIZE(phy_magic); i++, p++) {
@@ -1250,7 +1230,115 @@ static void rtl8169_hw_phy_config(struct net_device *dev)
 		rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 1); //w 4 11 11 1
 		rtl8169_write_gmii_reg_bit(ioaddr, 4, 11, 0); //w 4 11 11 0
 	}
-	mdio_write(ioaddr, 31, 0x0000); //w 31 2 0 0
+	mdio_write(ioaddr, 0x1f, 0x0000); //w 31 2 0 0
+}
+
+static void rtl8169sb_hw_phy_config(void __iomem *ioaddr)
+{
+	struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0002 },
+		{ 0x01, 0x90d0 },
+		{ 0x1f, 0x0000 }
+	};
+
+	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+static void rtl8168b_hw_phy_config(void __iomem *ioaddr)
+{
+	struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0000 },
+		{ 0x10, 0xf41b },
+		{ 0x1f, 0x0000 }
+	};
+
+	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
+static void rtl8168cp_hw_phy_config(void __iomem *ioaddr)
+{
+	struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0000 },
+		{ 0x1d, 0x0f00 },
+		{ 0x1f, 0x0002 },
+		{ 0x0c, 0x1ec8 },
+		{ 0x1f, 0x0000 }
+	};
+
+	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
+static void rtl8168c_hw_phy_config(void __iomem *ioaddr)
+{
+	struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0001 },
+		{ 0x12, 0x2300 },
+		{ 0x1f, 0x0002 },
+		{ 0x00, 0x88d4 },
+		{ 0x01, 0x82b1 },
+		{ 0x03, 0x7002 },
+		{ 0x08, 0x9e30 },
+		{ 0x09, 0x01f0 },
+		{ 0x0a, 0x5500 },
+		{ 0x0c, 0x00c8 },
+		{ 0x1f, 0x0003 },
+		{ 0x12, 0xc096 },
+		{ 0x16, 0x000a },
+		{ 0x1f, 0x0000 }
+	};
+
+	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
+static void rtl8168cx_hw_phy_config(void __iomem *ioaddr)
+{
+	struct phy_reg phy_reg_init[] = {
+		{ 0x1f, 0x0000 },
+		{ 0x12, 0x2300 },
+		{ 0x1f, 0x0003 },
+		{ 0x16, 0x0f0a },
+		{ 0x1f, 0x0000 },
+		{ 0x1f, 0x0002 },
+		{ 0x0c, 0x7eb8 },
+		{ 0x1f, 0x0000 }
+	};
+
+	rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
+static void rtl_hw_phy_config(struct net_device *dev)
+{
+	struct rtl8169_private *tp = netdev_priv(dev);
+	void __iomem *ioaddr = tp->mmio_addr;
+
+	rtl8169_print_mac_version(tp);
+
+	switch (tp->mac_version) {
+	case RTL_GIGA_MAC_VER_01:
+		break;
+	case RTL_GIGA_MAC_VER_02:
+	case RTL_GIGA_MAC_VER_03:
+		rtl8169s_hw_phy_config(ioaddr);
+		break;
+	case RTL_GIGA_MAC_VER_04:
+		rtl8169sb_hw_phy_config(ioaddr);
+		break;
+	case RTL_GIGA_MAC_VER_11:
+	case RTL_GIGA_MAC_VER_12:
+	case RTL_GIGA_MAC_VER_17:
+		rtl8168b_hw_phy_config(ioaddr);
+		break;
+	case RTL_GIGA_MAC_VER_18:
+		rtl8168cp_hw_phy_config(ioaddr);
+		break;
+	case RTL_GIGA_MAC_VER_19:
+		rtl8168c_hw_phy_config(ioaddr);
+		break;
+	case RTL_GIGA_MAC_VER_20:
+		rtl8168cx_hw_phy_config(ioaddr);
+		break;
+	default:
+		break;
+	}
 }
 
 static void rtl8169_phy_timer(unsigned long __opaque)
@@ -1262,7 +1350,6 @@ static void rtl8169_phy_timer(unsigned long __opaque)
 	unsigned long timeout = RTL8169_PHY_TIMEOUT;
 
 	assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
-	assert(tp->phy_version < RTL_GIGA_PHY_VER_H);
 
 	if (!(tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL))
 		return;
@@ -1297,8 +1384,7 @@ static inline void rtl8169_delete_timer(struct net_device *dev)
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct timer_list *timer = &tp->timer;
 
-	if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
-	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
+	if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
 		return;
 
 	del_timer_sync(timer);
@@ -1309,8 +1395,7 @@ static inline void rtl8169_request_timer(struct net_device *dev)
 	struct rtl8169_private *tp = netdev_priv(dev);
 	struct timer_list *timer = &tp->timer;
 
-	if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
-	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
+	if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
 		return;
 
 	mod_timer(timer, jiffies + RTL8169_PHY_TIMEOUT);
@@ -1362,7 +1447,7 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
 {
 	void __iomem *ioaddr = tp->mmio_addr;
 
-	rtl8169_hw_phy_config(dev);
+	rtl_hw_phy_config(dev);
 
 	dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
 	RTL_W8(0x82, 0x01);
@@ -1457,6 +1542,7 @@ static const struct rtl_cfg_info {
 	unsigned int align;
 	u16 intr_event;
 	u16 napi_event;
+	unsigned msi;
 } rtl_cfg_infos [] = {
 	[RTL_CFG_0] = {
 		.hw_start	= rtl_hw_start_8169,
@@ -1464,7 +1550,8 @@ static const struct rtl_cfg_info {
 		.align		= 0,
 		.intr_event	= SYSErr | LinkChg | RxOverflow |
 				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
-		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
+		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
+		.msi		= 0
 	},
 	[RTL_CFG_1] = {
 		.hw_start	= rtl_hw_start_8168,
@@ -1472,7 +1559,8 @@ static const struct rtl_cfg_info {
 		.align		= 8,
 		.intr_event	= SYSErr | LinkChg | RxOverflow |
 				  TxErr | TxOK | RxOK | RxErr,
-		.napi_event	= TxErr | TxOK | RxOK | RxOverflow
+		.napi_event	= TxErr | TxOK | RxOK | RxOverflow,
+		.msi		= RTL_FEATURE_MSI
 	},
 	[RTL_CFG_2] = {
 		.hw_start	= rtl_hw_start_8101,
@@ -1480,10 +1568,39 @@ static const struct rtl_cfg_info {
 		.align		= 8,
 		.intr_event	= SYSErr | LinkChg | RxOverflow | PCSTimeout |
 				  RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
-		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow
+		.napi_event	= RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
+		.msi		= RTL_FEATURE_MSI
 	}
 };
 
+/* Cfg9346_Unlock assumed. */
+static unsigned rtl_try_msi(struct pci_dev *pdev, void __iomem *ioaddr,
+			    const struct rtl_cfg_info *cfg)
+{
+	unsigned msi = 0;
+	u8 cfg2;
+
+	cfg2 = RTL_R8(Config2) & ~MSIEnable;
+	if (cfg->msi) {
+		if (pci_enable_msi(pdev)) {
+			dev_info(&pdev->dev, "no MSI. Back to INTx.\n");
+		} else {
+			cfg2 |= MSIEnable;
+			msi = RTL_FEATURE_MSI;
+		}
+	}
+	RTL_W8(Config2, cfg2);
+	return msi;
+}
+
+static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
+{
+	if (tp->features & RTL_FEATURE_MSI) {
+		pci_disable_msi(pdev);
+		tp->features &= ~RTL_FEATURE_MSI;
+	}
+}
+
 static int __devinit
 rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
@@ -1596,10 +1713,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	/* Identify chip attached to board */
 	rtl8169_get_mac_version(tp, ioaddr);
-	rtl8169_get_phy_version(tp, ioaddr);
 
 	rtl8169_print_mac_version(tp);
-	rtl8169_print_phy_version(tp);
 
 	for (i = ARRAY_SIZE(rtl_chip_info) - 1; i >= 0; i--) {
 		if (tp->mac_version == rtl_chip_info[i].mac_version)
@@ -1619,6 +1734,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	RTL_W8(Cfg9346, Cfg9346_Unlock);
 	RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
 	RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
+	tp->features |= rtl_try_msi(pdev, ioaddr, cfg);
 	RTL_W8(Cfg9346, Cfg9346_Lock);
 
 	if (RTL_R8(PHYstatus) & TBI_Enable) {
@@ -1686,7 +1802,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	rc = register_netdev(dev);
 	if (rc < 0)
-		goto err_out_unmap_5;
+		goto err_out_msi_5;
 
 	pci_set_drvdata(pdev, dev);
 
@@ -1709,7 +1825,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 out:
 	return rc;
 
-err_out_unmap_5:
+err_out_msi_5:
+	rtl_disable_msi(pdev, tp);
 	iounmap(ioaddr);
 err_out_free_res_4:
 	pci_release_regions(pdev);
@@ -1730,6 +1847,7 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
 	flush_scheduled_work();
 
 	unregister_netdev(dev);
+	rtl_disable_msi(pdev, tp);
 	rtl8169_release_board(pdev, dev, tp->mmio_addr);
 	pci_set_drvdata(pdev, NULL);
 }
@@ -1773,7 +1891,8 @@ static int rtl8169_open(struct net_device *dev)
 
 	smp_mb();
 
-	retval = request_irq(dev->irq, rtl8169_interrupt, IRQF_SHARED,
+	retval = request_irq(dev->irq, rtl8169_interrupt,
+			     (tp->features & RTL_FEATURE_MSI) ? 0 : IRQF_SHARED,
 			     dev->name, dev);
 	if (retval < 0)
 		goto err_release_ring_2;
@@ -1933,7 +2052,7 @@ static void rtl_hw_start_8169(struct net_device *dev)
 
 	if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
 	    (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
-		dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. "
+		dprintk("Set MAC Reg C+CR Offset 0xE0. "
 			"Bit-3 and bit-14 MUST be 1\n");
 		tp->cp_cmd |= (1 << 14);
 	}
@@ -2029,7 +2148,8 @@ static void rtl_hw_start_8101(struct net_device *dev)
 	void __iomem *ioaddr = tp->mmio_addr;
 	struct pci_dev *pdev = tp->pci_dev;
 
-	if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
+	if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_16)) {
 		pci_write_config_word(pdev, 0x68, 0x00);
 		pci_write_config_word(pdev, 0x69, 0x08);
 	}
@@ -2259,7 +2379,7 @@ static void rtl8169_tx_clear(struct rtl8169_private *tp)
 				dev_kfree_skb(skb);
 				tx_skb->skb = NULL;
 			}
-			tp->stats.tx_dropped++;
+			tp->dev->stats.tx_dropped++;
 		}
 	}
 	tp->cur_tx = tp->dirty_tx = 0;
@@ -2310,7 +2430,7 @@ static void rtl8169_reinit_task(struct work_struct *work)
 	ret = rtl8169_open(dev);
 	if (unlikely(ret < 0)) {
 		if (net_ratelimit() && netif_msg_drv(tp)) {
-			printk(PFX KERN_ERR "%s: reinit failure (status = %d)."
+			printk(KERN_ERR PFX "%s: reinit failure (status = %d)."
 			       " Rescheduling.\n", dev->name, ret);
 		}
 		rtl8169_schedule_work(dev, rtl8169_reinit_task);
@@ -2340,9 +2460,10 @@ static void rtl8169_reset_task(struct work_struct *work)
 		rtl8169_init_ring_indexes(tp);
 		rtl_hw_start(dev);
 		netif_wake_queue(dev);
+		rtl8169_check_link_status(dev, tp, tp->mmio_addr);
 	} else {
 		if (net_ratelimit() && netif_msg_intr(tp)) {
-			printk(PFX KERN_EMERG "%s: Rx buffers shortage\n",
+			printk(KERN_EMERG PFX "%s: Rx buffers shortage\n",
 			       dev->name);
 		}
 		rtl8169_schedule_work(dev, rtl8169_reset_task);
@@ -2496,7 +2617,7 @@ err_stop:
 	netif_stop_queue(dev);
 	ret = NETDEV_TX_BUSY;
 err_update_stats:
-	tp->stats.tx_dropped++;
+	dev->stats.tx_dropped++;
 	goto out;
 }
 
@@ -2571,8 +2692,8 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
 		if (status & DescOwn)
 			break;
 
-		tp->stats.tx_bytes += len;
-		tp->stats.tx_packets++;
+		dev->stats.tx_bytes += len;
+		dev->stats.tx_packets++;
 
 		rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
 
@@ -2672,14 +2793,14 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
 				       "%s: Rx ERROR. status = %08x\n",
 				       dev->name, status);
 			}
-			tp->stats.rx_errors++;
+			dev->stats.rx_errors++;
 			if (status & (RxRWT | RxRUNT))
-				tp->stats.rx_length_errors++;
+				dev->stats.rx_length_errors++;
 			if (status & RxCRC)
-				tp->stats.rx_crc_errors++;
+				dev->stats.rx_crc_errors++;
 			if (status & RxFOVF) {
 				rtl8169_schedule_work(dev, rtl8169_reset_task);
-				tp->stats.rx_fifo_errors++;
+				dev->stats.rx_fifo_errors++;
 			}
 			rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
 		} else {
@@ -2694,8 +2815,8 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
 			 * sized frames.
 			 */
 			if (unlikely(rtl8169_fragmented_frame(status))) {
-				tp->stats.rx_dropped++;
-				tp->stats.rx_length_errors++;
+				dev->stats.rx_dropped++;
+				dev->stats.rx_length_errors++;
 				rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
 				continue;
 			}
@@ -2719,8 +2840,8 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
 				rtl8169_rx_skb(skb);
 
 			dev->last_rx = jiffies;
-			tp->stats.rx_bytes += pkt_size;
-			tp->stats.rx_packets++;
+			dev->stats.rx_bytes += pkt_size;
+			dev->stats.rx_packets++;
 		}
 
 		/* Work around for AMD plateform. */
@@ -2881,7 +3002,7 @@ core_down:
 	rtl8169_asic_down(ioaddr);
 
 	/* Update the error counts. */
-	tp->stats.rx_missed_errors += RTL_R32(RxMissed);
+	dev->stats.rx_missed_errors += RTL_R32(RxMissed);
 	RTL_W32(RxMissed, 0);
 
 	spin_unlock_irq(&tp->lock);
@@ -2984,7 +3105,9 @@ static void rtl_set_rx_mode(struct net_device *dev)
 	    (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
 	    (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
 	    (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
-	    (tp->mac_version == RTL_GIGA_MAC_VER_15)) {
+	    (tp->mac_version == RTL_GIGA_MAC_VER_15) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_16) ||
+	    (tp->mac_version == RTL_GIGA_MAC_VER_17)) {
 		mc_filter[0] = 0xffffffff;
 		mc_filter[1] = 0xffffffff;
 	}
@@ -3011,12 +3134,12 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
 
 	if (netif_running(dev)) {
 		spin_lock_irqsave(&tp->lock, flags);
-		tp->stats.rx_missed_errors += RTL_R32(RxMissed);
+		dev->stats.rx_missed_errors += RTL_R32(RxMissed);
 		RTL_W32(RxMissed, 0);
 		spin_unlock_irqrestore(&tp->lock, flags);
 	}
 
-	return &tp->stats;
+	return &dev->stats;
 }
 
 #ifdef CONFIG_PM
@@ -3037,14 +3160,15 @@ static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
 
 	rtl8169_asic_down(ioaddr);
 
-	tp->stats.rx_missed_errors += RTL_R32(RxMissed);
+	dev->stats.rx_missed_errors += RTL_R32(RxMissed);
 	RTL_W32(RxMissed, 0);
 
 	spin_unlock_irq(&tp->lock);
 
 out_pci_suspend:
 	pci_save_state(pdev);
-	pci_enable_wake(pdev, pci_choose_state(pdev, state), tp->wol_enabled);
+	pci_enable_wake(pdev, pci_choose_state(pdev, state),
+		(tp->features & RTL_FEATURE_WOL) ? 1 : 0);
 	pci_set_power_state(pdev, pci_choose_state(pdev, state));
 
 	return 0;
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 24cfb62..c27c7d6 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -4271,7 +4271,7 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
 	del_timer_sync(&hw->watchdog_timer);
 	cancel_work_sync(&hw->restart_work);
 
-	for (i = hw->ports; i >= 0; --i)
+	for (i = hw->ports-1; i >= 0; --i)
 		unregister_netdev(hw->dev[i]);
 
 	sky2_write32(hw, B0_IMSK, 0);
@@ -4289,7 +4289,7 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 
-	for (i = hw->ports; i >= 0; --i)
+	for (i = hw->ports-1; i >= 0; --i)
 		free_netdev(hw->dev[i]);
 
 	iounmap(hw->regs);
diff --git a/include/linux/mv643xx.h b/include/linux/mv643xx.h
index 9c80490..d2ae618 100644
--- a/include/linux/mv643xx.h
+++ b/include/linux/mv643xx.h
@@ -14,6 +14,7 @@
 #define __ASM_MV643XX_H
 
 #include <asm/types.h>
+#include <linux/mv643xx_eth.h>
 
 /****************************************/
 /* Processor Address Space              */
@@ -658,120 +659,6 @@
 /*        Ethernet Unit Registers  		*/
 /****************************************/
 
-#define MV643XX_ETH_SHARED_REGS                                     0x2000
-#define MV643XX_ETH_SHARED_REGS_SIZE                                0x2000
-
-#define MV643XX_ETH_PHY_ADDR_REG                                    0x2000
-#define MV643XX_ETH_SMI_REG                                         0x2004
-#define MV643XX_ETH_UNIT_DEFAULT_ADDR_REG                           0x2008
-#define MV643XX_ETH_UNIT_DEFAULTID_REG                              0x200c
-#define MV643XX_ETH_UNIT_INTERRUPT_CAUSE_REG                        0x2080
-#define MV643XX_ETH_UNIT_INTERRUPT_MASK_REG                         0x2084
-#define MV643XX_ETH_UNIT_INTERNAL_USE_REG                           0x24fc
-#define MV643XX_ETH_UNIT_ERROR_ADDR_REG                             0x2094
-#define MV643XX_ETH_BAR_0                                           0x2200
-#define MV643XX_ETH_BAR_1                                           0x2208
-#define MV643XX_ETH_BAR_2                                           0x2210
-#define MV643XX_ETH_BAR_3                                           0x2218
-#define MV643XX_ETH_BAR_4                                           0x2220
-#define MV643XX_ETH_BAR_5                                           0x2228
-#define MV643XX_ETH_SIZE_REG_0                                      0x2204
-#define MV643XX_ETH_SIZE_REG_1                                      0x220c
-#define MV643XX_ETH_SIZE_REG_2                                      0x2214
-#define MV643XX_ETH_SIZE_REG_3                                      0x221c
-#define MV643XX_ETH_SIZE_REG_4                                      0x2224
-#define MV643XX_ETH_SIZE_REG_5                                      0x222c
-#define MV643XX_ETH_HEADERS_RETARGET_BASE_REG                       0x2230
-#define MV643XX_ETH_HEADERS_RETARGET_CONTROL_REG                    0x2234
-#define MV643XX_ETH_HIGH_ADDR_REMAP_REG_0                           0x2280
-#define MV643XX_ETH_HIGH_ADDR_REMAP_REG_1                           0x2284
-#define MV643XX_ETH_HIGH_ADDR_REMAP_REG_2                           0x2288
-#define MV643XX_ETH_HIGH_ADDR_REMAP_REG_3                           0x228c
-#define MV643XX_ETH_BASE_ADDR_ENABLE_REG                            0x2290
-#define MV643XX_ETH_ACCESS_PROTECTION_REG(port)                    (0x2294 + (port<<2))
-#define MV643XX_ETH_MIB_COUNTERS_BASE(port)                        (0x3000 + (port<<7))
-#define MV643XX_ETH_PORT_CONFIG_REG(port)                          (0x2400 + (port<<10))
-#define MV643XX_ETH_PORT_CONFIG_EXTEND_REG(port)                   (0x2404 + (port<<10))
-#define MV643XX_ETH_MII_SERIAL_PARAMETRS_REG(port)                 (0x2408 + (port<<10))
-#define MV643XX_ETH_GMII_SERIAL_PARAMETRS_REG(port)                (0x240c + (port<<10))
-#define MV643XX_ETH_VLAN_ETHERTYPE_REG(port)                       (0x2410 + (port<<10))
-#define MV643XX_ETH_MAC_ADDR_LOW(port)                             (0x2414 + (port<<10))
-#define MV643XX_ETH_MAC_ADDR_HIGH(port)                            (0x2418 + (port<<10))
-#define MV643XX_ETH_SDMA_CONFIG_REG(port)                          (0x241c + (port<<10))
-#define MV643XX_ETH_DSCP_0(port)                                   (0x2420 + (port<<10))
-#define MV643XX_ETH_DSCP_1(port)                                   (0x2424 + (port<<10))
-#define MV643XX_ETH_DSCP_2(port)                                   (0x2428 + (port<<10))
-#define MV643XX_ETH_DSCP_3(port)                                   (0x242c + (port<<10))
-#define MV643XX_ETH_DSCP_4(port)                                   (0x2430 + (port<<10))
-#define MV643XX_ETH_DSCP_5(port)                                   (0x2434 + (port<<10))
-#define MV643XX_ETH_DSCP_6(port)                                   (0x2438 + (port<<10))
-#define MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port)                  (0x243c + (port<<10))
-#define MV643XX_ETH_VLAN_PRIORITY_TAG_TO_PRIORITY(port)            (0x2440 + (port<<10))
-#define MV643XX_ETH_PORT_STATUS_REG(port)                          (0x2444 + (port<<10))
-#define MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port)               (0x2448 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_FIXED_PRIORITY(port)                  (0x244c + (port<<10))
-#define MV643XX_ETH_PORT_TX_TOKEN_BUCKET_RATE_CONFIG(port)         (0x2450 + (port<<10))
-#define MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port)                    (0x2458 + (port<<10))
-#define MV643XX_ETH_PORT_MAXIMUM_TOKEN_BUCKET_SIZE(port)           (0x245c + (port<<10))
-#define MV643XX_ETH_INTERRUPT_CAUSE_REG(port)                      (0x2460 + (port<<10))
-#define MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port)               (0x2464 + (port<<10))
-#define MV643XX_ETH_INTERRUPT_MASK_REG(port)                       (0x2468 + (port<<10))
-#define MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port)                (0x246c + (port<<10))
-#define MV643XX_ETH_RX_FIFO_URGENT_THRESHOLD_REG(port)             (0x2470 + (port<<10))
-#define MV643XX_ETH_TX_FIFO_URGENT_THRESHOLD_REG(port)             (0x2474 + (port<<10))
-#define MV643XX_ETH_RX_MINIMAL_FRAME_SIZE_REG(port)                (0x247c + (port<<10))
-#define MV643XX_ETH_RX_DISCARDED_FRAMES_COUNTER(port)              (0x2484 + (port<<10))
-#define MV643XX_ETH_PORT_DEBUG_0_REG(port)                         (0x248c + (port<<10))
-#define MV643XX_ETH_PORT_DEBUG_1_REG(port)                         (0x2490 + (port<<10))
-#define MV643XX_ETH_PORT_INTERNAL_ADDR_ERROR_REG(port)             (0x2494 + (port<<10))
-#define MV643XX_ETH_INTERNAL_USE_REG(port)                         (0x24fc + (port<<10))
-#define MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port)                (0x2680 + (port<<10))
-#define MV643XX_ETH_CURRENT_SERVED_TX_DESC_PTR(port)               (0x2684 + (port<<10))      
-#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_0(port)              (0x260c + (port<<10))     
-#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_1(port)              (0x261c + (port<<10))     
-#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_2(port)              (0x262c + (port<<10))     
-#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_3(port)              (0x263c + (port<<10))     
-#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_4(port)              (0x264c + (port<<10))     
-#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_5(port)              (0x265c + (port<<10))     
-#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_6(port)              (0x266c + (port<<10))     
-#define MV643XX_ETH_RX_CURRENT_QUEUE_DESC_PTR_7(port)              (0x267c + (port<<10))     
-#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_0(port)              (0x26c0 + (port<<10))     
-#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_1(port)              (0x26c4 + (port<<10))     
-#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_2(port)              (0x26c8 + (port<<10))     
-#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_3(port)              (0x26cc + (port<<10))     
-#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_4(port)              (0x26d0 + (port<<10))     
-#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_5(port)              (0x26d4 + (port<<10))     
-#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_6(port)              (0x26d8 + (port<<10))     
-#define MV643XX_ETH_TX_CURRENT_QUEUE_DESC_PTR_7(port)              (0x26dc + (port<<10))     
-#define MV643XX_ETH_TX_QUEUE_0_TOKEN_BUCKET_COUNT(port)            (0x2700 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_1_TOKEN_BUCKET_COUNT(port)            (0x2710 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_2_TOKEN_BUCKET_COUNT(port)            (0x2720 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_3_TOKEN_BUCKET_COUNT(port)            (0x2730 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_4_TOKEN_BUCKET_COUNT(port)            (0x2740 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_5_TOKEN_BUCKET_COUNT(port)            (0x2750 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_6_TOKEN_BUCKET_COUNT(port)            (0x2760 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_7_TOKEN_BUCKET_COUNT(port)            (0x2770 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_0_TOKEN_BUCKET_CONFIG(port)           (0x2704 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_1_TOKEN_BUCKET_CONFIG(port)           (0x2714 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_2_TOKEN_BUCKET_CONFIG(port)           (0x2724 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_3_TOKEN_BUCKET_CONFIG(port)           (0x2734 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_4_TOKEN_BUCKET_CONFIG(port)           (0x2744 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_5_TOKEN_BUCKET_CONFIG(port)           (0x2754 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_6_TOKEN_BUCKET_CONFIG(port)           (0x2764 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_7_TOKEN_BUCKET_CONFIG(port)           (0x2774 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_0_ARBITER_CONFIG(port)                (0x2708 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_1_ARBITER_CONFIG(port)                (0x2718 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_2_ARBITER_CONFIG(port)                (0x2728 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_3_ARBITER_CONFIG(port)                (0x2738 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_4_ARBITER_CONFIG(port)                (0x2748 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_5_ARBITER_CONFIG(port)                (0x2758 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_6_ARBITER_CONFIG(port)                (0x2768 + (port<<10))
-#define MV643XX_ETH_TX_QUEUE_7_ARBITER_CONFIG(port)                (0x2778 + (port<<10))
-#define MV643XX_ETH_PORT_TX_TOKEN_BUCKET_COUNT(port)               (0x2780 + (port<<10))
-#define MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(port)   (0x3400 + (port<<10))
-#define MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(port)     (0x3500 + (port<<10))
-#define MV643XX_ETH_DA_FILTER_UNICAST_TABLE_BASE(port)             (0x3600 + (port<<10))
-
 /*******************************************/
 /*          CUNIT  Registers               */
 /*******************************************/
@@ -1089,219 +976,6 @@ struct mv64xxx_i2c_pdata {
 	u32	retries;
 };
 
-/* These macros describe Ethernet Port configuration reg (Px_cR) bits */
-#define MV643XX_ETH_UNICAST_NORMAL_MODE		0
-#define MV643XX_ETH_UNICAST_PROMISCUOUS_MODE	(1<<0)
-#define MV643XX_ETH_DEFAULT_RX_QUEUE_0		0
-#define MV643XX_ETH_DEFAULT_RX_QUEUE_1		(1<<1)
-#define MV643XX_ETH_DEFAULT_RX_QUEUE_2		(1<<2)
-#define MV643XX_ETH_DEFAULT_RX_QUEUE_3		((1<<2) | (1<<1))
-#define MV643XX_ETH_DEFAULT_RX_QUEUE_4		(1<<3)
-#define MV643XX_ETH_DEFAULT_RX_QUEUE_5		((1<<3) | (1<<1))
-#define MV643XX_ETH_DEFAULT_RX_QUEUE_6		((1<<3) | (1<<2))
-#define MV643XX_ETH_DEFAULT_RX_QUEUE_7		((1<<3) | (1<<2) | (1<<1))
-#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_0	0
-#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_1	(1<<4)
-#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_2	(1<<5)
-#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_3	((1<<5) | (1<<4))
-#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_4	(1<<6)
-#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_5	((1<<6) | (1<<4))
-#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_6	((1<<6) | (1<<5))
-#define MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_7	((1<<6) | (1<<5) | (1<<4))
-#define MV643XX_ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP	0
-#define MV643XX_ETH_REJECT_BC_IF_NOT_IP_OR_ARP	(1<<7)
-#define MV643XX_ETH_RECEIVE_BC_IF_IP		0
-#define MV643XX_ETH_REJECT_BC_IF_IP		(1<<8)
-#define MV643XX_ETH_RECEIVE_BC_IF_ARP		0
-#define MV643XX_ETH_REJECT_BC_IF_ARP		(1<<9)
-#define MV643XX_ETH_TX_AM_NO_UPDATE_ERROR_SUMMARY (1<<12)
-#define MV643XX_ETH_CAPTURE_TCP_FRAMES_DIS	0
-#define MV643XX_ETH_CAPTURE_TCP_FRAMES_EN	(1<<14)
-#define MV643XX_ETH_CAPTURE_UDP_FRAMES_DIS	0
-#define MV643XX_ETH_CAPTURE_UDP_FRAMES_EN	(1<<15)
-#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_0	0
-#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_1	(1<<16)
-#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_2	(1<<17)
-#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_3	((1<<17) | (1<<16))
-#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_4	(1<<18)
-#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_5	((1<<18) | (1<<16))
-#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_6	((1<<18) | (1<<17))
-#define MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_7	((1<<18) | (1<<17) | (1<<16))
-#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_0	0
-#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_1	(1<<19)
-#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_2	(1<<20)
-#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_3	((1<<20) | (1<<19))
-#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_4	(1<<21)
-#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_5	((1<<21) | (1<<19))
-#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_6	((1<<21) | (1<<20))
-#define MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_7	((1<<21) | (1<<20) | (1<<19))
-#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_0	0
-#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_1	(1<<22)
-#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_2	(1<<23)
-#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_3	((1<<23) | (1<<22))
-#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_4	(1<<24)
-#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_5	((1<<24) | (1<<22))
-#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_6	((1<<24) | (1<<23))
-#define MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_7	((1<<24) | (1<<23) | (1<<22))
-
-#define	MV643XX_ETH_PORT_CONFIG_DEFAULT_VALUE			\
-		MV643XX_ETH_UNICAST_NORMAL_MODE		|	\
-		MV643XX_ETH_DEFAULT_RX_QUEUE_0		|	\
-		MV643XX_ETH_DEFAULT_RX_ARP_QUEUE_0	|	\
-		MV643XX_ETH_RECEIVE_BC_IF_NOT_IP_OR_ARP	|	\
-		MV643XX_ETH_RECEIVE_BC_IF_IP		|	\
-		MV643XX_ETH_RECEIVE_BC_IF_ARP		|	\
-		MV643XX_ETH_CAPTURE_TCP_FRAMES_DIS	|	\
-		MV643XX_ETH_CAPTURE_UDP_FRAMES_DIS	|	\
-		MV643XX_ETH_DEFAULT_RX_TCP_QUEUE_0	|	\
-		MV643XX_ETH_DEFAULT_RX_UDP_QUEUE_0	|	\
-		MV643XX_ETH_DEFAULT_RX_BPDU_QUEUE_0
-
-/* These macros describe Ethernet Port configuration extend reg (Px_cXR) bits*/
-#define MV643XX_ETH_CLASSIFY_EN				(1<<0)
-#define MV643XX_ETH_SPAN_BPDU_PACKETS_AS_NORMAL		0
-#define MV643XX_ETH_SPAN_BPDU_PACKETS_TO_RX_QUEUE_7	(1<<1)
-#define MV643XX_ETH_PARTITION_DISABLE			0
-#define MV643XX_ETH_PARTITION_ENABLE			(1<<2)
-
-#define	MV643XX_ETH_PORT_CONFIG_EXTEND_DEFAULT_VALUE		\
-		MV643XX_ETH_SPAN_BPDU_PACKETS_AS_NORMAL	|	\
-		MV643XX_ETH_PARTITION_DISABLE
-
-/* These macros describe Ethernet Port Sdma configuration reg (SDCR) bits */
-#define MV643XX_ETH_RIFB			(1<<0)
-#define MV643XX_ETH_RX_BURST_SIZE_1_64BIT		0
-#define MV643XX_ETH_RX_BURST_SIZE_2_64BIT		(1<<1)
-#define MV643XX_ETH_RX_BURST_SIZE_4_64BIT		(1<<2)
-#define MV643XX_ETH_RX_BURST_SIZE_8_64BIT		((1<<2) | (1<<1))
-#define MV643XX_ETH_RX_BURST_SIZE_16_64BIT		(1<<3)
-#define MV643XX_ETH_BLM_RX_NO_SWAP			(1<<4)
-#define MV643XX_ETH_BLM_RX_BYTE_SWAP			0
-#define MV643XX_ETH_BLM_TX_NO_SWAP			(1<<5)
-#define MV643XX_ETH_BLM_TX_BYTE_SWAP			0
-#define MV643XX_ETH_DESCRIPTORS_BYTE_SWAP		(1<<6)
-#define MV643XX_ETH_DESCRIPTORS_NO_SWAP			0
-#define MV643XX_ETH_TX_BURST_SIZE_1_64BIT		0
-#define MV643XX_ETH_TX_BURST_SIZE_2_64BIT		(1<<22)
-#define MV643XX_ETH_TX_BURST_SIZE_4_64BIT		(1<<23)
-#define MV643XX_ETH_TX_BURST_SIZE_8_64BIT		((1<<23) | (1<<22))
-#define MV643XX_ETH_TX_BURST_SIZE_16_64BIT		(1<<24)
-
-#define	MV643XX_ETH_IPG_INT_RX(value) ((value & 0x3fff) << 8)
-
-#define	MV643XX_ETH_PORT_SDMA_CONFIG_DEFAULT_VALUE		\
-		MV643XX_ETH_RX_BURST_SIZE_4_64BIT	|	\
-		MV643XX_ETH_IPG_INT_RX(0)		|	\
-		MV643XX_ETH_TX_BURST_SIZE_4_64BIT
-
-/* These macros describe Ethernet Port serial control reg (PSCR) bits */
-#define MV643XX_ETH_SERIAL_PORT_DISABLE			0
-#define MV643XX_ETH_SERIAL_PORT_ENABLE			(1<<0)
-#define MV643XX_ETH_FORCE_LINK_PASS			(1<<1)
-#define MV643XX_ETH_DO_NOT_FORCE_LINK_PASS		0
-#define MV643XX_ETH_ENABLE_AUTO_NEG_FOR_DUPLX		0
-#define MV643XX_ETH_DISABLE_AUTO_NEG_FOR_DUPLX		(1<<2)
-#define MV643XX_ETH_ENABLE_AUTO_NEG_FOR_FLOW_CTRL	0
-#define MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL	(1<<3)
-#define MV643XX_ETH_ADV_NO_FLOW_CTRL			0
-#define MV643XX_ETH_ADV_SYMMETRIC_FLOW_CTRL		(1<<4)
-#define MV643XX_ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX	0
-#define MV643XX_ETH_FORCE_FC_MODE_TX_PAUSE_DIS		(1<<5)
-#define MV643XX_ETH_FORCE_BP_MODE_NO_JAM		0
-#define MV643XX_ETH_FORCE_BP_MODE_JAM_TX		(1<<7)
-#define MV643XX_ETH_FORCE_BP_MODE_JAM_TX_ON_RX_ERR	(1<<8)
-#define MV643XX_ETH_SERIAL_PORT_CONTROL_RESERVED	(1<<9)
-#define MV643XX_ETH_FORCE_LINK_FAIL			0
-#define MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL		(1<<10)
-#define MV643XX_ETH_RETRANSMIT_16_ATTEMPTS		0
-#define MV643XX_ETH_RETRANSMIT_FOREVER			(1<<11)
-#define MV643XX_ETH_DISABLE_AUTO_NEG_SPEED_GMII		(1<<13)
-#define MV643XX_ETH_ENABLE_AUTO_NEG_SPEED_GMII		0
-#define MV643XX_ETH_DTE_ADV_0				0
-#define MV643XX_ETH_DTE_ADV_1				(1<<14)
-#define MV643XX_ETH_DISABLE_AUTO_NEG_BYPASS		0
-#define MV643XX_ETH_ENABLE_AUTO_NEG_BYPASS		(1<<15)
-#define MV643XX_ETH_AUTO_NEG_NO_CHANGE			0
-#define MV643XX_ETH_RESTART_AUTO_NEG			(1<<16)
-#define MV643XX_ETH_MAX_RX_PACKET_1518BYTE		0
-#define MV643XX_ETH_MAX_RX_PACKET_1522BYTE		(1<<17)
-#define MV643XX_ETH_MAX_RX_PACKET_1552BYTE		(1<<18)
-#define MV643XX_ETH_MAX_RX_PACKET_9022BYTE		((1<<18) | (1<<17))
-#define MV643XX_ETH_MAX_RX_PACKET_9192BYTE		(1<<19)
-#define MV643XX_ETH_MAX_RX_PACKET_9700BYTE		((1<<19) | (1<<17))
-#define MV643XX_ETH_SET_EXT_LOOPBACK			(1<<20)
-#define MV643XX_ETH_CLR_EXT_LOOPBACK			0
-#define MV643XX_ETH_SET_FULL_DUPLEX_MODE		(1<<21)
-#define MV643XX_ETH_SET_HALF_DUPLEX_MODE		0
-#define MV643XX_ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX (1<<22)
-#define MV643XX_ETH_DISABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX 0
-#define MV643XX_ETH_SET_GMII_SPEED_TO_10_100		0
-#define MV643XX_ETH_SET_GMII_SPEED_TO_1000		(1<<23)
-#define MV643XX_ETH_SET_MII_SPEED_TO_10			0
-#define MV643XX_ETH_SET_MII_SPEED_TO_100		(1<<24)
-
-#define MV643XX_ETH_MAX_RX_PACKET_MASK			(0x7<<17)
-
-#define	MV643XX_ETH_PORT_SERIAL_CONTROL_DEFAULT_VALUE		\
-		MV643XX_ETH_DO_NOT_FORCE_LINK_PASS	|	\
-		MV643XX_ETH_ENABLE_AUTO_NEG_FOR_DUPLX	|	\
-		MV643XX_ETH_DISABLE_AUTO_NEG_FOR_FLOW_CTRL |	\
-		MV643XX_ETH_ADV_SYMMETRIC_FLOW_CTRL	|	\
-		MV643XX_ETH_FORCE_FC_MODE_NO_PAUSE_DIS_TX |	\
-		MV643XX_ETH_FORCE_BP_MODE_NO_JAM	|	\
-		(1<<9)	/* reserved */			|	\
-		MV643XX_ETH_DO_NOT_FORCE_LINK_FAIL	|	\
-		MV643XX_ETH_RETRANSMIT_16_ATTEMPTS	|	\
-		MV643XX_ETH_ENABLE_AUTO_NEG_SPEED_GMII	|	\
-		MV643XX_ETH_DTE_ADV_0			|	\
-		MV643XX_ETH_DISABLE_AUTO_NEG_BYPASS	|	\
-		MV643XX_ETH_AUTO_NEG_NO_CHANGE		|	\
-		MV643XX_ETH_MAX_RX_PACKET_9700BYTE	|	\
-		MV643XX_ETH_CLR_EXT_LOOPBACK		|	\
-		MV643XX_ETH_SET_FULL_DUPLEX_MODE	|	\
-		MV643XX_ETH_ENABLE_FLOW_CTRL_TX_RX_IN_FULL_DUPLEX
-
-/* These macros describe Ethernet Serial Status reg (PSR) bits */
-#define MV643XX_ETH_PORT_STATUS_MODE_10_BIT		(1<<0)
-#define MV643XX_ETH_PORT_STATUS_LINK_UP			(1<<1)
-#define MV643XX_ETH_PORT_STATUS_FULL_DUPLEX		(1<<2)
-#define MV643XX_ETH_PORT_STATUS_FLOW_CONTROL		(1<<3)
-#define MV643XX_ETH_PORT_STATUS_GMII_1000		(1<<4)
-#define MV643XX_ETH_PORT_STATUS_MII_100			(1<<5)
-/* PSR bit 6 is undocumented */
-#define MV643XX_ETH_PORT_STATUS_TX_IN_PROGRESS		(1<<7)
-#define MV643XX_ETH_PORT_STATUS_AUTONEG_BYPASSED	(1<<8)
-#define MV643XX_ETH_PORT_STATUS_PARTITION		(1<<9)
-#define MV643XX_ETH_PORT_STATUS_TX_FIFO_EMPTY		(1<<10)
-/* PSR bits 11-31 are reserved */
-
-#define	MV643XX_ETH_PORT_DEFAULT_TRANSMIT_QUEUE_SIZE	800
-#define	MV643XX_ETH_PORT_DEFAULT_RECEIVE_QUEUE_SIZE	400
-
-#define MV643XX_ETH_DESC_SIZE				64
-
-#define MV643XX_ETH_SHARED_NAME	"mv643xx_eth_shared"
-#define MV643XX_ETH_NAME	"mv643xx_eth"
-
-struct mv643xx_eth_platform_data {
-	int		port_number;
-	u16		force_phy_addr;	/* force override if phy_addr == 0 */
-	u16		phy_addr;
-
-	/* If speed is 0, then speed and duplex are autonegotiated. */
-	int		speed;		/* 0, SPEED_10, SPEED_100, SPEED_1000 */
-	int		duplex;		/* DUPLEX_HALF or DUPLEX_FULL */
-
-	/* non-zero values of the following fields override defaults */
-	u32		tx_queue_size;
-	u32		rx_queue_size;
-	u32		tx_sram_addr;
-	u32		tx_sram_size;
-	u32		rx_sram_addr;
-	u32		rx_sram_size;
-	u8		mac_addr[6];	/* mac address if non-zero*/
-};
-
 /* Watchdog Platform Device, Driver Data */
 #define	MV64x60_WDT_NAME			"mv64x60_wdt"
 
diff --git a/include/linux/mv643xx_eth.h b/include/linux/mv643xx_eth.h
new file mode 100644
index 0000000..3f27239
--- /dev/null
+++ b/include/linux/mv643xx_eth.h
@@ -0,0 +1,31 @@
+/*
+ * MV-643XX ethernet platform device data definition file.
+ */
+#ifndef __LINUX_MV643XX_ETH_H
+#define __LINUX_MV643XX_ETH_H
+
+#define MV643XX_ETH_SHARED_NAME		"mv643xx_eth_shared"
+#define MV643XX_ETH_NAME		"mv643xx_eth"
+#define MV643XX_ETH_SHARED_REGS		0x2000
+#define MV643XX_ETH_SHARED_REGS_SIZE	0x2000
+
+struct mv643xx_eth_platform_data {
+	int		port_number;
+	u16		force_phy_addr;	/* force override if phy_addr == 0 */
+	u16		phy_addr;
+
+	/* If speed is 0, then speed and duplex are autonegotiated. */
+	int		speed;		/* 0, SPEED_10, SPEED_100, SPEED_1000 */
+	int		duplex;		/* DUPLEX_HALF or DUPLEX_FULL */
+
+	/* non-zero values of the following fields override defaults */
+	u32		tx_queue_size;
+	u32		rx_queue_size;
+	u32		tx_sram_addr;
+	u32		tx_sram_size;
+	u32		rx_sram_addr;
+	u32		rx_sram_size;
+	u8		mac_addr[6];	/* mac address if non-zero*/
+};
+
+#endif /* __LINUX_MV643XX_ETH_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 4a3f54e..c4de536 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -834,7 +834,7 @@ static inline int dev_hard_header(struct sk_buff *skb, struct net_device *dev,
 				  const void *daddr, const void *saddr,
 				  unsigned len)
 {
-	if (!dev->header_ops)
+	if (!dev->header_ops || !dev->header_ops->create)
 		return 0;
 
 	return dev->header_ops->create(skb, dev, type, daddr, saddr, len);

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-10-15 20:19 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2007-10-15 20:19 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML


The MIPS stuff was ACK'd by Ralf.

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 Documentation/networking/bonding.txt           |   33 +
 arch/mips/au1000/common/prom.c                 |   61 +-
 arch/mips/au1000/common/setup.c                |    5 +-
 arch/mips/au1000/db1x00/init.c                 |   10 +-
 arch/mips/au1000/mtx-1/init.c                  |    6 +-
 arch/mips/au1000/pb1000/init.c                 |   10 +-
 arch/mips/au1000/pb1100/init.c                 |   10 +-
 arch/mips/au1000/pb1200/board_setup.c          |    6 +-
 arch/mips/au1000/pb1200/init.c                 |   10 +-
 arch/mips/au1000/pb1500/init.c                 |   10 +-
 arch/mips/au1000/pb1550/init.c                 |   10 +-
 arch/mips/au1000/xxs1500/init.c                |   10 +-
 arch/powerpc/platforms/cell/axon_msi.c         |   11 +-
 arch/powerpc/sysdev/dcr.c                      |    4 +-
 arch/powerpc/sysdev/mpic.c                     |    4 +-
 drivers/infiniband/ulp/ipoib/ipoib.h           |    4 +-
 drivers/infiniband/ulp/ipoib/ipoib_main.c      |   29 +-
 drivers/infiniband/ulp/ipoib/ipoib_multicast.c |    3 +-
 drivers/net/Kconfig                            |    9 +
 drivers/net/Makefile                           |    1 +
 drivers/net/au1000_eth.c                       |   28 +-
 drivers/net/bonding/bond_main.c                |  207 ++++-
 drivers/net/bonding/bond_sysfs.c               |   74 ++-
 drivers/net/bonding/bonding.h                  |   10 +-
 drivers/net/cassini.c                          |    2 +-
 drivers/net/cpmac.c                            | 1174 ++++++++++++++++++++++++
 drivers/net/gianfar.c                          |   14 +-
 drivers/net/ibm_emac/ibm_emac_mal.c            |    5 +-
 drivers/net/ibm_emac/ibm_emac_mal.h            |    5 +-
 drivers/net/ibm_newemac/mal.c                  |    9 +-
 drivers/net/ibm_newemac/mal.h                  |    5 +-
 drivers/net/irda/donauboe.c                    |    2 +-
 drivers/net/jazzsonic.c                        |    1 -
 drivers/net/mipsnet.c                          |   63 +-
 drivers/net/mipsnet.h                          |   83 +-
 drivers/net/myri10ge/myri10ge.c                |  100 ++-
 drivers/net/myri10ge/myri10ge_mcp.h            |   90 ++-
 drivers/net/natsemi.c                          |   20 +-
 drivers/net/ne-h8300.c                         |    4 +-
 drivers/net/saa9730.c                          |    9 +-
 drivers/net/tc35815.c                          |    1 -
 drivers/net/tehuti.c                           |    3 +-
 drivers/net/tg3.c                              |    2 +-
 drivers/net/tulip/de4x5.c                      |    4 +-
 drivers/net/ucc_geth.c                         |    5 +-
 drivers/net/wan/sdla.c                         |    8 +-
 drivers/net/xen-netfront.c                     |   35 +-
 include/asm-mips/mach-au1x00/prom.h            |   13 +
 include/asm-powerpc/dcr-mmio.h                 |    6 +-
 include/asm-powerpc/dcr-native.h               |    6 +-
 include/linux/skbuff.h                         |    5 +
 51 files changed, 1914 insertions(+), 325 deletions(-)
 create mode 100644 drivers/net/cpmac.c
 create mode 100644 include/asm-mips/mach-au1x00/prom.h

Alejandro Martinez Ruiz (1):
      netdev: convert non-obvious instances to use ARRAY_SIZE()

Brice Goglin (5):
      myri10ge: fix some indentation, white spaces, and comments
      myri10ge: update firmware headers
      Add skb_is_gso_v6
      myri10ge: add IPv6 TSO support
      myri10ge: update driver version to 1.3.2-1.287

Emil Medve (1):
      ucc_geth: Fix build break introduced by commit 09f75cd7bf13720738e6a196cc0107ce9a5bd5a0

Florin Malita (1):
      tehuti: possible leak in bdx_probe

Jay Vosburgh (1):
      net/bonding: Optionally allow ethernet slaves to keep own MAC

Jeremy Fitzhardinge (1):
      xen-netfront: rearrange netfront structure to separate tx and rx

Li Yang (3):
      gianfar: Fix compile regression caused by bea3348e
      gianfar: Cleanup compile warning caused by 0795af57
      gianfar: Fix regression caused by new napi interface

Mark Brown (2):
      natsemi: Use round_jiffies() for slow timers
      natsemi: Check return value for pci_enable_device()

Matteo Croce (1):
      AR7 ethernet

Michael Ellerman (5):
      Update ibm_newemac to use dcr_host_t.base
      Use dcr_host_t.base in ibm_emac_mal
      Add dcr_host_t.base in dcr_read()/dcr_write()
      Use dcr_host_t.base in dcr_unmap()
      Remove msic_dcr_read() in axon_msi.c

Moni Shoua (8):
      IB/ipoib: Bound the net device to the ipoib_neigh structue
      IB/ipoib: Verify address handle validity on send
      net/bonding: Enable bonding to enslave non ARPHRD_ETHER
      net/bonding: Enable bonding to enslave netdevices not supporting set_mac_address()
      net/bonding: Enable IP multicast for bonding IPoIB devices
      net/bonding: Handlle wrong assumptions that slave is always an Ethernet device
      net/bonding: Delay sending of gratuitous ARP to avoid failure
      net/bonding: Destroy bonding master when last slave is gone

Ralf Baechle (4):
      SAA9730: Fix build
      TC35815: Fix build
      Jazzsonic: Fix warning about unused variable.
      MIPSsim: General cleanup

Yoichi Yuasa (2):
      update AU1000 get_ethernet_addr()
      add new prom.h for AU1x00

diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index 1da5666..1134062 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -281,6 +281,39 @@ downdelay
 	will be rounded down to the nearest multiple.  The default
 	value is 0.
 
+fail_over_mac
+
+	Specifies whether active-backup mode should set all slaves to
+	the same MAC address (the traditional behavior), or, when
+	enabled, change the bond's MAC address when changing the
+	active interface (i.e., fail over the MAC address itself).
+
+	Fail over MAC is useful for devices that cannot ever alter
+	their MAC address, or for devices that refuse incoming
+	broadcasts with their own source MAC (which interferes with
+	the ARP monitor).
+
+	The down side of fail over MAC is that every device on the
+	network must be updated via gratuitous ARP, vs. just updating
+	a switch or set of switches (which often takes place for any
+	traffic, not just ARP traffic, if the switch snoops incoming
+	traffic to update its tables) for the traditional method.  If
+	the gratuitous ARP is lost, communication may be disrupted.
+
+	When fail over MAC is used in conjuction with the mii monitor,
+	devices which assert link up prior to being able to actually
+	transmit and receive are particularly susecptible to loss of
+	the gratuitous ARP, and an appropriate updelay setting may be
+	required.
+
+	A value of 0 disables fail over MAC, and is the default.  A
+	value of 1 enables fail over MAC.  This option is enabled
+	automatically if the first slave added cannot change its MAC
+	address.  This option may be modified via sysfs only when no
+	slaves are present in the bond.
+
+	This option was added in bonding version 3.2.0.
+
 lacp_rate
 
 	Option specifying the rate in which we'll ask our link partner
diff --git a/arch/mips/au1000/common/prom.c b/arch/mips/au1000/common/prom.c
index a8637cd..90d7069 100644
--- a/arch/mips/au1000/common/prom.c
+++ b/arch/mips/au1000/common/prom.c
@@ -33,7 +33,6 @@
  *  with this program; if not, write  to the Free Software Foundation, Inc.,
  *  675 Mass Ave, Cambridge, MA 02139, USA.
  */
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -41,18 +40,16 @@
 
 #include <asm/bootinfo.h>
 
-/* #define DEBUG_CMDLINE */
-
-extern int prom_argc;
-extern char **prom_argv, **prom_envp;
-
+int prom_argc;
+char **prom_argv;
+char **prom_envp;
 
 char * __init_or_module prom_getcmdline(void)
 {
 	return &(arcs_cmdline[0]);
 }
 
-void  prom_init_cmdline(void)
+void prom_init_cmdline(void)
 {
 	char *cp;
 	int actr;
@@ -61,7 +58,7 @@ void  prom_init_cmdline(void)
 
 	cp = &(arcs_cmdline[0]);
 	while(actr < prom_argc) {
-	        strcpy(cp, prom_argv[actr]);
+		strcpy(cp, prom_argv[actr]);
 		cp += strlen(prom_argv[actr]);
 		*cp++ = ' ';
 		actr++;
@@ -70,10 +67,8 @@ void  prom_init_cmdline(void)
 		--cp;
 	if (prom_argc > 1)
 		*cp = '\0';
-
 }
 
-
 char *prom_getenv(char *envname)
 {
 	/*
@@ -95,21 +90,23 @@ char *prom_getenv(char *envname)
 		}
 		env++;
 	}
+
 	return NULL;
 }
 
-inline unsigned char str2hexnum(unsigned char c)
+static inline unsigned char str2hexnum(unsigned char c)
 {
-	if(c >= '0' && c <= '9')
+	if (c >= '0' && c <= '9')
 		return c - '0';
-	if(c >= 'a' && c <= 'f')
+	if (c >= 'a' && c <= 'f')
 		return c - 'a' + 10;
-	if(c >= 'A' && c <= 'F')
+	if (c >= 'A' && c <= 'F')
 		return c - 'A' + 10;
+
 	return 0; /* foo */
 }
 
-inline void str2eaddr(unsigned char *ea, unsigned char *str)
+static inline void str2eaddr(unsigned char *ea, unsigned char *str)
 {
 	int i;
 
@@ -124,35 +121,29 @@ inline void str2eaddr(unsigned char *ea, unsigned char *str)
 	}
 }
 
-int get_ethernet_addr(char *ethernet_addr)
+int prom_get_ethernet_addr(char *ethernet_addr)
 {
-        char *ethaddr_str;
+	char *ethaddr_str;
+	char *argptr;
 
-        ethaddr_str = prom_getenv("ethaddr");
+	/* Check the environment variables first */
+	ethaddr_str = prom_getenv("ethaddr");
 	if (!ethaddr_str) {
-	        printk("ethaddr not set in boot prom\n");
-		return -1;
-	}
-	str2eaddr(ethernet_addr, ethaddr_str);
-
-#if 0
-	{
-		int i;
+		/* Check command line */
+		argptr = prom_getcmdline();
+		ethaddr_str = strstr(argptr, "ethaddr=");
+		if (!ethaddr_str)
+			return -1;
 
-	printk("get_ethernet_addr: ");
-	for (i=0; i<5; i++)
-		printk("%02x:", (unsigned char)*(ethernet_addr+i));
-	printk("%02x\n", *(ethernet_addr+i));
+		ethaddr_str += strlen("ethaddr=");
 	}
-#endif
+
+	str2eaddr(ethernet_addr, ethaddr_str);
 
 	return 0;
 }
+EXPORT_SYMBOL(prom_get_ethernet_addr);
 
 void __init prom_free_prom_memory(void)
 {
 }
-
-EXPORT_SYMBOL(prom_getcmdline);
-EXPORT_SYMBOL(get_ethernet_addr);
-EXPORT_SYMBOL(str2eaddr);
diff --git a/arch/mips/au1000/common/setup.c b/arch/mips/au1000/common/setup.c
index b212c07..a90d425 100644
--- a/arch/mips/au1000/common/setup.c
+++ b/arch/mips/au1000/common/setup.c
@@ -40,10 +40,11 @@
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
 #include <asm/pgtable.h>
-#include <asm/mach-au1x00/au1000.h>
 #include <asm/time.h>
 
-extern char * prom_getcmdline(void);
+#include <au1000.h>
+#include <prom.h>
+
 extern void __init board_setup(void);
 extern void au1000_restart(char *);
 extern void au1000_halt(void);
diff --git a/arch/mips/au1000/db1x00/init.c b/arch/mips/au1000/db1x00/init.c
index 4d7bcfc..43298fd 100644
--- a/arch/mips/au1000/db1x00/init.c
+++ b/arch/mips/au1000/db1x00/init.c
@@ -31,15 +31,13 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void  __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
 
 const char *get_system_type(void)
 {
diff --git a/arch/mips/au1000/mtx-1/init.c b/arch/mips/au1000/mtx-1/init.c
index 2aa7b2e..cdeae32 100644
--- a/arch/mips/au1000/mtx-1/init.c
+++ b/arch/mips/au1000/mtx-1/init.c
@@ -34,13 +34,11 @@
 #include <linux/init.h>
 #include <linux/mm.h>
 #include <linux/bootmem.h>
+
 #include <asm/addrspace.h>
 #include <asm/bootinfo.h>
 
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void  __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <prom.h>
 
 const char *get_system_type(void)
 {
diff --git a/arch/mips/au1000/pb1000/init.c b/arch/mips/au1000/pb1000/init.c
index 4535f72..ddccaf6 100644
--- a/arch/mips/au1000/pb1000/init.c
+++ b/arch/mips/au1000/pb1000/init.c
@@ -30,15 +30,13 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void  __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
 
 const char *get_system_type(void)
 {
diff --git a/arch/mips/au1000/pb1100/init.c b/arch/mips/au1000/pb1100/init.c
index 7ba6852..c93fd39 100644
--- a/arch/mips/au1000/pb1100/init.c
+++ b/arch/mips/au1000/pb1100/init.c
@@ -31,15 +31,13 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void  __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
 
 const char *get_system_type(void)
 {
diff --git a/arch/mips/au1000/pb1200/board_setup.c b/arch/mips/au1000/pb1200/board_setup.c
index 2122515..5dbc986 100644
--- a/arch/mips/au1000/pb1200/board_setup.c
+++ b/arch/mips/au1000/pb1200/board_setup.c
@@ -41,8 +41,10 @@
 #include <asm/mipsregs.h>
 #include <asm/reboot.h>
 #include <asm/pgtable.h>
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/mach-au1x00/au1xxx_dbdma.h>
+
+#include <au1000.h>
+#include <au1xxx_dbdma.h>
+#include <prom.h>
 
 #ifdef CONFIG_MIPS_PB1200
 #include <asm/mach-pb1x00/pb1200.h>
diff --git a/arch/mips/au1000/pb1200/init.c b/arch/mips/au1000/pb1200/init.c
index 5a70029..c251570 100644
--- a/arch/mips/au1000/pb1200/init.c
+++ b/arch/mips/au1000/pb1200/init.c
@@ -31,15 +31,13 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void  __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
 
 const char *get_system_type(void)
 {
diff --git a/arch/mips/au1000/pb1500/init.c b/arch/mips/au1000/pb1500/init.c
index e58a9d6..507d4b2 100644
--- a/arch/mips/au1000/pb1500/init.c
+++ b/arch/mips/au1000/pb1500/init.c
@@ -31,15 +31,13 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void  __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
 
 const char *get_system_type(void)
 {
diff --git a/arch/mips/au1000/pb1550/init.c b/arch/mips/au1000/pb1550/init.c
index fad53bf..b03eee6 100644
--- a/arch/mips/au1000/pb1550/init.c
+++ b/arch/mips/au1000/pb1550/init.c
@@ -31,15 +31,13 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void  __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
 
 const char *get_system_type(void)
 {
diff --git a/arch/mips/au1000/xxs1500/init.c b/arch/mips/au1000/xxs1500/init.c
index 9f839c3..6532939 100644
--- a/arch/mips/au1000/xxs1500/init.c
+++ b/arch/mips/au1000/xxs1500/init.c
@@ -30,15 +30,13 @@
 #include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/bootmem.h>
-#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
 #include <linux/string.h>
 #include <linux/kernel.h>
 
-int prom_argc;
-char **prom_argv, **prom_envp;
-extern void  __init prom_init_cmdline(void);
-extern char *prom_getenv(char *envname);
+#include <asm/addrspace.h>
+#include <asm/bootinfo.h>
+
+#include <prom.h>
 
 const char *get_system_type(void)
 {
diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index 1245b2f..095988f 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -77,12 +77,7 @@ static void msic_dcr_write(struct axon_msic *msic, unsigned int dcr_n, u32 val)
 {
 	pr_debug("axon_msi: dcr_write(0x%x, 0x%x)\n", val, dcr_n);
 
-	dcr_write(msic->dcr_host, msic->dcr_host.base + dcr_n, val);
-}
-
-static u32 msic_dcr_read(struct axon_msic *msic, unsigned int dcr_n)
-{
-	return dcr_read(msic->dcr_host, msic->dcr_host.base + dcr_n);
+	dcr_write(msic->dcr_host, dcr_n, val);
 }
 
 static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
@@ -91,7 +86,7 @@ static void axon_msi_cascade(unsigned int irq, struct irq_desc *desc)
 	u32 write_offset, msi;
 	int idx;
 
-	write_offset = msic_dcr_read(msic, MSIC_WRITE_OFFSET_REG);
+	write_offset = dcr_read(msic->dcr_host, MSIC_WRITE_OFFSET_REG);
 	pr_debug("axon_msi: original write_offset 0x%x\n", write_offset);
 
 	/* write_offset doesn't wrap properly, so we have to mask it */
@@ -306,7 +301,7 @@ static int axon_msi_notify_reboot(struct notifier_block *nb,
 	list_for_each_entry(msic, &axon_msic_list, list) {
 		pr_debug("axon_msi: disabling %s\n",
 			  msic->irq_host->of_node->full_name);
-		tmp  = msic_dcr_read(msic, MSIC_CTRL_REG);
+		tmp  = dcr_read(msic->dcr_host, MSIC_CTRL_REG);
 		tmp &= ~MSIC_CTRL_ENABLE & ~MSIC_CTRL_IRQ_ENABLE;
 		msic_dcr_write(msic, MSIC_CTRL_REG, tmp);
 	}
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c
index ab11c0b..427027c 100644
--- a/arch/powerpc/sysdev/dcr.c
+++ b/arch/powerpc/sysdev/dcr.c
@@ -126,13 +126,13 @@ dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
 }
 EXPORT_SYMBOL_GPL(dcr_map);
 
-void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c)
+void dcr_unmap(dcr_host_t host, unsigned int dcr_c)
 {
 	dcr_host_t h = host;
 
 	if (h.token == NULL)
 		return;
-	h.token += dcr_n * h.stride;
+	h.token += host.base * h.stride;
 	iounmap(h.token);
 	h.token = NULL;
 }
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 893e654..e479388 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -156,7 +156,7 @@ static inline u32 _mpic_read(enum mpic_reg_type type,
 	switch(type) {
 #ifdef CONFIG_PPC_DCR
 	case mpic_access_dcr:
-		return dcr_read(rb->dhost, rb->dhost.base + reg);
+		return dcr_read(rb->dhost, reg);
 #endif
 	case mpic_access_mmio_be:
 		return in_be32(rb->base + (reg >> 2));
@@ -173,7 +173,7 @@ static inline void _mpic_write(enum mpic_reg_type type,
 	switch(type) {
 #ifdef CONFIG_PPC_DCR
 	case mpic_access_dcr:
-		return dcr_write(rb->dhost, rb->dhost.base + reg, value);
+		return dcr_write(rb->dhost, reg, value);
 #endif
 	case mpic_access_mmio_be:
 		return out_be32(rb->base + (reg >> 2), value);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
index 6545fa7..1b3327a 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib.h
+++ b/drivers/infiniband/ulp/ipoib/ipoib.h
@@ -349,6 +349,7 @@ struct ipoib_neigh {
 	struct sk_buff_head queue;
 
 	struct neighbour   *neighbour;
+	struct net_device *dev;
 
 	struct list_head    list;
 };
@@ -365,7 +366,8 @@ static inline struct ipoib_neigh **to_ipoib_neigh(struct neighbour *neigh)
 				     INFINIBAND_ALEN, sizeof(void *));
 }
 
-struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh);
+struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neigh,
+				      struct net_device *dev);
 void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh);
 
 extern struct workqueue_struct *ipoib_workqueue;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index e072f3c..362610d 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -517,7 +517,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
 	struct ipoib_path *path;
 	struct ipoib_neigh *neigh;
 
-	neigh = ipoib_neigh_alloc(skb->dst->neighbour);
+	neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
 	if (!neigh) {
 		++dev->stats.tx_dropped;
 		dev_kfree_skb_any(skb);
@@ -692,9 +692,10 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
 				goto out;
 			}
 		} else if (neigh->ah) {
-			if (unlikely(memcmp(&neigh->dgid.raw,
+			if (unlikely((memcmp(&neigh->dgid.raw,
 					    skb->dst->neighbour->ha + 4,
-					    sizeof(union ib_gid)))) {
+					    sizeof(union ib_gid))) ||
+					 (neigh->dev != dev))) {
 				spin_lock(&priv->lock);
 				/*
 				 * It's safe to call ipoib_put_ah() inside
@@ -817,6 +818,13 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
 	unsigned long flags;
 	struct ipoib_ah *ah = NULL;
 
+	neigh = *to_ipoib_neigh(n);
+	if (neigh) {
+		priv = netdev_priv(neigh->dev);
+		ipoib_dbg(priv, "neigh_destructor for bonding device: %s\n",
+			  n->dev->name);
+	} else
+		return;
 	ipoib_dbg(priv,
 		  "neigh_cleanup for %06x " IPOIB_GID_FMT "\n",
 		  IPOIB_QPN(n->ha),
@@ -824,13 +832,10 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
 
 	spin_lock_irqsave(&priv->lock, flags);
 
-	neigh = *to_ipoib_neigh(n);
-	if (neigh) {
-		if (neigh->ah)
-			ah = neigh->ah;
-		list_del(&neigh->list);
-		ipoib_neigh_free(n->dev, neigh);
-	}
+	if (neigh->ah)
+		ah = neigh->ah;
+	list_del(&neigh->list);
+	ipoib_neigh_free(n->dev, neigh);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -838,7 +843,8 @@ static void ipoib_neigh_cleanup(struct neighbour *n)
 		ipoib_put_ah(ah);
 }
 
-struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
+struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour,
+				      struct net_device *dev)
 {
 	struct ipoib_neigh *neigh;
 
@@ -847,6 +853,7 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
 		return NULL;
 
 	neigh->neighbour = neighbour;
+	neigh->dev = dev;
 	*to_ipoib_neigh(neighbour) = neigh;
 	skb_queue_head_init(&neigh->queue);
 	ipoib_cm_set(neigh, NULL);
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 827820e..9bcfc7a 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -705,7 +705,8 @@ out:
 		if (skb->dst            &&
 		    skb->dst->neighbour &&
 		    !*to_ipoib_neigh(skb->dst->neighbour)) {
-			struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour);
+			struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour,
+									skb->dev);
 
 			if (neigh) {
 				kref_get(&mcast->ah->ref);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9c635a2..8f99a06 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1780,6 +1780,15 @@ config SC92031
 	  To compile this driver as a module, choose M here: the module
 	  will be called sc92031.  This is recommended.
 
+config CPMAC
+	tristate "TI AR7 CPMAC Ethernet support (EXPERIMENTAL)"
+	depends on NET_ETHERNET && EXPERIMENTAL && AR7
+	select PHYLIB
+	select FIXED_PHY
+	select FIXED_MII_100_FDX
+	help
+	  TI AR7 CPMAC Ethernet support
+
 config NET_POCKET
 	bool "Pocket and portable adapters"
 	depends on PARPORT
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index d2e0f35..22f78cb 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -159,6 +159,7 @@ obj-$(CONFIG_8139CP) += 8139cp.o
 obj-$(CONFIG_8139TOO) += 8139too.o
 obj-$(CONFIG_ZNET) += znet.o
 obj-$(CONFIG_LAN_SAA9730) += saa9730.o
+obj-$(CONFIG_CPMAC) += cpmac.o
 obj-$(CONFIG_DEPCA) += depca.o
 obj-$(CONFIG_EWRK3) += ewrk3.o
 obj-$(CONFIG_ATP) += atp.o
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index b46c5d8..185f98e 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -54,13 +54,16 @@
 #include <linux/delay.h>
 #include <linux/crc32.h>
 #include <linux/phy.h>
+
+#include <asm/cpu.h>
 #include <asm/mipsregs.h>
 #include <asm/irq.h>
 #include <asm/io.h>
 #include <asm/processor.h>
 
-#include <asm/mach-au1x00/au1000.h>
-#include <asm/cpu.h>
+#include <au1000.h>
+#include <prom.h>
+
 #include "au1000_eth.h"
 
 #ifdef AU1000_ETH_DEBUG
@@ -96,11 +99,6 @@ static void mdio_write(struct net_device *, int, int, u16);
 static void au1000_adjust_link(struct net_device *);
 static void enable_mac(struct net_device *, int);
 
-// externs
-extern int get_ethernet_addr(char *ethernet_addr);
-extern void str2eaddr(unsigned char *ea, unsigned char *str);
-extern char * prom_getcmdline(void);
-
 /*
  * Theory of operation
  *
@@ -619,7 +617,6 @@ static struct net_device * au1000_probe(int port_num)
 	struct au1000_private *aup = NULL;
 	struct net_device *dev = NULL;
 	db_dest_t *pDB, *pDBfree;
-	char *pmac, *argptr;
 	char ethaddr[6];
 	int irq, i, err;
 	u32 base, macen;
@@ -677,21 +674,12 @@ static struct net_device * au1000_probe(int port_num)
 	au_macs[port_num] = aup;
 
 	if (port_num == 0) {
-		/* Check the environment variables first */
-		if (get_ethernet_addr(ethaddr) == 0)
+		if (prom_get_ethernet_addr(ethaddr) == 0)
 			memcpy(au1000_mac_addr, ethaddr, sizeof(au1000_mac_addr));
 		else {
-			/* Check command line */
-			argptr = prom_getcmdline();
-			if ((pmac = strstr(argptr, "ethaddr=")) == NULL)
-				printk(KERN_INFO "%s: No MAC address found\n",
-						 dev->name);
+			printk(KERN_INFO "%s: No MAC address found\n",
+					 dev->name);
 				/* Use the hard coded MAC addresses */
-			else {
-				str2eaddr(ethaddr, pmac + strlen("ethaddr="));
-				memcpy(au1000_mac_addr, ethaddr,
-				       sizeof(au1000_mac_addr));
-			}
 		}
 
 		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 64bfec3..db80f24 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -98,6 +98,7 @@ static char *xmit_hash_policy = NULL;
 static int arp_interval = BOND_LINK_ARP_INTERV;
 static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
 static char *arp_validate = NULL;
+static int fail_over_mac = 0;
 struct bond_params bonding_defaults;
 
 module_param(max_bonds, int, 0);
@@ -131,6 +132,8 @@ module_param_array(arp_ip_target, charp, NULL, 0);
 MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
 module_param(arp_validate, charp, 0);
 MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
+module_param(fail_over_mac, int, 0);
+MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC.  0 of off (default), 1 for on.");
 
 /*----------------------------- Global variables ----------------------------*/
 
@@ -1096,7 +1099,21 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active)
 		if (new_active) {
 			bond_set_slave_active_flags(new_active);
 		}
-		bond_send_gratuitous_arp(bond);
+
+		/* when bonding does not set the slave MAC address, the bond MAC
+		 * address is the one of the active slave.
+		 */
+		if (new_active && bond->params.fail_over_mac)
+			memcpy(bond->dev->dev_addr,  new_active->dev->dev_addr,
+				new_active->dev->addr_len);
+		if (bond->curr_active_slave &&
+			test_bit(__LINK_STATE_LINKWATCH_PENDING,
+					&bond->curr_active_slave->dev->state)) {
+			dprintk("delaying gratuitous arp on %s\n",
+				bond->curr_active_slave->dev->name);
+			bond->send_grat_arp = 1;
+		} else
+			bond_send_gratuitous_arp(bond);
 	}
 }
 
@@ -1217,7 +1234,8 @@ static int bond_compute_features(struct bonding *bond)
 	struct slave *slave;
 	struct net_device *bond_dev = bond->dev;
 	unsigned long features = bond_dev->features;
-	unsigned short max_hard_header_len = ETH_HLEN;
+	unsigned short max_hard_header_len = max((u16)ETH_HLEN,
+						bond_dev->hard_header_len);
 	int i;
 
 	features &= ~(NETIF_F_ALL_CSUM | BOND_VLAN_FEATURES);
@@ -1238,6 +1256,23 @@ static int bond_compute_features(struct bonding *bond)
 	return 0;
 }
 
+
+static void bond_setup_by_slave(struct net_device *bond_dev,
+				struct net_device *slave_dev)
+{
+	struct bonding *bond = bond_dev->priv;
+
+	bond_dev->neigh_setup           = slave_dev->neigh_setup;
+
+	bond_dev->type		    = slave_dev->type;
+	bond_dev->hard_header_len   = slave_dev->hard_header_len;
+	bond_dev->addr_len	    = slave_dev->addr_len;
+
+	memcpy(bond_dev->broadcast, slave_dev->broadcast,
+		slave_dev->addr_len);
+	bond->setup_by_slave = 1;
+}
+
 /* enslave device <slave> to bond device <master> */
 int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 {
@@ -1258,8 +1293,9 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 
 	/* bond must be initialized by bond_open() before enslaving */
 	if (!(bond_dev->flags & IFF_UP)) {
-		dprintk("Error, master_dev is not up\n");
-		return -EPERM;
+		printk(KERN_WARNING DRV_NAME
+			" %s: master_dev is not up in bond_enslave\n",
+			bond_dev->name);
 	}
 
 	/* already enslaved */
@@ -1312,14 +1348,42 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 		goto err_undo_flags;
 	}
 
+	/* set bonding device ether type by slave - bonding netdevices are
+	 * created with ether_setup, so when the slave type is not ARPHRD_ETHER
+	 * there is a need to override some of the type dependent attribs/funcs.
+	 *
+	 * bond ether type mutual exclusion - don't allow slaves of dissimilar
+	 * ether type (eg ARPHRD_ETHER and ARPHRD_INFINIBAND) share the same bond
+	 */
+	if (bond->slave_cnt == 0) {
+		if (slave_dev->type != ARPHRD_ETHER)
+			bond_setup_by_slave(bond_dev, slave_dev);
+	} else if (bond_dev->type != slave_dev->type) {
+		printk(KERN_ERR DRV_NAME ": %s ether type (%d) is different "
+			"from other slaves (%d), can not enslave it.\n",
+			slave_dev->name,
+			slave_dev->type, bond_dev->type);
+			res = -EINVAL;
+			goto err_undo_flags;
+	}
+
 	if (slave_dev->set_mac_address == NULL) {
-		printk(KERN_ERR DRV_NAME
-			": %s: Error: The slave device you specified does "
-			"not support setting the MAC address. "
-			"Your kernel likely does not support slave "
-			"devices.\n", bond_dev->name);
-  		res = -EOPNOTSUPP;
-		goto err_undo_flags;
+		if (bond->slave_cnt == 0) {
+			printk(KERN_WARNING DRV_NAME
+			       ": %s: Warning: The first slave device "
+			       "specified does not support setting the MAC "
+			       "address. Enabling the fail_over_mac option.",
+			       bond_dev->name);
+			bond->params.fail_over_mac = 1;
+		} else if (!bond->params.fail_over_mac) {
+			printk(KERN_ERR DRV_NAME
+				": %s: Error: The slave device specified "
+				"does not support setting the MAC address, "
+				"but fail_over_mac is not enabled.\n"
+				, bond_dev->name);
+			res = -EOPNOTSUPP;
+			goto err_undo_flags;
+		}
 	}
 
 	new_slave = kzalloc(sizeof(struct slave), GFP_KERNEL);
@@ -1340,16 +1404,18 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 	 */
 	memcpy(new_slave->perm_hwaddr, slave_dev->dev_addr, ETH_ALEN);
 
-	/*
-	 * Set slave to master's mac address.  The application already
-	 * set the master's mac address to that of the first slave
-	 */
-	memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
-	addr.sa_family = slave_dev->type;
-	res = dev_set_mac_address(slave_dev, &addr);
-	if (res) {
-		dprintk("Error %d calling set_mac_address\n", res);
-		goto err_free;
+	if (!bond->params.fail_over_mac) {
+		/*
+		 * Set slave to master's mac address.  The application already
+		 * set the master's mac address to that of the first slave
+		 */
+		memcpy(addr.sa_data, bond_dev->dev_addr, bond_dev->addr_len);
+		addr.sa_family = slave_dev->type;
+		res = dev_set_mac_address(slave_dev, &addr);
+		if (res) {
+			dprintk("Error %d calling set_mac_address\n", res);
+			goto err_free;
+		}
 	}
 
 	res = netdev_set_master(slave_dev, bond_dev);
@@ -1574,9 +1640,11 @@ err_close:
 	dev_close(slave_dev);
 
 err_restore_mac:
-	memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
-	addr.sa_family = slave_dev->type;
-	dev_set_mac_address(slave_dev, &addr);
+	if (!bond->params.fail_over_mac) {
+		memcpy(addr.sa_data, new_slave->perm_hwaddr, ETH_ALEN);
+		addr.sa_family = slave_dev->type;
+		dev_set_mac_address(slave_dev, &addr);
+	}
 
 err_free:
 	kfree(new_slave);
@@ -1749,10 +1817,12 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 	/* close slave before restoring its mac address */
 	dev_close(slave_dev);
 
-	/* restore original ("permanent") mac address */
-	memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
-	addr.sa_family = slave_dev->type;
-	dev_set_mac_address(slave_dev, &addr);
+	if (!bond->params.fail_over_mac) {
+		/* restore original ("permanent") mac address */
+		memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
+		addr.sa_family = slave_dev->type;
+		dev_set_mac_address(slave_dev, &addr);
+	}
 
 	slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
 				   IFF_SLAVE_INACTIVE | IFF_BONDING |
@@ -1764,6 +1834,35 @@ int bond_release(struct net_device *bond_dev, struct net_device *slave_dev)
 }
 
 /*
+* Destroy a bonding device.
+* Must be under rtnl_lock when this function is called.
+*/
+void bond_destroy(struct bonding *bond)
+{
+	bond_deinit(bond->dev);
+	bond_destroy_sysfs_entry(bond);
+	unregister_netdevice(bond->dev);
+}
+
+/*
+* First release a slave and than destroy the bond if no more slaves iare left.
+* Must be under rtnl_lock when this function is called.
+*/
+int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev)
+{
+	struct bonding *bond = bond_dev->priv;
+	int ret;
+
+	ret = bond_release(bond_dev, slave_dev);
+	if ((ret == 0) && (bond->slave_cnt == 0)) {
+		printk(KERN_INFO DRV_NAME ": %s: destroying bond %s.\n",
+		       bond_dev->name, bond_dev->name);
+		bond_destroy(bond);
+	}
+	return ret;
+}
+
+/*
  * This function releases all slaves.
  */
 static int bond_release_all(struct net_device *bond_dev)
@@ -1839,10 +1938,12 @@ static int bond_release_all(struct net_device *bond_dev)
 		/* close slave before restoring its mac address */
 		dev_close(slave_dev);
 
-		/* restore original ("permanent") mac address*/
-		memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
-		addr.sa_family = slave_dev->type;
-		dev_set_mac_address(slave_dev, &addr);
+		if (!bond->params.fail_over_mac) {
+			/* restore original ("permanent") mac address*/
+			memcpy(addr.sa_data, slave->perm_hwaddr, ETH_ALEN);
+			addr.sa_family = slave_dev->type;
+			dev_set_mac_address(slave_dev, &addr);
+		}
 
 		slave_dev->priv_flags &= ~(IFF_MASTER_8023AD | IFF_MASTER_ALB |
 					   IFF_SLAVE_INACTIVE);
@@ -2013,6 +2114,17 @@ void bond_mii_monitor(struct net_device *bond_dev)
 	 * program could monitor the link itself if needed.
 	 */
 
+	if (bond->send_grat_arp) {
+		if (bond->curr_active_slave && test_bit(__LINK_STATE_LINKWATCH_PENDING,
+				&bond->curr_active_slave->dev->state))
+			dprintk("Needs to send gratuitous arp but not yet\n");
+		else {
+			dprintk("sending delayed gratuitous arp on on %s\n",
+				bond->curr_active_slave->dev->name);
+			bond_send_gratuitous_arp(bond);
+			bond->send_grat_arp = 0;
+		}
+	}
 	read_lock(&bond->curr_slave_lock);
 	oldcurrent = bond->curr_active_slave;
 	read_unlock(&bond->curr_slave_lock);
@@ -2414,7 +2526,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond)
 
 	if (bond->master_ip) {
 		bond_arp_send(slave->dev, ARPOP_REPLY, bond->master_ip,
-				  bond->master_ip, 0);
+				bond->master_ip, 0);
 	}
 
 	list_for_each_entry(vlan, &bond->vlan_list, vlan_list) {
@@ -2951,9 +3063,15 @@ static void bond_info_show_master(struct seq_file *seq)
 	curr = bond->curr_active_slave;
 	read_unlock(&bond->curr_slave_lock);
 
-	seq_printf(seq, "Bonding Mode: %s\n",
+	seq_printf(seq, "Bonding Mode: %s",
 		   bond_mode_name(bond->params.mode));
 
+	if (bond->params.mode == BOND_MODE_ACTIVEBACKUP &&
+	    bond->params.fail_over_mac)
+		seq_printf(seq, " (fail_over_mac)");
+
+	seq_printf(seq, "\n");
+
 	if (bond->params.mode == BOND_MODE_XOR ||
 		bond->params.mode == BOND_MODE_8023AD) {
 		seq_printf(seq, "Transmit Hash Policy: %s (%d)\n",
@@ -3248,6 +3366,11 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave
 		 * ... Or is it this?
 		 */
 		break;
+	case NETDEV_GOING_DOWN:
+		dprintk("slave %s is going down\n", slave_dev->name);
+		if (bond->setup_by_slave)
+			bond_release_and_destroy(bond_dev, slave_dev);
+		break;
 	case NETDEV_CHANGEMTU:
 		/*
 		 * TODO: Should slaves be allowed to
@@ -3880,6 +4003,13 @@ static int bond_set_mac_address(struct net_device *bond_dev, void *addr)
 
 	dprintk("bond=%p, name=%s\n", bond, (bond_dev ? bond_dev->name : "None"));
 
+	/*
+	 * If fail_over_mac is enabled, do nothing and return success.
+	 * Returning an error causes ifenslave to fail.
+	 */
+	if (bond->params.fail_over_mac)
+		return 0;
+
 	if (!is_valid_ether_addr(sa->sa_data)) {
 		return -EADDRNOTAVAIL;
 	}
@@ -4217,6 +4347,8 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
 	bond->current_arp_slave = NULL;
 	bond->primary_slave = NULL;
 	bond->dev = bond_dev;
+	bond->send_grat_arp = 0;
+	bond->setup_by_slave = 0;
 	INIT_LIST_HEAD(&bond->vlan_list);
 
 	/* Initialize the device entry points */
@@ -4265,7 +4397,6 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
 #ifdef CONFIG_PROC_FS
 	bond_create_proc_entry(bond);
 #endif
-
 	list_add_tail(&bond->bond_list, &bond_dev_list);
 
 	return 0;
@@ -4599,6 +4730,11 @@ static int bond_check_params(struct bond_params *params)
 		primary = NULL;
 	}
 
+	if (fail_over_mac && (bond_mode != BOND_MODE_ACTIVEBACKUP))
+		printk(KERN_WARNING DRV_NAME
+		       ": Warning: fail_over_mac only affects "
+		       "active-backup mode.\n");
+
 	/* fill params struct with the proper values */
 	params->mode = bond_mode;
 	params->xmit_policy = xmit_hashtype;
@@ -4610,6 +4746,7 @@ static int bond_check_params(struct bond_params *params)
 	params->use_carrier = use_carrier;
 	params->lacp_fast = lacp_fast;
 	params->primary[0] = 0;
+	params->fail_over_mac = fail_over_mac;
 
 	if (primary) {
 		strncpy(params->primary, primary, IFNAMSIZ);
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 6f49ca7..80c0c8c 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -164,9 +164,7 @@ static ssize_t bonding_store_bonds(struct class *cls, const char *buffer, size_t
 				printk(KERN_INFO DRV_NAME
 					": %s is being deleted...\n",
 					bond->dev->name);
-				bond_deinit(bond->dev);
-		        	bond_destroy_sysfs_entry(bond);
-				unregister_netdevice(bond->dev);
+				bond_destroy(bond);
 				rtnl_unlock();
 				goto out;
 			}
@@ -260,17 +258,16 @@ static ssize_t bonding_store_slaves(struct device *d,
 	char command[IFNAMSIZ + 1] = { 0, };
 	char *ifname;
 	int i, res, found, ret = count;
+	u32 original_mtu;
 	struct slave *slave;
 	struct net_device *dev = NULL;
 	struct bonding *bond = to_bond(d);
 
 	/* Quick sanity check -- is the bond interface up? */
 	if (!(bond->dev->flags & IFF_UP)) {
-		printk(KERN_ERR DRV_NAME
-		       ": %s: Unable to update slaves because interface is down.\n",
+		printk(KERN_WARNING DRV_NAME
+		       ": %s: doing slave updates when interface is down.\n",
 		       bond->dev->name);
-		ret = -EPERM;
-		goto out;
 	}
 
 	/* Note:  We can't hold bond->lock here, as bond_create grabs it. */
@@ -327,6 +324,7 @@ static ssize_t bonding_store_slaves(struct device *d,
 		}
 
 		/* Set the slave's MTU to match the bond */
+		original_mtu = dev->mtu;
 		if (dev->mtu != bond->dev->mtu) {
 			if (dev->change_mtu) {
 				res = dev->change_mtu(dev,
@@ -341,6 +339,9 @@ static ssize_t bonding_store_slaves(struct device *d,
 		}
 		rtnl_lock();
 		res = bond_enslave(bond->dev, dev);
+		bond_for_each_slave(bond, slave, i)
+			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0)
+				slave->original_mtu = original_mtu;
 		rtnl_unlock();
 		if (res) {
 			ret = res;
@@ -353,13 +354,17 @@ static ssize_t bonding_store_slaves(struct device *d,
 		bond_for_each_slave(bond, slave, i)
 			if (strnicmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
 				dev = slave->dev;
+				original_mtu = slave->original_mtu;
 				break;
 			}
 		if (dev) {
 			printk(KERN_INFO DRV_NAME ": %s: Removing slave %s\n",
 				bond->dev->name, dev->name);
 			rtnl_lock();
-			res = bond_release(bond->dev, dev);
+			if (bond->setup_by_slave)
+				res = bond_release_and_destroy(bond->dev, dev);
+			else
+				res = bond_release(bond->dev, dev);
 			rtnl_unlock();
 			if (res) {
 				ret = res;
@@ -367,9 +372,9 @@ static ssize_t bonding_store_slaves(struct device *d,
 			}
 			/* set the slave MTU to the default */
 			if (dev->change_mtu) {
-				dev->change_mtu(dev, 1500);
+				dev->change_mtu(dev, original_mtu);
 			} else {
-				dev->mtu = 1500;
+				dev->mtu = original_mtu;
 			}
 		}
 		else {
@@ -563,6 +568,54 @@ static ssize_t bonding_store_arp_validate(struct device *d,
 static DEVICE_ATTR(arp_validate, S_IRUGO | S_IWUSR, bonding_show_arp_validate, bonding_store_arp_validate);
 
 /*
+ * Show and store fail_over_mac.  User only allowed to change the
+ * value when there are no slaves.
+ */
+static ssize_t bonding_show_fail_over_mac(struct device *d, struct device_attribute *attr, char *buf)
+{
+	struct bonding *bond = to_bond(d);
+
+	return sprintf(buf, "%d\n", bond->params.fail_over_mac) + 1;
+}
+
+static ssize_t bonding_store_fail_over_mac(struct device *d, struct device_attribute *attr, const char *buf, size_t count)
+{
+	int new_value;
+	int ret = count;
+	struct bonding *bond = to_bond(d);
+
+	if (bond->slave_cnt != 0) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: Can't alter fail_over_mac with slaves in bond.\n",
+		       bond->dev->name);
+		ret = -EPERM;
+		goto out;
+	}
+
+	if (sscanf(buf, "%d", &new_value) != 1) {
+		printk(KERN_ERR DRV_NAME
+		       ": %s: no fail_over_mac value specified.\n",
+		       bond->dev->name);
+		ret = -EINVAL;
+		goto out;
+	}
+
+	if ((new_value == 0) || (new_value == 1)) {
+		bond->params.fail_over_mac = new_value;
+		printk(KERN_INFO DRV_NAME ": %s: Setting fail_over_mac to %d.\n",
+		       bond->dev->name, new_value);
+	} else {
+		printk(KERN_INFO DRV_NAME
+		       ": %s: Ignoring invalid fail_over_mac value %d.\n",
+		       bond->dev->name, new_value);
+	}
+out:
+	return ret;
+}
+
+static DEVICE_ATTR(fail_over_mac, S_IRUGO | S_IWUSR, bonding_show_fail_over_mac, bonding_store_fail_over_mac);
+
+/*
  * Show and set the arp timer interval.  There are two tricky bits
  * here.  First, if ARP monitoring is activated, then we must disable
  * MII monitoring.  Second, if the ARP timer isn't running, we must
@@ -1383,6 +1436,7 @@ static DEVICE_ATTR(ad_partner_mac, S_IRUGO, bonding_show_ad_partner_mac, NULL);
 static struct attribute *per_bond_attrs[] = {
 	&dev_attr_slaves.attr,
 	&dev_attr_mode.attr,
+	&dev_attr_fail_over_mac.attr,
 	&dev_attr_arp_validate.attr,
 	&dev_attr_arp_interval.attr,
 	&dev_attr_arp_ip_target.attr,
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index 2a6af7d..a8bbd56 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -22,8 +22,8 @@
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION	"3.1.3"
-#define DRV_RELDATE	"June 13, 2007"
+#define DRV_VERSION	"3.2.0"
+#define DRV_RELDATE	"September 13, 2007"
 #define DRV_NAME	"bonding"
 #define DRV_DESCRIPTION	"Ethernet Channel Bonding Driver"
 
@@ -128,6 +128,7 @@ struct bond_params {
 	int arp_interval;
 	int arp_validate;
 	int use_carrier;
+	int fail_over_mac;
 	int updelay;
 	int downdelay;
 	int lacp_fast;
@@ -156,6 +157,7 @@ struct slave {
 	s8     link;    /* one of BOND_LINK_XXXX */
 	s8     state;   /* one of BOND_STATE_XXXX */
 	u32    original_flags;
+	u32    original_mtu;
 	u32    link_failure_count;
 	u16    speed;
 	u8     duplex;
@@ -185,6 +187,8 @@ struct bonding {
 	struct   timer_list mii_timer;
 	struct   timer_list arp_timer;
 	s8       kill_timers;
+	s8	 send_grat_arp;
+	s8	 setup_by_slave;
 	struct   net_device_stats stats;
 #ifdef CONFIG_PROC_FS
 	struct   proc_dir_entry *proc_entry;
@@ -292,6 +296,8 @@ static inline void bond_unset_master_alb_flags(struct bonding *bond)
 struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr);
 int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev);
 int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
+void bond_destroy(struct bonding *bond);
+int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
 void bond_deinit(struct net_device *bond_dev);
 int bond_create_sysfs(void);
 void bond_destroy_sysfs(void);
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 563bf5f..7df31b5 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -4443,7 +4443,7 @@ static struct {
 	{REG_MAC_COLL_EXCESS},
 	{REG_MAC_COLL_LATE}
 };
-#define CAS_REG_LEN 	(sizeof(ethtool_register_table)/sizeof(int))
+#define CAS_REG_LEN 	ARRAY_SIZE(ethtool_register_table)
 #define CAS_MAX_REGS 	(sizeof (u32)*CAS_REG_LEN)
 
 static void cas_read_regs(struct cas *cp, u8 *ptr, int len)
diff --git a/drivers/net/cpmac.c b/drivers/net/cpmac.c
new file mode 100644
index 0000000..ed53aaa
--- /dev/null
+++ b/drivers/net/cpmac.c
@@ -0,0 +1,1174 @@
+/*
+ * Copyright (C) 2006, 2007 Eugene Konev
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that 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
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <asm/gpio.h>
+
+MODULE_AUTHOR("Eugene Konev <ejka@imfi.kspu.ru>");
+MODULE_DESCRIPTION("TI AR7 ethernet driver (CPMAC)");
+MODULE_LICENSE("GPL");
+
+static int debug_level = 8;
+static int dumb_switch;
+
+/* Next 2 are only used in cpmac_probe, so it's pointless to change them */
+module_param(debug_level, int, 0444);
+module_param(dumb_switch, int, 0444);
+
+MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable");
+MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
+
+#define CPMAC_VERSION "0.5.0"
+/* stolen from net/ieee80211.h */
+#ifndef MAC_FMT
+#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
+#define MAC_ARG(x) ((u8*)(x))[0], ((u8*)(x))[1], ((u8*)(x))[2], \
+		   ((u8*)(x))[3], ((u8*)(x))[4], ((u8*)(x))[5]
+#endif
+/* frame size + 802.1q tag */
+#define CPMAC_SKB_SIZE		(ETH_FRAME_LEN + 4)
+#define CPMAC_QUEUES	8
+
+/* Ethernet registers */
+#define CPMAC_TX_CONTROL		0x0004
+#define CPMAC_TX_TEARDOWN		0x0008
+#define CPMAC_RX_CONTROL		0x0014
+#define CPMAC_RX_TEARDOWN		0x0018
+#define CPMAC_MBP			0x0100
+# define MBP_RXPASSCRC			0x40000000
+# define MBP_RXQOS			0x20000000
+# define MBP_RXNOCHAIN			0x10000000
+# define MBP_RXCMF			0x01000000
+# define MBP_RXSHORT			0x00800000
+# define MBP_RXCEF			0x00400000
+# define MBP_RXPROMISC			0x00200000
+# define MBP_PROMISCCHAN(channel)	(((channel) & 0x7) << 16)
+# define MBP_RXBCAST			0x00002000
+# define MBP_BCASTCHAN(channel)		(((channel) & 0x7) << 8)
+# define MBP_RXMCAST			0x00000020
+# define MBP_MCASTCHAN(channel)		((channel) & 0x7)
+#define CPMAC_UNICAST_ENABLE		0x0104
+#define CPMAC_UNICAST_CLEAR		0x0108
+#define CPMAC_MAX_LENGTH		0x010c
+#define CPMAC_BUFFER_OFFSET		0x0110
+#define CPMAC_MAC_CONTROL		0x0160
+# define MAC_TXPTYPE			0x00000200
+# define MAC_TXPACE			0x00000040
+# define MAC_MII			0x00000020
+# define MAC_TXFLOW			0x00000010
+# define MAC_RXFLOW			0x00000008
+# define MAC_MTEST			0x00000004
+# define MAC_LOOPBACK			0x00000002
+# define MAC_FDX			0x00000001
+#define CPMAC_MAC_STATUS		0x0164
+# define MAC_STATUS_QOS			0x00000004
+# define MAC_STATUS_RXFLOW		0x00000002
+# define MAC_STATUS_TXFLOW		0x00000001
+#define CPMAC_TX_INT_ENABLE		0x0178
+#define CPMAC_TX_INT_CLEAR		0x017c
+#define CPMAC_MAC_INT_VECTOR		0x0180
+# define MAC_INT_STATUS			0x00080000
+# define MAC_INT_HOST			0x00040000
+# define MAC_INT_RX			0x00020000
+# define MAC_INT_TX			0x00010000
+#define CPMAC_MAC_EOI_VECTOR		0x0184
+#define CPMAC_RX_INT_ENABLE		0x0198
+#define CPMAC_RX_INT_CLEAR		0x019c
+#define CPMAC_MAC_INT_ENABLE		0x01a8
+#define CPMAC_MAC_INT_CLEAR		0x01ac
+#define CPMAC_MAC_ADDR_LO(channel) 	(0x01b0 + (channel) * 4)
+#define CPMAC_MAC_ADDR_MID		0x01d0
+#define CPMAC_MAC_ADDR_HI		0x01d4
+#define CPMAC_MAC_HASH_LO		0x01d8
+#define CPMAC_MAC_HASH_HI		0x01dc
+#define CPMAC_TX_PTR(channel)		(0x0600 + (channel) * 4)
+#define CPMAC_RX_PTR(channel)		(0x0620 + (channel) * 4)
+#define CPMAC_TX_ACK(channel)		(0x0640 + (channel) * 4)
+#define CPMAC_RX_ACK(channel)		(0x0660 + (channel) * 4)
+#define CPMAC_REG_END			0x0680
+/*
+ * Rx/Tx statistics
+ * TODO: use some of them to fill stats in cpmac_stats()
+ */
+#define CPMAC_STATS_RX_GOOD		0x0200
+#define CPMAC_STATS_RX_BCAST		0x0204
+#define CPMAC_STATS_RX_MCAST		0x0208
+#define CPMAC_STATS_RX_PAUSE		0x020c
+#define CPMAC_STATS_RX_CRC		0x0210
+#define CPMAC_STATS_RX_ALIGN		0x0214
+#define CPMAC_STATS_RX_OVER		0x0218
+#define CPMAC_STATS_RX_JABBER		0x021c
+#define CPMAC_STATS_RX_UNDER		0x0220
+#define CPMAC_STATS_RX_FRAG		0x0224
+#define CPMAC_STATS_RX_FILTER		0x0228
+#define CPMAC_STATS_RX_QOSFILTER	0x022c
+#define CPMAC_STATS_RX_OCTETS		0x0230
+
+#define CPMAC_STATS_TX_GOOD		0x0234
+#define CPMAC_STATS_TX_BCAST		0x0238
+#define CPMAC_STATS_TX_MCAST		0x023c
+#define CPMAC_STATS_TX_PAUSE		0x0240
+#define CPMAC_STATS_TX_DEFER		0x0244
+#define CPMAC_STATS_TX_COLLISION	0x0248
+#define CPMAC_STATS_TX_SINGLECOLL	0x024c
+#define CPMAC_STATS_TX_MULTICOLL	0x0250
+#define CPMAC_STATS_TX_EXCESSCOLL	0x0254
+#define CPMAC_STATS_TX_LATECOLL		0x0258
+#define CPMAC_STATS_TX_UNDERRUN		0x025c
+#define CPMAC_STATS_TX_CARRIERSENSE	0x0260
+#define CPMAC_STATS_TX_OCTETS		0x0264
+
+#define cpmac_read(base, reg)		(readl((void __iomem *)(base) + (reg)))
+#define cpmac_write(base, reg, val)	(writel(val, (void __iomem *)(base) + \
+						(reg)))
+
+/* MDIO bus */
+#define CPMAC_MDIO_VERSION		0x0000
+#define CPMAC_MDIO_CONTROL		0x0004
+# define MDIOC_IDLE			0x80000000
+# define MDIOC_ENABLE			0x40000000
+# define MDIOC_PREAMBLE			0x00100000
+# define MDIOC_FAULT			0x00080000
+# define MDIOC_FAULTDETECT		0x00040000
+# define MDIOC_INTTEST			0x00020000
+# define MDIOC_CLKDIV(div)		((div) & 0xff)
+#define CPMAC_MDIO_ALIVE		0x0008
+#define CPMAC_MDIO_LINK			0x000c
+#define CPMAC_MDIO_ACCESS(channel)	(0x0080 + (channel) * 8)
+# define MDIO_BUSY			0x80000000
+# define MDIO_WRITE			0x40000000
+# define MDIO_REG(reg)			(((reg) & 0x1f) << 21)
+# define MDIO_PHY(phy)			(((phy) & 0x1f) << 16)
+# define MDIO_DATA(data)		((data) & 0xffff)
+#define CPMAC_MDIO_PHYSEL(channel)	(0x0084 + (channel) * 8)
+# define PHYSEL_LINKSEL			0x00000040
+# define PHYSEL_LINKINT			0x00000020
+
+struct cpmac_desc {
+	u32 hw_next;
+	u32 hw_data;
+	u16 buflen;
+	u16 bufflags;
+	u16 datalen;
+	u16 dataflags;
+#define CPMAC_SOP			0x8000
+#define CPMAC_EOP			0x4000
+#define CPMAC_OWN			0x2000
+#define CPMAC_EOQ			0x1000
+	struct sk_buff *skb;
+	struct cpmac_desc *next;
+	dma_addr_t mapping;
+	dma_addr_t data_mapping;
+};
+
+struct cpmac_priv {
+	spinlock_t lock;
+	spinlock_t rx_lock;
+	struct cpmac_desc *rx_head;
+	int ring_size;
+	struct cpmac_desc *desc_ring;
+	dma_addr_t dma_ring;
+	void __iomem *regs;
+	struct mii_bus *mii_bus;
+	struct phy_device *phy;
+	char phy_name[BUS_ID_SIZE];
+	int oldlink, oldspeed, oldduplex;
+	u32 msg_enable;
+	struct net_device *dev;
+	struct work_struct reset_work;
+	struct platform_device *pdev;
+};
+
+static irqreturn_t cpmac_irq(int, void *);
+static void cpmac_hw_start(struct net_device *dev);
+static void cpmac_hw_stop(struct net_device *dev);
+static int cpmac_stop(struct net_device *dev);
+static int cpmac_open(struct net_device *dev);
+
+static void cpmac_dump_regs(struct net_device *dev)
+{
+	int i;
+	struct cpmac_priv *priv = netdev_priv(dev);
+	for (i = 0; i < CPMAC_REG_END; i += 4) {
+		if (i % 16 == 0) {
+			if (i)
+				printk("\n");
+			printk(KERN_DEBUG "%s: reg[%p]:", dev->name,
+			       priv->regs + i);
+		}
+		printk(" %08x", cpmac_read(priv->regs, i));
+	}
+	printk("\n");
+}
+
+static void cpmac_dump_desc(struct net_device *dev, struct cpmac_desc *desc)
+{
+	int i;
+	printk(KERN_DEBUG "%s: desc[%p]:", dev->name, desc);
+	for (i = 0; i < sizeof(*desc) / 4; i++)
+		printk(" %08x", ((u32 *)desc)[i]);
+	printk("\n");
+}
+
+static void cpmac_dump_skb(struct net_device *dev, struct sk_buff *skb)
+{
+	int i;
+	printk(KERN_DEBUG "%s: skb 0x%p, len=%d\n", dev->name, skb, skb->len);
+	for (i = 0; i < skb->len; i++) {
+		if (i % 16 == 0) {
+			if (i)
+				printk("\n");
+			printk(KERN_DEBUG "%s: data[%p]:", dev->name,
+			       skb->data + i);
+		}
+		printk(" %02x", ((u8 *)skb->data)[i]);
+	}
+	printk("\n");
+}
+
+static int cpmac_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+{
+	u32 val;
+
+	while (cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0)) & MDIO_BUSY)
+		cpu_relax();
+	cpmac_write(bus->priv, CPMAC_MDIO_ACCESS(0), MDIO_BUSY | MDIO_REG(reg) |
+		    MDIO_PHY(phy_id));
+	while ((val = cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0))) & MDIO_BUSY)
+		cpu_relax();
+	return MDIO_DATA(val);
+}
+
+static int cpmac_mdio_write(struct mii_bus *bus, int phy_id,
+			    int reg, u16 val)
+{
+	while (cpmac_read(bus->priv, CPMAC_MDIO_ACCESS(0)) & MDIO_BUSY)
+		cpu_relax();
+	cpmac_write(bus->priv, CPMAC_MDIO_ACCESS(0), MDIO_BUSY | MDIO_WRITE |
+		    MDIO_REG(reg) | MDIO_PHY(phy_id) | MDIO_DATA(val));
+	return 0;
+}
+
+static int cpmac_mdio_reset(struct mii_bus *bus)
+{
+	ar7_device_reset(AR7_RESET_BIT_MDIO);
+	cpmac_write(bus->priv, CPMAC_MDIO_CONTROL, MDIOC_ENABLE |
+		    MDIOC_CLKDIV(ar7_cpmac_freq() / 2200000 - 1));
+	return 0;
+}
+
+static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, };
+
+static struct mii_bus cpmac_mii = {
+	.name = "cpmac-mii",
+	.read = cpmac_mdio_read,
+	.write = cpmac_mdio_write,
+	.reset = cpmac_mdio_reset,
+	.irq = mii_irqs,
+};
+
+static int cpmac_config(struct net_device *dev, struct ifmap *map)
+{
+	if (dev->flags & IFF_UP)
+		return -EBUSY;
+
+	/* Don't allow changing the I/O address */
+	if (map->base_addr != dev->base_addr)
+		return -EOPNOTSUPP;
+
+	/* ignore other fields */
+	return 0;
+}
+
+static void cpmac_set_multicast_list(struct net_device *dev)
+{
+	struct dev_mc_list *iter;
+	int i;
+	u8 tmp;
+	u32 mbp, bit, hash[2] = { 0, };
+	struct cpmac_priv *priv = netdev_priv(dev);
+
+	mbp = cpmac_read(priv->regs, CPMAC_MBP);
+	if (dev->flags & IFF_PROMISC) {
+		cpmac_write(priv->regs, CPMAC_MBP, (mbp & ~MBP_PROMISCCHAN(0)) |
+			    MBP_RXPROMISC);
+	} else {
+		cpmac_write(priv->regs, CPMAC_MBP, mbp & ~MBP_RXPROMISC);
+		if (dev->flags & IFF_ALLMULTI) {
+			/* enable all multicast mode */
+			cpmac_write(priv->regs, CPMAC_MAC_HASH_LO, 0xffffffff);
+			cpmac_write(priv->regs, CPMAC_MAC_HASH_HI, 0xffffffff);
+		} else {
+			/*
+			 * cpmac uses some strange mac address hashing
+			 * (not crc32)
+			 */
+			for (i = 0, iter = dev->mc_list; i < dev->mc_count;
+			     i++, iter = iter->next) {
+				bit = 0;
+				tmp = iter->dmi_addr[0];
+				bit  ^= (tmp >> 2) ^ (tmp << 4);
+				tmp = iter->dmi_addr[1];
+				bit  ^= (tmp >> 4) ^ (tmp << 2);
+				tmp = iter->dmi_addr[2];
+				bit  ^= (tmp >> 6) ^ tmp;
+				tmp = iter->dmi_addr[3];
+				bit  ^= (tmp >> 2) ^ (tmp << 4);
+				tmp = iter->dmi_addr[4];
+				bit  ^= (tmp >> 4) ^ (tmp << 2);
+				tmp = iter->dmi_addr[5];
+				bit  ^= (tmp >> 6) ^ tmp;
+				bit &= 0x3f;
+				hash[bit / 32] |= 1 << (bit % 32);
+			}
+
+			cpmac_write(priv->regs, CPMAC_MAC_HASH_LO, hash[0]);
+			cpmac_write(priv->regs, CPMAC_MAC_HASH_HI, hash[1]);
+		}
+	}
+}
+
+static struct sk_buff *cpmac_rx_one(struct net_device *dev,
+				    struct cpmac_priv *priv,
+				    struct cpmac_desc *desc)
+{
+	struct sk_buff *skb, *result = NULL;
+
+	if (unlikely(netif_msg_hw(priv)))
+		cpmac_dump_desc(dev, desc);
+	cpmac_write(priv->regs, CPMAC_RX_ACK(0), (u32)desc->mapping);
+	if (unlikely(!desc->datalen)) {
+		if (netif_msg_rx_err(priv) && net_ratelimit())
+			printk(KERN_WARNING "%s: rx: spurious interrupt\n",
+			       dev->name);
+		return NULL;
+	}
+
+	skb = netdev_alloc_skb(dev, CPMAC_SKB_SIZE);
+	if (likely(skb)) {
+		skb_reserve(skb, 2);
+		skb_put(desc->skb, desc->datalen);
+		desc->skb->protocol = eth_type_trans(desc->skb, dev);
+		desc->skb->ip_summed = CHECKSUM_NONE;
+		dev->stats.rx_packets++;
+		dev->stats.rx_bytes += desc->datalen;
+		result = desc->skb;
+		dma_unmap_single(&dev->dev, desc->data_mapping, CPMAC_SKB_SIZE,
+				 DMA_FROM_DEVICE);
+		desc->skb = skb;
+		desc->data_mapping = dma_map_single(&dev->dev, skb->data,
+						    CPMAC_SKB_SIZE,
+						    DMA_FROM_DEVICE);
+		desc->hw_data = (u32)desc->data_mapping;
+		if (unlikely(netif_msg_pktdata(priv))) {
+			printk(KERN_DEBUG "%s: received packet:\n", dev->name);
+			cpmac_dump_skb(dev, result);
+		}
+	} else {
+		if (netif_msg_rx_err(priv) && net_ratelimit())
+			printk(KERN_WARNING
+			       "%s: low on skbs, dropping packet\n", dev->name);
+		dev->stats.rx_dropped++;
+	}
+
+	desc->buflen = CPMAC_SKB_SIZE;
+	desc->dataflags = CPMAC_OWN;
+
+	return result;
+}
+
+static int cpmac_poll(struct net_device *dev, int *budget)
+{
+	struct sk_buff *skb;
+	struct cpmac_desc *desc;
+	int received = 0, quota = min(dev->quota, *budget);
+	struct cpmac_priv *priv = netdev_priv(dev);
+
+	spin_lock(&priv->rx_lock);
+	if (unlikely(!priv->rx_head)) {
+		if (netif_msg_rx_err(priv) && net_ratelimit())
+			printk(KERN_WARNING "%s: rx: polling, but no queue\n",
+			       dev->name);
+		netif_rx_complete(dev);
+		return 0;
+	}
+
+	desc = priv->rx_head;
+	while ((received < quota) && ((desc->dataflags & CPMAC_OWN) == 0)) {
+		skb = cpmac_rx_one(dev, priv, desc);
+		if (likely(skb)) {
+			netif_receive_skb(skb);
+			received++;
+		}
+		desc = desc->next;
+	}
+
+	priv->rx_head = desc;
+	spin_unlock(&priv->rx_lock);
+	*budget -= received;
+	dev->quota -= received;
+	if (unlikely(netif_msg_rx_status(priv)))
+		printk(KERN_DEBUG "%s: poll processed %d packets\n", dev->name,
+		       received);
+	if (desc->dataflags & CPMAC_OWN) {
+		netif_rx_complete(dev);
+		cpmac_write(priv->regs, CPMAC_RX_PTR(0), (u32)desc->mapping);
+		cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int cpmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	int queue, len;
+	struct cpmac_desc *desc;
+	struct cpmac_priv *priv = netdev_priv(dev);
+
+	if (unlikely(skb_padto(skb, ETH_ZLEN))) {
+		if (netif_msg_tx_err(priv) && net_ratelimit())
+			printk(KERN_WARNING
+			       "%s: tx: padding failed, dropping\n", dev->name);
+		spin_lock(&priv->lock);
+		dev->stats.tx_dropped++;
+		spin_unlock(&priv->lock);
+		return -ENOMEM;
+	}
+
+	len = max(skb->len, ETH_ZLEN);
+	queue = skb->queue_mapping;
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	netif_stop_subqueue(dev, queue);
+#else
+	netif_stop_queue(dev);
+#endif
+
+	desc = &priv->desc_ring[queue];
+	if (unlikely(desc->dataflags & CPMAC_OWN)) {
+		if (netif_msg_tx_err(priv) && net_ratelimit())
+			printk(KERN_WARNING "%s: tx dma ring full, dropping\n",
+			       dev->name);
+		spin_lock(&priv->lock);
+		dev->stats.tx_dropped++;
+		spin_unlock(&priv->lock);
+		dev_kfree_skb_any(skb);
+		return -ENOMEM;
+	}
+
+	spin_lock(&priv->lock);
+	dev->trans_start = jiffies;
+	spin_unlock(&priv->lock);
+	desc->dataflags = CPMAC_SOP | CPMAC_EOP | CPMAC_OWN;
+	desc->skb = skb;
+	desc->data_mapping = dma_map_single(&dev->dev, skb->data, len,
+					    DMA_TO_DEVICE);
+	desc->hw_data = (u32)desc->data_mapping;
+	desc->datalen = len;
+	desc->buflen = len;
+	if (unlikely(netif_msg_tx_queued(priv)))
+		printk(KERN_DEBUG "%s: sending 0x%p, len=%d\n", dev->name, skb,
+		       skb->len);
+	if (unlikely(netif_msg_hw(priv)))
+		cpmac_dump_desc(dev, desc);
+	if (unlikely(netif_msg_pktdata(priv)))
+		cpmac_dump_skb(dev, skb);
+	cpmac_write(priv->regs, CPMAC_TX_PTR(queue), (u32)desc->mapping);
+
+	return 0;
+}
+
+static void cpmac_end_xmit(struct net_device *dev, int queue)
+{
+	struct cpmac_desc *desc;
+	struct cpmac_priv *priv = netdev_priv(dev);
+
+	desc = &priv->desc_ring[queue];
+	cpmac_write(priv->regs, CPMAC_TX_ACK(queue), (u32)desc->mapping);
+	if (likely(desc->skb)) {
+		spin_lock(&priv->lock);
+		dev->stats.tx_packets++;
+		dev->stats.tx_bytes += desc->skb->len;
+		spin_unlock(&priv->lock);
+		dma_unmap_single(&dev->dev, desc->data_mapping, desc->skb->len,
+				 DMA_TO_DEVICE);
+
+		if (unlikely(netif_msg_tx_done(priv)))
+			printk(KERN_DEBUG "%s: sent 0x%p, len=%d\n", dev->name,
+			       desc->skb, desc->skb->len);
+
+		dev_kfree_skb_irq(desc->skb);
+		desc->skb = NULL;
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+		if (netif_subqueue_stopped(dev, queue))
+			netif_wake_subqueue(dev, queue);
+#else
+		if (netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+#endif
+	} else {
+		if (netif_msg_tx_err(priv) && net_ratelimit())
+			printk(KERN_WARNING
+			       "%s: end_xmit: spurious interrupt\n", dev->name);
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+		if (netif_subqueue_stopped(dev, queue))
+			netif_wake_subqueue(dev, queue);
+#else
+		if (netif_queue_stopped(dev))
+			netif_wake_queue(dev);
+#endif
+	}
+}
+
+static void cpmac_hw_stop(struct net_device *dev)
+{
+	int i;
+	struct cpmac_priv *priv = netdev_priv(dev);
+	struct plat_cpmac_data *pdata = priv->pdev->dev.platform_data;
+
+	ar7_device_reset(pdata->reset_bit);
+	cpmac_write(priv->regs, CPMAC_RX_CONTROL,
+		    cpmac_read(priv->regs, CPMAC_RX_CONTROL) & ~1);
+	cpmac_write(priv->regs, CPMAC_TX_CONTROL,
+		    cpmac_read(priv->regs, CPMAC_TX_CONTROL) & ~1);
+	for (i = 0; i < 8; i++) {
+		cpmac_write(priv->regs, CPMAC_TX_PTR(i), 0);
+		cpmac_write(priv->regs, CPMAC_RX_PTR(i), 0);
+	}
+	cpmac_write(priv->regs, CPMAC_UNICAST_CLEAR, 0xff);
+	cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 0xff);
+	cpmac_write(priv->regs, CPMAC_TX_INT_CLEAR, 0xff);
+	cpmac_write(priv->regs, CPMAC_MAC_INT_CLEAR, 0xff);
+	cpmac_write(priv->regs, CPMAC_MAC_CONTROL,
+		    cpmac_read(priv->regs, CPMAC_MAC_CONTROL) & ~MAC_MII);
+}
+
+static void cpmac_hw_start(struct net_device *dev)
+{
+	int i;
+	struct cpmac_priv *priv = netdev_priv(dev);
+	struct plat_cpmac_data *pdata = priv->pdev->dev.platform_data;
+
+	ar7_device_reset(pdata->reset_bit);
+	for (i = 0; i < 8; i++) {
+		cpmac_write(priv->regs, CPMAC_TX_PTR(i), 0);
+		cpmac_write(priv->regs, CPMAC_RX_PTR(i), 0);
+	}
+	cpmac_write(priv->regs, CPMAC_RX_PTR(0), priv->rx_head->mapping);
+
+	cpmac_write(priv->regs, CPMAC_MBP, MBP_RXSHORT | MBP_RXBCAST |
+		    MBP_RXMCAST);
+	cpmac_write(priv->regs, CPMAC_BUFFER_OFFSET, 0);
+	for (i = 0; i < 8; i++)
+		cpmac_write(priv->regs, CPMAC_MAC_ADDR_LO(i), dev->dev_addr[5]);
+	cpmac_write(priv->regs, CPMAC_MAC_ADDR_MID, dev->dev_addr[4]);
+	cpmac_write(priv->regs, CPMAC_MAC_ADDR_HI, dev->dev_addr[0] |
+		    (dev->dev_addr[1] << 8) | (dev->dev_addr[2] << 16) |
+		    (dev->dev_addr[3] << 24));
+	cpmac_write(priv->regs, CPMAC_MAX_LENGTH, CPMAC_SKB_SIZE);
+	cpmac_write(priv->regs, CPMAC_UNICAST_CLEAR, 0xff);
+	cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 0xff);
+	cpmac_write(priv->regs, CPMAC_TX_INT_CLEAR, 0xff);
+	cpmac_write(priv->regs, CPMAC_MAC_INT_CLEAR, 0xff);
+	cpmac_write(priv->regs, CPMAC_UNICAST_ENABLE, 1);
+	cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
+	cpmac_write(priv->regs, CPMAC_TX_INT_ENABLE, 0xff);
+	cpmac_write(priv->regs, CPMAC_MAC_INT_ENABLE, 3);
+
+	cpmac_write(priv->regs, CPMAC_RX_CONTROL,
+		    cpmac_read(priv->regs, CPMAC_RX_CONTROL) | 1);
+	cpmac_write(priv->regs, CPMAC_TX_CONTROL,
+		    cpmac_read(priv->regs, CPMAC_TX_CONTROL) | 1);
+	cpmac_write(priv->regs, CPMAC_MAC_CONTROL,
+		    cpmac_read(priv->regs, CPMAC_MAC_CONTROL) | MAC_MII |
+		    MAC_FDX);
+}
+
+static void cpmac_clear_rx(struct net_device *dev)
+{
+	struct cpmac_priv *priv = netdev_priv(dev);
+	struct cpmac_desc *desc;
+	int i;
+	if (unlikely(!priv->rx_head))
+		return;
+	desc = priv->rx_head;
+	for (i = 0; i < priv->ring_size; i++) {
+		if ((desc->dataflags & CPMAC_OWN) == 0) {
+			if (netif_msg_rx_err(priv) && net_ratelimit())
+				printk(KERN_WARNING "%s: packet dropped\n",
+				       dev->name);
+			if (unlikely(netif_msg_hw(priv)))
+				cpmac_dump_desc(dev, desc);
+			desc->dataflags = CPMAC_OWN;
+			dev->stats.rx_dropped++;
+		}
+		desc = desc->next;
+	}
+}
+
+static void cpmac_clear_tx(struct net_device *dev)
+{
+	struct cpmac_priv *priv = netdev_priv(dev);
+	int i;
+	if (unlikely(!priv->desc_ring))
+		return;
+	for (i = 0; i < CPMAC_QUEUES; i++)
+		if (priv->desc_ring[i].skb) {
+			dev_kfree_skb_any(priv->desc_ring[i].skb);
+			if (netif_subqueue_stopped(dev, i))
+			    netif_wake_subqueue(dev, i);
+		}
+}
+
+static void cpmac_hw_error(struct work_struct *work)
+{
+	struct cpmac_priv *priv =
+		container_of(work, struct cpmac_priv, reset_work);
+
+	spin_lock(&priv->rx_lock);
+	cpmac_clear_rx(priv->dev);
+	spin_unlock(&priv->rx_lock);
+	cpmac_clear_tx(priv->dev);
+	cpmac_hw_start(priv->dev);
+	netif_start_queue(priv->dev);
+}
+
+static irqreturn_t cpmac_irq(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	struct cpmac_priv *priv;
+	int queue;
+	u32 status;
+
+	if (!dev)
+		return IRQ_NONE;
+
+	priv = netdev_priv(dev);
+
+	status = cpmac_read(priv->regs, CPMAC_MAC_INT_VECTOR);
+
+	if (unlikely(netif_msg_intr(priv)))
+		printk(KERN_DEBUG "%s: interrupt status: 0x%08x\n", dev->name,
+		       status);
+
+	if (status & MAC_INT_TX)
+		cpmac_end_xmit(dev, (status & 7));
+
+	if (status & MAC_INT_RX) {
+		queue = (status >> 8) & 7;
+		netif_rx_schedule(dev);
+		cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue);
+	}
+
+	cpmac_write(priv->regs, CPMAC_MAC_EOI_VECTOR, 0);
+
+	if (unlikely(status & (MAC_INT_HOST | MAC_INT_STATUS))) {
+		if (netif_msg_drv(priv) && net_ratelimit())
+			printk(KERN_ERR "%s: hw error, resetting...\n",
+			       dev->name);
+		netif_stop_queue(dev);
+		cpmac_hw_stop(dev);
+		schedule_work(&priv->reset_work);
+		if (unlikely(netif_msg_hw(priv)))
+			cpmac_dump_regs(dev);
+	}
+
+	return IRQ_HANDLED;
+}
+
+static void cpmac_tx_timeout(struct net_device *dev)
+{
+	struct cpmac_priv *priv = netdev_priv(dev);
+	int i;
+
+	spin_lock(&priv->lock);
+	dev->stats.tx_errors++;
+	spin_unlock(&priv->lock);
+	if (netif_msg_tx_err(priv) && net_ratelimit())
+		printk(KERN_WARNING "%s: transmit timeout\n", dev->name);
+	/* 
+	 * FIXME: waking up random queue is not the best thing to
+	 * do... on the other hand why we got here at all?
+	 */
+#ifdef CONFIG_NETDEVICES_MULTIQUEUE
+	for (i = 0; i < CPMAC_QUEUES; i++)
+		if (priv->desc_ring[i].skb) {
+			dev_kfree_skb_any(priv->desc_ring[i].skb);
+			netif_wake_subqueue(dev, i);
+			break;
+		}
+#else
+	if (priv->desc_ring[0].skb)
+		dev_kfree_skb_any(priv->desc_ring[0].skb);
+	netif_wake_queue(dev);
+#endif
+}
+
+static int cpmac_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct cpmac_priv *priv = netdev_priv(dev);
+	if (!(netif_running(dev)))
+		return -EINVAL;
+	if (!priv->phy)
+		return -EINVAL;
+	if ((cmd == SIOCGMIIPHY) || (cmd == SIOCGMIIREG) ||
+	    (cmd == SIOCSMIIREG))
+		return phy_mii_ioctl(priv->phy, if_mii(ifr), cmd);
+
+	return -EOPNOTSUPP;
+}
+
+static int cpmac_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct cpmac_priv *priv = netdev_priv(dev);
+
+	if (priv->phy)
+		return phy_ethtool_gset(priv->phy, cmd);
+
+	return -EINVAL;
+}
+
+static int cpmac_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct cpmac_priv *priv = netdev_priv(dev);
+
+	if (!capable(CAP_NET_ADMIN))
+		return -EPERM;
+
+	if (priv->phy)
+		return phy_ethtool_sset(priv->phy, cmd);
+
+	return -EINVAL;
+}
+
+static void cpmac_get_ringparam(struct net_device *dev, struct ethtool_ringparam* ring)
+{
+	struct cpmac_priv *priv = netdev_priv(dev);
+
+	ring->rx_max_pending = 1024;
+	ring->rx_mini_max_pending = 1;
+	ring->rx_jumbo_max_pending = 1;
+	ring->tx_max_pending = 1;
+
+	ring->rx_pending = priv->ring_size;
+	ring->rx_mini_pending = 1;
+	ring->rx_jumbo_pending = 1;
+	ring->tx_pending = 1;
+}
+
+static int cpmac_set_ringparam(struct net_device *dev, struct ethtool_ringparam* ring)
+{
+	struct cpmac_priv *priv = netdev_priv(dev);
+
+	if (dev->flags && IFF_UP)
+		return -EBUSY;
+	priv->ring_size = ring->rx_pending;
+	return 0;
+}
+
+static void cpmac_get_drvinfo(struct net_device *dev,
+			      struct ethtool_drvinfo *info)
+{
+	strcpy(info->driver, "cpmac");
+	strcpy(info->version, CPMAC_VERSION);
+	info->fw_version[0] = '\0';
+	sprintf(info->bus_info, "%s", "cpmac");
+	info->regdump_len = 0;
+}
+
+static const struct ethtool_ops cpmac_ethtool_ops = {
+	.get_settings = cpmac_get_settings,
+	.set_settings = cpmac_set_settings,
+	.get_drvinfo = cpmac_get_drvinfo,
+	.get_link = ethtool_op_get_link,
+	.get_ringparam = cpmac_get_ringparam,
+	.set_ringparam = cpmac_set_ringparam,
+};
+
+static void cpmac_adjust_link(struct net_device *dev)
+{
+	struct cpmac_priv *priv = netdev_priv(dev);
+	int new_state = 0;
+
+	spin_lock(&priv->lock);
+	if (priv->phy->link) {
+		netif_start_queue(dev);
+		if (priv->phy->duplex != priv->oldduplex) {
+			new_state = 1;
+			priv->oldduplex = priv->phy->duplex;
+		}
+
+		if (priv->phy->speed != priv->oldspeed) {
+			new_state = 1;
+			priv->oldspeed = priv->phy->speed;
+		}
+
+		if (!priv->oldlink) {
+			new_state = 1;
+			priv->oldlink = 1;
+			netif_schedule(dev);
+		}
+	} else if (priv->oldlink) {
+		netif_stop_queue(dev);
+		new_state = 1;
+		priv->oldlink = 0;
+		priv->oldspeed = 0;
+		priv->oldduplex = -1;
+	}
+
+	if (new_state && netif_msg_link(priv) && net_ratelimit())
+		phy_print_status(priv->phy);
+
+	spin_unlock(&priv->lock);
+}
+
+static int cpmac_open(struct net_device *dev)
+{
+	int i, size, res;
+	struct cpmac_priv *priv = netdev_priv(dev);
+	struct resource *mem;
+	struct cpmac_desc *desc;
+	struct sk_buff *skb;
+
+	priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link,
+				0, PHY_INTERFACE_MODE_MII);
+	if (IS_ERR(priv->phy)) {
+		if (netif_msg_drv(priv))
+			printk(KERN_ERR "%s: Could not attach to PHY\n",
+			       dev->name);
+		return PTR_ERR(priv->phy);
+	}
+
+	mem = platform_get_resource_byname(priv->pdev, IORESOURCE_MEM, "regs");
+	if (!request_mem_region(mem->start, mem->end - mem->start, dev->name)) {
+		if (netif_msg_drv(priv))
+			printk(KERN_ERR "%s: failed to request registers\n",
+			       dev->name);
+		res = -ENXIO;
+		goto fail_reserve;
+	}
+
+	priv->regs = ioremap(mem->start, mem->end - mem->start);
+	if (!priv->regs) {
+		if (netif_msg_drv(priv))
+			printk(KERN_ERR "%s: failed to remap registers\n",
+			       dev->name);
+		res = -ENXIO;
+		goto fail_remap;
+	}
+
+	size = priv->ring_size + CPMAC_QUEUES;
+	priv->desc_ring = dma_alloc_coherent(&dev->dev,
+					     sizeof(struct cpmac_desc) * size,
+					     &priv->dma_ring,
+					     GFP_KERNEL);
+	if (!priv->desc_ring) {
+		res = -ENOMEM;
+		goto fail_alloc;
+	}
+
+	for (i = 0; i < size; i++)
+		priv->desc_ring[i].mapping = priv->dma_ring + sizeof(*desc) * i;
+
+	priv->rx_head = &priv->desc_ring[CPMAC_QUEUES];
+	for (i = 0, desc = priv->rx_head; i < priv->ring_size; i++, desc++) {
+		skb = netdev_alloc_skb(dev, CPMAC_SKB_SIZE);
+		if (unlikely(!skb)) {
+			res = -ENOMEM;
+			goto fail_desc;
+		}
+		skb_reserve(skb, 2);
+		desc->skb = skb;
+		desc->data_mapping = dma_map_single(&dev->dev, skb->data,
+						    CPMAC_SKB_SIZE,
+						    DMA_FROM_DEVICE);
+		desc->hw_data = (u32)desc->data_mapping;
+		desc->buflen = CPMAC_SKB_SIZE;
+		desc->dataflags = CPMAC_OWN;
+		desc->next = &priv->rx_head[(i + 1) % priv->ring_size];
+		desc->hw_next = (u32)desc->next->mapping;
+	}
+
+	if ((res = request_irq(dev->irq, cpmac_irq, IRQF_SHARED,
+			       dev->name, dev))) {
+		if (netif_msg_drv(priv))
+			printk(KERN_ERR "%s: failed to obtain irq\n",
+			       dev->name);
+		goto fail_irq;
+	}
+
+	INIT_WORK(&priv->reset_work, cpmac_hw_error);
+	cpmac_hw_start(dev);
+
+	priv->phy->state = PHY_CHANGELINK;
+	phy_start(priv->phy);
+
+	return 0;
+
+fail_irq:
+fail_desc:
+	for (i = 0; i < priv->ring_size; i++) {
+		if (priv->rx_head[i].skb) {
+			dma_unmap_single(&dev->dev,
+					 priv->rx_head[i].data_mapping,
+					 CPMAC_SKB_SIZE,
+					 DMA_FROM_DEVICE);
+			kfree_skb(priv->rx_head[i].skb);
+		}
+	}
+fail_alloc:
+	kfree(priv->desc_ring);
+	iounmap(priv->regs);
+
+fail_remap:
+	release_mem_region(mem->start, mem->end - mem->start);
+
+fail_reserve:
+	phy_disconnect(priv->phy);
+
+	return res;
+}
+
+static int cpmac_stop(struct net_device *dev)
+{
+	int i;
+	struct cpmac_priv *priv = netdev_priv(dev);
+	struct resource *mem;
+
+	netif_stop_queue(dev);
+
+	cancel_work_sync(&priv->reset_work);
+	phy_stop(priv->phy);
+	phy_disconnect(priv->phy);
+	priv->phy = NULL;
+
+	cpmac_hw_stop(dev);
+
+	for (i = 0; i < 8; i++)
+		cpmac_write(priv->regs, CPMAC_TX_PTR(i), 0);
+	cpmac_write(priv->regs, CPMAC_RX_PTR(0), 0);
+	cpmac_write(priv->regs, CPMAC_MBP, 0);
+
+	free_irq(dev->irq, dev);
+	iounmap(priv->regs);
+	mem = platform_get_resource_byname(priv->pdev, IORESOURCE_MEM, "regs");
+	release_mem_region(mem->start, mem->end - mem->start);
+	priv->rx_head = &priv->desc_ring[CPMAC_QUEUES];
+	for (i = 0; i < priv->ring_size; i++) {
+		if (priv->rx_head[i].skb) {
+			dma_unmap_single(&dev->dev,
+					 priv->rx_head[i].data_mapping,
+					 CPMAC_SKB_SIZE,
+					 DMA_FROM_DEVICE);
+			kfree_skb(priv->rx_head[i].skb);
+		}
+	}
+
+	dma_free_coherent(&dev->dev, sizeof(struct cpmac_desc) *
+			  (CPMAC_QUEUES + priv->ring_size),
+			  priv->desc_ring, priv->dma_ring);
+	return 0;
+}
+
+static int external_switch;
+
+static int __devinit cpmac_probe(struct platform_device *pdev)
+{
+	int rc, phy_id;
+	struct resource *mem;
+	struct cpmac_priv *priv;
+	struct net_device *dev;
+	struct plat_cpmac_data *pdata;
+
+	pdata = pdev->dev.platform_data;
+
+	for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) {
+		if (!(pdata->phy_mask & (1 << phy_id)))
+			continue;
+		if (!cpmac_mii.phy_map[phy_id])
+			continue;
+		break;
+	}
+
+	if (phy_id == PHY_MAX_ADDR) {
+		if (external_switch || dumb_switch)
+			phy_id = 0;
+		else {
+			printk(KERN_ERR "cpmac: no PHY present\n");
+			return -ENODEV;
+		}
+	}
+
+	dev = alloc_etherdev_mq(sizeof(*priv), CPMAC_QUEUES);
+
+	if (!dev) {
+		printk(KERN_ERR "cpmac: Unable to allocate net_device\n");
+		return -ENOMEM;
+	}
+
+	platform_set_drvdata(pdev, dev);
+	priv = netdev_priv(dev);
+
+	priv->pdev = pdev;
+	mem = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+	if (!mem) {
+		rc = -ENODEV;
+		goto fail;
+	}
+
+	dev->irq = platform_get_irq_byname(pdev, "irq");
+
+	dev->open               = cpmac_open;
+	dev->stop               = cpmac_stop;
+	dev->set_config         = cpmac_config;
+	dev->hard_start_xmit    = cpmac_start_xmit;
+	dev->do_ioctl           = cpmac_ioctl;
+	dev->set_multicast_list = cpmac_set_multicast_list;
+	dev->tx_timeout         = cpmac_tx_timeout;
+	dev->ethtool_ops        = &cpmac_ethtool_ops;
+	dev->poll = cpmac_poll;
+	dev->weight = 64;
+	dev->features |= NETIF_F_MULTI_QUEUE;
+
+	spin_lock_init(&priv->lock);
+	spin_lock_init(&priv->rx_lock);
+	priv->dev = dev;
+	priv->ring_size = 64;
+	priv->msg_enable = netif_msg_init(debug_level, 0xff);
+	memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
+	if (phy_id == 31) {
+		snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT,
+			 cpmac_mii.id, phy_id);
+	} else
+		snprintf(priv->phy_name, BUS_ID_SIZE, "fixed@%d:%d", 100, 1);
+
+	if ((rc = register_netdev(dev))) {
+		printk(KERN_ERR "cpmac: error %i registering device %s\n", rc,
+		       dev->name);
+		goto fail;
+	}
+
+	if (netif_msg_probe(priv)) {
+		printk(KERN_INFO
+		       "cpmac: device %s (regs: %p, irq: %d, phy: %s, mac: "
+		       MAC_FMT ")\n", dev->name, (void *)mem->start, dev->irq,
+		       priv->phy_name, MAC_ARG(dev->dev_addr));
+	}
+	return 0;
+
+fail:
+	free_netdev(dev);
+	return rc;
+}
+
+static int __devexit cpmac_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+	unregister_netdev(dev);
+	free_netdev(dev);
+	return 0;
+}
+
+static struct platform_driver cpmac_driver = {
+	.driver.name = "cpmac",
+	.probe = cpmac_probe,
+	.remove = __devexit_p(cpmac_remove),
+};
+
+int __devinit cpmac_init(void)
+{
+	u32 mask;
+	int i, res;
+
+	cpmac_mii.priv = ioremap(AR7_REGS_MDIO, 256);
+
+	if (!cpmac_mii.priv) {
+		printk(KERN_ERR "Can't ioremap mdio registers\n");
+		return -ENXIO;
+	}
+
+#warning FIXME: unhardcode gpio&reset bits
+	ar7_gpio_disable(26);
+	ar7_gpio_disable(27);
+	ar7_device_reset(AR7_RESET_BIT_CPMAC_LO);
+	ar7_device_reset(AR7_RESET_BIT_CPMAC_HI);
+	ar7_device_reset(AR7_RESET_BIT_EPHY);
+
+	cpmac_mii.reset(&cpmac_mii);
+
+	for (i = 0; i < 300000; i++)
+		if ((mask = cpmac_read(cpmac_mii.priv, CPMAC_MDIO_ALIVE)))
+			break;
+		else
+			cpu_relax();
+
+	mask &= 0x7fffffff;
+	if (mask & (mask - 1)) {
+		external_switch = 1;
+		mask = 0;
+	}
+
+	cpmac_mii.phy_mask = ~(mask | 0x80000000);
+
+	res = mdiobus_register(&cpmac_mii);
+	if (res)
+		goto fail_mii;
+
+	res = platform_driver_register(&cpmac_driver);
+	if (res)
+		goto fail_cpmac;
+
+	return 0;
+
+fail_cpmac:
+	mdiobus_unregister(&cpmac_mii);
+
+fail_mii:
+	iounmap(cpmac_mii.priv);
+
+	return res;
+}
+
+void __devexit cpmac_exit(void)
+{
+	platform_driver_unregister(&cpmac_driver);
+	mdiobus_unregister(&cpmac_mii);
+	iounmap(cpmac_mii.priv);
+}
+
+module_init(cpmac_init);
+module_exit(cpmac_exit);
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 0db5e6f..558440c 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -168,7 +168,6 @@ static int gfar_probe(struct platform_device *pdev)
 	struct gfar_private *priv = NULL;
 	struct gianfar_platform_data *einfo;
 	struct resource *r;
-	int idx;
 	int err = 0;
 	DECLARE_MAC_BUF(mac);
 
@@ -261,7 +260,9 @@ static int gfar_probe(struct platform_device *pdev)
 	dev->hard_start_xmit = gfar_start_xmit;
 	dev->tx_timeout = gfar_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_GFAR_NAPI
 	netif_napi_add(dev, &priv->napi, gfar_poll, GFAR_DEV_WEIGHT);
+#endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	dev->poll_controller = gfar_netpoll;
 #endif
@@ -931,9 +932,14 @@ tx_skb_fail:
 /* Returns 0 for success. */
 static int gfar_enet_open(struct net_device *dev)
 {
+#ifdef CONFIG_GFAR_NAPI
+	struct gfar_private *priv = netdev_priv(dev);
+#endif
 	int err;
 
+#ifdef CONFIG_GFAR_NAPI
 	napi_enable(&priv->napi);
+#endif
 
 	/* Initialize a bunch of registers */
 	init_registers(dev);
@@ -943,13 +949,17 @@ static int gfar_enet_open(struct net_device *dev)
 	err = init_phy(dev);
 
 	if(err) {
+#ifdef CONFIG_GFAR_NAPI
 		napi_disable(&priv->napi);
+#endif
 		return err;
 	}
 
 	err = startup_gfar(dev);
 	if (err)
+#ifdef CONFIG_GFAR_NAPI
 		napi_disable(&priv->napi);
+#endif
 
 	netif_start_queue(dev);
 
@@ -1103,7 +1113,9 @@ static int gfar_close(struct net_device *dev)
 {
 	struct gfar_private *priv = netdev_priv(dev);
 
+#ifdef CONFIG_GFAR_NAPI
 	napi_disable(&priv->napi);
+#endif
 
 	stop_gfar(dev);
 
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c
index 4e49e8c..dcd8826 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.c
+++ b/drivers/net/ibm_emac/ibm_emac_mal.c
@@ -413,7 +413,10 @@ static int __init mal_probe(struct ocp_device *ocpdev)
 		       ocpdev->def->index);
 		return -ENOMEM;
 	}
-	mal->dcrbase = maldata->dcr_base;
+
+	/* XXX This only works for native dcr for now */
+	mal->dcrhost = dcr_map(NULL, maldata->dcr_base, 0);
+
 	mal->def = ocpdev->def;
 
 	INIT_LIST_HEAD(&mal->poll_list);
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h
index 8f54d62..b8adbe6 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.h
+++ b/drivers/net/ibm_emac/ibm_emac_mal.h
@@ -191,7 +191,6 @@ struct mal_commac {
 };
 
 struct ibm_ocp_mal {
-	int			dcrbase;
 	dcr_host_t		dcrhost;
 
 	struct list_head	poll_list;
@@ -209,12 +208,12 @@ struct ibm_ocp_mal {
 
 static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg)
 {
-	return dcr_read(mal->dcrhost, mal->dcrbase + reg);
+	return dcr_read(mal->dcrhost, reg);
 }
 
 static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val)
 {
-	dcr_write(mal->dcrhost, mal->dcrbase + reg, val);
+	dcr_write(mal->dcrhost, reg, val);
 }
 
 /* Register MAL devices */
diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c
index 5885411..39f4cb6 100644
--- a/drivers/net/ibm_newemac/mal.c
+++ b/drivers/net/ibm_newemac/mal.c
@@ -461,6 +461,7 @@ static int __devinit mal_probe(struct of_device *ofdev,
 	struct mal_instance *mal;
 	int err = 0, i, bd_size;
 	int index = mal_count++;
+	unsigned int dcr_base;
 	const u32 *prop;
 	u32 cfg;
 
@@ -497,14 +498,14 @@ static int __devinit mal_probe(struct of_device *ofdev,
 	}
 	mal->num_rx_chans = prop[0];
 
-	mal->dcr_base = dcr_resource_start(ofdev->node, 0);
-	if (mal->dcr_base == 0) {
+	dcr_base = dcr_resource_start(ofdev->node, 0);
+	if (dcr_base == 0) {
 		printk(KERN_ERR
 		       "mal%d: can't find DCR resource!\n", index);
 		err = -ENODEV;
 		goto fail;
 	}
-        mal->dcr_host = dcr_map(ofdev->node, mal->dcr_base, 0x100);
+	mal->dcr_host = dcr_map(ofdev->node, dcr_base, 0x100);
 	if (!DCR_MAP_OK(mal->dcr_host)) {
 		printk(KERN_ERR
 		       "mal%d: failed to map DCRs !\n", index);
@@ -626,7 +627,7 @@ static int __devinit mal_probe(struct of_device *ofdev,
  fail2:
 	dma_free_coherent(&ofdev->dev, bd_size, mal->bd_virt, mal->bd_dma);
  fail_unmap:
-	dcr_unmap(mal->dcr_host, mal->dcr_base, 0x100);
+	dcr_unmap(mal->dcr_host, 0x100);
  fail:
 	kfree(mal);
 
diff --git a/drivers/net/ibm_newemac/mal.h b/drivers/net/ibm_newemac/mal.h
index cb1a16d..784edb8 100644
--- a/drivers/net/ibm_newemac/mal.h
+++ b/drivers/net/ibm_newemac/mal.h
@@ -185,7 +185,6 @@ struct mal_commac {
 
 struct mal_instance {
 	int			version;
-	int			dcr_base;
 	dcr_host_t		dcr_host;
 
 	int			num_tx_chans;	/* Number of TX channels */
@@ -213,12 +212,12 @@ struct mal_instance {
 
 static inline u32 get_mal_dcrn(struct mal_instance *mal, int reg)
 {
-	return dcr_read(mal->dcr_host, mal->dcr_base + reg);
+	return dcr_read(mal->dcr_host, reg);
 }
 
 static inline void set_mal_dcrn(struct mal_instance *mal, int reg, u32 val)
 {
-	dcr_write(mal->dcr_host, mal->dcr_base + reg, val);
+	dcr_write(mal->dcr_host, reg, val);
 }
 
 /* Register MAL devices */
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 3e5eca1..a82d8f9 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -840,7 +840,7 @@ toshoboe_probe (struct toshoboe_cb *self)
 
   /* test 1: SIR filter and back to back */
 
-  for (j = 0; j < (sizeof (bauds) / sizeof (int)); ++j)
+  for (j = 0; j < ARRAY_SIZE(bauds); ++j)
     {
       int fir = (j > 1);
       toshoboe_stopchip (self);
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index d3825c8..5c154fe 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -208,7 +208,6 @@ static int __init jazz_sonic_probe(struct platform_device *pdev)
 	struct sonic_local *lp;
 	struct resource *res;
 	int err = 0;
-	int i;
 	DECLARE_MAC_BUF(mac);
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
diff --git a/drivers/net/mipsnet.c b/drivers/net/mipsnet.c
index d593175..37707a0 100644
--- a/drivers/net/mipsnet.c
+++ b/drivers/net/mipsnet.c
@@ -7,12 +7,12 @@
 #define DEBUG
 
 #include <linux/init.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/platform_device.h>
-#include <asm/io.h>
 #include <asm/mips-boards/simint.h>
 
 #include "mipsnet.h"		/* actual device IO mapping */
@@ -33,9 +33,8 @@ static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
 	if (available_len < len)
 		return -EFAULT;
 
-	for (; len > 0; len--, kdata++) {
+	for (; len > 0; len--, kdata++)
 		*kdata = inb(mipsnet_reg_address(dev, rxDataBuffer));
-	}
 
 	return inl(mipsnet_reg_address(dev, rxDataCount));
 }
@@ -47,16 +46,15 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
 	char *buf_ptr = skb->data;
 
 	pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n",
-	         dev->name, __FUNCTION__, skb->len);
+		 dev->name, __FUNCTION__, skb->len);
 
 	outl(skb->len, mipsnet_reg_address(dev, txDataCount));
 
 	pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n",
-	         dev->name, __FUNCTION__, skb->len);
+		 dev->name, __FUNCTION__, skb->len);
 
-	for (; count_to_go; buf_ptr++, count_to_go--) {
+	for (; count_to_go; buf_ptr++, count_to_go--)
 		outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer));
-	}
 
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
@@ -67,7 +65,7 @@ static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
 static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	pr_debug("%s:%s(): transmitting %d bytes\n",
-	         dev->name, __FUNCTION__, skb->len);
+		 dev->name, __FUNCTION__, skb->len);
 
 	/* Only one packet at a time. Once TXDONE interrupt is serviced, the
 	 * queue will be restarted.
@@ -83,7 +81,8 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
 	struct sk_buff *skb;
 	size_t len = count;
 
-	if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
+	skb = alloc_skb(len + 2, GFP_KERNEL);
+	if (!skb) {
 		dev->stats.rx_dropped++;
 		return -ENOMEM;
 	}
@@ -96,7 +95,7 @@ static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
 	skb->ip_summed = CHECKSUM_UNNECESSARY;
 
 	pr_debug("%s:%s(): pushing RXed data to kernel\n",
-	         dev->name, __FUNCTION__);
+		 dev->name, __FUNCTION__);
 	netif_rx(skb);
 
 	dev->stats.rx_packets++;
@@ -114,42 +113,44 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
 
 	if (irq == dev->irq) {
 		pr_debug("%s:%s(): irq %d for device\n",
-		         dev->name, __FUNCTION__, irq);
+			 dev->name, __FUNCTION__, irq);
 
 		retval = IRQ_HANDLED;
 
 		interruptFlags =
 		    inl(mipsnet_reg_address(dev, interruptControl));
 		pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
-		         __FUNCTION__, interruptFlags);
+			 __FUNCTION__, interruptFlags);
 
 		if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
 			pr_debug("%s:%s(): got TXDone\n",
-			         dev->name, __FUNCTION__);
+				 dev->name, __FUNCTION__);
 			outl(MIPSNET_INTCTL_TXDONE,
 			     mipsnet_reg_address(dev, interruptControl));
-			// only one packet at a time, we are done.
+			/* only one packet at a time, we are done. */
 			netif_wake_queue(dev);
 		} else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
 			pr_debug("%s:%s(): got RX data\n",
-			         dev->name, __FUNCTION__);
+				 dev->name, __FUNCTION__);
 			mipsnet_get_fromdev(dev,
-			            inl(mipsnet_reg_address(dev, rxDataCount)));
+				    inl(mipsnet_reg_address(dev, rxDataCount)));
 			pr_debug("%s:%s(): clearing RX int\n",
-			         dev->name, __FUNCTION__);
+				 dev->name, __FUNCTION__);
 			outl(MIPSNET_INTCTL_RXDONE,
 			     mipsnet_reg_address(dev, interruptControl));
 
 		} else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
 			pr_debug("%s:%s(): got test interrupt\n",
-			         dev->name, __FUNCTION__);
-			// TESTBIT is cleared on read.
-			//    And takes effect after a write with 0
+				 dev->name, __FUNCTION__);
+			/*
+			 * TESTBIT is cleared on read.
+			 * And takes effect after a write with 0
+			 */
 			outl(0, mipsnet_reg_address(dev, interruptControl));
 		} else {
 			pr_debug("%s:%s(): no valid fags 0x%016llx\n",
-			         dev->name, __FUNCTION__, interruptFlags);
-			// Maybe shared IRQ, just ignore, no clearing.
+				 dev->name, __FUNCTION__, interruptFlags);
+			/* Maybe shared IRQ, just ignore, no clearing. */
 			retval = IRQ_NONE;
 		}
 
@@ -159,7 +160,7 @@ static irqreturn_t mipsnet_interrupt(int irq, void *dev_id)
 		retval = IRQ_NONE;
 	}
 	return retval;
-}				//mipsnet_interrupt()
+}
 
 static int mipsnet_open(struct net_device *dev)
 {
@@ -171,18 +172,18 @@ static int mipsnet_open(struct net_device *dev)
 
 	if (err) {
 		pr_debug("%s: %s(): can't get irq %d\n",
-		         dev->name, __FUNCTION__, dev->irq);
+			 dev->name, __FUNCTION__, dev->irq);
 		release_region(dev->base_addr, MIPSNET_IO_EXTENT);
 		return err;
 	}
 
 	pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n",
-	         dev->name, __FUNCTION__, dev->base_addr, dev->irq);
+		 dev->name, __FUNCTION__, dev->base_addr, dev->irq);
 
 
 	netif_start_queue(dev);
 
-	// test interrupt handler
+	/* test interrupt handler */
 	outl(MIPSNET_INTCTL_TESTBIT,
 	     mipsnet_reg_address(dev, interruptControl));
 
@@ -199,8 +200,6 @@ static int mipsnet_close(struct net_device *dev)
 
 static void mipsnet_set_mclist(struct net_device *dev)
 {
-	// we don't do anything
-	return;
 }
 
 static int __init mipsnet_probe(struct device *dev)
@@ -226,13 +225,13 @@ static int __init mipsnet_probe(struct device *dev)
 	 */
 	netdev->base_addr = 0x4200;
 	netdev->irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_MB0 +
-	              inl(mipsnet_reg_address(netdev, interruptInfo));
+		      inl(mipsnet_reg_address(netdev, interruptInfo));
 
-	// Get the io region now, get irq on open()
+	/* Get the io region now, get irq on open() */
 	if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) {
 		pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} "
-		         "for dev is not availble.\n", netdev->name,
-		         __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
+			 "for dev is not availble.\n", netdev->name,
+			 __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
 		err = -EBUSY;
 		goto out_free_netdev;
 	}
diff --git a/drivers/net/mipsnet.h b/drivers/net/mipsnet.h
index 026c732..0132c67 100644
--- a/drivers/net/mipsnet.h
+++ b/drivers/net/mipsnet.h
@@ -9,32 +9,34 @@
 /*
  *  Id of this Net device, as seen by the core.
  */
-#define MIPS_NET_DEV_ID ((uint64_t)           \
-	                     ((uint64_t)'M'<< 0)| \
-	                     ((uint64_t)'I'<< 8)| \
-	                     ((uint64_t)'P'<<16)| \
-	                     ((uint64_t)'S'<<24)| \
-	                     ((uint64_t)'N'<<32)| \
-	                     ((uint64_t)'E'<<40)| \
-	                     ((uint64_t)'T'<<48)| \
-	                     ((uint64_t)'0'<<56))
+#define MIPS_NET_DEV_ID ((uint64_t)	   \
+			     ((uint64_t) 'M' <<  0)| \
+			     ((uint64_t) 'I' <<  8)| \
+			     ((uint64_t) 'P' << 16)| \
+			     ((uint64_t) 'S' << 24)| \
+			     ((uint64_t) 'N' << 32)| \
+			     ((uint64_t) 'E' << 40)| \
+			     ((uint64_t) 'T' << 48)| \
+			     ((uint64_t) '0' << 56))
 
 /*
  * Net status/control block as seen by sw in the core.
  * (Why not use bit fields? can't be bothered with cross-platform struct
  *  packing.)
  */
-typedef struct _net_control_block {
-	/// dev info for probing
-	///  reads as MIPSNET%d where %d is some form of version
-	uint64_t devId;		/*0x00 */
+struct net_control_block {
+	/*
+	 * dev info for probing
+	 * reads as MIPSNET%d where %d is some form of version
+	 */
+	uint64_t devId;		/* 0x00 */
 
 	/*
 	 * read only busy flag.
 	 * Set and cleared by the Net Device to indicate that an rx or a tx
 	 * is in progress.
 	 */
-	uint32_t busy;		/*0x08 */
+	uint32_t busy;		/* 0x08 */
 
 	/*
 	 * Set by the Net Device.
@@ -43,16 +45,16 @@ typedef struct _net_control_block {
 	 * rxDataBuffer.  The value will decrease till 0 until all the data
 	 * from rxDataBuffer has been read.
 	 */
-	uint32_t rxDataCount;	/*0x0c */
+	uint32_t rxDataCount;	/* 0x0c */
 #define MIPSNET_MAX_RXTX_DATACOUNT (1<<16)
 
 	/*
-	 * Settable from the MIPS core, cleared by the Net Device.
-	 * The core should set the number of bytes it wants to send,
-	 *   then it should write those bytes of data to txDataBuffer.
-	 * The device will clear txDataCount has been processed (not necessarily sent).
+	 * Settable from the MIPS core, cleared by the Net Device.  The core
+	 * should set the number of bytes it wants to send, then it should
+	 * write those bytes of data to txDataBuffer.  The device will clear
+	 * txDataCount has been processed (not necessarily sent).
 	 */
-	uint32_t txDataCount;	/*0x10 */
+	uint32_t txDataCount;	/* 0x10 */
 
 	/*
 	 * Interrupt control
@@ -69,39 +71,42 @@ typedef struct _net_control_block {
 	 *    To clear the test interrupt, write 0 to this register.
 	 */
 	uint32_t interruptControl;	/*0x14 */
-#define MIPSNET_INTCTL_TXDONE     ((uint32_t)(1<< 0))
-#define MIPSNET_INTCTL_RXDONE     ((uint32_t)(1<< 1))
-#define MIPSNET_INTCTL_TESTBIT    ((uint32_t)(1<<31))
-#define MIPSNET_INTCTL_ALLSOURCES (MIPSNET_INTCTL_TXDONE|MIPSNET_INTCTL_RXDONE|MIPSNET_INTCTL_TESTBIT)
+#define MIPSNET_INTCTL_TXDONE     ((uint32_t)(1 <<  0))
+#define MIPSNET_INTCTL_RXDONE     ((uint32_t)(1 <<  1))
+#define MIPSNET_INTCTL_TESTBIT    ((uint32_t)(1 << 31))
+#define MIPSNET_INTCTL_ALLSOURCES	(MIPSNET_INTCTL_TXDONE | \
+					 MIPSNET_INTCTL_RXDONE | \
+					 MIPSNET_INTCTL_TESTBIT)
 
 	/*
-	 * Readonly core-specific interrupt info for the device to signal the core.
-	 * The meaning of the contents of this field might change.
-	 */
-	/*###\todo: the whole memIntf interrupt scheme is messy: the device should have
-	 *  no control what so ever of what VPE/register set is being used.
-	 *  The MemIntf should only expose interrupt lines, and something in the
-	 *  config should be responsible for the line<->core/vpe bindings.
+	 * Readonly core-specific interrupt info for the device to signal the
+	 * core.  The meaning of the contents of this field might change.
+	 *
+	 * TODO: the whole memIntf interrupt scheme is messy: the device should
+	 *       have no control what so ever of what VPE/register set is being
+	 *       used.  The MemIntf should only expose interrupt lines, and
+	 *       something in the config should be responsible for the
+	 *       line<->core/vpe bindings.
 	 */
-	uint32_t interruptInfo;	/*0x18 */
+	uint32_t interruptInfo;	/* 0x18 */
 
 	/*
 	 *  This is where the received data is read out.
 	 *  There is more data to read until rxDataReady is 0.
 	 *  Only 1 byte at this regs offset is used.
 	 */
-	uint32_t rxDataBuffer;	/*0x1c */
+	uint32_t rxDataBuffer;	/* 0x1c */
 
 	/*
-	 * This is where the data to transmit is written.
-	 * Data should be written for the amount specified in the txDataCount register.
-	 *  Only 1 byte at this regs offset is used.
+	 * This is where the data to transmit is written.  Data should be
+	 * written for the amount specified in the txDataCount register.  Only
+	 * 1 byte at this regs offset is used.
 	 */
-	uint32_t txDataBuffer;	/*0x20 */
-} MIPS_T_NetControl;
+	uint32_t txDataBuffer;	/* 0x20 */
+};
 
 #define MIPSNET_IO_EXTENT 0x40	/* being generous */
 
-#define field_offset(field) ((int)&((MIPS_T_NetControl*)(0))->field)
+#define field_offset(field) (offsetof(struct net_control_block, field))
 
 #endif /* __MIPSNET_H */
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index e8afa10..64c8151 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -75,7 +75,7 @@
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.3.2-1.269"
+#define MYRI10GE_VERSION_STR "1.3.2-1.287"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -214,6 +214,8 @@ struct myri10ge_priv {
 	unsigned long serial_number;
 	int vendor_specific_offset;
 	int fw_multicast_support;
+	unsigned long features;
+	u32 max_tso6;
 	u32 read_dma;
 	u32 write_dma;
 	u32 read_write_dma;
@@ -311,6 +313,7 @@ MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
 #define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
 
 static void myri10ge_set_multicast_list(struct net_device *dev);
+static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev);
 
 static inline void put_be32(__be32 val, __be32 __iomem * p)
 {
@@ -612,6 +615,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
 	__be32 buf[16];
 	u32 dma_low, dma_high, size;
 	int status, i;
+	struct myri10ge_cmd cmd;
 
 	size = 0;
 	status = myri10ge_load_hotplug_firmware(mgp, &size);
@@ -688,6 +692,14 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp)
 	dev_info(&mgp->pdev->dev, "handoff confirmed\n");
 	myri10ge_dummy_rdma(mgp, 1);
 
+	/* probe for IPv6 TSO support */
+	mgp->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
+	status = myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
+				   &cmd, 0);
+	if (status == 0) {
+		mgp->max_tso6 = cmd.data0;
+		mgp->features |= NETIF_F_TSO6;
+	}
 	return 0;
 }
 
@@ -1047,7 +1059,8 @@ myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
 
 	hlen = MYRI10GE_HLEN > len ? len : MYRI10GE_HLEN;
 
-	/* allocate an skb to attach the page(s) to. */
+	/* allocate an skb to attach the page(s) to. This is done
+	 * after trying LRO, so as to avoid skb allocation overheads */
 
 	skb = netdev_alloc_skb(dev, MYRI10GE_HLEN + 16);
 	if (unlikely(skb == NULL)) {
@@ -1217,7 +1230,8 @@ static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
 
 static int myri10ge_poll(struct napi_struct *napi, int budget)
 {
-	struct myri10ge_priv *mgp = container_of(napi, struct myri10ge_priv, napi);
+	struct myri10ge_priv *mgp =
+	    container_of(napi, struct myri10ge_priv, napi);
 	struct net_device *netdev = mgp->dev;
 	struct myri10ge_rx_done *rx_done = &mgp->rx_done;
 	int work_done;
@@ -1382,6 +1396,18 @@ static int myri10ge_set_rx_csum(struct net_device *netdev, u32 csum_enabled)
 	return 0;
 }
 
+static int myri10ge_set_tso(struct net_device *netdev, u32 tso_enabled)
+{
+	struct myri10ge_priv *mgp = netdev_priv(netdev);
+	unsigned long flags = mgp->features & (NETIF_F_TSO6 | NETIF_F_TSO);
+
+	if (tso_enabled)
+		netdev->features |= flags;
+	else
+		netdev->features &= ~flags;
+	return 0;
+}
+
 static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
 	"rx_packets", "tx_packets", "rx_bytes", "tx_bytes", "rx_errors",
 	"tx_errors", "rx_dropped", "tx_dropped", "multicast", "collisions",
@@ -1506,7 +1532,7 @@ static const struct ethtool_ops myri10ge_ethtool_ops = {
 	.set_rx_csum = myri10ge_set_rx_csum,
 	.set_tx_csum = ethtool_op_set_tx_hw_csum,
 	.set_sg = ethtool_op_set_sg,
-	.set_tso = ethtool_op_set_tso,
+	.set_tso = myri10ge_set_tso,
 	.get_link = ethtool_op_get_link,
 	.get_strings = myri10ge_get_strings,
 	.get_sset_count = myri10ge_get_sset_count,
@@ -2164,7 +2190,8 @@ again:
 		pseudo_hdr_offset = cksum_offset + skb->csum_offset;
 		/* If the headers are excessively large, then we must
 		 * fall back to a software checksum */
-		if (unlikely(cksum_offset > 255 || pseudo_hdr_offset > 127)) {
+		if (unlikely(!mss && (cksum_offset > 255 ||
+				      pseudo_hdr_offset > 127))) {
 			if (skb_checksum_help(skb))
 				goto drop;
 			cksum_offset = 0;
@@ -2184,9 +2211,18 @@ again:
 		/* negative cum_len signifies to the
 		 * send loop that we are still in the
 		 * header portion of the TSO packet.
-		 * TSO header must be at most 134 bytes long */
+		 * TSO header can be at most 1KB long */
 		cum_len = -(skb_transport_offset(skb) + tcp_hdrlen(skb));
 
+		/* for IPv6 TSO, the checksum offset stores the
+		 * TCP header length, to save the firmware from
+		 * the need to parse the headers */
+		if (skb_is_gso_v6(skb)) {
+			cksum_offset = tcp_hdrlen(skb);
+			/* Can only handle headers <= max_tso6 long */
+			if (unlikely(-cum_len > mgp->max_tso6))
+				return myri10ge_sw_tso(skb, dev);
+		}
 		/* for TSO, pseudo_hdr_offset holds mss.
 		 * The firmware figures out where to put
 		 * the checksum by parsing the header. */
@@ -2301,10 +2337,12 @@ again:
 			req++;
 			count++;
 			rdma_count++;
-			if (unlikely(cksum_offset > seglen))
-				cksum_offset -= seglen;
-			else
-				cksum_offset = 0;
+			if (cksum_offset != 0 && !(mss && skb_is_gso_v6(skb))) {
+				if (unlikely(cksum_offset > seglen))
+					cksum_offset -= seglen;
+				else
+					cksum_offset = 0;
+			}
 		}
 		if (frag_idx == frag_cnt)
 			break;
@@ -2387,6 +2425,41 @@ drop:
 
 }
 
+static int myri10ge_sw_tso(struct sk_buff *skb, struct net_device *dev)
+{
+	struct sk_buff *segs, *curr;
+	struct myri10ge_priv *mgp = dev->priv;
+	int status;
+
+	segs = skb_gso_segment(skb, dev->features & ~NETIF_F_TSO6);
+	if (unlikely(IS_ERR(segs)))
+		goto drop;
+
+	while (segs) {
+		curr = segs;
+		segs = segs->next;
+		curr->next = NULL;
+		status = myri10ge_xmit(curr, dev);
+		if (status != 0) {
+			dev_kfree_skb_any(curr);
+			if (segs != NULL) {
+				curr = segs;
+				segs = segs->next;
+				curr->next = NULL;
+				dev_kfree_skb_any(segs);
+			}
+			goto drop;
+		}
+	}
+	dev_kfree_skb_any(skb);
+	return 0;
+
+drop:
+	dev_kfree_skb_any(skb);
+	mgp->stats.tx_dropped += 1;
+	return 0;
+}
+
 static struct net_device_stats *myri10ge_get_stats(struct net_device *dev)
 {
 	struct myri10ge_priv *mgp = netdev_priv(dev);
@@ -2706,7 +2779,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
 }
 
 #ifdef CONFIG_PM
-
 static int myri10ge_suspend(struct pci_dev *pdev, pm_message_t state)
 {
 	struct myri10ge_priv *mgp;
@@ -2787,7 +2859,6 @@ abort_with_enabled:
 	return -EIO;
 
 }
-
 #endif				/* CONFIG_PM */
 
 static u32 myri10ge_read_reboot(struct myri10ge_priv *mgp)
@@ -2954,8 +3025,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	mgp = netdev_priv(netdev);
 	mgp->dev = netdev;
-	netif_napi_add(netdev, &mgp->napi,
-		       myri10ge_poll, myri10ge_napi_weight);
+	netif_napi_add(netdev, &mgp->napi, myri10ge_poll, myri10ge_napi_weight);
 	mgp->pdev = pdev;
 	mgp->csum_flag = MXGEFW_FLAGS_CKSUM;
 	mgp->pause = myri10ge_flow_control;
@@ -3077,7 +3147,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	netdev->change_mtu = myri10ge_change_mtu;
 	netdev->set_multicast_list = myri10ge_set_multicast_list;
 	netdev->set_mac_address = myri10ge_set_mac_address;
-	netdev->features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_TSO;
+	netdev->features = mgp->features;
 	if (dac_enabled)
 		netdev->features |= NETIF_F_HIGHDMA;
 
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h
index a1d2a22..58e5717 100644
--- a/drivers/net/myri10ge/myri10ge_mcp.h
+++ b/drivers/net/myri10ge/myri10ge_mcp.h
@@ -10,7 +10,7 @@ struct mcp_dma_addr {
 	__be32 low;
 };
 
-/* 4 Bytes */
+/* 4 Bytes.  8 Bytes for NDIS drivers. */
 struct mcp_slot {
 	__sum16 checksum;
 	__be16 length;
@@ -205,8 +205,87 @@ enum myri10ge_mcp_cmd_type {
 	/* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned
 	 * chipset */
 
-	MXGEFW_CMD_UNALIGNED_STATUS
-	    /* return data = boolean, true if the chipset is known to be unaligned */
+	MXGEFW_CMD_UNALIGNED_STATUS,
+	/* return data = boolean, true if the chipset is known to be unaligned */
+
+	MXGEFW_CMD_ALWAYS_USE_N_BIG_BUFFERS,
+	/* data0 = number of big buffers to use.  It must be 0 or a power of 2.
+	 * 0 indicates that the NIC consumes as many buffers as they are required
+	 * for packet. This is the default behavior.
+	 * A power of 2 number indicates that the NIC always uses the specified
+	 * number of buffers for each big receive packet.
+	 * It is up to the driver to ensure that this value is big enough for
+	 * the NIC to be able to receive maximum-sized packets.
+	 */
+
+	MXGEFW_CMD_GET_MAX_RSS_QUEUES,
+	MXGEFW_CMD_ENABLE_RSS_QUEUES,
+	/* data0 = number of slices n (0, 1, ..., n-1) to enable
+	 * data1 = interrupt mode. 0=share one INTx/MSI, 1=use one MSI-X per queue.
+	 * If all queues share one interrupt, the driver must have set
+	 * RSS_SHARED_INTERRUPT_DMA before enabling queues.
+	 */
+	MXGEFW_CMD_GET_RSS_SHARED_INTERRUPT_MASK_OFFSET,
+	MXGEFW_CMD_SET_RSS_SHARED_INTERRUPT_DMA,
+	/* data0, data1 = bus address lsw, msw */
+	MXGEFW_CMD_GET_RSS_TABLE_OFFSET,
+	/* get the offset of the indirection table */
+	MXGEFW_CMD_SET_RSS_TABLE_SIZE,
+	/* set the size of the indirection table */
+	MXGEFW_CMD_GET_RSS_KEY_OFFSET,
+	/* get the offset of the secret key */
+	MXGEFW_CMD_RSS_KEY_UPDATED,
+	/* tell nic that the secret key's been updated */
+	MXGEFW_CMD_SET_RSS_ENABLE,
+	/* data0 = enable/disable rss
+	 * 0: disable rss.  nic does not distribute receive packets.
+	 * 1: enable rss.  nic distributes receive packets among queues.
+	 * data1 = hash type
+	 * 1: IPV4
+	 * 2: TCP_IPV4
+	 * 3: IPV4 | TCP_IPV4
+	 */
+
+	MXGEFW_CMD_GET_MAX_TSO6_HDR_SIZE,
+	/* Return data = the max. size of the entire headers of a IPv6 TSO packet.
+	 * If the header size of a IPv6 TSO packet is larger than the specified
+	 * value, then the driver must not use TSO.
+	 * This size restriction only applies to IPv6 TSO.
+	 * For IPv4 TSO, the maximum size of the headers is fixed, and the NIC
+	 * always has enough header buffer to store maximum-sized headers.
+	 */
+
+	MXGEFW_CMD_SET_TSO_MODE,
+	/* data0 = TSO mode.
+	 * 0: Linux/FreeBSD style (NIC default)
+	 * 1: NDIS/NetBSD style
+	 */
+
+	MXGEFW_CMD_MDIO_READ,
+	/* data0 = dev_addr (PMA/PMD or PCS ...), data1 = register/addr */
+	MXGEFW_CMD_MDIO_WRITE,
+	/* data0 = dev_addr,  data1 = register/addr, data2 = value  */
+
+	MXGEFW_CMD_XFP_I2C_READ,
+	/* Starts to get a fresh copy of one byte or of the whole xfp i2c table, the
+	 * obtained data is cached inside the xaui-xfi chip :
+	 *   data0 : "all" flag : 0 => get one byte, 1=> get 256 bytes,
+	 *   data1 : if (data0 == 0): index of byte to refresh [ not used otherwise ]
+	 * The operation might take ~1ms for a single byte or ~65ms when refreshing all 256 bytes
+	 * During the i2c operation,  MXGEFW_CMD_XFP_I2C_READ or MXGEFW_CMD_XFP_BYTE attempts
+	 *  will return MXGEFW_CMD_ERROR_BUSY
+	 */
+	MXGEFW_CMD_XFP_BYTE,
+	/* Return the last obtained copy of a given byte in the xfp i2c table
+	 * (copy cached during the last relevant MXGEFW_CMD_XFP_I2C_READ)
+	 *   data0 : index of the desired table entry
+	 *  Return data = the byte stored at the requested index in the table
+	 */
+
+	MXGEFW_CMD_GET_VPUMP_OFFSET,
+	/* Return data = NIC memory offset of mcp_vpump_public_global */
+	MXGEFW_CMD_RESET_VPUMP,
+	/* Resets the VPUMP state */
 };
 
 enum myri10ge_mcp_cmd_status {
@@ -220,7 +299,10 @@ enum myri10ge_mcp_cmd_status {
 	MXGEFW_CMD_ERROR_BAD_PORT,
 	MXGEFW_CMD_ERROR_RESOURCES,
 	MXGEFW_CMD_ERROR_MULTICAST,
-	MXGEFW_CMD_ERROR_UNALIGNED
+	MXGEFW_CMD_ERROR_UNALIGNED,
+	MXGEFW_CMD_ERROR_NO_MDIO,
+	MXGEFW_CMD_ERROR_XFP_FAILURE,
+	MXGEFW_CMD_ERROR_XFP_ABSENT
 };
 
 #define MXGEFW_OLD_IRQ_DATA_LEN 40
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 527f9dc..50e1ec6 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -1576,7 +1576,7 @@ static int netdev_open(struct net_device *dev)
 
 	/* Set the timer to check for link beat. */
 	init_timer(&np->timer);
-	np->timer.expires = jiffies + NATSEMI_TIMER_FREQ;
+	np->timer.expires = round_jiffies(jiffies + NATSEMI_TIMER_FREQ);
 	np->timer.data = (unsigned long)dev;
 	np->timer.function = &netdev_timer; /* timer handler */
 	add_timer(&np->timer);
@@ -1856,7 +1856,11 @@ static void netdev_timer(unsigned long data)
 			next_tick = 1;
 		}
 	}
-	mod_timer(&np->timer, jiffies + next_tick);
+
+	if (next_tick > 1)
+		mod_timer(&np->timer, round_jiffies(jiffies + next_tick));
+	else
+		mod_timer(&np->timer, jiffies + next_tick);
 }
 
 static void dump_ring(struct net_device *dev)
@@ -3310,13 +3314,19 @@ static int natsemi_resume (struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata (pdev);
 	struct netdev_private *np = netdev_priv(dev);
+	int ret = 0;
 
 	rtnl_lock();
 	if (netif_device_present(dev))
 		goto out;
 	if (netif_running(dev)) {
 		BUG_ON(!np->hands_off);
-		pci_enable_device(pdev);
+		ret = pci_enable_device(pdev);
+		if (ret < 0) {
+			dev_err(&pdev->dev,
+				"pci_enable_device() failed: %d\n", ret);
+			goto out;
+		}
 	/*	pci_power_on(pdev); */
 
 		napi_enable(&np->napi);
@@ -3331,12 +3341,12 @@ static int natsemi_resume (struct pci_dev *pdev)
 		spin_unlock_irq(&np->lock);
 		enable_irq(dev->irq);
 
-		mod_timer(&np->timer, jiffies + 1*HZ);
+		mod_timer(&np->timer, round_jiffies(jiffies + 1*HZ));
 	}
 	netif_device_attach(dev);
 out:
 	rtnl_unlock();
-	return 0;
+	return ret;
 }
 
 #endif /* CONFIG_PM */
diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c
index 368f256..fbc7531 100644
--- a/drivers/net/ne-h8300.c
+++ b/drivers/net/ne-h8300.c
@@ -93,7 +93,7 @@ static int __init init_reg_offset(struct net_device *dev,unsigned long base_addr
 	bus_width = *(volatile unsigned char *)ABWCR;
 	bus_width &= 1 << ((base_addr >> 21) & 7);
 
-	for (i = 0; i < sizeof(reg_offset) / sizeof(u32); i++)
+	for (i = 0; i < ARRAY_SIZE(reg_offset); i++)
 		if (bus_width == 0)
 			reg_offset[i] = i * 2 + 1;
 		else
@@ -115,7 +115,7 @@ static int h8300_ne_irq[] = {EXT_IRQ5};
 
 static inline int init_dev(struct net_device *dev)
 {
-	if (h8300_ne_count < (sizeof(h8300_ne_base) / sizeof(unsigned long))) {
+	if (h8300_ne_count < ARRAY_SIZE(h8300_ne_base)) {
 		dev->base_addr = h8300_ne_base[h8300_ne_count];
 		dev->irq       = h8300_ne_irq[h8300_ne_count];
 		h8300_ne_count++;
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index 14361e8..c65199d 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -97,13 +97,16 @@ static void evm_saa9730_unblock_lan_int(struct lan_saa9730_private *lp)
 	       &lp->evm_saa9730_regs->InterruptBlock1);
 }
 
-static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
+static void __used show_saa9730_regs(struct net_device *dev)
 {
+	struct lan_saa9730_private *lp = netdev_priv(dev);
 	int i, j;
+
 	printk("TxmBufferA = %p\n", lp->TxmBuffer[0][0]);
 	printk("TxmBufferB = %p\n", lp->TxmBuffer[1][0]);
 	printk("RcvBufferA = %p\n", lp->RcvBuffer[0][0]);
 	printk("RcvBufferB = %p\n", lp->RcvBuffer[1][0]);
+
 	for (i = 0; i < LAN_SAA9730_BUFFERS; i++) {
 		for (j = 0; j < LAN_SAA9730_TXM_Q_SIZE; j++) {
 			printk("TxmBuffer[%d][%d] = %x\n", i, j,
@@ -146,11 +149,13 @@ static void __attribute_used__ show_saa9730_regs(struct lan_saa9730_private *lp)
 	       readl(&lp->lan_saa9730_regs->RxCtl));
 	printk("lp->lan_saa9730_regs->RxStatus = %x\n",
 	       readl(&lp->lan_saa9730_regs->RxStatus));
+
 	for (i = 0; i < LAN_SAA9730_CAM_DWORDS; i++) {
 		writel(i, &lp->lan_saa9730_regs->CamAddress);
 		printk("lp->lan_saa9730_regs->CamData = %x\n",
 		       readl(&lp->lan_saa9730_regs->CamData));
 	}
+
 	printk("dev->stats.tx_packets = %lx\n", dev->stats.tx_packets);
 	printk("dev->stats.tx_errors = %lx\n", dev->stats.tx_errors);
 	printk("dev->stats.tx_aborted_errors = %lx\n",
@@ -855,7 +860,7 @@ static void lan_saa9730_tx_timeout(struct net_device *dev)
 	/* Transmitter timeout, serious problems */
 	dev->stats.tx_errors++;
 	printk("%s: transmit timed out, reset\n", dev->name);
-	/*show_saa9730_regs(lp); */
+	/*show_saa9730_regs(dev); */
 	lan_saa9730_restart(lp);
 
 	dev->trans_start = jiffies;
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index a679f43..8038f28 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -1461,7 +1461,6 @@ static irqreturn_t tc35815_interrupt(int irq, void *dev_id)
 	}
 	return IRQ_NONE;
 #else
-	struct tc35815_local *lp = dev->priv;
 	int handled;
 	u32 status;
 
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 8d04654..4e1b84e 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -1906,7 +1906,7 @@ bdx_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
     /************** pci *****************/
 	if ((err = pci_enable_device(pdev)))	/* it trigers interrupt, dunno why. */
-		RET(err);			/* it's not a problem though */
+		goto err_pci;			/* it's not a problem though */
 
 	if (!(err = pci_set_dma_mask(pdev, DMA_64BIT_MASK)) &&
 	    !(err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))) {
@@ -2076,6 +2076,7 @@ err_out_res:
 	pci_release_regions(pdev);
 err_dma:
 	pci_disable_device(pdev);
+err_pci:
 	vfree(nic);
 
 	RET(err);
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 30b1cca..76efb3f 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -9034,7 +9034,7 @@ static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len)
 	int i;
 	u32 j;
 
-	for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) {
+	for (i = 0; i < ARRAY_SIZE(test_pattern); i++) {
 		for (j = 0; j < len; j += 4) {
 			u32 val;
 
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 9b9cd83..41f34bb 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -1041,7 +1041,7 @@ static struct InfoLeaf infoleaf_array[] = {
     {DC21142, dc21142_infoleaf},
     {DC21143, dc21143_infoleaf}
 };
-#define INFOLEAF_SIZE (sizeof(infoleaf_array)/(sizeof(int)+sizeof(int *)))
+#define INFOLEAF_SIZE ARRAY_SIZE(infoleaf_array)
 
 /*
 ** List the SROM info block functions
@@ -1056,7 +1056,7 @@ static int (*dc_infoblock[])(struct net_device *dev, u_char, u_char *) = {
     compact_infoblock
 };
 
-#define COMPACT (sizeof(dc_infoblock)/sizeof(int *) - 1)
+#define COMPACT (ARRAY_SIZE(dc_infoblock) - 1)
 
 /*
 ** Miscellaneous defines...
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index d00e7d4..bec413b 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -63,7 +63,7 @@
 #define UGETH_MSG_DEFAULT	(NETIF_MSG_IFUP << 1 ) - 1
 
 void uec_set_ethtool_ops(struct net_device *netdev);
-	
+
 static DEFINE_SPINLOCK(ugeth_lock);
 
 static struct {
@@ -3454,9 +3454,12 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
 	u16 length, howmany = 0;
 	u32 bd_status;
 	u8 *bdBuffer;
+	struct net_device * dev;
 
 	ugeth_vdbg("%s: IN", __FUNCTION__);
 
+	dev = ugeth->dev;
+
 	/* collect received buffers */
 	bd = ugeth->rxBd[rxQ];
 
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index b39a541..05df0a3 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -1342,11 +1342,11 @@ static int sdla_set_config(struct net_device *dev, struct ifmap *map)
 	if (flp->initialized)
 		return(-EINVAL);
 
-	for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++)
+	for(i=0; i < ARRAY_SIZE(valid_port); i++)
 		if (valid_port[i] == map->base_addr)
 			break;   
 
-	if (i == sizeof(valid_port) / sizeof(int))
+	if (i == ARRAY_SIZE(valid_port))
 		return(-EINVAL);
 
 	if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){
@@ -1487,12 +1487,12 @@ got_type:
 		}
 	}
 
-	for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++)
+	for(i=0; i < ARRAY_SIZE(valid_mem); i++)
 		if (valid_mem[i] == map->mem_start)
 			break;   
 
 	err = -EINVAL;
-	if (i == sizeof(valid_mem) / sizeof(int))
+	if (i == ARRAY_SIZE(valid_mem))
 		goto fail2;
 
 	if (flp->type == SDLA_S502A && (map->mem_start & 0xF000) >> 12 == 0x0E)
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
index f464b82..7fd505c 100644
--- a/drivers/net/xen-netfront.c
+++ b/drivers/net/xen-netfront.c
@@ -74,22 +74,12 @@ struct netfront_info {
 
 	struct napi_struct napi;
 
-	struct xen_netif_tx_front_ring tx;
-	struct xen_netif_rx_front_ring rx;
-
-	spinlock_t   tx_lock;
-	spinlock_t   rx_lock;
-
 	unsigned int evtchn;
+	struct xenbus_device *xbdev;
 
-	/* Receive-ring batched refills. */
-#define RX_MIN_TARGET 8
-#define RX_DFL_MIN_TARGET 64
-#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
-	unsigned rx_min_target, rx_max_target, rx_target;
-	struct sk_buff_head rx_batch;
-
-	struct timer_list rx_refill_timer;
+	spinlock_t   tx_lock;
+	struct xen_netif_tx_front_ring tx;
+	int tx_ring_ref;
 
 	/*
 	 * {tx,rx}_skbs store outstanding skbuffs. Free tx_skb entries
@@ -108,14 +98,23 @@ struct netfront_info {
 	grant_ref_t grant_tx_ref[NET_TX_RING_SIZE];
 	unsigned tx_skb_freelist;
 
+	spinlock_t   rx_lock ____cacheline_aligned_in_smp;
+	struct xen_netif_rx_front_ring rx;
+	int rx_ring_ref;
+
+	/* Receive-ring batched refills. */
+#define RX_MIN_TARGET 8
+#define RX_DFL_MIN_TARGET 64
+#define RX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256)
+	unsigned rx_min_target, rx_max_target, rx_target;
+	struct sk_buff_head rx_batch;
+
+	struct timer_list rx_refill_timer;
+
 	struct sk_buff *rx_skbs[NET_RX_RING_SIZE];
 	grant_ref_t gref_rx_head;
 	grant_ref_t grant_rx_ref[NET_RX_RING_SIZE];
 
-	struct xenbus_device *xbdev;
-	int tx_ring_ref;
-	int rx_ring_ref;
-
 	unsigned long rx_pfn_array[NET_RX_RING_SIZE];
 	struct multicall_entry rx_mcl[NET_RX_RING_SIZE+1];
 	struct mmu_update rx_mmu[NET_RX_RING_SIZE];
diff --git a/include/asm-mips/mach-au1x00/prom.h b/include/asm-mips/mach-au1x00/prom.h
new file mode 100644
index 0000000..e387155
--- /dev/null
+++ b/include/asm-mips/mach-au1x00/prom.h
@@ -0,0 +1,13 @@
+#ifndef __AU1X00_PROM_H
+#define __AU1X00_PROM_H
+
+extern int prom_argc;
+extern char **prom_argv;
+extern char **prom_envp;
+
+extern void prom_init_cmdline(void);
+extern char *prom_getcmdline(void);
+extern char *prom_getenv(char *envname);
+extern int prom_get_ethernet_addr(char *ethernet_addr);
+
+#endif
diff --git a/include/asm-powerpc/dcr-mmio.h b/include/asm-powerpc/dcr-mmio.h
index 6b82c3b..08532ff 100644
--- a/include/asm-powerpc/dcr-mmio.h
+++ b/include/asm-powerpc/dcr-mmio.h
@@ -33,16 +33,16 @@ typedef struct {
 
 extern dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
 			  unsigned int dcr_c);
-extern void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c);
+extern void dcr_unmap(dcr_host_t host, unsigned int dcr_c);
 
 static inline u32 dcr_read(dcr_host_t host, unsigned int dcr_n)
 {
-	return in_be32(host.token + dcr_n * host.stride);
+	return in_be32(host.token + ((host.base + dcr_n) * host.stride));
 }
 
 static inline void dcr_write(dcr_host_t host, unsigned int dcr_n, u32 value)
 {
-	out_be32(host.token + dcr_n * host.stride, value);
+	out_be32(host.token + ((host.base + dcr_n) * host.stride), value);
 }
 
 extern u64 of_translate_dcr_address(struct device_node *dev,
diff --git a/include/asm-powerpc/dcr-native.h b/include/asm-powerpc/dcr-native.h
index f41058c..8dbb1ab 100644
--- a/include/asm-powerpc/dcr-native.h
+++ b/include/asm-powerpc/dcr-native.h
@@ -29,9 +29,9 @@ typedef struct {
 #define DCR_MAP_OK(host)	(1)
 
 #define dcr_map(dev, dcr_n, dcr_c)	((dcr_host_t){ .base = (dcr_n) })
-#define dcr_unmap(host, dcr_n, dcr_c)	do {} while (0)
-#define dcr_read(host, dcr_n)		mfdcr(dcr_n)
-#define dcr_write(host, dcr_n, value)	mtdcr(dcr_n, value)
+#define dcr_unmap(host, dcr_c)		do {} while (0)
+#define dcr_read(host, dcr_n)		mfdcr(dcr_n + host.base)
+#define dcr_write(host, dcr_n, value)	mtdcr(dcr_n + host.base, value)
 
 /* Device Control Registers */
 void __mtdcr(int reg, unsigned int val);
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index a656cec..8101e8b 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1781,6 +1781,11 @@ static inline int skb_is_gso(const struct sk_buff *skb)
 	return skb_shinfo(skb)->gso_size;
 }
 
+static inline int skb_is_gso_v6(const struct sk_buff *skb)
+{
+	return skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6;
+}
+
 static inline void skb_forward_csum(struct sk_buff *skb)
 {
 	/* Unfortunately we don't support this one.  Any brave souls? */

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-10-10  1:03 Jeff Garzik
@ 2007-10-10  1:12 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2007-10-10  1:12 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Tue, 9 Oct 2007 21:03:26 -0400

> 
> Please pull from the 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem
> 
> to receive these changes:

Pulled and pushed back out, thanks Jeff!

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-10-10  1:03 Jeff Garzik
  2007-10-10  1:12 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2007-10-10  1:03 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


Please pull from the 'upstream-davem' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

to receive these changes:

Auke Kok (2):
      e1000e: Simple optimizations in e1000_xmit_frame
      e1000e: restore flow control settings properly

Jan-Bernd Themann (1):
      ehea: use kernel event queue

Krishna Kumar (1):
      e1000: Simple optimizations in e1000_xmit_frame

Mark Brown (1):
      natsemi: Use NATSEMI_TIMER_FREQ consistently

Roland Dreier (4):
      IPoIB: Fix unused variable warning
      ibm_emac: Convert to use napi_struct independent of struct net_device
      ibm_new_emac: Nuke SET_MODULE_OWNER() use
      ibm_emac: Convert to use napi_struct independent of struct net_device

Stephen Hemminger (4):
      s2io: sparse warnings fix (rev2)
      network drivers: sparse warning fixes
      chelsio: sparse warning fixes (old cxgb2)
      cxgb3 sparse warning fixes

 drivers/infiniband/ulp/ipoib/ipoib_main.c |    1 
 drivers/net/acenic.c                      |   37 +--
 drivers/net/atl1/atl1_main.c              |    5 
 drivers/net/chelsio/Makefile              |    2 
 drivers/net/chelsio/common.h              |    1 
 drivers/net/chelsio/mac.c                 |  368 ------------------------------
 drivers/net/chelsio/subr.c                |    2 
 drivers/net/cxgb3/cxgb3_main.c            |    4 
 drivers/net/cxgb3/cxgb3_offload.c         |   44 +--
 drivers/net/cxgb3/sge.c                   |    6 
 drivers/net/cxgb3/t3_hw.c                 |    8 
 drivers/net/cxgb3/xgmac.c                 |    2 
 drivers/net/dl2k.c                        |    8 
 drivers/net/e100.c                        |    2 
 drivers/net/e1000/e1000_main.c            |    9 
 drivers/net/e1000e/ethtool.c              |    1 
 drivers/net/e1000e/lib.c                  |   12 
 drivers/net/e1000e/netdev.c               |   10 
 drivers/net/ehea/ehea.h                   |    3 
 drivers/net/ehea/ehea_main.c              |   28 --
 drivers/net/ehea/ehea_qmr.c               |    3 
 drivers/net/hamachi.c                     |    3 
 drivers/net/ibm_emac/ibm_emac_mal.c       |   48 +--
 drivers/net/ibm_emac/ibm_emac_mal.h       |    2 
 drivers/net/ibm_newemac/core.c            |    1 
 drivers/net/ibm_newemac/mal.c             |   55 +---
 drivers/net/ibm_newemac/mal.h             |    2 
 drivers/net/natsemi.c                     |   10 
 drivers/net/s2io.c                        |   97 ++++---
 drivers/net/tehuti.c                      |    4 
 include/linux/netdevice.h                 |   10 
 31 files changed, 195 insertions(+), 593 deletions(-)

diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 6b1b4b2..855c9de 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -854,7 +854,6 @@ struct ipoib_neigh *ipoib_neigh_alloc(struct neighbour *neighbour)
 
 void ipoib_neigh_free(struct net_device *dev, struct ipoib_neigh *neigh)
 {
-	struct ipoib_dev_priv *priv = netdev_priv(dev);
 	struct sk_buff *skb;
 	*to_ipoib_neigh(neigh->neighbour) = NULL;
 	while ((skb = __skb_dequeue(&neigh->queue))) {
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 2c2ed6d..6c19265 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -406,7 +406,7 @@ MODULE_DEVICE_TABLE(pci, acenic_pci_tbl);
 #define DEF_STAT		(2 * TICKS_PER_SEC)
 
 
-static int link[ACE_MAX_MOD_PARMS];
+static int link_state[ACE_MAX_MOD_PARMS];
 static int trace[ACE_MAX_MOD_PARMS];
 static int tx_coal_tick[ACE_MAX_MOD_PARMS];
 static int rx_coal_tick[ACE_MAX_MOD_PARMS];
@@ -419,7 +419,7 @@ MODULE_AUTHOR("Jes Sorensen <jes@trained-monkey.org>");
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("AceNIC/3C985/GA620 Gigabit Ethernet driver");
 
-module_param_array(link, int, NULL, 0);
+module_param_array_named(link, link_state, int, NULL, 0);
 module_param_array(trace, int, NULL, 0);
 module_param_array(tx_coal_tick, int, NULL, 0);
 module_param_array(max_tx_desc, int, NULL, 0);
@@ -987,27 +987,27 @@ static int __devinit ace_init(struct net_device *dev)
 
 	mac1 = 0;
 	for(i = 0; i < 4; i++) {
-		int tmp;
+		int t;
 
 		mac1 = mac1 << 8;
-		tmp = read_eeprom_byte(dev, 0x8c+i);
-		if (tmp < 0) {
+		t = read_eeprom_byte(dev, 0x8c+i);
+		if (t < 0) {
 			ecode = -EIO;
 			goto init_error;
 		} else
-			mac1 |= (tmp & 0xff);
+			mac1 |= (t & 0xff);
 	}
 	mac2 = 0;
 	for(i = 4; i < 8; i++) {
-		int tmp;
+		int t;
 
 		mac2 = mac2 << 8;
-		tmp = read_eeprom_byte(dev, 0x8c+i);
-		if (tmp < 0) {
+		t = read_eeprom_byte(dev, 0x8c+i);
+		if (t < 0) {
 			ecode = -EIO;
 			goto init_error;
 		} else
-			mac2 |= (tmp & 0xff);
+			mac2 |= (t & 0xff);
 	}
 
 	writel(mac1, &regs->MacAddrHi);
@@ -1305,10 +1305,10 @@ static int __devinit ace_init(struct net_device *dev)
 	writel(TX_RING_BASE, &regs->WinBase);
 
 	if (ACE_IS_TIGON_I(ap)) {
-		ap->tx_ring = (struct tx_desc *) regs->Window;
+		ap->tx_ring = (__force struct tx_desc *) regs->Window;
 		for (i = 0; i < (TIGON_I_TX_RING_ENTRIES
 				 * sizeof(struct tx_desc)) / sizeof(u32); i++)
-			writel(0, (void __iomem *)ap->tx_ring  + i * 4);
+			writel(0, (__force void __iomem *)ap->tx_ring  + i * 4);
 
 		set_aceaddr(&info->tx_ctrl.rngptr, TX_RING_BASE);
 	} else {
@@ -1394,8 +1394,8 @@ static int __devinit ace_init(struct net_device *dev)
 	/*
 	 * Override link default parameters
 	 */
-	if ((board_idx >= 0) && link[board_idx]) {
-		int option = link[board_idx];
+	if ((board_idx >= 0) && link_state[board_idx]) {
+		int option = link_state[board_idx];
 
 		tmp = LNK_ENABLE;
 
@@ -2383,8 +2383,9 @@ static int ace_close(struct net_device *dev)
 
 		if (mapping) {
 			if (ACE_IS_TIGON_I(ap)) {
-				struct tx_desc __iomem *tx
-					= (struct tx_desc __iomem *) &ap->tx_ring[i];
+				/* NB: TIGON_1 is special, tx_ring is in io space */
+				struct tx_desc __iomem *tx;
+				tx = (__force struct tx_desc __iomem *) &ap->tx_ring[i];
 				writel(0, &tx->addr.addrhi);
 				writel(0, &tx->addr.addrlo);
 				writel(0, &tx->flagsize);
@@ -2444,7 +2445,7 @@ ace_load_tx_bd(struct ace_private *ap, struct tx_desc *desc, u64 addr,
 #endif
 
 	if (ACE_IS_TIGON_I(ap)) {
-		struct tx_desc __iomem *io = (struct tx_desc __iomem *) desc;
+		struct tx_desc __iomem *io = (__force struct tx_desc __iomem *) desc;
 		writel(addr >> 32, &io->addr.addrhi);
 		writel(addr & 0xffffffff, &io->addr.addrlo);
 		writel(flagsize, &io->flagsize);
@@ -2936,7 +2937,7 @@ static void __devinit ace_clear(struct ace_regs __iomem *regs, u32 dest, int siz
  * This operation requires the NIC to be halted and is performed with
  * interrupts disabled and with the spinlock hold.
  */
-int __devinit ace_load_firmware(struct net_device *dev)
+static int __devinit ace_load_firmware(struct net_device *dev)
 {
 	struct ace_private *ap = netdev_priv(dev);
 	struct ace_regs __iomem *regs = ap->regs;
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 4c728f1..35b0a7d 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -1367,7 +1367,6 @@ rrd_ok:
 	if (count) {
 		u32 tpd_next_to_use;
 		u32 rfd_next_to_use;
-		u32 rrd_next_to_clean;
 
 		spin_lock(&adapter->mb_lock);
 
@@ -1512,7 +1511,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
 	unsigned int f;
 	u16 tpd_next_to_use;
 	u16 proto_hdr_len;
-	u16 i, m, len12;
+	u16 len12;
 
 	first_buf_len -= skb->data_len;
 	nr_frags = skb_shinfo(skb)->nr_frags;
@@ -1536,6 +1535,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
 			tpd_next_to_use = 0;
 
 		if (first_buf_len > proto_hdr_len) {
+			int i, m;
+
 			len12 = first_buf_len - proto_hdr_len;
 			m = (len12 + ATL1_MAX_TX_BUF_LEN - 1) /
 				ATL1_MAX_TX_BUF_LEN;
diff --git a/drivers/net/chelsio/Makefile b/drivers/net/chelsio/Makefile
index 743ad8b..57a4b26 100644
--- a/drivers/net/chelsio/Makefile
+++ b/drivers/net/chelsio/Makefile
@@ -4,6 +4,6 @@
 
 obj-$(CONFIG_CHELSIO_T1) += cxgb.o
 
-cxgb-$(CONFIG_CHELSIO_T1_1G) += mac.o mv88e1xxx.o vsc7326.o
+cxgb-$(CONFIG_CHELSIO_T1_1G) += mv88e1xxx.o vsc7326.o
 cxgb-objs := cxgb2.o espi.o tp.o pm3393.o sge.o subr.o \
 	     mv88x201x.o my3126.o $(cxgb-y)
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
index b5de445..846ca53 100644
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -372,6 +372,7 @@ extern void t1_interrupts_enable(adapter_t *adapter);
 extern void t1_interrupts_disable(adapter_t *adapter);
 extern void t1_interrupts_clear(adapter_t *adapter);
 extern int t1_elmer0_ext_intr_handler(adapter_t *adapter);
+extern void t1_elmer0_ext_intr(adapter_t *adapter);
 extern int t1_slow_intr_handler(adapter_t *adapter);
 
 extern int t1_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc);
diff --git a/drivers/net/chelsio/mac.c b/drivers/net/chelsio/mac.c
deleted file mode 100644
index 1d97282..0000000
--- a/drivers/net/chelsio/mac.c
+++ /dev/null
@@ -1,368 +0,0 @@
-/* $Date: 2005/10/22 00:42:59 $ $RCSfile: mac.c,v $ $Revision: 1.32 $ */
-#include "gmac.h"
-#include "regs.h"
-#include "fpga_defs.h"
-
-#define MAC_CSR_INTERFACE_GMII      0x0
-#define MAC_CSR_INTERFACE_TBI       0x1
-#define MAC_CSR_INTERFACE_MII       0x2
-#define MAC_CSR_INTERFACE_RMII      0x3
-
-/* Chelsio's MAC statistics. */
-struct mac_statistics {
-
-	/* Transmit */
-	u32 TxFramesTransmittedOK;
-	u32 TxReserved1;
-	u32 TxReserved2;
-	u32 TxOctetsTransmittedOK;
-	u32 TxFramesWithDeferredXmissions;
-	u32 TxLateCollisions;
-	u32 TxFramesAbortedDueToXSCollisions;
-	u32 TxFramesLostDueToIntMACXmitError;
-	u32 TxReserved3;
-	u32 TxMulticastFrameXmittedOK;
-	u32 TxBroadcastFramesXmittedOK;
-	u32 TxFramesWithExcessiveDeferral;
-	u32 TxPAUSEMACCtrlFramesTransmitted;
-
-	/* Receive */
-	u32 RxFramesReceivedOK;
-	u32 RxFrameCheckSequenceErrors;
-	u32 RxAlignmentErrors;
-	u32 RxOctetsReceivedOK;
-	u32 RxFramesLostDueToIntMACRcvError;
-	u32 RxMulticastFramesReceivedOK;
-	u32 RxBroadcastFramesReceivedOK;
-	u32 RxInRangeLengthErrors;
-	u32 RxTxOutOfRangeLengthField;
-	u32 RxFrameTooLongErrors;
-	u32 RxPAUSEMACCtrlFramesReceived;
-};
-
-static int static_aPorts[] = {
-	FPGA_GMAC_INTERRUPT_PORT0,
-	FPGA_GMAC_INTERRUPT_PORT1,
-	FPGA_GMAC_INTERRUPT_PORT2,
-	FPGA_GMAC_INTERRUPT_PORT3
-};
-
-struct _cmac_instance {
-	u32 index;
-};
-
-static int mac_intr_enable(struct cmac *mac)
-{
-	u32 mac_intr;
-
-	if (t1_is_asic(mac->adapter)) {
-		/* ASIC */
-
-		/* We don't use the on chip MAC for ASIC products. */
-	} else {
-		/* FPGA */
-
-		/* Set parent gmac interrupt. */
-		mac_intr = readl(mac->adapter->regs + A_PL_ENABLE);
-		mac_intr |= FPGA_PCIX_INTERRUPT_GMAC;
-		writel(mac_intr, mac->adapter->regs + A_PL_ENABLE);
-
-		mac_intr = readl(mac->adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_ENABLE);
-		mac_intr |= static_aPorts[mac->instance->index];
-		writel(mac_intr,
-		       mac->adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_ENABLE);
-	}
-
-	return 0;
-}
-
-static int mac_intr_disable(struct cmac *mac)
-{
-	u32 mac_intr;
-
-	if (t1_is_asic(mac->adapter)) {
-		/* ASIC */
-
-		/* We don't use the on chip MAC for ASIC products. */
-	} else {
-		/* FPGA */
-
-		/* Set parent gmac interrupt. */
-		mac_intr = readl(mac->adapter->regs + A_PL_ENABLE);
-		mac_intr &= ~FPGA_PCIX_INTERRUPT_GMAC;
-		writel(mac_intr, mac->adapter->regs + A_PL_ENABLE);
-
-		mac_intr = readl(mac->adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_ENABLE);
-		mac_intr &= ~(static_aPorts[mac->instance->index]);
-		writel(mac_intr,
-		       mac->adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_ENABLE);
-	}
-
-	return 0;
-}
-
-static int mac_intr_clear(struct cmac *mac)
-{
-	u32 mac_intr;
-
-	if (t1_is_asic(mac->adapter)) {
-		/* ASIC */
-
-		/* We don't use the on chip MAC for ASIC products. */
-	} else {
-		/* FPGA */
-
-		/* Set parent gmac interrupt. */
-		writel(FPGA_PCIX_INTERRUPT_GMAC,
-		       mac->adapter->regs +  A_PL_CAUSE);
-		mac_intr = readl(mac->adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_CAUSE);
-		mac_intr |= (static_aPorts[mac->instance->index]);
-		writel(mac_intr,
-		       mac->adapter->regs + FPGA_GMAC_ADDR_INTERRUPT_CAUSE);
-	}
-
-	return 0;
-}
-
-static int mac_get_address(struct cmac *mac, u8 addr[6])
-{
-	u32 data32_lo, data32_hi;
-
-	data32_lo = readl(mac->adapter->regs
-			  + MAC_REG_IDLO(mac->instance->index));
-	data32_hi = readl(mac->adapter->regs
-			  + MAC_REG_IDHI(mac->instance->index));
-
-	addr[0] = (u8) ((data32_hi >> 8) & 0xFF);
-	addr[1] = (u8) ((data32_hi) & 0xFF);
-	addr[2] = (u8) ((data32_lo >> 24) & 0xFF);
-	addr[3] = (u8) ((data32_lo >> 16) & 0xFF);
-	addr[4] = (u8) ((data32_lo >> 8) & 0xFF);
-	addr[5] = (u8) ((data32_lo) & 0xFF);
-	return 0;
-}
-
-static int mac_reset(struct cmac *mac)
-{
-	u32 data32;
-	int mac_in_reset, time_out = 100;
-	int idx = mac->instance->index;
-
-	data32 = readl(mac->adapter->regs + MAC_REG_CSR(idx));
-	writel(data32 | F_MAC_RESET,
-	       mac->adapter->regs + MAC_REG_CSR(idx));
-
-	do {
-		data32 = readl(mac->adapter->regs + MAC_REG_CSR(idx));
-
-		mac_in_reset = data32 & F_MAC_RESET;
-		if (mac_in_reset)
-			udelay(1);
-	} while (mac_in_reset && --time_out);
-
-	if (mac_in_reset) {
-		CH_ERR("%s: MAC %d reset timed out\n",
-		       mac->adapter->name, idx);
-		return 2;
-	}
-
-	return 0;
-}
-
-static int mac_set_rx_mode(struct cmac *mac, struct t1_rx_mode *rm)
-{
-	u32 val;
-
-	val = readl(mac->adapter->regs
-			    + MAC_REG_CSR(mac->instance->index));
-	val &= ~(F_MAC_PROMISC | F_MAC_MC_ENABLE);
-	val |= V_MAC_PROMISC(t1_rx_mode_promisc(rm) != 0);
-	val |= V_MAC_MC_ENABLE(t1_rx_mode_allmulti(rm) != 0);
-	writel(val,
-	       mac->adapter->regs + MAC_REG_CSR(mac->instance->index));
-
-	return 0;
-}
-
-static int mac_set_speed_duplex_fc(struct cmac *mac, int speed, int duplex,
-				   int fc)
-{
-	u32 data32;
-
-	data32 = readl(mac->adapter->regs
-			       + MAC_REG_CSR(mac->instance->index));
-	data32 &= ~(F_MAC_HALF_DUPLEX | V_MAC_SPEED(M_MAC_SPEED) |
-		V_INTERFACE(M_INTERFACE) | F_MAC_TX_PAUSE_ENABLE |
-		F_MAC_RX_PAUSE_ENABLE);
-
-	switch (speed) {
-	case SPEED_10:
-	case SPEED_100:
-		data32 |= V_INTERFACE(MAC_CSR_INTERFACE_MII);
-		data32 |= V_MAC_SPEED(speed == SPEED_10 ? 0 : 1);
-		break;
-	case SPEED_1000:
-		data32 |= V_INTERFACE(MAC_CSR_INTERFACE_GMII);
-		data32 |= V_MAC_SPEED(2);
-		break;
-	}
-
-	if (duplex >= 0)
-		data32 |= V_MAC_HALF_DUPLEX(duplex == DUPLEX_HALF);
-
-	if (fc >= 0) {
-		data32 |= V_MAC_RX_PAUSE_ENABLE((fc & PAUSE_RX) != 0);
-		data32 |= V_MAC_TX_PAUSE_ENABLE((fc & PAUSE_TX) != 0);
-	}
-
-	writel(data32,
-	       mac->adapter->regs + MAC_REG_CSR(mac->instance->index));
-	return 0;
-}
-
-static int mac_enable(struct cmac *mac, int which)
-{
-	u32 val;
-
-	val = readl(mac->adapter->regs
-			    + MAC_REG_CSR(mac->instance->index));
-	if (which & MAC_DIRECTION_RX)
-		val |= F_MAC_RX_ENABLE;
-	if (which & MAC_DIRECTION_TX)
-		val |= F_MAC_TX_ENABLE;
-	writel(val,
-	       mac->adapter->regs + MAC_REG_CSR(mac->instance->index));
-	return 0;
-}
-
-static int mac_disable(struct cmac *mac, int which)
-{
-	u32 val;
-
-	val = readl(mac->adapter->regs
-			    + MAC_REG_CSR(mac->instance->index));
-	if (which & MAC_DIRECTION_RX)
-		val &= ~F_MAC_RX_ENABLE;
-	if (which & MAC_DIRECTION_TX)
-		val &= ~F_MAC_TX_ENABLE;
-	writel(val,
-	       mac->adapter->regs + MAC_REG_CSR(mac->instance->index));
-	return 0;
-}
-
-#if 0
-static int mac_set_ifs(struct cmac *mac, u32 mode)
-{
-	t1_write_reg_4(mac->adapter,
-		       MAC_REG_IFS(mac->instance->index),
-		       mode);
-	return 0;
-}
-
-static int mac_enable_isl(struct cmac *mac)
-{
-	u32 data32 = readl(mac->adapter->regs
-				   + MAC_REG_CSR(mac->instance->index));
-	data32 |= F_MAC_RX_ENABLE | F_MAC_TX_ENABLE;
-	t1_write_reg_4(mac->adapter,
-		       MAC_REG_CSR(mac->instance->index),
-		       data32);
-	return 0;
-}
-#endif
-
-static int mac_set_mtu(struct cmac *mac, int mtu)
-{
-	if (mtu > 9600)
-		return -EINVAL;
-	writel(mtu + ETH_HLEN + VLAN_HLEN,
-	       mac->adapter->regs + MAC_REG_LARGEFRAMELENGTH(mac->instance->index));
-
-	return 0;
-}
-
-static const struct cmac_statistics *mac_update_statistics(struct cmac *mac,
-							   int flag)
-{
-	struct mac_statistics st;
-	u32 *p = (u32 *) & st, i;
-
-	writel(0,
-	       mac->adapter->regs + MAC_REG_RMCNT(mac->instance->index));
-
-	for (i = 0; i < sizeof(st) / sizeof(u32); i++)
-		*p++ = readl(mac->adapter->regs
-			     + MAC_REG_RMDATA(mac->instance->index));
-
-	/* XXX convert stats */
-	return &mac->stats;
-}
-
-static void mac_destroy(struct cmac *mac)
-{
-	kfree(mac);
-}
-
-static struct cmac_ops chelsio_mac_ops = {
-	.destroy                 = mac_destroy,
-	.reset                   = mac_reset,
-	.interrupt_enable        = mac_intr_enable,
-	.interrupt_disable       = mac_intr_disable,
-	.interrupt_clear         = mac_intr_clear,
-	.enable                  = mac_enable,
-	.disable                 = mac_disable,
-	.set_mtu                 = mac_set_mtu,
-	.set_rx_mode             = mac_set_rx_mode,
-	.set_speed_duplex_fc     = mac_set_speed_duplex_fc,
-	.macaddress_get          = mac_get_address,
-	.statistics_update       = mac_update_statistics,
-};
-
-static struct cmac *mac_create(adapter_t *adapter, int index)
-{
-	struct cmac *mac;
-	u32 data32;
-
-	if (index >= 4)
-		return NULL;
-
-	mac = kzalloc(sizeof(*mac) + sizeof(cmac_instance), GFP_KERNEL);
-	if (!mac)
-		return NULL;
-
-	mac->ops = &chelsio_mac_ops;
-	mac->instance = (cmac_instance *) (mac + 1);
-
-	mac->instance->index = index;
-	mac->adapter = adapter;
-
-	data32 = readl(adapter->regs + MAC_REG_CSR(mac->instance->index));
-	data32 &= ~(F_MAC_RESET | F_MAC_PROMISC | F_MAC_PROMISC |
-		    F_MAC_LB_ENABLE | F_MAC_RX_ENABLE | F_MAC_TX_ENABLE);
-	data32 |= F_MAC_JUMBO_ENABLE;
-	writel(data32, adapter->regs + MAC_REG_CSR(mac->instance->index));
-
-	/* Initialize the random backoff seed. */
-	data32 = 0x55aa + (3 * index);
-	writel(data32,
-	       adapter->regs + MAC_REG_GMRANDBACKOFFSEED(mac->instance->index));
-
-	/* Check to see if the mac address needs to be set manually. */
-	data32 = readl(adapter->regs + MAC_REG_IDLO(mac->instance->index));
-	if (data32 == 0 || data32 == 0xffffffff) {
-		/*
-		 * Add a default MAC address if we can't read one.
-		 */
-		writel(0x43FFFFFF - index,
-		       adapter->regs + MAC_REG_IDLO(mac->instance->index));
-		writel(0x0007,
-		       adapter->regs + MAC_REG_IDHI(mac->instance->index));
-	}
-
-	(void) mac_set_mtu(mac, 1500);
-	return mac;
-}
-
-const struct gmac t1_chelsio_mac_ops = {
-	.create = mac_create
-};
diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c
index 7de9a61..dc50151 100644
--- a/drivers/net/chelsio/subr.c
+++ b/drivers/net/chelsio/subr.c
@@ -884,7 +884,7 @@ static int asic_slow_intr(adapter_t *adapter)
 	if (cause & F_PL_INTR_PCIX)
 		t1_pci_intr_handler(adapter);
 	if (cause & F_PL_INTR_EXT)
-		t1_elmer0_ext_intr_handler(adapter);
+		t1_elmer0_ext_intr(adapter);
 
 	/* Clear the interrupts just processed. */
 	writel(cause, adapter->regs + A_PL_CAUSE);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index e22d065..61ffc92 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -740,7 +740,7 @@ static inline char t3rev2char(struct adapter *adapter)
 	return rev;
 }
 
-int update_tpsram(struct adapter *adap)
+static int update_tpsram(struct adapter *adap)
 {
 	const struct firmware *tpsram;
 	char buf[64];
@@ -1769,7 +1769,6 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
 	}
 	case CHELSIO_SET_QSET_NUM:{
 		struct ch_reg edata;
-		struct port_info *pi = netdev_priv(dev);
 		unsigned int i, first_qset = 0, other_qsets = 0;
 
 		if (!capable(CAP_NET_ADMIN))
@@ -1801,7 +1800,6 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
 	}
 	case CHELSIO_GET_QSET_NUM:{
 		struct ch_reg edata;
-		struct port_info *pi = netdev_priv(dev);
 
 		edata.cmd = CHELSIO_GET_QSET_NUM;
 		edata.val = pi->nqsets;
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index 1c8eec3..bd25421 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -222,32 +222,32 @@ static int cxgb_rdma_ctl(struct adapter *adapter, unsigned int req, void *data)
 	int ret = 0;
 
 	switch (req) {
-	case RDMA_GET_PARAMS:{
-		struct rdma_info *req = data;
+	case RDMA_GET_PARAMS: {
+		struct rdma_info *rdma = data;
 		struct pci_dev *pdev = adapter->pdev;
 
-		req->udbell_physbase = pci_resource_start(pdev, 2);
-		req->udbell_len = pci_resource_len(pdev, 2);
-		req->tpt_base =
+		rdma->udbell_physbase = pci_resource_start(pdev, 2);
+		rdma->udbell_len = pci_resource_len(pdev, 2);
+		rdma->tpt_base =
 			t3_read_reg(adapter, A_ULPTX_TPT_LLIMIT);
-		req->tpt_top = t3_read_reg(adapter, A_ULPTX_TPT_ULIMIT);
-		req->pbl_base =
+		rdma->tpt_top = t3_read_reg(adapter, A_ULPTX_TPT_ULIMIT);
+		rdma->pbl_base =
 			t3_read_reg(adapter, A_ULPTX_PBL_LLIMIT);
-		req->pbl_top = t3_read_reg(adapter, A_ULPTX_PBL_ULIMIT);
-		req->rqt_base = t3_read_reg(adapter, A_ULPRX_RQ_LLIMIT);
-		req->rqt_top = t3_read_reg(adapter, A_ULPRX_RQ_ULIMIT);
-		req->kdb_addr = adapter->regs + A_SG_KDOORBELL;
-		req->pdev = pdev;
+		rdma->pbl_top = t3_read_reg(adapter, A_ULPTX_PBL_ULIMIT);
+		rdma->rqt_base = t3_read_reg(adapter, A_ULPRX_RQ_LLIMIT);
+		rdma->rqt_top = t3_read_reg(adapter, A_ULPRX_RQ_ULIMIT);
+		rdma->kdb_addr = adapter->regs + A_SG_KDOORBELL;
+		rdma->pdev = pdev;
 		break;
 	}
 	case RDMA_CQ_OP:{
 		unsigned long flags;
-		struct rdma_cq_op *req = data;
+		struct rdma_cq_op *rdma = data;
 
 		/* may be called in any context */
 		spin_lock_irqsave(&adapter->sge.reg_lock, flags);
-		ret = t3_sge_cqcntxt_op(adapter, req->id, req->op,
-					req->credits);
+		ret = t3_sge_cqcntxt_op(adapter, rdma->id, rdma->op,
+					rdma->credits);
 		spin_unlock_irqrestore(&adapter->sge.reg_lock, flags);
 		break;
 	}
@@ -274,15 +274,15 @@ static int cxgb_rdma_ctl(struct adapter *adapter, unsigned int req, void *data)
 		break;
 	}
 	case RDMA_CQ_SETUP:{
-		struct rdma_cq_setup *req = data;
+		struct rdma_cq_setup *rdma = data;
 
 		spin_lock_irq(&adapter->sge.reg_lock);
 		ret =
-			t3_sge_init_cqcntxt(adapter, req->id,
-					req->base_addr, req->size,
+			t3_sge_init_cqcntxt(adapter, rdma->id,
+					rdma->base_addr, rdma->size,
 					ASYNC_NOTIF_RSPQ,
-					req->ovfl_mode, req->credits,
-					req->credit_thres);
+					rdma->ovfl_mode, rdma->credits,
+					rdma->credit_thres);
 		spin_unlock_irq(&adapter->sge.reg_lock);
 		break;
 	}
@@ -292,13 +292,13 @@ static int cxgb_rdma_ctl(struct adapter *adapter, unsigned int req, void *data)
 		spin_unlock_irq(&adapter->sge.reg_lock);
 		break;
 	case RDMA_CTRL_QP_SETUP:{
-		struct rdma_ctrlqp_setup *req = data;
+		struct rdma_ctrlqp_setup *rdma = data;
 
 		spin_lock_irq(&adapter->sge.reg_lock);
 		ret = t3_sge_init_ecntxt(adapter, FW_RI_SGEEC_START, 0,
 						SGE_CNTXT_RDMA,
 						ASYNC_NOTIF_RSPQ,
-						req->base_addr, req->size,
+						rdma->base_addr, rdma->size,
 						FW_RI_TID_START, 1, 0);
 		spin_unlock_irq(&adapter->sge.reg_lock);
 		break;
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 77f3ec5..994b5d6 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -544,7 +544,7 @@ static void *alloc_ring(struct pci_dev *pdev, size_t nelem, size_t elem_size,
  *	as HW contexts, packet buffers, and descriptor rings.  Traffic to the
  *	queue set must be quiesced prior to calling this.
  */
-void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
+static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
 {
 	int i;
 	struct pci_dev *pdev = adapter->pdev;
@@ -2215,7 +2215,7 @@ irqreturn_t t3_sge_intr_msix(int irq, void *cookie)
  * The MSI-X interrupt handler for an SGE response queue for the NAPI case
  * (i.e., response queue serviced by NAPI polling).
  */
-irqreturn_t t3_sge_intr_msix_napi(int irq, void *cookie)
+static irqreturn_t t3_sge_intr_msix_napi(int irq, void *cookie)
 {
 	struct sge_qset *qs = cookie;
 	struct sge_rspq *q = &qs->rspq;
@@ -2284,7 +2284,7 @@ static int rspq_check_napi(struct sge_qset *qs)
  * one SGE response queue per port in this mode and protect all response
  * queues with queue 0's lock.
  */
-irqreturn_t t3_intr_msi_napi(int irq, void *cookie)
+static irqreturn_t t3_intr_msi_napi(int irq, void *cookie)
 {
 	int new_packets;
 	struct adapter *adap = cookie;
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c
index 0583293..d4ee00d 100644
--- a/drivers/net/cxgb3/t3_hw.c
+++ b/drivers/net/cxgb3/t3_hw.c
@@ -119,9 +119,9 @@ void t3_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask,
  *	Reads registers that are accessed indirectly through an address/data
  *	register pair.
  */
-void t3_read_indirect(struct adapter *adap, unsigned int addr_reg,
-		      unsigned int data_reg, u32 *vals, unsigned int nregs,
-		      unsigned int start_idx)
+static void t3_read_indirect(struct adapter *adap, unsigned int addr_reg,
+			     unsigned int data_reg, u32 *vals,
+			     unsigned int nregs, unsigned int start_idx)
 {
 	while (nregs--) {
 		t3_write_reg(adap, addr_reg, start_idx);
@@ -3407,7 +3407,7 @@ void early_hw_init(struct adapter *adapter, const struct adapter_info *ai)
  * Older PCIe cards lose their config space during reset, PCI-X
  * ones don't.
  */
-int t3_reset_adapter(struct adapter *adapter)
+static int t3_reset_adapter(struct adapter *adapter)
 {
 	int i, save_and_restore_pcie = 
 	    adapter->params.rev < T3_REV_B2 && is_pcie(adapter);
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index bcb5bc4..eeb766a 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -142,7 +142,7 @@ int t3_mac_reset(struct cmac *mac)
 	return 0;
 }
 
-int t3b2_mac_reset(struct cmac *mac)
+static int t3b2_mac_reset(struct cmac *mac)
 {
 	struct adapter *adap = mac->adapter;
 	unsigned int oft = mac->offset;
diff --git a/drivers/net/dl2k.c b/drivers/net/dl2k.c
index e91b709..5066beb 100644
--- a/drivers/net/dl2k.c
+++ b/drivers/net/dl2k.c
@@ -290,7 +290,7 @@ rio_probe1 (struct pci_dev *pdev, const struct pci_device_id *ent)
 	return err;
 }
 
-int
+static int
 find_miiphy (struct net_device *dev)
 {
 	int i, phy_found = 0;
@@ -314,7 +314,7 @@ find_miiphy (struct net_device *dev)
 	return 0;
 }
 
-int
+static int
 parse_eeprom (struct net_device *dev)
 {
 	int i, j;
@@ -1096,7 +1096,7 @@ clear_stats (struct net_device *dev)
 }
 
 
-int
+static int
 change_mtu (struct net_device *dev, int new_mtu)
 {
 	struct netdev_private *np = netdev_priv(dev);
@@ -1331,7 +1331,7 @@ rio_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
 #define EEP_BUSY 0x8000
 /* Read the EEPROM word */
 /* We use I/O instruction to read/write eeprom to avoid fail on some machines */
-int
+static int
 read_eeprom (long ioaddr, int eep_addr)
 {
 	int i = 1000;
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 7bd9604..64f35e2 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1990,7 +1990,7 @@ static int e100_poll(struct napi_struct *napi, int budget)
 {
 	struct nic *nic = container_of(napi, struct nic, napi);
 	struct net_device *netdev = nic->netdev;
-	int work_done = 0;
+	unsigned int work_done = 0;
 	int tx_cleaned;
 
 	e100_rx_clean(nic, &work_done, budget);
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 10505de..0472638 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3261,14 +3261,13 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
 	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
 	unsigned int tx_flags = 0;
-	unsigned int len = skb->len;
+	unsigned int len = skb->len - skb->data_len;
 	unsigned long flags;
-	unsigned int nr_frags = 0;
-	unsigned int mss = 0;
+	unsigned int nr_frags;
+	unsigned int mss;
 	int count = 0;
 	int tso;
 	unsigned int f;
-	len -= skb->data_len;
 
 	/* This goes back to the question of how to logically map a tx queue
 	 * to a flow.  Right now, performance is impacted slightly negatively
@@ -3302,7 +3301,7 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		* points to just header, pull a few bytes of payload from
 		* frags into skb->data */
 		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-		if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) {
+		if (skb->data_len && hdr_len == len) {
 			switch (adapter->hw.mac_type) {
 				unsigned int pull_size;
 			case e1000_82544:
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 2e8218f..b7a7e2a 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -301,6 +301,7 @@ static int e1000_set_pauseparam(struct net_device *netdev,
 	hw->mac.original_fc = hw->mac.fc;
 
 	if (adapter->fc_autoneg == AUTONEG_ENABLE) {
+		hw->mac.fc = e1000_fc_default;
 		if (netif_running(adapter->netdev)) {
 			e1000e_down(adapter);
 			e1000e_up(adapter);
diff --git a/drivers/net/e1000e/lib.c b/drivers/net/e1000e/lib.c
index 3bbfe60..0bdeca3 100644
--- a/drivers/net/e1000e/lib.c
+++ b/drivers/net/e1000e/lib.c
@@ -639,9 +639,15 @@ s32 e1000e_setup_link(struct e1000_hw *hw)
 	if (e1000_check_reset_block(hw))
 		return 0;
 
-	ret_val = e1000_set_default_fc_generic(hw);
-	if (ret_val)
-		return ret_val;
+	/*
+	 * If flow control is set to default, set flow control based on
+	 * the EEPROM flow control settings.
+	 */
+	if (mac->fc == e1000_fc_default) {
+		ret_val = e1000_set_default_fc_generic(hw);
+		if (ret_val)
+			return ret_val;
+	}
 
 	/* We want to save off the original Flow Control configuration just
 	 * in case we get disconnected and then reconnected into a different
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 3a0bb2a..033e124 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -3424,14 +3424,13 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	unsigned int max_per_txd = E1000_MAX_PER_TXD;
 	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
 	unsigned int tx_flags = 0;
-	unsigned int len = skb->len;
+	unsigned int len = skb->len - skb->data_len;
 	unsigned long irq_flags;
-	unsigned int nr_frags = 0;
-	unsigned int mss = 0;
+	unsigned int nr_frags;
+	unsigned int mss;
 	int count = 0;
 	int tso;
 	unsigned int f;
-	len -= skb->data_len;
 
 	if (test_bit(__E1000_DOWN, &adapter->state)) {
 		dev_kfree_skb_any(skb);
@@ -3459,7 +3458,7 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		* points to just header, pull a few bytes of payload from
 		* frags into skb->data */
 		hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
-		if (skb->data_len && (hdr_len == (skb->len - skb->data_len))) {
+		if (skb->data_len && (hdr_len == len)) {
 			unsigned int pull_size;
 
 			pull_size = min((unsigned int)4, skb->data_len);
@@ -4196,6 +4195,7 @@ static int __devinit e1000_probe(struct pci_dev *pdev,
 
 	/* Initialize link parameters. User can change them with ethtool */
 	adapter->hw.mac.autoneg = 1;
+	adapter->fc_autoneg = 1;
 	adapter->hw.mac.original_fc = e1000_fc_default;
 	adapter->hw.mac.fc = e1000_fc_default;
 	adapter->hw.phy.autoneg_advertised = 0x2f;
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 3022089..ac21526 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0077"
+#define DRV_VERSION	"EHEA_0078"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
@@ -391,7 +391,6 @@ struct ehea_adapter {
 	struct ibmebus_dev *ebus_dev;
 	struct ehea_port *port[EHEA_MAX_PORTS];
 	struct ehea_eq *neq;       /* notification event queue */
-	struct workqueue_struct *ehea_wq;
 	struct tasklet_struct neq_tasklet;
 	struct ehea_mr mr;
 	u32 pd;                    /* protection domain */
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 5bc0a15..2ba57e6 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -94,7 +94,6 @@ MODULE_PARM_DESC(use_lro, " Large Receive Offload, 1: enable, 0: disable, "
 static int port_name_cnt = 0;
 static LIST_HEAD(adapter_list);
 u64 ehea_driver_flags = 0;
-struct workqueue_struct *ehea_driver_wq;
 struct work_struct ehea_rereg_mr_task;
 
 struct semaphore dlpar_mem_lock;
@@ -421,7 +420,7 @@ static int ehea_treat_poll_error(struct ehea_port_res *pr, int rq,
 
 	if (cqe->status & EHEA_CQE_STAT_FAT_ERR_MASK) {
 		ehea_error("Critical receive error. Resetting port.");
-		queue_work(pr->port->adapter->ehea_wq, &pr->port->reset_task);
+		schedule_work(&pr->port->reset_task);
 		return 1;
 	}
 
@@ -596,8 +595,7 @@ static struct ehea_cqe *ehea_proc_cqes(struct ehea_port_res *pr, int my_quota)
 			ehea_error("Send Completion Error: Resetting port");
 			if (netif_msg_tx_err(pr->port))
 				ehea_dump(cqe, sizeof(*cqe), "Send CQE");
-			queue_work(pr->port->adapter->ehea_wq,
-				   &pr->port->reset_task);
+			schedule_work(&pr->port->reset_task);
 			break;
 		}
 
@@ -716,7 +714,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
 		eqe = ehea_poll_eq(port->qp_eq);
 	}
 
-	queue_work(port->adapter->ehea_wq, &port->reset_task);
+	schedule_work(&port->reset_task);
 
 	return IRQ_HANDLED;
 }
@@ -2395,7 +2393,7 @@ static int ehea_stop(struct net_device *dev)
 	if (netif_msg_ifdown(port))
 		ehea_info("disabling port %s", dev->name);
 
-	flush_workqueue(port->adapter->ehea_wq);
+	flush_scheduled_work();
 	down(&port->port_lock);
 	netif_stop_queue(dev);
 	ret = ehea_down(dev);
@@ -2710,7 +2708,7 @@ static void ehea_tx_watchdog(struct net_device *dev)
 
 	if (netif_carrier_ok(dev) &&
 	    !test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))
-		queue_work(port->adapter->ehea_wq, &port->reset_task);
+		schedule_work(&port->reset_task);
 }
 
 int ehea_sense_adapter_attr(struct ehea_adapter *adapter)
@@ -3243,15 +3241,9 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
 		goto out_kill_eq;
 	}
 
-	adapter->ehea_wq = create_workqueue("ehea_wq");
-	if (!adapter->ehea_wq) {
-		ret = -EIO;
-		goto out_free_irq;
-	}
-
 	ret = ehea_create_device_sysfs(dev);
 	if (ret)
-		goto out_kill_wq;
+		goto out_free_irq;
 
 	ret = ehea_setup_ports(adapter);
 	if (ret) {
@@ -3265,9 +3257,6 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
 out_rem_dev_sysfs:
 	ehea_remove_device_sysfs(dev);
 
-out_kill_wq:
-	destroy_workqueue(adapter->ehea_wq);
-
 out_free_irq:
 	ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter);
 
@@ -3293,7 +3282,7 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev)
 
 	ehea_remove_device_sysfs(dev);
 
-	destroy_workqueue(adapter->ehea_wq);
+	flush_scheduled_work();
 
 	ibmebus_free_irq(NULL, adapter->neq->attr.ist1, adapter);
 	tasklet_kill(&adapter->neq_tasklet);
@@ -3351,7 +3340,6 @@ int __init ehea_module_init(void)
 	printk(KERN_INFO "IBM eHEA ethernet device driver (Release %s)\n",
 	       DRV_VERSION);
 
-	ehea_driver_wq = create_workqueue("ehea_driver_wq");
 
 	INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs);
 	sema_init(&dlpar_mem_lock, 1);
@@ -3385,7 +3373,7 @@ out:
 
 static void __exit ehea_module_exit(void)
 {
-	destroy_workqueue(ehea_driver_wq);
+	flush_scheduled_work();
 	driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
 	ibmebus_unregister_driver(&ehea_driver);
 	ehea_destroy_busmap();
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 329a252..83b7643 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -34,7 +34,6 @@
 
 struct ehea_busmap ehea_bmap = { 0, 0, NULL };
 extern u64 ehea_driver_flags;
-extern struct workqueue_struct *ehea_driver_wq;
 extern struct work_struct ehea_rereg_mr_task;
 
 
@@ -618,7 +617,7 @@ u64 ehea_map_vaddr(void *caddr)
 
 	if (unlikely(mapped_addr == -1))
 		if (!test_and_set_bit(__EHEA_STOP_XFER, &ehea_driver_flags))
-			queue_work(ehea_driver_wq, &ehea_rereg_mr_task);
+			schedule_work(&ehea_rereg_mr_task);
 
 	return mapped_addr;
 }
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 015ed3a..ed407c8 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -1017,7 +1017,7 @@ static inline int hamachi_tx(struct net_device *dev)
 			break;
 		/* Free the original skb. */
 		skb = hmp->tx_skbuff[entry];
-		if (skb != 0) {
+		if (skb) {
 			pci_unmap_single(hmp->pci_dev,
 				hmp->tx_ring[entry].addr, skb->len,
 				PCI_DMA_TODEVICE);
@@ -1069,7 +1069,6 @@ static void hamachi_tx_timeout(struct net_device *dev)
 		   " resetting...\n", dev->name, (int)readw(ioaddr + TxStatus));
 
 	{
-		int i;
 		printk(KERN_DEBUG "  Rx ring %p: ", hmp->rx_ring);
 		for (i = 0; i < RX_RING_SIZE; i++)
 			printk(" %8.8x", (unsigned int)hmp->rx_ring[i].status_n_length);
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.c b/drivers/net/ibm_emac/ibm_emac_mal.c
index cabd984..4e49e8c 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.c
+++ b/drivers/net/ibm_emac/ibm_emac_mal.c
@@ -207,10 +207,10 @@ static irqreturn_t mal_serr(int irq, void *dev_instance)
 
 static inline void mal_schedule_poll(struct ibm_ocp_mal *mal)
 {
-	if (likely(netif_rx_schedule_prep(&mal->poll_dev))) {
+	if (likely(napi_schedule_prep(&mal->napi))) {
 		MAL_DBG2("%d: schedule_poll" NL, mal->def->index);
 		mal_disable_eob_irq(mal);
-		__netif_rx_schedule(&mal->poll_dev);
+		__napi_schedule(&mal->napi);
 	} else
 		MAL_DBG2("%d: already in poll" NL, mal->def->index);
 }
@@ -273,11 +273,11 @@ static irqreturn_t mal_rxde(int irq, void *dev_instance)
 	return IRQ_HANDLED;
 }
 
-static int mal_poll(struct net_device *ndev, int *budget)
+static int mal_poll(struct napi_struct *napi, int budget)
 {
-	struct ibm_ocp_mal *mal = ndev->priv;
+	struct ibm_ocp_mal *mal = container_of(napi, struct ibm_ocp_mal, napi);
 	struct list_head *l;
-	int rx_work_limit = min(ndev->quota, *budget), received = 0, done;
+	int received = 0;
 
 	MAL_DBG2("%d: poll(%d) %d ->" NL, mal->def->index, *budget,
 		 rx_work_limit);
@@ -295,38 +295,34 @@ static int mal_poll(struct net_device *ndev, int *budget)
 	list_for_each(l, &mal->poll_list) {
 		struct mal_commac *mc =
 		    list_entry(l, struct mal_commac, poll_list);
-		int n = mc->ops->poll_rx(mc->dev, rx_work_limit);
+		int n = mc->ops->poll_rx(mc->dev, budget);
 		if (n) {
 			received += n;
-			rx_work_limit -= n;
-			if (rx_work_limit <= 0) {
-				done = 0;
+			budget -= n;
+			if (budget <= 0)
 				goto more_work;	// XXX What if this is the last one ?
-			}
 		}
 	}
 
 	/* We need to disable IRQs to protect from RXDE IRQ here */
 	local_irq_disable();
-	__netif_rx_complete(ndev);
+	__napi_complete(napi);
 	mal_enable_eob_irq(mal);
 	local_irq_enable();
 
-	done = 1;
-
 	/* Check for "rotting" packet(s) */
 	list_for_each(l, &mal->poll_list) {
 		struct mal_commac *mc =
 		    list_entry(l, struct mal_commac, poll_list);
 		if (unlikely(mc->ops->peek_rx(mc->dev) || mc->rx_stopped)) {
 			MAL_DBG2("%d: rotting packet" NL, mal->def->index);
-			if (netif_rx_reschedule(ndev, received))
+			if (napi_reschedule(napi))
 				mal_disable_eob_irq(mal);
 			else
 				MAL_DBG2("%d: already in poll list" NL,
 					 mal->def->index);
 
-			if (rx_work_limit > 0)
+			if (budget > 0)
 				goto again;
 			else
 				goto more_work;
@@ -335,12 +331,8 @@ static int mal_poll(struct net_device *ndev, int *budget)
 	}
 
       more_work:
-	ndev->quota -= received;
-	*budget -= received;
-
-	MAL_DBG2("%d: poll() %d <- %d" NL, mal->def->index, *budget,
-		 done ? 0 : 1);
-	return done ? 0 : 1;
+	MAL_DBG2("%d: poll() %d <- %d" NL, mal->def->index, budget, received);
+	return received;
 }
 
 static void mal_reset(struct ibm_ocp_mal *mal)
@@ -425,11 +417,8 @@ static int __init mal_probe(struct ocp_device *ocpdev)
 	mal->def = ocpdev->def;
 
 	INIT_LIST_HEAD(&mal->poll_list);
-	set_bit(__LINK_STATE_START, &mal->poll_dev.state);
-	mal->poll_dev.weight = CONFIG_IBM_EMAC_POLL_WEIGHT;
-	mal->poll_dev.poll = mal_poll;
-	mal->poll_dev.priv = mal;
-	atomic_set(&mal->poll_dev.refcnt, 1);
+	mal->napi.weight = CONFIG_IBM_EMAC_POLL_WEIGHT;
+	mal->napi.poll = mal_poll;
 
 	INIT_LIST_HEAD(&mal->list);
 
@@ -520,11 +509,8 @@ static void __exit mal_remove(struct ocp_device *ocpdev)
 
 	MAL_DBG("%d: remove" NL, mal->def->index);
 
-	/* Syncronize with scheduled polling, 
-	   stolen from net/core/dev.c:dev_close() 
-	 */
-	clear_bit(__LINK_STATE_START, &mal->poll_dev.state);
-	netif_poll_disable(&mal->poll_dev);
+	/* Synchronize with scheduled polling */
+	napi_disable(&mal->napi);
 
 	if (!list_empty(&mal->list)) {
 		/* This is *very* bad */
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h
index 64bc338..8f54d62 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.h
+++ b/drivers/net/ibm_emac/ibm_emac_mal.h
@@ -195,7 +195,7 @@ struct ibm_ocp_mal {
 	dcr_host_t		dcrhost;
 
 	struct list_head	poll_list;
-	struct net_device	poll_dev;
+	struct napi_struct	napi;
 
 	struct list_head	list;
 	u32			tx_chan_mask;
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index ce127b9..8ea5009 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -2549,7 +2549,6 @@ static int __devinit emac_probe(struct of_device *ofdev,
 	dev->ndev = ndev;
 	dev->ofdev = ofdev;
 	dev->blist = blist;
-	SET_MODULE_OWNER(ndev);
 	SET_NETDEV_DEV(ndev, &ofdev->dev);
 
 	/* Initialize some embedded data structures */
diff --git a/drivers/net/ibm_newemac/mal.c b/drivers/net/ibm_newemac/mal.c
index c4335b7..5885411 100644
--- a/drivers/net/ibm_newemac/mal.c
+++ b/drivers/net/ibm_newemac/mal.c
@@ -235,10 +235,10 @@ static irqreturn_t mal_serr(int irq, void *dev_instance)
 
 static inline void mal_schedule_poll(struct mal_instance *mal)
 {
-	if (likely(netif_rx_schedule_prep(&mal->poll_dev))) {
+	if (likely(napi_schedule_prep(&mal->napi))) {
 		MAL_DBG2(mal, "schedule_poll" NL);
 		mal_disable_eob_irq(mal);
-		__netif_rx_schedule(&mal->poll_dev);
+		__napi_schedule(&mal->napi);
 	} else
 		MAL_DBG2(mal, "already in poll" NL);
 }
@@ -318,8 +318,7 @@ void mal_poll_disable(struct mal_instance *mal, struct mal_commac *commac)
 		msleep(1);
 
 	/* Synchronize with the MAL NAPI poller. */
-	while (test_bit(__LINK_STATE_RX_SCHED, &mal->poll_dev.state))
-		msleep(1);
+	napi_disable(&mal->napi);
 }
 
 void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac)
@@ -330,11 +329,11 @@ void mal_poll_enable(struct mal_instance *mal, struct mal_commac *commac)
 	// XXX might want to kick a poll now...
 }
 
-static int mal_poll(struct net_device *ndev, int *budget)
+static int mal_poll(struct napi_struct *napi, int budget)
 {
-	struct mal_instance *mal = netdev_priv(ndev);
+	struct mal_instance *mal = container_of(napi, struct mal_instance, napi);
 	struct list_head *l;
-	int rx_work_limit = min(ndev->quota, *budget), received = 0, done;
+	int received = 0;
 	unsigned long flags;
 
 	MAL_DBG2(mal, "poll(%d) %d ->" NL, *budget,
@@ -358,26 +357,21 @@ static int mal_poll(struct net_device *ndev, int *budget)
 		int n;
 		if (unlikely(test_bit(MAL_COMMAC_POLL_DISABLED, &mc->flags)))
 			continue;
-		n = mc->ops->poll_rx(mc->dev, rx_work_limit);
+		n = mc->ops->poll_rx(mc->dev, budget);
 		if (n) {
 			received += n;
-			rx_work_limit -= n;
-			if (rx_work_limit <= 0) {
-				done = 0;
-				// XXX What if this is the last one ?
-				goto more_work;
-			}
+			budget -= n;
+			if (budget <= 0)
+				goto more_work; // XXX What if this is the last one ?
 		}
 	}
 
 	/* We need to disable IRQs to protect from RXDE IRQ here */
 	spin_lock_irqsave(&mal->lock, flags);
-	__netif_rx_complete(ndev);
+	__napi_complete(napi);
 	mal_enable_eob_irq(mal);
 	spin_unlock_irqrestore(&mal->lock, flags);
 
-	done = 1;
-
 	/* Check for "rotting" packet(s) */
 	list_for_each(l, &mal->poll_list) {
 		struct mal_commac *mc =
@@ -387,12 +381,12 @@ static int mal_poll(struct net_device *ndev, int *budget)
 		if (unlikely(mc->ops->peek_rx(mc->dev) ||
 			     test_bit(MAL_COMMAC_RX_STOPPED, &mc->flags))) {
 			MAL_DBG2(mal, "rotting packet" NL);
-			if (netif_rx_reschedule(ndev, received))
+			if (napi_reschedule(napi))
 				mal_disable_eob_irq(mal);
 			else
 				MAL_DBG2(mal, "already in poll list" NL);
 
-			if (rx_work_limit > 0)
+			if (budget > 0)
 				goto again;
 			else
 				goto more_work;
@@ -401,13 +395,8 @@ static int mal_poll(struct net_device *ndev, int *budget)
 	}
 
  more_work:
-	ndev->quota -= received;
-	*budget -= received;
-
-	MAL_DBG2(mal, "poll() %d <- %d" NL, *budget,
-		 done ? 0 : 1);
-
-	return done ? 0 : 1;
+	MAL_DBG2(mal, "poll() %d <- %d" NL, budget, received);
+	return received;
 }
 
 static void mal_reset(struct mal_instance *mal)
@@ -538,11 +527,8 @@ static int __devinit mal_probe(struct of_device *ofdev,
 	}
 
 	INIT_LIST_HEAD(&mal->poll_list);
-	set_bit(__LINK_STATE_START, &mal->poll_dev.state);
-	mal->poll_dev.weight = CONFIG_IBM_NEW_EMAC_POLL_WEIGHT;
-	mal->poll_dev.poll = mal_poll;
-	mal->poll_dev.priv = mal;
-	atomic_set(&mal->poll_dev.refcnt, 1);
+	mal->napi.weight = CONFIG_IBM_NEW_EMAC_POLL_WEIGHT;
+	mal->napi.poll = mal_poll;
 	INIT_LIST_HEAD(&mal->list);
 	spin_lock_init(&mal->lock);
 
@@ -653,11 +639,8 @@ static int __devexit mal_remove(struct of_device *ofdev)
 
 	MAL_DBG(mal, "remove" NL);
 
-	/* Syncronize with scheduled polling,
-	   stolen from net/core/dev.c:dev_close()
-	 */
-	clear_bit(__LINK_STATE_START, &mal->poll_dev.state);
-	netif_poll_disable(&mal->poll_dev);
+	/* Synchronize with scheduled polling */
+	napi_disable(&mal->napi);
 
 	if (!list_empty(&mal->list)) {
 		/* This is *very* bad */
diff --git a/drivers/net/ibm_newemac/mal.h b/drivers/net/ibm_newemac/mal.h
index 57b69dc..cb1a16d 100644
--- a/drivers/net/ibm_newemac/mal.h
+++ b/drivers/net/ibm_newemac/mal.h
@@ -197,7 +197,7 @@ struct mal_instance {
 	int			serr_irq;	/* MAL System Error IRQ    */
 
 	struct list_head	poll_list;
-	struct net_device	poll_dev;
+	struct napi_struct	napi;
 
 	struct list_head	list;
 	u32			tx_chan_mask;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index ea38da6..527f9dc 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -108,7 +108,7 @@ static int full_duplex[MAX_UNITS];
 #define TX_TIMEOUT  (2*HZ)
 
 #define NATSEMI_HW_TIMEOUT	400
-#define NATSEMI_TIMER_FREQ	3*HZ
+#define NATSEMI_TIMER_FREQ	5*HZ
 #define NATSEMI_PG0_NREGS	64
 #define NATSEMI_RFDR_NREGS	8
 #define NATSEMI_PG1_NREGS	4
@@ -1615,7 +1615,7 @@ static void do_cable_magic(struct net_device *dev)
 		 * (these values all come from National)
 		 */
 		if (!(data & 0x80) || ((data >= 0xd8) && (data <= 0xff))) {
-			struct netdev_private *np = netdev_priv(dev);
+			np = netdev_priv(dev);
 
 			/* the bug has been triggered - fix the coefficient */
 			writew(TSTDAT_FIXED, ioaddr + TSTDAT);
@@ -1798,7 +1798,7 @@ static void netdev_timer(unsigned long data)
 	struct net_device *dev = (struct net_device *)data;
 	struct netdev_private *np = netdev_priv(dev);
 	void __iomem * ioaddr = ns_ioaddr(dev);
-	int next_tick = 5*HZ;
+	int next_tick = NATSEMI_TIMER_FREQ;
 
 	if (netif_msg_timer(np)) {
 		/* DO NOT read the IntrStatus register,
@@ -2502,8 +2502,8 @@ static void __set_rx_mode(struct net_device *dev)
 		memset(mc_filter, 0, sizeof(mc_filter));
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 			 i++, mclist = mclist->next) {
-			int i = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 23) & 0x1ff;
-			mc_filter[i/8] |= (1 << (i & 0x07));
+			int b = (ether_crc(ETH_ALEN, mclist->dmi_addr) >> 23) & 0x1ff;
+			mc_filter[b/8] |= (1 << (b & 0x07));
 		}
 		rx_mode = RxFilterEnable | AcceptBroadcast
 			| AcceptMulticast | AcceptMyPhys;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 203cc1e..22e4054 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -38,7 +38,7 @@
  * Tx descriptors that can be associated with each corresponding FIFO.
  * intr_type: This defines the type of interrupt. The values can be 0(INTA),
  *     2(MSI_X). Default value is '2(MSI_X)'
- * lro: Specifies whether to enable Large Receive Offload (LRO) or not.
+ * lro_enable: Specifies whether to enable Large Receive Offload (LRO) or not.
  *     Possible values '1' for enable '0' for disable. Default is '0'
  * lro_max_pkts: This parameter defines maximum number of packets can be
  *     aggregated as a single large packet
@@ -276,46 +276,46 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
 	{"ring_5_full_cnt"},
 	{"ring_6_full_cnt"},
 	{"ring_7_full_cnt"},
-	("alarm_transceiver_temp_high"),
-	("alarm_transceiver_temp_low"),
-	("alarm_laser_bias_current_high"),
-	("alarm_laser_bias_current_low"),
-	("alarm_laser_output_power_high"),
-	("alarm_laser_output_power_low"),
-	("warn_transceiver_temp_high"),
-	("warn_transceiver_temp_low"),
-	("warn_laser_bias_current_high"),
-	("warn_laser_bias_current_low"),
-	("warn_laser_output_power_high"),
-	("warn_laser_output_power_low"),
-	("lro_aggregated_pkts"),
-	("lro_flush_both_count"),
-	("lro_out_of_sequence_pkts"),
-	("lro_flush_due_to_max_pkts"),
-	("lro_avg_aggr_pkts"),
-	("mem_alloc_fail_cnt"),
-	("pci_map_fail_cnt"),
-	("watchdog_timer_cnt"),
-	("mem_allocated"),
-	("mem_freed"),
-	("link_up_cnt"),
-	("link_down_cnt"),
-	("link_up_time"),
-	("link_down_time"),
-	("tx_tcode_buf_abort_cnt"),
-	("tx_tcode_desc_abort_cnt"),
-	("tx_tcode_parity_err_cnt"),
-	("tx_tcode_link_loss_cnt"),
-	("tx_tcode_list_proc_err_cnt"),
-	("rx_tcode_parity_err_cnt"),
-	("rx_tcode_abort_cnt"),
-	("rx_tcode_parity_abort_cnt"),
-	("rx_tcode_rda_fail_cnt"),
-	("rx_tcode_unkn_prot_cnt"),
-	("rx_tcode_fcs_err_cnt"),
-	("rx_tcode_buf_size_err_cnt"),
-	("rx_tcode_rxd_corrupt_cnt"),
-	("rx_tcode_unkn_err_cnt"),
+	{"alarm_transceiver_temp_high"},
+	{"alarm_transceiver_temp_low"},
+	{"alarm_laser_bias_current_high"},
+	{"alarm_laser_bias_current_low"},
+	{"alarm_laser_output_power_high"},
+	{"alarm_laser_output_power_low"},
+	{"warn_transceiver_temp_high"},
+	{"warn_transceiver_temp_low"},
+	{"warn_laser_bias_current_high"},
+	{"warn_laser_bias_current_low"},
+	{"warn_laser_output_power_high"},
+	{"warn_laser_output_power_low"},
+	{"lro_aggregated_pkts"},
+	{"lro_flush_both_count"},
+	{"lro_out_of_sequence_pkts"},
+	{"lro_flush_due_to_max_pkts"},
+	{"lro_avg_aggr_pkts"},
+	{"mem_alloc_fail_cnt"},
+	{"pci_map_fail_cnt"},
+	{"watchdog_timer_cnt"},
+	{"mem_allocated"},
+	{"mem_freed"},
+	{"link_up_cnt"},
+	{"link_down_cnt"},
+	{"link_up_time"},
+	{"link_down_time"},
+	{"tx_tcode_buf_abort_cnt"},
+	{"tx_tcode_desc_abort_cnt"},
+	{"tx_tcode_parity_err_cnt"},
+	{"tx_tcode_link_loss_cnt"},
+	{"tx_tcode_list_proc_err_cnt"},
+	{"rx_tcode_parity_err_cnt"},
+	{"rx_tcode_abort_cnt"},
+	{"rx_tcode_parity_abort_cnt"},
+	{"rx_tcode_rda_fail_cnt"},
+	{"rx_tcode_unkn_prot_cnt"},
+	{"rx_tcode_fcs_err_cnt"},
+	{"rx_tcode_buf_size_err_cnt"},
+	{"rx_tcode_rxd_corrupt_cnt"},
+	{"rx_tcode_unkn_err_cnt"},
 	{"tda_err_cnt"},
 	{"pfc_err_cnt"},
 	{"pcc_err_cnt"},
@@ -468,7 +468,9 @@ S2IO_PARM_INT(rxsync_frequency, 3);
 /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */
 S2IO_PARM_INT(intr_type, 2);
 /* Large receive offload feature */
-S2IO_PARM_INT(lro, 0);
+static unsigned int lro_enable;
+module_param_named(lro, lro_enable, uint, 0);
+
 /* Max pkts to be aggregated by LRO at one time. If not specified,
  * aggregation happens until we hit max IP pkt size(64K)
  */
@@ -1759,7 +1761,7 @@ static void do_s2io_write_bits(u64 value, int flag, void __iomem *addr)
 	writeq(temp64, addr);
 }
 
-void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
+static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag)
 {
 	struct XENA_dev_config __iomem *bar0 = nic->bar0;
 	register u64 gen_int_mask = 0;
@@ -4228,7 +4230,7 @@ static void s2io_txpic_intr_handle(struct s2io_nic *sp)
  *  1 - if alarm bit set
  *  0 - if alarm bit is not set
  */
-int do_s2io_chk_alarm_bit(u64 value, void __iomem * addr,
+static int do_s2io_chk_alarm_bit(u64 value, void __iomem * addr,
 			  unsigned long long *cnt)
 {
 	u64 val64;
@@ -7135,7 +7137,8 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 				int ret = 0;
 
 				ret = s2io_club_tcp_session(skb->data, &tcp,
-						&tcp_len, &lro, rxdp, sp);
+							    &tcp_len, &lro,
+							    rxdp, sp);
 				switch (ret) {
 					case 3: /* Begin anew */
 						lro->parent = skb;
@@ -7451,7 +7454,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre)
 	else
 		sp->device_type = XFRAME_I_DEVICE;
 
-	sp->lro = lro;
+	sp->lro = lro_enable;
 
 	/* Initialize some PCI/PCI-X fields of the NIC. */
 	s2io_init_pci(sp);
@@ -7798,7 +7801,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
  * the module loadable parameters and initializes PCI configuration space.
  */
 
-int __init s2io_starter(void)
+static int __init s2io_starter(void)
 {
 	return pci_register_driver(&s2io_driver);
 }
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c
index 2483431..8d04654 100644
--- a/drivers/net/tehuti.c
+++ b/drivers/net/tehuti.c
@@ -750,7 +750,6 @@ bdx_vlan_rx_register(struct net_device *ndev, struct vlan_group *grp)
  */
 static int bdx_change_mtu(struct net_device *ndev, int new_mtu)
 {
-	BDX_ASSERT(ndev == 0);
 	ENTER;
 
 	if (new_mtu == ndev->mtu)
@@ -1002,7 +1001,7 @@ static inline void bdx_rxdb_free_elem(struct rxdb *db, int n)
 static int bdx_rx_init(struct bdx_priv *priv)
 {
 	ENTER;
-	BDX_ASSERT(priv == 0);
+
 	if (bdx_fifo_init(priv, &priv->rxd_fifo0.m, priv->rxd_size,
 			  regRXD_CFG0_0, regRXD_CFG1_0,
 			  regRXD_RPTR_0, regRXD_WPTR_0))
@@ -1747,7 +1746,6 @@ static void bdx_tx_cleanup(struct bdx_priv *priv)
 		tx_level -= db->rptr->len;	/* '-' koz len is negative */
 
 		/* now should come skb pointer - free it */
-		BDX_ASSERT(db->rptr->addr.skb == 0);
 		dev_kfree_skb_irq(db->rptr->addr.skb);
 		bdx_tx_db_inc_rptr(db);
 	}
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 91cd3f3..4848c7a 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -349,6 +349,16 @@ static inline void napi_schedule(struct napi_struct *n)
 		__napi_schedule(n);
 }
 
+/* Try to reschedule poll. Called by dev->poll() after napi_complete().  */
+static inline int napi_reschedule(struct napi_struct *napi)
+{
+	if (napi_schedule_prep(napi)) {
+		__napi_schedule(napi);
+		return 1;
+	}
+	return 0;
+}
+
 /**
  *	napi_complete - NAPI processing complete
  *	@n: napi context

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-10-05 18:20 Jeff Garzik
@ 2007-10-08  6:06 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2007-10-08  6:06 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Fri, 5 Oct 2007 14:20:08 -0400

> Please pull from 'upstream-davem' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem
> 

Pulled, and pushed back out to net-2.6.24, thanks Jeff.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-10-05 18:20 Jeff Garzik
  2007-10-08  6:06 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2007-10-05 18:20 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


Please pull from 'upstream-davem' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-davem

to receive the following updates:

Auke Kok (2):
      e1000e: fix debugging printout code
      e1000e: Fix ethtool register test code

Frank Blaschka (1):
      qeth: EDDP does not work on large MTUs

Klaus D. Wacker (2):
      qeth: HiperSockets layer-3 interface drop non IPv4 or non IPv6 packets
      lcs: Channel errors drive lcs_recovery which leads to kernel panic.

Ursula Braun (2):
      qeth: avoid duplicate deletion of multicast addresses
      qeth: discard inbound packets with unknown header id

 drivers/net/e1000e/ethtool.c |   14 ++++++++++----
 drivers/net/e1000e/hw.h      |    2 +-
 drivers/net/e1000e/netdev.c  |    4 +---
 drivers/s390/net/lcs.c       |   11 ++++++++---
 drivers/s390/net/lcs.h       |    1 +
 drivers/s390/net/qeth_eddp.c |   16 +++++++++-------
 drivers/s390/net/qeth_main.c |   19 +++++++++++++------
 7 files changed, 43 insertions(+), 24 deletions(-)

diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c
index 3423f33..2e8218f 100644
--- a/drivers/net/e1000e/ethtool.c
+++ b/drivers/net/e1000e/ethtool.c
@@ -784,10 +784,16 @@ static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
 	REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB);
 	REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000);
 
-	REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x01FFFFFF);
-	REG_PATTERN_TEST(E1000_RDBAL, 0xFFFFF000, 0xFFFFFFFF);
-	REG_PATTERN_TEST(E1000_TXCW, 0x0000FFFF, 0x0000FFFF);
-	REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFF000, 0xFFFFFFFF);
+	REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF);
+	REG_PATTERN_TEST(E1000_RDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
+	if ((mac->type != e1000_ich8lan) &&
+	    (mac->type != e1000_ich9lan))
+		REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF);
+	REG_PATTERN_TEST(E1000_TDBAL, 0xFFFFFFF0, 0xFFFFFFFF);
+	REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF);
+	for (i = 0; i < mac->rar_entry_count; i++)
+		REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1),
+				       0x8003FFFF, 0xFFFFFFFF);
 
 	for (i = 0; i < mac->mta_reg_count; i++)
 		REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF);
diff --git a/drivers/net/e1000e/hw.h b/drivers/net/e1000e/hw.h
index 848217a..aa82f1a 100644
--- a/drivers/net/e1000e/hw.h
+++ b/drivers/net/e1000e/hw.h
@@ -852,7 +852,7 @@ struct e1000_hw {
 
 #ifdef DEBUG
 #define hw_dbg(hw, format, arg...) \
-	printk(KERN_DEBUG, "%s: " format, e1000_get_hw_dev_name(hw), ##arg);
+	printk(KERN_DEBUG, "%s: " format, e1000e_get_hw_dev_name(hw), ##arg);
 #else
 static inline int __attribute__ ((format (printf, 2, 3)))
 hw_dbg(struct e1000_hw *hw, const char *format, ...)
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 4a21d7d..3a0bb2a 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -66,9 +66,7 @@ static const struct e1000_info *e1000_info_tbl[] = {
  **/
 char *e1000e_get_hw_dev_name(struct e1000_hw *hw)
 {
-	struct e1000_adapter *adapter = hw->back;
-	struct net_device *netdev = adapter->netdev;
-	return netdev->name;
+	return hw->adapter->netdev->name;
 }
 #endif
 
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index e4b11af..0fd663b 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -1400,11 +1400,14 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
 		PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n",
 			    cdev->dev.bus_id, dstat, cstat);
 		if (rc) {
-			lcs_schedule_recovery(card);
-			wake_up(&card->wait_q);
-			return;
+			channel->state = LCS_CH_STATE_ERROR;
 		}
 	}
+	if (channel->state == LCS_CH_STATE_ERROR) {
+		lcs_schedule_recovery(card);
+		wake_up(&card->wait_q);
+		return;
+	}
 	/* How far in the ccw chain have we processed? */
 	if ((channel->state != LCS_CH_STATE_INIT) &&
 	    (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) {
@@ -1708,6 +1711,8 @@ lcs_stopcard(struct lcs_card *card)
 
 	if (card->read.state != LCS_CH_STATE_STOPPED &&
 	    card->write.state != LCS_CH_STATE_STOPPED &&
+	    card->read.state != LCS_CH_STATE_ERROR &&
+	    card->write.state != LCS_CH_STATE_ERROR &&
 	    card->state == DEV_STATE_UP) {
 		lcs_clear_multicast_list(card);
 		rc = lcs_send_stoplan(card,LCS_INITIATOR_TCPIP);
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index 0e1e4a0..8976fb0 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -138,6 +138,7 @@ enum lcs_channel_states {
 	LCS_CH_STATE_RUNNING,
 	LCS_CH_STATE_SUSPENDED,
 	LCS_CH_STATE_CLEARED,
+	LCS_CH_STATE_ERROR,
 };
 
 /**
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index 70108fb..e3c268c 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -159,13 +159,15 @@ qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
 		buffer = buf->buffer;
 		/* fill one skb into buffer */
 		for (i = 0; i < ctx->elements_per_skb; ++i){
-			buffer->element[buf->next_element_to_fill].addr =
-				ctx->elements[element].addr;
-			buffer->element[buf->next_element_to_fill].length =
-				ctx->elements[element].length;
-			buffer->element[buf->next_element_to_fill].flags =
-				ctx->elements[element].flags;
-			buf->next_element_to_fill++;
+			if (ctx->elements[element].length != 0) {
+				buffer->element[buf->next_element_to_fill].
+				addr = ctx->elements[element].addr;
+				buffer->element[buf->next_element_to_fill].
+				length = ctx->elements[element].length;
+				buffer->element[buf->next_element_to_fill].
+				flags = ctx->elements[element].flags;
+				buf->next_element_to_fill++;
+			}
 			element++;
 			elements--;
 		}
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 778ddfb..c67e7df 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -823,14 +823,15 @@ __qeth_delete_all_mc(struct qeth_card *card, unsigned long *flags)
 again:
 	list_for_each_entry_safe(addr, tmp, &card->ip_list, entry) {
 		if (addr->is_multicast) {
+			list_del(&addr->entry);
 			spin_unlock_irqrestore(&card->ip_lock, *flags);
 			rc = qeth_deregister_addr_entry(card, addr);
 			spin_lock_irqsave(&card->ip_lock, *flags);
 			if (!rc) {
-				list_del(&addr->entry);
 				kfree(addr);
 				goto again;
-			}
+			} else
+				list_add(&addr->entry, &card->ip_list);
 		}
 	}
 }
@@ -2701,10 +2702,15 @@ qeth_process_inbound_buffer(struct qeth_card *card,
 			qeth_layer2_rebuild_skb(card, skb, hdr);
 		else if (hdr->hdr.l3.id == QETH_HEADER_TYPE_LAYER3)
 			vlan_tag = qeth_rebuild_skb(card, skb, hdr);
-		else { /*in case of OSN*/
+		else if (hdr->hdr.osn.id == QETH_HEADER_TYPE_OSN) {
 			skb_push(skb, sizeof(struct qeth_hdr));
 			skb_copy_to_linear_data(skb, hdr,
 						sizeof(struct qeth_hdr));
+		} else { /* unknown header type */
+			dev_kfree_skb_any(skb);
+			QETH_DBF_TEXT(trace, 3, "inbunkno");
+			QETH_DBF_HEX(control, 3, hdr, QETH_DBF_CONTROL_LEN);
+			continue;
 		}
 		/* is device UP ? */
 		if (!(card->dev->flags & IFF_UP)){
@@ -4508,7 +4514,8 @@ qeth_do_send_packet(struct qeth_card *card, struct qeth_qdio_out_q *queue,
 			/* check if we have enough elements (including following
 			 * free buffers) to handle eddp context */
 			if (qeth_eddp_check_buffers_for_context(queue,ctx) < 0){
-				printk("eddp tx_dropped 1\n");
+				if (net_ratelimit())
+					PRINT_WARN("eddp tx_dropped 1\n");
 				rc = -EBUSY;
 				goto out;
 			}
@@ -4719,8 +4726,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
 		rc = qeth_do_send_packet(card, queue, new_skb, hdr,
 					 elements_needed, ctx);
 	else {
-		if ((skb->protocol == htons(ETH_P_ARP)) &&
-		    (card->dev->flags & IFF_NOARP)) {
+		if ((!card->options.layer2) &&
+		    (ipv == 0)) {
 			__qeth_free_new_skb(skb, new_skb);
 			return -EPERM;
 		}

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-10-03 18:39 Jeff Garzik
@ 2007-10-03 22:33 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2007-10-03 22:33 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Wed, 3 Oct 2007 14:39:16 -0400

> 
> Normally I wait a day or two between pushes, to queue up patches and
> also to avoid annoying my upstream :)  But this includes a couple fixes
> I felt should be upstreamed sooner rather than later.
> 
> Please pull from 'upstream' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream

Pulled, thanks Jeff!

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-10-03 18:39 Jeff Garzik
  2007-10-03 22:33 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2007-10-03 18:39 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


Normally I wait a day or two between pushes, to queue up patches and
also to avoid annoying my upstream :)  But this includes a couple fixes
I felt should be upstreamed sooner rather than later.


Please pull from 'upstream' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream

to receive the following updates:

Jeff Garzik (1):
      drivers/net/qla3xxx: trim trailing whitespace

Olof Johansson (11):
      pasemi_mac: basic error checking
      pasemi_mac: fix bug in receive buffer dma mapping
      pasemi_mac: rework ring management
      pasemi_mac: implement sg support
      pasemi_mac: workaround for erratum 5971
      pasemi_mac: add local skb alignment
      pasemi_mac: further performance tweaks
      pasemi_mac: update todo list
      pasemi_mac: clear out old errors on interface open
      pasemi_mac: use buffer index pointer in clean_rx()
      pasemi_mac: enable iommu support

trem (1):
      ipg.c doesn't compile with with CONFIG_HIGHMEM64G

vbarshak@ru.mvista.com (1):
      Fix typo in new EMAC driver.

 arch/powerpc/platforms/pasemi/Kconfig |   10 
 arch/powerpc/platforms/pasemi/iommu.c |   15 
 drivers/net/ibm_newemac/core.c        |    4 
 drivers/net/ipg.c                     |   10 
 drivers/net/pasemi_mac.c              |  595 ++++++++++++++++++++++------------
 drivers/net/pasemi_mac.h              |   67 ++-
 drivers/net/qla3xxx.c                 |  128 +++----
 drivers/net/qla3xxx.h                 |    6 
 8 files changed, 527 insertions(+), 308 deletions(-)

diff --git a/arch/powerpc/platforms/pasemi/Kconfig b/arch/powerpc/platforms/pasemi/Kconfig
index 95cd90f..e95261e 100644
--- a/arch/powerpc/platforms/pasemi/Kconfig
+++ b/arch/powerpc/platforms/pasemi/Kconfig
@@ -18,6 +18,16 @@ config PPC_PASEMI_IOMMU
 	help
 	  IOMMU support for PA6T-1682M
 
+config PPC_PASEMI_IOMMU_DMA_FORCE
+	bool "Force DMA engine to use IOMMU"
+	depends on PPC_PASEMI_IOMMU
+	help
+	  This option forces the use of the IOMMU also for the
+	  DMA engine. Otherwise the kernel will use it only when
+	  running under a hypervisor.
+
+	  If in doubt, say "N".
+
 config PPC_PASEMI_MDIO
 	depends on PHYLIB
 	tristate "MDIO support via GPIO"
diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c
index 9014d55..a1111b5 100644
--- a/arch/powerpc/platforms/pasemi/iommu.c
+++ b/arch/powerpc/platforms/pasemi/iommu.c
@@ -25,6 +25,7 @@
 #include <asm/iommu.h>
 #include <asm/machdep.h>
 #include <asm/abs_addr.h>
+#include <asm/firmware.h>
 
 
 #define IOBMAP_PAGE_SHIFT	12
@@ -175,13 +176,17 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev)
 {
 	pr_debug("pci_dma_dev_setup, dev %p (%s)\n", dev, pci_name(dev));
 
-	/* DMA device is untranslated, but all other PCI-e goes through
-	 * the IOMMU
+#if !defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE)
+	/* For non-LPAR environment, don't translate anything for the DMA
+	 * engine. The exception to this is if the user has enabled
+	 * CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE at build time.
 	 */
-	if (dev->vendor == 0x1959 && dev->device == 0xa007)
+	if (dev->vendor == 0x1959 && dev->device == 0xa007 &&
+	    !firmware_has_feature(FW_FEATURE_LPAR))
 		dev->dev.archdata.dma_ops = &dma_direct_ops;
-	else
-		dev->dev.archdata.dma_data = &iommu_table_iobmap;
+#endif
+
+	dev->dev.archdata.dma_data = &iommu_table_iobmap;
 }
 
 static void pci_dma_bus_setup_null(struct pci_bus *b) { }
diff --git a/drivers/net/ibm_newemac/core.c b/drivers/net/ibm_newemac/core.c
index 653bfdc..ce127b9 100644
--- a/drivers/net/ibm_newemac/core.c
+++ b/drivers/net/ibm_newemac/core.c
@@ -1232,9 +1232,9 @@ static inline int emac_xmit_finish(struct emac_instance *dev, int len)
 	 * instead
 	 */
 	if (emac_has_feature(dev, EMAC_FTR_EMAC4))
-		out_be32(&p->tmr0, EMAC_TMR0_XMIT);
-	else
 		out_be32(&p->tmr0, EMAC4_TMR0_XMIT);
+	else
+		out_be32(&p->tmr0, EMAC_TMR0_XMIT);
 
 	if (unlikely(++dev->tx_cnt == NUM_TX_BUFF)) {
 		netif_stop_queue(ndev);
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index dfdc96f..59898ce 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -25,6 +25,8 @@
 #include <linux/mii.h>
 #include <linux/mutex.h>
 
+#include <asm/div64.h>
+
 #define IPG_RX_RING_BYTES	(sizeof(struct ipg_rx) * IPG_RFDLIST_LENGTH)
 #define IPG_TX_RING_BYTES	(sizeof(struct ipg_tx) * IPG_TFDLIST_LENGTH)
 #define IPG_RESET_MASK \
@@ -836,10 +838,14 @@ static void ipg_nic_txfree(struct net_device *dev)
 {
 	struct ipg_nic_private *sp = netdev_priv(dev);
 	void __iomem *ioaddr = sp->ioaddr;
-	const unsigned int curr = ipg_r32(TFD_LIST_PTR_0) -
-		(sp->txd_map / sizeof(struct ipg_tx)) - 1;
+	unsigned int curr;
+	u64 txd_map;
 	unsigned int released, pending;
 
+	txd_map = (u64)sp->txd_map;
+	curr = ipg_r32(TFD_LIST_PTR_0) -
+		do_div(txd_map, sizeof(struct ipg_tx)) - 1;
+
 	IPG_DEBUG_MSG("_nic_txfree\n");
 
 	pending = sp->tx_current - sp->tx_dirty;
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index c2d34a8..9f9a421 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -34,24 +34,29 @@
 #include <net/checksum.h>
 
 #include <asm/irq.h>
+#include <asm/firmware.h>
 
 #include "pasemi_mac.h"
 
+/* We have our own align, since ppc64 in general has it at 0 because
+ * of design flaws in some of the server bridge chips. However, for
+ * PWRficient doing the unaligned copies is more expensive than doing
+ * unaligned DMA, so make sure the data is aligned instead.
+ */
+#define LOCAL_SKB_ALIGN	2
 
 /* TODO list
  *
- * - Get rid of pci_{read,write}_config(), map registers with ioremap
- *   for performance
- * - PHY support
  * - Multicast support
  * - Large MTU support
- * - Other performance improvements
+ * - SW LRO
+ * - Multiqueue RX/TX
  */
 
 
 /* Must be a power of two */
-#define RX_RING_SIZE 512
-#define TX_RING_SIZE 512
+#define RX_RING_SIZE 4096
+#define TX_RING_SIZE 4096
 
 #define DEFAULT_MSG_ENABLE	  \
 	(NETIF_MSG_DRV		| \
@@ -63,10 +68,10 @@
 	 NETIF_MSG_RX_ERR	| \
 	 NETIF_MSG_TX_ERR)
 
-#define TX_DESC(mac, num)	((mac)->tx->desc[(num) & (TX_RING_SIZE-1)])
-#define TX_DESC_INFO(mac, num)	((mac)->tx->desc_info[(num) & (TX_RING_SIZE-1)])
-#define RX_DESC(mac, num)	((mac)->rx->desc[(num) & (RX_RING_SIZE-1)])
-#define RX_DESC_INFO(mac, num)	((mac)->rx->desc_info[(num) & (RX_RING_SIZE-1)])
+#define TX_RING(mac, num)	((mac)->tx->ring[(num) & (TX_RING_SIZE-1)])
+#define TX_RING_INFO(mac, num)	((mac)->tx->ring_info[(num) & (TX_RING_SIZE-1)])
+#define RX_RING(mac, num)	((mac)->rx->ring[(num) & (RX_RING_SIZE-1)])
+#define RX_RING_INFO(mac, num)	((mac)->rx->ring_info[(num) & (RX_RING_SIZE-1)])
 #define RX_BUFF(mac, num)	((mac)->rx->buffers[(num) & (RX_RING_SIZE-1)])
 
 #define RING_USED(ring)		(((ring)->next_to_fill - (ring)->next_to_clean) \
@@ -85,6 +90,15 @@ MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
 
 static struct pasdma_status *dma_status;
 
+static int translation_enabled(void)
+{
+#if defined(CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE)
+	return 1;
+#else
+	return firmware_has_feature(FW_FEATURE_LPAR);
+#endif
+}
+
 static void write_iob_reg(struct pasemi_mac *mac, unsigned int reg,
 			  unsigned int val)
 {
@@ -160,11 +174,36 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
 	return 0;
 }
 
+static int pasemi_mac_unmap_tx_skb(struct pasemi_mac *mac,
+				    struct sk_buff *skb,
+				    dma_addr_t *dmas)
+{
+	int f;
+	int nfrags = skb_shinfo(skb)->nr_frags;
+
+	pci_unmap_single(mac->dma_pdev, dmas[0], skb_headlen(skb),
+			 PCI_DMA_TODEVICE);
+
+	for (f = 0; f < nfrags; f++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[f];
+
+		pci_unmap_page(mac->dma_pdev, dmas[f+1], frag->size,
+			       PCI_DMA_TODEVICE);
+	}
+	dev_kfree_skb_irq(skb);
+
+	/* Freed descriptor slot + main SKB ptr + nfrags additional ptrs,
+	 * aligned up to a power of 2
+	 */
+	return (nfrags + 3) & ~1;
+}
+
 static int pasemi_mac_setup_rx_resources(struct net_device *dev)
 {
 	struct pasemi_mac_rxring *ring;
 	struct pasemi_mac *mac = netdev_priv(dev);
 	int chan_id = mac->dma_rxch;
+	unsigned int cfg;
 
 	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
 
@@ -174,22 +213,21 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev)
 	spin_lock_init(&ring->lock);
 
 	ring->size = RX_RING_SIZE;
-	ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
+	ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
 				  RX_RING_SIZE, GFP_KERNEL);
 
-	if (!ring->desc_info)
-		goto out_desc_info;
+	if (!ring->ring_info)
+		goto out_ring_info;
 
 	/* Allocate descriptors */
-	ring->desc = dma_alloc_coherent(&mac->dma_pdev->dev,
-					RX_RING_SIZE *
-					sizeof(struct pas_dma_xct_descr),
+	ring->ring = dma_alloc_coherent(&mac->dma_pdev->dev,
+					RX_RING_SIZE * sizeof(u64),
 					&ring->dma, GFP_KERNEL);
 
-	if (!ring->desc)
-		goto out_desc;
+	if (!ring->ring)
+		goto out_ring_desc;
 
-	memset(ring->desc, 0, RX_RING_SIZE * sizeof(struct pas_dma_xct_descr));
+	memset(ring->ring, 0, RX_RING_SIZE * sizeof(u64));
 
 	ring->buffers = dma_alloc_coherent(&mac->dma_pdev->dev,
 					   RX_RING_SIZE * sizeof(u64),
@@ -203,20 +241,30 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev)
 
 	write_dma_reg(mac, PAS_DMA_RXCHAN_BASEU(chan_id),
 			   PAS_DMA_RXCHAN_BASEU_BRBH(ring->dma >> 32) |
-			   PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 2));
+			   PAS_DMA_RXCHAN_BASEU_SIZ(RX_RING_SIZE >> 3));
 
-	write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id),
-			   PAS_DMA_RXCHAN_CFG_HBU(2));
+	cfg = PAS_DMA_RXCHAN_CFG_HBU(2);
+
+	if (translation_enabled())
+		cfg |= PAS_DMA_RXCHAN_CFG_CTR;
+
+	write_dma_reg(mac, PAS_DMA_RXCHAN_CFG(chan_id), cfg);
 
 	write_dma_reg(mac, PAS_DMA_RXINT_BASEL(mac->dma_if),
-			   PAS_DMA_RXINT_BASEL_BRBL(__pa(ring->buffers)));
+			   PAS_DMA_RXINT_BASEL_BRBL(ring->buf_dma));
 
 	write_dma_reg(mac, PAS_DMA_RXINT_BASEU(mac->dma_if),
-			   PAS_DMA_RXINT_BASEU_BRBH(__pa(ring->buffers) >> 32) |
+			   PAS_DMA_RXINT_BASEU_BRBH(ring->buf_dma >> 32) |
 			   PAS_DMA_RXINT_BASEU_SIZ(RX_RING_SIZE >> 3));
 
-	write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if),
-			   PAS_DMA_RXINT_CFG_DHL(2));
+	cfg = PAS_DMA_RXINT_CFG_DHL(3) | PAS_DMA_RXINT_CFG_L2 |
+	      PAS_DMA_RXINT_CFG_LW | PAS_DMA_RXINT_CFG_RBP |
+	      PAS_DMA_RXINT_CFG_HEN;
+
+	if (translation_enabled())
+		cfg |= PAS_DMA_RXINT_CFG_ITRR | PAS_DMA_RXINT_CFG_ITR;
+
+	write_dma_reg(mac, PAS_DMA_RXINT_CFG(mac->dma_if), cfg);
 
 	ring->next_to_fill = 0;
 	ring->next_to_clean = 0;
@@ -229,11 +277,11 @@ static int pasemi_mac_setup_rx_resources(struct net_device *dev)
 
 out_buffers:
 	dma_free_coherent(&mac->dma_pdev->dev,
-			  RX_RING_SIZE * sizeof(struct pas_dma_xct_descr),
-			  mac->rx->desc, mac->rx->dma);
-out_desc:
-	kfree(ring->desc_info);
-out_desc_info:
+			  RX_RING_SIZE * sizeof(u64),
+			  mac->rx->ring, mac->rx->dma);
+out_ring_desc:
+	kfree(ring->ring_info);
+out_ring_info:
 	kfree(ring);
 out_ring:
 	return -ENOMEM;
@@ -246,6 +294,7 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
 	u32 val;
 	int chan_id = mac->dma_txch;
 	struct pasemi_mac_txring *ring;
+	unsigned int cfg;
 
 	ring = kzalloc(sizeof(*ring), GFP_KERNEL);
 	if (!ring)
@@ -254,33 +303,36 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
 	spin_lock_init(&ring->lock);
 
 	ring->size = TX_RING_SIZE;
-	ring->desc_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
+	ring->ring_info = kzalloc(sizeof(struct pasemi_mac_buffer) *
 				  TX_RING_SIZE, GFP_KERNEL);
-	if (!ring->desc_info)
-		goto out_desc_info;
+	if (!ring->ring_info)
+		goto out_ring_info;
 
 	/* Allocate descriptors */
-	ring->desc = dma_alloc_coherent(&mac->dma_pdev->dev,
-					TX_RING_SIZE *
-					sizeof(struct pas_dma_xct_descr),
+	ring->ring = dma_alloc_coherent(&mac->dma_pdev->dev,
+					TX_RING_SIZE * sizeof(u64),
 					&ring->dma, GFP_KERNEL);
-	if (!ring->desc)
-		goto out_desc;
+	if (!ring->ring)
+		goto out_ring_desc;
 
-	memset(ring->desc, 0, TX_RING_SIZE * sizeof(struct pas_dma_xct_descr));
+	memset(ring->ring, 0, TX_RING_SIZE * sizeof(u64));
 
 	write_dma_reg(mac, PAS_DMA_TXCHAN_BASEL(chan_id),
 			   PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
 	val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
-	val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
+	val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 3);
 
 	write_dma_reg(mac, PAS_DMA_TXCHAN_BASEU(chan_id), val);
 
-	write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id),
-			   PAS_DMA_TXCHAN_CFG_TY_IFACE |
-			   PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
-			   PAS_DMA_TXCHAN_CFG_UP |
-			   PAS_DMA_TXCHAN_CFG_WT(2));
+	cfg = PAS_DMA_TXCHAN_CFG_TY_IFACE |
+	      PAS_DMA_TXCHAN_CFG_TATTR(mac->dma_if) |
+	      PAS_DMA_TXCHAN_CFG_UP |
+	      PAS_DMA_TXCHAN_CFG_WT(2);
+
+	if (translation_enabled())
+		cfg |= PAS_DMA_TXCHAN_CFG_TRD | PAS_DMA_TXCHAN_CFG_TRR;
+
+	write_dma_reg(mac, PAS_DMA_TXCHAN_CFG(chan_id), cfg);
 
 	ring->next_to_fill = 0;
 	ring->next_to_clean = 0;
@@ -291,9 +343,9 @@ static int pasemi_mac_setup_tx_resources(struct net_device *dev)
 
 	return 0;
 
-out_desc:
-	kfree(ring->desc_info);
-out_desc_info:
+out_ring_desc:
+	kfree(ring->ring_info);
+out_ring_info:
 	kfree(ring);
 out_ring:
 	return -ENOMEM;
@@ -302,33 +354,37 @@ out_ring:
 static void pasemi_mac_free_tx_resources(struct net_device *dev)
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
-	unsigned int i;
+	unsigned int i, j;
 	struct pasemi_mac_buffer *info;
-	struct pas_dma_xct_descr *dp;
-
-	for (i = 0; i < TX_RING_SIZE; i++) {
-		info = &TX_DESC_INFO(mac, i);
-		dp = &TX_DESC(mac, i);
-		if (info->dma) {
-			if (info->skb) {
-				pci_unmap_single(mac->dma_pdev,
-						 info->dma,
-						 info->skb->len,
-						 PCI_DMA_TODEVICE);
-				dev_kfree_skb_any(info->skb);
-			}
-			info->dma = 0;
-			info->skb = NULL;
-			dp->mactx = 0;
-			dp->ptr = 0;
-		}
+	dma_addr_t dmas[MAX_SKB_FRAGS+1];
+	int freed;
+	int start, limit;
+
+	start = mac->tx->next_to_clean;
+	limit = mac->tx->next_to_fill;
+
+	/* Compensate for when fill has wrapped and clean has not */
+	if (start > limit)
+		limit += TX_RING_SIZE;
+
+	for (i = start; i < limit; i += freed) {
+		info = &TX_RING_INFO(mac, i+1);
+		if (info->dma && info->skb) {
+			for (j = 0; j <= skb_shinfo(info->skb)->nr_frags; j++)
+				dmas[j] = TX_RING_INFO(mac, i+1+j).dma;
+			freed = pasemi_mac_unmap_tx_skb(mac, info->skb, dmas);
+		} else
+			freed = 2;
 	}
 
+	for (i = 0; i < TX_RING_SIZE; i++)
+		TX_RING(mac, i) = 0;
+
 	dma_free_coherent(&mac->dma_pdev->dev,
-			  TX_RING_SIZE * sizeof(struct pas_dma_xct_descr),
-			  mac->tx->desc, mac->tx->dma);
+			  TX_RING_SIZE * sizeof(u64),
+			  mac->tx->ring, mac->tx->dma);
 
-	kfree(mac->tx->desc_info);
+	kfree(mac->tx->ring_info);
 	kfree(mac->tx);
 	mac->tx = NULL;
 }
@@ -338,34 +394,31 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev)
 	struct pasemi_mac *mac = netdev_priv(dev);
 	unsigned int i;
 	struct pasemi_mac_buffer *info;
-	struct pas_dma_xct_descr *dp;
 
 	for (i = 0; i < RX_RING_SIZE; i++) {
-		info = &RX_DESC_INFO(mac, i);
-		dp = &RX_DESC(mac, i);
-		if (info->skb) {
-			if (info->dma) {
-				pci_unmap_single(mac->dma_pdev,
-						 info->dma,
-						 info->skb->len,
-						 PCI_DMA_FROMDEVICE);
-				dev_kfree_skb_any(info->skb);
-			}
-			info->dma = 0;
-			info->skb = NULL;
-			dp->macrx = 0;
-			dp->ptr = 0;
+		info = &RX_RING_INFO(mac, i);
+		if (info->skb && info->dma) {
+			pci_unmap_single(mac->dma_pdev,
+					 info->dma,
+					 info->skb->len,
+					 PCI_DMA_FROMDEVICE);
+			dev_kfree_skb_any(info->skb);
 		}
+		info->dma = 0;
+		info->skb = NULL;
 	}
 
+	for (i = 0; i < RX_RING_SIZE; i++)
+		RX_RING(mac, i) = 0;
+
 	dma_free_coherent(&mac->dma_pdev->dev,
-			  RX_RING_SIZE * sizeof(struct pas_dma_xct_descr),
-			  mac->rx->desc, mac->rx->dma);
+			  RX_RING_SIZE * sizeof(u64),
+			  mac->rx->ring, mac->rx->dma);
 
 	dma_free_coherent(&mac->dma_pdev->dev, RX_RING_SIZE * sizeof(u64),
 			  mac->rx->buffers, mac->rx->buf_dma);
 
-	kfree(mac->rx->desc_info);
+	kfree(mac->rx->ring_info);
 	kfree(mac->rx);
 	mac->rx = NULL;
 }
@@ -373,30 +426,34 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev)
 static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit)
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
-	unsigned int i;
-	int start = mac->rx->next_to_fill;
-	int count;
+	int fill, count;
 
 	if (limit <= 0)
 		return;
 
-	i = start;
+	fill = mac->rx->next_to_fill;
 	for (count = 0; count < limit; count++) {
-		struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i);
-		u64 *buff = &RX_BUFF(mac, i);
+		struct pasemi_mac_buffer *info = &RX_RING_INFO(mac, fill);
+		u64 *buff = &RX_BUFF(mac, fill);
 		struct sk_buff *skb;
 		dma_addr_t dma;
 
+		/* Entry in use? */
+		WARN_ON(*buff);
+
 		/* skb might still be in there for recycle on short receives */
 		if (info->skb)
 			skb = info->skb;
-		else
+		else {
 			skb = dev_alloc_skb(BUF_SIZE);
+			skb_reserve(skb, LOCAL_SKB_ALIGN);
+		}
 
 		if (unlikely(!skb))
 			break;
 
-		dma = pci_map_single(mac->dma_pdev, skb->data, skb->len,
+		dma = pci_map_single(mac->dma_pdev, skb->data,
+				     BUF_SIZE - LOCAL_SKB_ALIGN,
 				     PCI_DMA_FROMDEVICE);
 
 		if (unlikely(dma_mapping_error(dma))) {
@@ -407,15 +464,15 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit)
 		info->skb = skb;
 		info->dma = dma;
 		*buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma);
-		i++;
+		fill++;
 	}
 
 	wmb();
 
-	write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), count);
 	write_dma_reg(mac, PAS_DMA_RXINT_INCR(mac->dma_if), count);
 
-	mac->rx->next_to_fill += count;
+	mac->rx->next_to_fill = (mac->rx->next_to_fill + count) &
+				(RX_RING_SIZE - 1);
 }
 
 static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
@@ -445,64 +502,91 @@ static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
 }
 
 
+static inline void pasemi_mac_rx_error(struct pasemi_mac *mac, u64 macrx)
+{
+	unsigned int rcmdsta, ccmdsta;
+
+	if (!netif_msg_rx_err(mac))
+		return;
+
+	rcmdsta = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
+	ccmdsta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch));
+
+	printk(KERN_ERR "pasemi_mac: rx error. macrx %016lx, rx status %lx\n",
+		macrx, *mac->rx_status);
+
+	printk(KERN_ERR "pasemi_mac: rcmdsta %08x ccmdsta %08x\n",
+		rcmdsta, ccmdsta);
+}
+
+static inline void pasemi_mac_tx_error(struct pasemi_mac *mac, u64 mactx)
+{
+	unsigned int cmdsta;
+
+	if (!netif_msg_tx_err(mac))
+		return;
+
+	cmdsta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch));
+
+	printk(KERN_ERR "pasemi_mac: tx error. mactx 0x%016lx, "\
+		"tx status 0x%016lx\n", mactx, *mac->tx_status);
+
+	printk(KERN_ERR "pasemi_mac: tcmdsta 0x%08x\n", cmdsta);
+}
+
 static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 {
 	unsigned int n;
 	int count;
-	struct pas_dma_xct_descr *dp;
 	struct pasemi_mac_buffer *info;
 	struct sk_buff *skb;
-	unsigned int i, len;
+	unsigned int len;
 	u64 macrx;
 	dma_addr_t dma;
+	int buf_index;
+	u64 eval;
 
 	spin_lock(&mac->rx->lock);
 
 	n = mac->rx->next_to_clean;
 
-	for (count = limit; count; count--) {
+	prefetch(RX_RING(mac, n));
 
-		rmb();
+	for (count = 0; count < limit; count++) {
+		macrx = RX_RING(mac, n);
 
-		dp = &RX_DESC(mac, n);
-		prefetchw(dp);
-		macrx = dp->macrx;
+		if ((macrx & XCT_MACRX_E) ||
+		    (*mac->rx_status & PAS_STATUS_ERROR))
+			pasemi_mac_rx_error(mac, macrx);
 
 		if (!(macrx & XCT_MACRX_O))
 			break;
 
-
 		info = NULL;
 
-		/* We have to scan for our skb since there's no way
-		 * to back-map them from the descriptor, and if we
-		 * have several receive channels then they might not
-		 * show up in the same order as they were put on the
-		 * interface ring.
-		 */
+		BUG_ON(!(macrx & XCT_MACRX_RR_8BRES));
 
-		dma = (dp->ptr & XCT_PTR_ADDR_M);
-		for (i = n; i < (n + RX_RING_SIZE); i++) {
-			info = &RX_DESC_INFO(mac, i);
-			if (info->dma == dma)
-				break;
-		}
-		prefetchw(info);
+		eval = (RX_RING(mac, n+1) & XCT_RXRES_8B_EVAL_M) >>
+			XCT_RXRES_8B_EVAL_S;
+		buf_index = eval-1;
+
+		dma = (RX_RING(mac, n+2) & XCT_PTR_ADDR_M);
+		info = &RX_RING_INFO(mac, buf_index);
 
 		skb = info->skb;
-		prefetchw(skb);
-		info->dma = 0;
 
-		pci_unmap_single(mac->dma_pdev, dma, skb->len,
-				 PCI_DMA_FROMDEVICE);
+		prefetch(skb);
+		prefetch(&skb->data_len);
 
 		len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
 
 		if (len < 256) {
-			struct sk_buff *new_skb =
-			    netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN);
+			struct sk_buff *new_skb;
+
+			new_skb = netdev_alloc_skb(mac->netdev,
+						   len + LOCAL_SKB_ALIGN);
 			if (new_skb) {
-				skb_reserve(new_skb, NET_IP_ALIGN);
+				skb_reserve(new_skb, LOCAL_SKB_ALIGN);
 				memcpy(new_skb->data, skb->data, len);
 				/* save the skb in buffer_info as good */
 				skb = new_skb;
@@ -511,6 +595,10 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 		} else
 			info->skb = NULL;
 
+		pci_unmap_single(mac->dma_pdev, dma, len, PCI_DMA_FROMDEVICE);
+
+		info->dma = 0;
+
 		skb_put(skb, len);
 
 		if (likely((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK)) {
@@ -526,72 +614,109 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 		skb->protocol = eth_type_trans(skb, mac->netdev);
 		netif_receive_skb(skb);
 
-		dp->ptr = 0;
-		dp->macrx = 0;
+		RX_RING(mac, n) = 0;
+		RX_RING(mac, n+1) = 0;
 
-		n++;
+		/* Need to zero it out since hardware doesn't, since the
+		 * replenish loop uses it to tell when it's done.
+		 */
+		RX_BUFF(mac, buf_index) = 0;
+
+		n += 4;
+	}
+
+	if (n > RX_RING_SIZE) {
+		/* Errata 5971 workaround: L2 target of headers */
+		write_iob_reg(mac, PAS_IOB_COM_PKTHDRCNT, 0);
+		n &= (RX_RING_SIZE-1);
 	}
 
-	mac->rx->next_to_clean += limit - count;
-	pasemi_mac_replenish_rx_ring(mac->netdev, limit-count);
+	mac->rx->next_to_clean = n;
+
+	/* Increase is in number of 16-byte entries, and since each descriptor
+	 * with an 8BRES takes up 3x8 bytes (padded to 4x8), increase with
+	 * count*2.
+	 */
+	write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), count << 1);
+
+	pasemi_mac_replenish_rx_ring(mac->netdev, count);
 
 	spin_unlock(&mac->rx->lock);
 
 	return count;
 }
 
+/* Can't make this too large or we blow the kernel stack limits */
+#define TX_CLEAN_BATCHSIZE (128/MAX_SKB_FRAGS)
+
 static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
 {
-	int i;
-	struct pasemi_mac_buffer *info;
-	struct pas_dma_xct_descr *dp;
-	unsigned int start, count, limit;
+	int i, j;
+	unsigned int start, descr_count, buf_count, batch_limit;
+	unsigned int ring_limit;
 	unsigned int total_count;
 	unsigned long flags;
-	struct sk_buff *skbs[32];
-	dma_addr_t dmas[32];
+	struct sk_buff *skbs[TX_CLEAN_BATCHSIZE];
+	dma_addr_t dmas[TX_CLEAN_BATCHSIZE][MAX_SKB_FRAGS+1];
 
 	total_count = 0;
+	batch_limit = TX_CLEAN_BATCHSIZE;
 restart:
 	spin_lock_irqsave(&mac->tx->lock, flags);
 
 	start = mac->tx->next_to_clean;
-	limit = min(mac->tx->next_to_fill, start+32);
+	ring_limit = mac->tx->next_to_fill;
 
-	count = 0;
+	/* Compensate for when fill has wrapped but clean has not */
+	if (start > ring_limit)
+		ring_limit += TX_RING_SIZE;
+
+	buf_count = 0;
+	descr_count = 0;
+
+	for (i = start;
+	     descr_count < batch_limit && i < ring_limit;
+	     i += buf_count) {
+		u64 mactx = TX_RING(mac, i);
+		struct sk_buff *skb;
 
-	for (i = start; i < limit; i++) {
-		dp = &TX_DESC(mac, i);
+		if ((mactx  & XCT_MACTX_E) ||
+		    (*mac->tx_status & PAS_STATUS_ERROR))
+			pasemi_mac_tx_error(mac, mactx);
 
-		if (unlikely(dp->mactx & XCT_MACTX_O))
+		if (unlikely(mactx & XCT_MACTX_O))
 			/* Not yet transmitted */
 			break;
 
-		info = &TX_DESC_INFO(mac, i);
-		skbs[count] = info->skb;
-		dmas[count] = info->dma;
+		skb = TX_RING_INFO(mac, i+1).skb;
+		skbs[descr_count] = skb;
 
-		info->skb = NULL;
-		info->dma = 0;
-		dp->mactx = 0;
-		dp->ptr = 0;
+		buf_count = 2 + skb_shinfo(skb)->nr_frags;
+		for (j = 0; j <= skb_shinfo(skb)->nr_frags; j++)
+			dmas[descr_count][j] = TX_RING_INFO(mac, i+1+j).dma;
+
+		TX_RING(mac, i) = 0;
+		TX_RING(mac, i+1) = 0;
 
-		count++;
+		/* Since we always fill with an even number of entries, make
+		 * sure we skip any unused one at the end as well.
+		 */
+		if (buf_count & 1)
+			buf_count++;
+		descr_count++;
 	}
-	mac->tx->next_to_clean += count;
+	mac->tx->next_to_clean = i & (TX_RING_SIZE-1);
+
 	spin_unlock_irqrestore(&mac->tx->lock, flags);
 	netif_wake_queue(mac->netdev);
 
-	for (i = 0; i < count; i++) {
-		pci_unmap_single(mac->dma_pdev, dmas[i],
-				 skbs[i]->len, PCI_DMA_TODEVICE);
-		dev_kfree_skb_irq(skbs[i]);
-	}
+	for (i = 0; i < descr_count; i++)
+		pasemi_mac_unmap_tx_skb(mac, skbs[i], dmas[i]);
 
-	total_count += count;
+	total_count += descr_count;
 
 	/* If the batch was full, try to clean more */
-	if (count == 32)
+	if (descr_count == batch_limit)
 		goto restart;
 
 	return total_count;
@@ -607,9 +732,6 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
 	if (!(*mac->rx_status & PAS_STATUS_CAUSE_M))
 		return IRQ_NONE;
 
-	if (*mac->rx_status & PAS_STATUS_ERROR)
-		printk("rx_status reported error\n");
-
 	/* Don't reset packet count so it won't fire again but clear
 	 * all others.
 	 */
@@ -809,19 +931,32 @@ static int pasemi_mac_open(struct net_device *dev)
 
 	/* enable rx if */
 	write_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
-			   PAS_DMA_RXINT_RCMDSTA_EN);
+			   PAS_DMA_RXINT_RCMDSTA_EN |
+			   PAS_DMA_RXINT_RCMDSTA_DROPS_M |
+			   PAS_DMA_RXINT_RCMDSTA_BP |
+			   PAS_DMA_RXINT_RCMDSTA_OO |
+			   PAS_DMA_RXINT_RCMDSTA_BT);
 
 	/* enable rx channel */
 	write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
 			   PAS_DMA_RXCHAN_CCMDSTA_EN |
-			   PAS_DMA_RXCHAN_CCMDSTA_DU);
+			   PAS_DMA_RXCHAN_CCMDSTA_DU |
+			   PAS_DMA_RXCHAN_CCMDSTA_OD |
+			   PAS_DMA_RXCHAN_CCMDSTA_FD |
+			   PAS_DMA_RXCHAN_CCMDSTA_DT);
 
 	/* enable tx channel */
 	write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
-			   PAS_DMA_TXCHAN_TCMDSTA_EN);
+			   PAS_DMA_TXCHAN_TCMDSTA_EN |
+			   PAS_DMA_TXCHAN_TCMDSTA_SZ |
+			   PAS_DMA_TXCHAN_TCMDSTA_DB |
+			   PAS_DMA_TXCHAN_TCMDSTA_DE |
+			   PAS_DMA_TXCHAN_TCMDSTA_DA);
 
 	pasemi_mac_replenish_rx_ring(dev, RX_RING_SIZE);
 
+	write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), RX_RING_SIZE>>1);
+
 	flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE |
 		PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE;
 
@@ -893,7 +1028,7 @@ out_rx_resources:
 static int pasemi_mac_close(struct net_device *dev)
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
-	unsigned int stat;
+	unsigned int sta;
 	int retries;
 
 	if (mac->phydev) {
@@ -904,6 +1039,26 @@ static int pasemi_mac_close(struct net_device *dev)
 	netif_stop_queue(dev);
 	napi_disable(&mac->napi);
 
+	sta = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
+	if (sta & (PAS_DMA_RXINT_RCMDSTA_BP |
+		      PAS_DMA_RXINT_RCMDSTA_OO |
+		      PAS_DMA_RXINT_RCMDSTA_BT))
+		printk(KERN_DEBUG "pasemi_mac: rcmdsta error: 0x%08x\n", sta);
+
+	sta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch));
+	if (sta & (PAS_DMA_RXCHAN_CCMDSTA_DU |
+		     PAS_DMA_RXCHAN_CCMDSTA_OD |
+		     PAS_DMA_RXCHAN_CCMDSTA_FD |
+		     PAS_DMA_RXCHAN_CCMDSTA_DT))
+		printk(KERN_DEBUG "pasemi_mac: ccmdsta error: 0x%08x\n", sta);
+
+	sta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch));
+	if (sta & (PAS_DMA_TXCHAN_TCMDSTA_SZ |
+		      PAS_DMA_TXCHAN_TCMDSTA_DB |
+		      PAS_DMA_TXCHAN_TCMDSTA_DE |
+		      PAS_DMA_TXCHAN_TCMDSTA_DA))
+		printk(KERN_DEBUG "pasemi_mac: tcmdsta error: 0x%08x\n", sta);
+
 	/* Clean out any pending buffers */
 	pasemi_mac_clean_tx(mac);
 	pasemi_mac_clean_rx(mac, RX_RING_SIZE);
@@ -914,33 +1069,33 @@ static int pasemi_mac_close(struct net_device *dev)
 	write_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), PAS_DMA_RXCHAN_CCMDSTA_ST);
 
 	for (retries = 0; retries < MAX_RETRIES; retries++) {
-		stat = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch));
-		if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
+		sta = read_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch));
+		if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT))
 			break;
 		cond_resched();
 	}
 
-	if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
+	if (sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)
 		dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n");
 
 	for (retries = 0; retries < MAX_RETRIES; retries++) {
-		stat = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch));
-		if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT))
+		sta = read_dma_reg(mac, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch));
+		if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT))
 			break;
 		cond_resched();
 	}
 
-	if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)
+	if (sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)
 		dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n");
 
 	for (retries = 0; retries < MAX_RETRIES; retries++) {
-		stat = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
-		if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT))
+		sta = read_dma_reg(mac, PAS_DMA_RXINT_RCMDSTA(mac->dma_if));
+		if (!(sta & PAS_DMA_RXINT_RCMDSTA_ACT))
 			break;
 		cond_resched();
 	}
 
-	if (stat & PAS_DMA_RXINT_RCMDSTA_ACT)
+	if (sta & PAS_DMA_RXINT_RCMDSTA_ACT)
 		dev_err(&mac->dma_pdev->dev, "Failed to stop rx interface\n");
 
 	/* Then, disable the channel. This must be done separately from
@@ -965,11 +1120,11 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
 	struct pasemi_mac_txring *txring;
-	struct pasemi_mac_buffer *info;
-	struct pas_dma_xct_descr *dp;
-	u64 dflags, mactx, ptr;
-	dma_addr_t map;
+	u64 dflags, mactx;
+	dma_addr_t map[MAX_SKB_FRAGS+1];
+	unsigned int map_size[MAX_SKB_FRAGS+1];
 	unsigned long flags;
+	int i, nfrags;
 
 	dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_SS | XCT_MACTX_CRC_PAD;
 
@@ -990,54 +1145,78 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 
-	map = pci_map_single(mac->dma_pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
+	nfrags = skb_shinfo(skb)->nr_frags;
+
+	map[0] = pci_map_single(mac->dma_pdev, skb->data, skb_headlen(skb),
+				PCI_DMA_TODEVICE);
+	map_size[0] = skb_headlen(skb);
+	if (dma_mapping_error(map[0]))
+		goto out_err_nolock;
 
-	if (dma_mapping_error(map))
-		return NETDEV_TX_BUSY;
+	for (i = 0; i < nfrags; i++) {
+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+		map[i+1] = pci_map_page(mac->dma_pdev, frag->page,
+					frag->page_offset, frag->size,
+					PCI_DMA_TODEVICE);
+		map_size[i+1] = frag->size;
+		if (dma_mapping_error(map[i+1])) {
+			nfrags = i;
+			goto out_err_nolock;
+		}
+	}
 
 	mactx = dflags | XCT_MACTX_LLEN(skb->len);
-	ptr   = XCT_PTR_LEN(skb->len) | XCT_PTR_ADDR(map);
 
 	txring = mac->tx;
 
 	spin_lock_irqsave(&txring->lock, flags);
 
-	if (RING_AVAIL(txring) <= 1) {
-		spin_unlock_irqrestore(&txring->lock, flags);
-		pasemi_mac_clean_tx(mac);
-		pasemi_mac_restart_tx_intr(mac);
-		spin_lock_irqsave(&txring->lock, flags);
-
-		if (RING_AVAIL(txring) <= 1) {
-			/* Still no room -- stop the queue and wait for tx
-			 * intr when there's room.
-			 */
-			netif_stop_queue(dev);
-			goto out_err;
-		}
+	/* Avoid stepping on the same cache line that the DMA controller
+	 * is currently about to send, so leave at least 8 words available.
+	 * Total free space needed is mactx + fragments + 8
+	 */
+	if (RING_AVAIL(txring) < nfrags + 10) {
+		/* no room -- stop the queue and wait for tx intr */
+		netif_stop_queue(dev);
+		goto out_err;
+	}
+
+	TX_RING(mac, txring->next_to_fill) = mactx;
+	txring->next_to_fill++;
+	TX_RING_INFO(mac, txring->next_to_fill).skb = skb;
+	for (i = 0; i <= nfrags; i++) {
+		TX_RING(mac, txring->next_to_fill+i) =
+		XCT_PTR_LEN(map_size[i]) | XCT_PTR_ADDR(map[i]);
+		TX_RING_INFO(mac, txring->next_to_fill+i).dma = map[i];
 	}
 
-	dp = &TX_DESC(mac, txring->next_to_fill);
-	info = &TX_DESC_INFO(mac, txring->next_to_fill);
+	/* We have to add an even number of 8-byte entries to the ring
+	 * even if the last one is unused. That means always an odd number
+	 * of pointers + one mactx descriptor.
+	 */
+	if (nfrags & 1)
+		nfrags++;
 
-	dp->mactx = mactx;
-	dp->ptr   = ptr;
-	info->dma = map;
-	info->skb = skb;
+	txring->next_to_fill = (txring->next_to_fill + nfrags + 1) &
+				(TX_RING_SIZE-1);
 
-	txring->next_to_fill++;
 	dev->stats.tx_packets++;
 	dev->stats.tx_bytes += skb->len;
 
 	spin_unlock_irqrestore(&txring->lock, flags);
 
-	write_dma_reg(mac, PAS_DMA_TXCHAN_INCR(mac->dma_txch), 1);
+	write_dma_reg(mac, PAS_DMA_TXCHAN_INCR(mac->dma_txch), (nfrags+2) >> 1);
 
 	return NETDEV_TX_OK;
 
 out_err:
 	spin_unlock_irqrestore(&txring->lock, flags);
-	pci_unmap_single(mac->dma_pdev, map, skb->len, PCI_DMA_TODEVICE);
+out_err_nolock:
+	while (nfrags--)
+		pci_unmap_single(mac->dma_pdev, map[nfrags], map_size[nfrags],
+				 PCI_DMA_TODEVICE);
+
 	return NETDEV_TX_BUSY;
 }
 
@@ -1173,7 +1352,7 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 	netif_napi_add(dev, &mac->napi, pasemi_mac_poll, 64);
 
-	dev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX;
+	dev->features = NETIF_F_HW_CSUM | NETIF_F_LLTX | NETIF_F_SG;
 
 	/* These should come out of the device tree eventually */
 	mac->dma_txch = index;
@@ -1230,7 +1409,7 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		dev_err(&mac->pdev->dev, "register_netdev failed with error %d\n",
 			err);
 		goto out;
-	} else
+	} else if netif_msg_probe(mac)
 		printk(KERN_INFO "%s: PA Semi %s: intf %d, txch %d, rxch %d, "
 		       "hw addr %s\n",
 		       dev->name, mac->type == MAC_TYPE_GMAC ? "GMAC" : "XAUI",
diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
index c52cfcb..60368df 100644
--- a/drivers/net/pasemi_mac.h
+++ b/drivers/net/pasemi_mac.h
@@ -28,25 +28,25 @@
 
 struct pasemi_mac_txring {
 	spinlock_t	 lock;
-	struct pas_dma_xct_descr	*desc;
+	u64		*ring;
 	dma_addr_t	 dma;
 	unsigned int	 size;
 	unsigned int	 next_to_fill;
 	unsigned int	 next_to_clean;
-	struct pasemi_mac_buffer *desc_info;
+	struct pasemi_mac_buffer *ring_info;
 	char		 irq_name[10];  /* "eth%d tx" */
 };
 
 struct pasemi_mac_rxring {
 	spinlock_t	 lock;
-	struct pas_dma_xct_descr	*desc;	/* RX channel descriptor ring */
+	u64		*ring;	/* RX channel descriptor ring */
 	dma_addr_t	 dma;
 	u64		*buffers;	/* RX interface buffer ring */
 	dma_addr_t	 buf_dma;
 	unsigned int	 size;
 	unsigned int	 next_to_fill;
 	unsigned int	 next_to_clean;
-	struct pasemi_mac_buffer *desc_info;
+	struct pasemi_mac_buffer *ring_info;
 	char		 irq_name[10];  /* "eth%d rx" */
 };
 
@@ -88,7 +88,7 @@ struct pasemi_mac {
 	char	phy_id[BUS_ID_SIZE];
 };
 
-/* Software status descriptor (desc_info) */
+/* Software status descriptor (ring_info) */
 struct pasemi_mac_buffer {
 	struct sk_buff *skb;
 	dma_addr_t	dma;
@@ -101,20 +101,7 @@ struct pasdma_status {
 	u64 tx_sta[20];
 };
 
-/* descriptor structure */
-struct pas_dma_xct_descr {
-	union {
-		u64	mactx;
-		u64	macrx;
-	};
-	union {
-		u64	ptr;
-		u64	rxb;
-	};
-};
-
 /* MAC CFG register offsets */
-
 enum {
 	PAS_MAC_CFG_PCFG = 0x80,
 	PAS_MAC_CFG_TXP = 0x98,
@@ -219,10 +206,16 @@ enum {
 #define    PAS_DMA_RXINT_RCMDSTA_DROPS_M	0xfffe0000
 #define    PAS_DMA_RXINT_RCMDSTA_DROPS_S	17
 #define PAS_DMA_RXINT_CFG(i)		(0x204+(i)*_PAS_DMA_RXINT_STRIDE)
+#define    PAS_DMA_RXINT_CFG_RBP	0x80000000
+#define    PAS_DMA_RXINT_CFG_ITRR	0x40000000
 #define    PAS_DMA_RXINT_CFG_DHL_M	0x07000000
 #define    PAS_DMA_RXINT_CFG_DHL_S	24
 #define    PAS_DMA_RXINT_CFG_DHL(x)	(((x) << PAS_DMA_RXINT_CFG_DHL_S) & \
 					 PAS_DMA_RXINT_CFG_DHL_M)
+#define    PAS_DMA_RXINT_CFG_ITR	0x00400000
+#define    PAS_DMA_RXINT_CFG_LW		0x00200000
+#define    PAS_DMA_RXINT_CFG_L2		0x00100000
+#define    PAS_DMA_RXINT_CFG_HEN	0x00080000
 #define    PAS_DMA_RXINT_CFG_WIF	0x00000002
 #define    PAS_DMA_RXINT_CFG_WIL	0x00000001
 
@@ -252,6 +245,10 @@ enum {
 #define    PAS_DMA_TXCHAN_TCMDSTA_EN	0x00000001	/* Enabled */
 #define    PAS_DMA_TXCHAN_TCMDSTA_ST	0x00000002	/* Stop interface */
 #define    PAS_DMA_TXCHAN_TCMDSTA_ACT	0x00010000	/* Active */
+#define    PAS_DMA_TXCHAN_TCMDSTA_SZ	0x00000800
+#define    PAS_DMA_TXCHAN_TCMDSTA_DB	0x00000400
+#define    PAS_DMA_TXCHAN_TCMDSTA_DE	0x00000200
+#define    PAS_DMA_TXCHAN_TCMDSTA_DA	0x00000100
 #define PAS_DMA_TXCHAN_CFG(c)     (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
 #define    PAS_DMA_TXCHAN_CFG_TY_IFACE	0x00000000	/* Type = interface */
 #define    PAS_DMA_TXCHAN_CFG_TATTR_M	0x0000003c
@@ -262,9 +259,11 @@ enum {
 #define    PAS_DMA_TXCHAN_CFG_WT_S	6
 #define    PAS_DMA_TXCHAN_CFG_WT(x)	(((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
 					 PAS_DMA_TXCHAN_CFG_WT_M)
-#define    PAS_DMA_TXCHAN_CFG_CF	0x00001000	/* Clean first line */
-#define    PAS_DMA_TXCHAN_CFG_CL	0x00002000	/* Clean last line */
+#define    PAS_DMA_TXCHAN_CFG_TRD	0x00010000	/* translate data */
+#define    PAS_DMA_TXCHAN_CFG_TRR	0x00008000	/* translate rings */
 #define    PAS_DMA_TXCHAN_CFG_UP	0x00004000	/* update tx descr when sent */
+#define    PAS_DMA_TXCHAN_CFG_CL	0x00002000	/* Clean last line */
+#define    PAS_DMA_TXCHAN_CFG_CF	0x00001000	/* Clean first line */
 #define PAS_DMA_TXCHAN_INCR(c)    (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
 #define PAS_DMA_TXCHAN_BASEL(c)   (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
 #define    PAS_DMA_TXCHAN_BASEL_BRBL_M	0xffffffc0
@@ -294,7 +293,11 @@ enum {
 #define    PAS_DMA_RXCHAN_CCMDSTA_ST	0x00000002	/* Stop interface */
 #define    PAS_DMA_RXCHAN_CCMDSTA_ACT	0x00010000	/* Active */
 #define    PAS_DMA_RXCHAN_CCMDSTA_DU	0x00020000
+#define    PAS_DMA_RXCHAN_CCMDSTA_OD	0x00002000
+#define    PAS_DMA_RXCHAN_CCMDSTA_FD	0x00001000
+#define    PAS_DMA_RXCHAN_CCMDSTA_DT	0x00000800
 #define PAS_DMA_RXCHAN_CFG(c)     (0x804+(c)*_PAS_DMA_RXCHAN_STRIDE)
+#define    PAS_DMA_RXCHAN_CFG_CTR	0x00000400
 #define    PAS_DMA_RXCHAN_CFG_HBU_M	0x00000380
 #define    PAS_DMA_RXCHAN_CFG_HBU_S	7
 #define    PAS_DMA_RXCHAN_CFG_HBU(x)	(((x) << PAS_DMA_RXCHAN_CFG_HBU_S) & \
@@ -328,6 +331,12 @@ enum {
 #define    PAS_STATUS_SOFT		0x4000000000000000ull
 #define    PAS_STATUS_INT		0x8000000000000000ull
 
+#define PAS_IOB_COM_PKTHDRCNT		0x120
+#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR1_M	0x0fff0000
+#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR1_S	16
+#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR0_M	0x00000fff
+#define    PAS_IOB_COM_PKTHDRCNT_PKTHDR0_S	0
+
 #define PAS_IOB_DMA_RXCH_CFG(i)		(0x1100 + (i)*4)
 #define    PAS_IOB_DMA_RXCH_CFG_CNTTH_M		0x00000fff
 #define    PAS_IOB_DMA_RXCH_CFG_CNTTH_S		0
@@ -423,10 +432,9 @@ enum {
 /* Receive descriptor fields */
 #define	XCT_MACRX_T		0x8000000000000000ull
 #define	XCT_MACRX_ST		0x4000000000000000ull
-#define XCT_MACRX_NORES		0x0000000000000000ull
-#define XCT_MACRX_8BRES		0x1000000000000000ull
-#define XCT_MACRX_24BRES	0x2000000000000000ull
-#define XCT_MACRX_40BRES	0x3000000000000000ull
+#define XCT_MACRX_RR_M		0x3000000000000000ull
+#define XCT_MACRX_RR_NORES	0x0000000000000000ull
+#define XCT_MACRX_RR_8BRES	0x1000000000000000ull
 #define XCT_MACRX_O		0x0400000000000000ull
 #define XCT_MACRX_E		0x0200000000000000ull
 #define XCT_MACRX_FF		0x0100000000000000ull
@@ -474,6 +482,17 @@ enum {
 #define XCT_PTR_ADDR(x)		((((long)(x)) << XCT_PTR_ADDR_S) & \
 				 XCT_PTR_ADDR_M)
 
+/* Receive interface 8byte result fields */
+#define XCT_RXRES_8B_L4O_M	0xff00000000000000ull
+#define XCT_RXRES_8B_L4O_S	56
+#define XCT_RXRES_8B_RULE_M	0x00ffff0000000000ull
+#define XCT_RXRES_8B_RULE_S	40
+#define XCT_RXRES_8B_EVAL_M	0x000000ffff000000ull
+#define XCT_RXRES_8B_EVAL_S	24
+#define XCT_RXRES_8B_HTYPE_M	0x0000000000f00000ull
+#define XCT_RXRES_8B_HASH_M	0x00000000000fffffull
+#define XCT_RXRES_8B_HASH_S	0
+
 /* Receive interface buffer fields */
 #define XCT_RXB_LEN_M		0x0ffff00000000000ull
 #define XCT_RXB_LEN_S		44
diff --git a/drivers/net/qla3xxx.c b/drivers/net/qla3xxx.c
old mode 100755
new mode 100644
index 7907da1..6dad20e
--- a/drivers/net/qla3xxx.c
+++ b/drivers/net/qla3xxx.c
@@ -81,7 +81,7 @@ typedef enum {
 } PHY_DEVICE_et;
 
 typedef struct {
-	PHY_DEVICE_et phyDevice; 
+	PHY_DEVICE_et phyDevice;
 	u32		phyIdOUI;
 	u16		phyIdModel;
 	char 		*name;
@@ -330,7 +330,7 @@ static void ql_release_to_lrg_buf_free_list(struct ql3_adapter *qdev,
 					     PCI_DMA_FROMDEVICE);
 			err = pci_dma_mapping_error(map);
 			if(err) {
-				printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", 
+				printk(KERN_ERR "%s: PCI mapping failed with error: %d\n",
 				       qdev->ndev->name, err);
 				dev_kfree_skb(lrg_buf_cb->skb);
 				lrg_buf_cb->skb = NULL;
@@ -884,14 +884,14 @@ static void ql_petbi_start_neg_ex(struct ql3_adapter *qdev)
 	u16 reg;
 
 	/* Enable Auto-negotiation sense */
-	ql_mii_read_reg_ex(qdev, PETBI_TBI_CTRL, &reg, 
+	ql_mii_read_reg_ex(qdev, PETBI_TBI_CTRL, &reg,
 			   PHYAddr[qdev->mac_index]);
 	reg |= PETBI_TBI_AUTO_SENSE;
-	ql_mii_write_reg_ex(qdev, PETBI_TBI_CTRL, reg, 
+	ql_mii_write_reg_ex(qdev, PETBI_TBI_CTRL, reg,
 			    PHYAddr[qdev->mac_index]);
 
 	ql_mii_write_reg_ex(qdev, PETBI_NEG_ADVER,
-			    PETBI_NEG_PAUSE | PETBI_NEG_DUPLEX, 
+			    PETBI_NEG_PAUSE | PETBI_NEG_DUPLEX,
 			    PHYAddr[qdev->mac_index]);
 
 	ql_mii_write_reg_ex(qdev, PETBI_CONTROL_REG,
@@ -945,7 +945,7 @@ static void phyAgereSpecificInit(struct ql3_adapter *qdev, u32 miiAddr)
 	ql_mii_write_reg_ex(qdev, 0x10, 0x2806, miiAddr);
 	/* Write new PHYAD w/bit 5 set */
 	ql_mii_write_reg_ex(qdev, 0x11, 0x0020 | (PHYAddr[qdev->mac_index] >> 8), miiAddr);
-	/* 
+	/*
 	 * Disable diagnostic mode bit 2 = 0
 	 * Power up device bit 11 = 0
 	 * Link up (on) and activity (blink)
@@ -955,18 +955,18 @@ static void phyAgereSpecificInit(struct ql3_adapter *qdev, u32 miiAddr)
 	ql_mii_write_reg(qdev, 0x1c, 0xfaf0);
 }
 
-static PHY_DEVICE_et getPhyType (struct ql3_adapter *qdev, 
+static PHY_DEVICE_et getPhyType (struct ql3_adapter *qdev,
 				 u16 phyIdReg0, u16 phyIdReg1)
 {
 	PHY_DEVICE_et result = PHY_TYPE_UNKNOWN;
-	u32   oui;     
+	u32   oui;
 	u16   model;
-	int i;   
+	int i;
 
 	if (phyIdReg0 == 0xffff) {
 		return result;
 	}
-   
+
 	if (phyIdReg1 == 0xffff) {
 		return result;
 	}
@@ -984,7 +984,7 @@ static PHY_DEVICE_et getPhyType (struct ql3_adapter *qdev,
 
 			printk(KERN_INFO "%s: Phy: %s\n",
 				qdev->ndev->name, PHY_DEVICES[i].name);
-			
+
 		        break;
 		}
 	}
@@ -1033,7 +1033,7 @@ static int ql_is_full_dup(struct ql3_adapter *qdev)
 	{
 		if (ql_mii_read_reg(qdev, 0x1A, &reg))
 			return 0;
-			
+
 		return ((reg & 0x0080) && (reg & 0x1000)) != 0;
 	}
 	case PHY_VITESSE_VSC8211:
@@ -1082,19 +1082,19 @@ static int PHY_Setup(struct ql3_adapter *qdev)
 	/*  Check if we have a Agere PHY */
 	if ((reg1 == 0xffff) || (reg2 == 0xffff)) {
 
-		/* Determine which MII address we should be using 
+		/* Determine which MII address we should be using
 		   determined by the index of the card */
 		if (qdev->mac_index == 0) {
 			miiAddr = MII_AGERE_ADDR_1;
 		} else {
 			miiAddr = MII_AGERE_ADDR_2;
 		}
-      
+
 		err =ql_mii_read_reg_ex(qdev, PHY_ID_0_REG, &reg1, miiAddr);
 		if(err != 0) {
 			printk(KERN_ERR "%s: Could not read from reg PHY_ID_0_REG after Agere detected\n",
 		       	       qdev->ndev->name);
-                	return err; 
+                	return err;
 		}
 
 		err = ql_mii_read_reg_ex(qdev, PHY_ID_1_REG, &reg2, miiAddr);
@@ -1103,9 +1103,9 @@ static int PHY_Setup(struct ql3_adapter *qdev)
 			       qdev->ndev->name);
         	        return err;
 		}
-   
+
 		/*  We need to remember to initialize the Agere PHY */
-         	agereAddrChangeNeeded = true; 
+         	agereAddrChangeNeeded = true;
 	}
 
 	/*  Determine the particular PHY we have on board to apply
@@ -1114,7 +1114,7 @@ static int PHY_Setup(struct ql3_adapter *qdev)
 
 	if ((qdev->phyType == PHY_AGERE_ET1011C) && agereAddrChangeNeeded) {
 		/* need this here so address gets changed */
-		phyAgereSpecificInit(qdev, miiAddr);  
+		phyAgereSpecificInit(qdev, miiAddr);
 	} else if (qdev->phyType == PHY_TYPE_UNKNOWN) {
 		printk(KERN_ERR "%s: PHY is unknown\n", qdev->ndev->name);
 		return -EIO;
@@ -1427,7 +1427,7 @@ static int ql_this_adapter_controls_port(struct ql3_adapter *qdev)
 
 static void ql_phy_reset_ex(struct ql3_adapter *qdev)
 {
-	ql_mii_write_reg_ex(qdev, CONTROL_REG, PHY_CTRL_SOFT_RESET, 
+	ql_mii_write_reg_ex(qdev, CONTROL_REG, PHY_CTRL_SOFT_RESET,
 			    PHYAddr[qdev->mac_index]);
 }
 
@@ -1438,7 +1438,7 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev)
 
 	if(qdev->phyType == PHY_AGERE_ET1011C) {
 		/* turn off external loopback */
-		ql_mii_write_reg(qdev, 0x13, 0x0000); 
+		ql_mii_write_reg(qdev, 0x13, 0x0000);
 	}
 
 	if(qdev->mac_index == 0)
@@ -1452,23 +1452,23 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev)
 		portConfiguration = PORT_CONFIG_DEFAULT;
 
 	/* Set the 1000 advertisements */
-	ql_mii_read_reg_ex(qdev, PHY_GIG_CONTROL, &reg, 
+	ql_mii_read_reg_ex(qdev, PHY_GIG_CONTROL, &reg,
 			   PHYAddr[qdev->mac_index]);
 	reg &= ~PHY_GIG_ALL_PARAMS;
 
-	if(portConfiguration & 
+	if(portConfiguration &
 	   PORT_CONFIG_FULL_DUPLEX_ENABLED &
 	   PORT_CONFIG_1000MB_SPEED) {
 		reg |= PHY_GIG_ADV_1000F;
 	}
-	 
-	if(portConfiguration & 
+
+	if(portConfiguration &
 	   PORT_CONFIG_HALF_DUPLEX_ENABLED &
 	   PORT_CONFIG_1000MB_SPEED) {
 		reg |= PHY_GIG_ADV_1000H;
 	}
 
-	ql_mii_write_reg_ex(qdev, PHY_GIG_CONTROL, reg, 
+	ql_mii_write_reg_ex(qdev, PHY_GIG_CONTROL, reg,
 			    PHYAddr[qdev->mac_index]);
 
 	/* Set the 10/100 & pause negotiation advertisements */
@@ -1482,7 +1482,7 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev)
 	if(portConfiguration & PORT_CONFIG_FULL_DUPLEX_ENABLED) {
 		if(portConfiguration & PORT_CONFIG_100MB_SPEED)
 			reg |= PHY_NEG_ADV_100F;
-		
+
 		if(portConfiguration & PORT_CONFIG_10MB_SPEED)
 			reg |= PHY_NEG_ADV_10F;
 	}
@@ -1490,22 +1490,22 @@ static void ql_phy_start_neg_ex(struct ql3_adapter *qdev)
 	if(portConfiguration & PORT_CONFIG_HALF_DUPLEX_ENABLED) {
 		if(portConfiguration & PORT_CONFIG_100MB_SPEED)
 			reg |= PHY_NEG_ADV_100H;
-		
+
 		if(portConfiguration & PORT_CONFIG_10MB_SPEED)
 			reg |= PHY_NEG_ADV_10H;
 	}
 
 	if(portConfiguration &
 	   PORT_CONFIG_1000MB_SPEED) {
-		reg |= 1;	
+		reg |= 1;
 	}
 
-	ql_mii_write_reg_ex(qdev, PHY_NEG_ADVER, reg, 
+	ql_mii_write_reg_ex(qdev, PHY_NEG_ADVER, reg,
 			    PHYAddr[qdev->mac_index]);
 
 	ql_mii_read_reg_ex(qdev, CONTROL_REG, &reg, PHYAddr[qdev->mac_index]);
-	
-	ql_mii_write_reg_ex(qdev, CONTROL_REG, 
+
+	ql_mii_write_reg_ex(qdev, CONTROL_REG,
 			    reg | PHY_CTRL_RESTART_NEG | PHY_CTRL_AUTO_NEG,
 			    PHYAddr[qdev->mac_index]);
 }
@@ -1660,7 +1660,7 @@ static void ql_link_state_machine(struct ql3_adapter *qdev)
 			       "%s: Reset in progress, skip processing link "
 			       "state.\n", qdev->ndev->name);
 
-		spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);		
+		spin_unlock_irqrestore(&qdev->hw_lock, hw_flags);
 		return;
 	}
 
@@ -1752,7 +1752,7 @@ static int ql_mii_setup(struct ql3_adapter *qdev)
 		return -1;
 
 	if (qdev->device_id == QL3032_DEVICE_ID)
-		ql_write_page0_reg(qdev, 
+		ql_write_page0_reg(qdev,
 			&port_regs->macMIIMgmtControlReg, 0x0f00000);
 
 	/* Divide 125MHz clock by 28 to meet PHY timing requirements */
@@ -1936,7 +1936,7 @@ static int ql_populate_free_queue(struct ql3_adapter *qdev)
 
 				err = pci_dma_mapping_error(map);
 				if(err) {
-					printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", 
+					printk(KERN_ERR "%s: PCI mapping failed with error: %d\n",
 					       qdev->ndev->name, err);
 					dev_kfree_skb(lrg_buf_cb->skb);
 					lrg_buf_cb->skb = NULL;
@@ -2044,7 +2044,7 @@ static void ql_process_mac_tx_intr(struct ql3_adapter *qdev,
 	if(mac_rsp->flags & OB_MAC_IOCB_RSP_S) {
 		printk(KERN_WARNING "Frame short but, frame was padded and sent.\n");
 	}
-	
+
 	tx_cb = &qdev->tx_buf[mac_rsp->transaction_id];
 
 	/*  Check the transmit response flags for any errors */
@@ -2108,13 +2108,13 @@ static struct ql_rcv_buf_cb *ql_get_lbuf(struct ql3_adapter *qdev)
 
 /*
  * The difference between 3022 and 3032 for inbound completions:
- * 3022 uses two buffers per completion.  The first buffer contains 
- * (some) header info, the second the remainder of the headers plus 
- * the data.  For this chip we reserve some space at the top of the 
- * receive buffer so that the header info in buffer one can be 
- * prepended to the buffer two.  Buffer two is the sent up while 
+ * 3022 uses two buffers per completion.  The first buffer contains
+ * (some) header info, the second the remainder of the headers plus
+ * the data.  For this chip we reserve some space at the top of the
+ * receive buffer so that the header info in buffer one can be
+ * prepended to the buffer two.  Buffer two is the sent up while
  * buffer one is returned to the hardware to be reused.
- * 3032 receives all of it's data and headers in one buffer for a 
+ * 3032 receives all of it's data and headers in one buffer for a
  * simpler process.  3032 also supports checksum verification as
  * can be seen in ql_process_macip_rx_intr().
  */
@@ -2205,13 +2205,13 @@ static void ql_process_macip_rx_intr(struct ql3_adapter *qdev,
 						 skb_push(skb2, size), size);
 	} else {
 		u16 checksum = le16_to_cpu(ib_ip_rsp_ptr->checksum);
-		if (checksum & 
-			(IB_IP_IOCB_RSP_3032_ICE | 
-			 IB_IP_IOCB_RSP_3032_CE)) { 
+		if (checksum &
+			(IB_IP_IOCB_RSP_3032_ICE |
+			 IB_IP_IOCB_RSP_3032_CE)) {
 			printk(KERN_ERR
 			       "%s: Bad checksum for this %s packet, checksum = %x.\n",
 			       __func__,
-			       ((checksum & 
+			       ((checksum &
 				IB_IP_IOCB_RSP_3032_TCP) ? "TCP" :
 				"UDP"),checksum);
 		} else if ((checksum & IB_IP_IOCB_RSP_3032_TCP) ||
@@ -2387,12 +2387,12 @@ static irqreturn_t ql3xxx_isr(int irq, void *dev_id)
 }
 
 /*
- * Get the total number of segments needed for the 
+ * Get the total number of segments needed for the
  * given number of fragments.  This is necessary because
  * outbound address lists (OAL) will be used when more than
- * two frags are given.  Each address list has 5 addr/len 
+ * two frags are given.  Each address list has 5 addr/len
  * pairs.  The 5th pair in each AOL is used to  point to
- * the next AOL if more frags are coming.  
+ * the next AOL if more frags are coming.
  * That is why the frags:segment count  ratio is not linear.
  */
 static int ql_get_seg_count(struct ql3_adapter *qdev,
@@ -2469,12 +2469,12 @@ static int ql_send_map(struct ql3_adapter *qdev,
 
 	err = pci_dma_mapping_error(map);
 	if(err) {
-		printk(KERN_ERR "%s: PCI mapping failed with error: %d\n", 
+		printk(KERN_ERR "%s: PCI mapping failed with error: %d\n",
 		       qdev->ndev->name, err);
 
 		return NETDEV_TX_BUSY;
 	}
-	
+
 	oal_entry = (struct oal_entry *)&mac_iocb_ptr->buf_addr0_low;
 	oal_entry->dma_lo = cpu_to_le32(LS_64BITS(map));
 	oal_entry->dma_hi = cpu_to_le32(MS_64BITS(map));
@@ -2504,7 +2504,7 @@ static int ql_send_map(struct ql3_adapter *qdev,
 				err = pci_dma_mapping_error(map);
 				if(err) {
 
-					printk(KERN_ERR "%s: PCI mapping outbound address list with error: %d\n", 
+					printk(KERN_ERR "%s: PCI mapping outbound address list with error: %d\n",
 					       qdev->ndev->name, err);
 					goto map_error;
 				}
@@ -2530,7 +2530,7 @@ static int ql_send_map(struct ql3_adapter *qdev,
 
 			err = pci_dma_mapping_error(map);
 			if(err) {
-				printk(KERN_ERR "%s: PCI mapping frags failed with error: %d\n", 
+				printk(KERN_ERR "%s: PCI mapping frags failed with error: %d\n",
 				       qdev->ndev->name, err);
 				goto map_error;
 			}
@@ -2551,10 +2551,10 @@ static int ql_send_map(struct ql3_adapter *qdev,
 
 map_error:
 	/* A PCI mapping failed and now we will need to back out
-	 * We need to traverse through the oal's and associated pages which 
+	 * We need to traverse through the oal's and associated pages which
 	 * have been mapped and now we must unmap them to clean up properly
 	 */
-	
+
 	seg = 1;
 	oal_entry = (struct oal_entry *)&mac_iocb_ptr->buf_addr0_low;
 	oal = tx_cb->oal;
@@ -2592,11 +2592,11 @@ map_error:
  * The difference between 3022 and 3032 sends:
  * 3022 only supports a simple single segment transmission.
  * 3032 supports checksumming and scatter/gather lists (fragments).
- * The 3032 supports sglists by using the 3 addr/len pairs (ALP) 
- * in the IOCB plus a chain of outbound address lists (OAL) that 
- * each contain 5 ALPs.  The last ALP of the IOCB (3rd) or OAL (5th) 
- * will used to point to an OAL when more ALP entries are required.  
- * The IOCB is always the top of the chain followed by one or more 
+ * The 3032 supports sglists by using the 3 addr/len pairs (ALP)
+ * in the IOCB plus a chain of outbound address lists (OAL) that
+ * each contain 5 ALPs.  The last ALP of the IOCB (3rd) or OAL (5th)
+ * will used to point to an OAL when more ALP entries are required.
+ * The IOCB is always the top of the chain followed by one or more
  * OALs (when necessary).
  */
 static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev)
@@ -2610,14 +2610,14 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev)
 	if (unlikely(atomic_read(&qdev->tx_count) < 2)) {
 		return NETDEV_TX_BUSY;
 	}
-	
+
 	tx_cb = &qdev->tx_buf[qdev->req_producer_index] ;
 	if((tx_cb->seg_count = ql_get_seg_count(qdev,
 						(skb_shinfo(skb)->nr_frags))) == -1) {
 		printk(KERN_ERR PFX"%s: invalid segment count!\n",__func__);
 		return NETDEV_TX_OK;
 	}
-	
+
 	mac_iocb_ptr = tx_cb->queue_entry;
 	memset((void *)mac_iocb_ptr, 0, sizeof(struct ob_mac_iocb_req));
 	mac_iocb_ptr->opcode = qdev->mac_ob_opcode;
@@ -2629,12 +2629,12 @@ static int ql3xxx_send(struct sk_buff *skb, struct net_device *ndev)
 	if (qdev->device_id == QL3032_DEVICE_ID &&
 	    skb->ip_summed == CHECKSUM_PARTIAL)
 		ql_hw_csum_setup(skb, mac_iocb_ptr);
-	
+
 	if(ql_send_map(qdev,mac_iocb_ptr,tx_cb,skb) != NETDEV_TX_OK) {
 		printk(KERN_ERR PFX"%s: Could not map the segments!\n",__func__);
 		return NETDEV_TX_BUSY;
 	}
-	
+
 	wmb();
 	qdev->req_producer_index++;
 	if (qdev->req_producer_index == NUM_REQ_Q_ENTRIES)
@@ -2732,7 +2732,7 @@ static int ql_alloc_buffer_queues(struct ql3_adapter *qdev)
 		       "%s: qdev->lrg_buf alloc failed.\n", qdev->ndev->name);
 		return -ENOMEM;
 	}
-	
+
 	qdev->lrg_buf_q_alloc_virt_addr =
 	    pci_alloc_consistent(qdev->pdev,
 				 qdev->lrg_buf_q_alloc_size,
diff --git a/drivers/net/qla3xxx.h b/drivers/net/qla3xxx.h
old mode 100755
new mode 100644
index 483840f..fbcb0b9
--- a/drivers/net/qla3xxx.h
+++ b/drivers/net/qla3xxx.h
@@ -556,7 +556,7 @@ enum {
 	IP_ADDR_INDEX_REG_FUNC_3_SEC = 0x0007,
 	IP_ADDR_INDEX_REG_6 = 0x0008,
 	IP_ADDR_INDEX_REG_OFFSET_MASK = 0x0030,
-	IP_ADDR_INDEX_REG_E = 0x0040, 
+	IP_ADDR_INDEX_REG_E = 0x0040,
 };
 enum {
 	QL3032_PORT_CONTROL_DS = 0x0001,
@@ -1112,7 +1112,7 @@ struct ql_rcv_buf_cb {
  * OAL has 5 entries:
  * 1 thru 4 point to frags
  * fifth points to next oal.
- */ 
+ */
 #define MAX_OAL_CNT ((MAX_SKB_FRAGS-1)/4 + 1)
 
 struct oal_entry {
@@ -1137,7 +1137,7 @@ struct ql_tx_buf_cb {
 	struct ob_mac_iocb_req *queue_entry ;
 	int seg_count;
 	struct oal *oal;
-	struct map_list map[MAX_SKB_FRAGS+1]; 
+	struct map_list map[MAX_SKB_FRAGS+1];
 };
 
 /* definitions for type field */

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-10-02 17:41 Jeff Garzik
@ 2007-10-02 23:38 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2007-10-02 23:38 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Tue, 2 Oct 2007 13:41:50 -0400

> Please pull from the 'upstream' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream

Pulled and pushed back out to net-2.6.24, thanks Jeff!

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-10-02 17:41 Jeff Garzik
  2007-10-02 23:38 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2007-10-02 17:41 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


[note #0: this is the same additional-push text I give to Linus]


Note:  The changes below are in the same linear history as the
previous push (on Sept 29) -- appended onto that history.  As such,
if you have already pulled that, you will only get the changes below.

If you have NOT pulled the Sept 29 changes, you will get both sets of
changes.


Please pull from the 'upstream' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream

to receive the following changes:

Hans-Jürgen Koch (1):
      Fix a compile problem in macb.c

Jan-Bernd Themann (1):
      ehea: DLPAR memory add fix

Komuro (1):
      PCMCIA-NETDEV : add new id (axnet_cs, pcnet_cs)

Markus Brunner (1):
      smc911x irq sense request and MPR2 board support

Nobuhiro Iwamatsu (1):
      smc91x Hitachi Solution Engine (SuperH) Support

Scott Wood (9):
      fs_enet: Whitespace cleanup.
      fs_enet: Fix build breakage.
      fs_enet: Include linux/string.h from linux/fs_enet_pd.h
      fs_enet: mac-fcc: Eliminate __fcc-* macros.
      fs_enet: Align receive buffers.
      fs_enet: Be an of_platform device when CONFIG_PPC_CPM_NEW_BINDING is set.
      Generic bitbanged MDIO library
      fs_enet: Convert mii-bitbang to use the generic bitbang MDIO code.
      fs_enet: sparse fixes

 drivers/net/Kconfig                |    2 
 drivers/net/ehea/ehea.h            |    4 
 drivers/net/ehea/ehea_main.c       |  276 ++++++++++++++++++++--
 drivers/net/ehea/ehea_phyp.h       |    1 
 drivers/net/ehea/ehea_qmr.c        |   20 -
 drivers/net/ehea/ehea_qmr.h        |    4 
 drivers/net/fs_enet/Kconfig        |    1 
 drivers/net/fs_enet/fs_enet-main.c |  386 +++++++++++++++++++++++++------
 drivers/net/fs_enet/fs_enet.h      |   90 +------
 drivers/net/fs_enet/mac-fcc.c      |  180 +++++++++-----
 drivers/net/fs_enet/mac-fec.c      |   53 ++--
 drivers/net/fs_enet/mac-scc.c      |   90 ++++---
 drivers/net/fs_enet/mii-bitbang.c  |  448 +++++++++++++++++--------------------
 drivers/net/fs_enet/mii-fec.c      |  152 ++++++++++++
 drivers/net/macb.c                 |    4 
 drivers/net/pcmcia/axnet_cs.c      |    1 
 drivers/net/pcmcia/pcnet_cs.c      |    1 
 drivers/net/phy/Kconfig            |    9 
 drivers/net/phy/Makefile           |    1 
 drivers/net/phy/mdio-bitbang.c     |  187 +++++++++++++++
 drivers/net/smc911x.c              |    2 
 drivers/net/smc911x.h              |    6 
 drivers/net/smc91x.h               |    1 
 include/linux/fs_enet_pd.h         |    6 
 include/linux/mdio-bitbang.h       |   42 +++
 25 files changed, 1404 insertions(+), 563 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 45f6cf5..0e48b29 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -944,7 +944,7 @@ config SMC911X
 	tristate "SMSC LAN911[5678] support"
 	select CRC32
 	select MII
-	depends on ARCH_PXA
+	depends on ARCH_PXA || SUPERH
 	help
 	  This is a driver for SMSC's LAN911x series of Ethernet chipsets
 	  including the new LAN9115, LAN9116, LAN9117, and LAN9118.
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index c0cbd94..3022089 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -40,13 +40,13 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0074"
+#define DRV_VERSION	"EHEA_0077"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
 #define DLPAR_MEM_ADD      2
 #define DLPAR_MEM_REM      4
-#define EHEA_CAPABILITIES  (DLPAR_PORT_ADD_REM)
+#define EHEA_CAPABILITIES  (DLPAR_PORT_ADD_REM | DLPAR_MEM_ADD)
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
 	| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 62d6c1e..5bc0a15 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -97,6 +97,7 @@ u64 ehea_driver_flags = 0;
 struct workqueue_struct *ehea_driver_wq;
 struct work_struct ehea_rereg_mr_task;
 
+struct semaphore dlpar_mem_lock;
 
 static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
 					const struct of_device_id *id);
@@ -177,16 +178,24 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
 	struct sk_buff **skb_arr_rq1 = pr->rq1_skba.arr;
 	struct net_device *dev = pr->port->netdev;
 	int max_index_mask = pr->rq1_skba.len - 1;
+	int fill_wqes = pr->rq1_skba.os_skbs + nr_of_wqes;
+	int adder = 0;
 	int i;
 
-	if (!nr_of_wqes)
+	pr->rq1_skba.os_skbs = 0;
+
+	if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) {
+		pr->rq1_skba.index = index;
+		pr->rq1_skba.os_skbs = fill_wqes;
 		return;
+	}
 
-	for (i = 0; i < nr_of_wqes; i++) {
+	for (i = 0; i < fill_wqes; i++) {
 		if (!skb_arr_rq1[index]) {
 			skb_arr_rq1[index] = netdev_alloc_skb(dev,
 							      EHEA_L_PKT_SIZE);
 			if (!skb_arr_rq1[index]) {
+				pr->rq1_skba.os_skbs = fill_wqes - i;
 				ehea_error("%s: no mem for skb/%d wqes filled",
 					   dev->name, i);
 				break;
@@ -194,9 +203,14 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
 		}
 		index--;
 		index &= max_index_mask;
+		adder++;
 	}
+
+	if (adder == 0)
+		return;
+
 	/* Ring doorbell */
-	ehea_update_rq1a(pr->qp, i);
+	ehea_update_rq1a(pr->qp, adder);
 }
 
 static int ehea_init_fill_rq1(struct ehea_port_res *pr, int nr_rq1a)
@@ -230,16 +244,21 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
 	struct sk_buff **skb_arr = q_skba->arr;
 	struct ehea_rwqe *rwqe;
 	int i, index, max_index_mask, fill_wqes;
+	int adder = 0;
 	int ret = 0;
 
 	fill_wqes = q_skba->os_skbs + num_wqes;
+	q_skba->os_skbs = 0;
 
-	if (!fill_wqes)
+	if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) {
+		q_skba->os_skbs = fill_wqes;
 		return ret;
+	}
 
 	index = q_skba->index;
 	max_index_mask = q_skba->len - 1;
 	for (i = 0; i < fill_wqes; i++) {
+		u64 tmp_addr;
 		struct sk_buff *skb = netdev_alloc_skb(dev, packet_size);
 		if (!skb) {
 			ehea_error("%s: no mem for skb/%d wqes filled",
@@ -251,30 +270,37 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
 		skb_reserve(skb, NET_IP_ALIGN);
 
 		skb_arr[index] = skb;
+		tmp_addr = ehea_map_vaddr(skb->data);
+		if (tmp_addr == -1) {
+			dev_kfree_skb(skb);
+			q_skba->os_skbs = fill_wqes - i;
+			ret = 0;
+			break;
+		}
 
 		rwqe = ehea_get_next_rwqe(qp, rq_nr);
 		rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type)
 			    | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index);
 		rwqe->sg_list[0].l_key = pr->recv_mr.lkey;
-		rwqe->sg_list[0].vaddr = ehea_map_vaddr(skb->data);
+		rwqe->sg_list[0].vaddr = tmp_addr;
 		rwqe->sg_list[0].len = packet_size;
 		rwqe->data_segments = 1;
 
 		index++;
 		index &= max_index_mask;
-
-		if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)))
-			goto out;
+		adder++;
 	}
 
 	q_skba->index = index;
+	if (adder == 0)
+		goto out;
 
 	/* Ring doorbell */
 	iosync();
 	if (rq_nr == 2)
-		ehea_update_rq2a(pr->qp, i);
+		ehea_update_rq2a(pr->qp, adder);
 	else
-		ehea_update_rq3a(pr->qp, i);
+		ehea_update_rq3a(pr->qp, adder);
 out:
 	return ret;
 }
@@ -1967,11 +1993,12 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		ehea_dump(swqe, 512, "swqe");
 	}
 
-	if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)))
-		goto out;
+	if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) {
+		netif_stop_queue(dev);
+		swqe->tx_control |= EHEA_SWQE_PURGE;
+	}
 
 	ehea_post_swqe(pr->qp, swqe);
-	pr->tx_packets++;
 
 	if (unlikely(atomic_read(&pr->swqe_avail) <= 1)) {
 		spin_lock_irqsave(&pr->netif_queue, flags);
@@ -1984,7 +2011,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 	dev->trans_start = jiffies;
 	spin_unlock(&pr->xmit_lock);
-out:
+
 	return NETDEV_TX_OK;
 }
 
@@ -2376,6 +2403,192 @@ static int ehea_stop(struct net_device *dev)
 	return ret;
 }
 
+void ehea_purge_sq(struct ehea_qp *orig_qp)
+{
+	struct ehea_qp qp = *orig_qp;
+	struct ehea_qp_init_attr *init_attr = &qp.init_attr;
+	struct ehea_swqe *swqe;
+	int wqe_index;
+	int i;
+
+	for (i = 0; i < init_attr->act_nr_send_wqes; i++) {
+		swqe = ehea_get_swqe(&qp, &wqe_index);
+		swqe->tx_control |= EHEA_SWQE_PURGE;
+	}
+}
+
+int ehea_stop_qps(struct net_device *dev)
+{
+	struct ehea_port *port = netdev_priv(dev);
+	struct ehea_adapter *adapter = port->adapter;
+	struct hcp_modify_qp_cb0* cb0;
+	int ret = -EIO;
+	int dret;
+	int i;
+	u64 hret;
+	u64 dummy64 = 0;
+	u16 dummy16 = 0;
+
+	cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!cb0) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < (port->num_def_qps + port->num_add_tx_qps); i++) {
+		struct ehea_port_res *pr =  &port->port_res[i];
+		struct ehea_qp *qp = pr->qp;
+
+		/* Purge send queue */
+		ehea_purge_sq(qp);
+
+		/* Disable queue pair */
+		hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle,
+					    EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF),
+					    cb0);
+		if (hret != H_SUCCESS) {
+			ehea_error("query_ehea_qp failed (1)");
+			goto out;
+		}
+
+		cb0->qp_ctl_reg = (cb0->qp_ctl_reg & H_QP_CR_RES_STATE) << 8;
+		cb0->qp_ctl_reg &= ~H_QP_CR_ENABLED;
+
+		hret = ehea_h_modify_ehea_qp(adapter->handle, 0, qp->fw_handle,
+					     EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG,
+							    1), cb0, &dummy64,
+					     &dummy64, &dummy16, &dummy16);
+		if (hret != H_SUCCESS) {
+			ehea_error("modify_ehea_qp failed (1)");
+			goto out;
+		}
+
+		hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle,
+					    EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF),
+					    cb0);
+		if (hret != H_SUCCESS) {
+			ehea_error("query_ehea_qp failed (2)");
+			goto out;
+		}
+
+		/* deregister shared memory regions */
+		dret = ehea_rem_smrs(pr);
+		if (dret) {
+			ehea_error("unreg shared memory region failed");
+			goto out;
+		}
+	}
+
+	ret = 0;
+out:
+	kfree(cb0);
+
+	return ret;
+}
+
+void ehea_update_rqs(struct ehea_qp *orig_qp, struct ehea_port_res * pr)
+{
+	struct ehea_qp qp = *orig_qp;
+	struct ehea_qp_init_attr *init_attr = &qp.init_attr;
+	struct ehea_rwqe *rwqe;
+	struct sk_buff **skba_rq2 = pr->rq2_skba.arr;
+	struct sk_buff **skba_rq3 = pr->rq3_skba.arr;
+	struct sk_buff *skb;
+	u32 lkey = pr->recv_mr.lkey;
+
+
+	int i;
+	int index;
+
+	for (i = 0; i < init_attr->act_nr_rwqes_rq2 + 1; i++) {
+		rwqe = ehea_get_next_rwqe(&qp, 2);
+		rwqe->sg_list[0].l_key = lkey;
+		index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, rwqe->wr_id);
+		skb = skba_rq2[index];
+		if (skb)
+			rwqe->sg_list[0].vaddr = ehea_map_vaddr(skb->data);
+	}
+
+	for (i = 0; i < init_attr->act_nr_rwqes_rq3 + 1; i++) {
+		rwqe = ehea_get_next_rwqe(&qp, 3);
+		rwqe->sg_list[0].l_key = lkey;
+		index = EHEA_BMASK_GET(EHEA_WR_ID_INDEX, rwqe->wr_id);
+		skb = skba_rq3[index];
+		if (skb)
+			rwqe->sg_list[0].vaddr = ehea_map_vaddr(skb->data);
+	}
+}
+
+int ehea_restart_qps(struct net_device *dev)
+{
+	struct ehea_port *port = netdev_priv(dev);
+	struct ehea_adapter *adapter = port->adapter;
+	int ret = 0;
+	int i;
+
+	struct hcp_modify_qp_cb0* cb0;
+	u64 hret;
+	u64 dummy64 = 0;
+	u16 dummy16 = 0;
+
+	cb0 = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!cb0) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	for (i = 0; i < (port->num_def_qps + port->num_add_tx_qps); i++) {
+		struct ehea_port_res *pr =  &port->port_res[i];
+		struct ehea_qp *qp = pr->qp;
+
+		ret = ehea_gen_smrs(pr);
+		if (ret) {
+			ehea_error("creation of shared memory regions failed");
+			goto out;
+		}
+
+		ehea_update_rqs(qp, pr);
+
+		/* Enable queue pair */
+		hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle,
+					    EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF),
+					    cb0);
+		if (hret != H_SUCCESS) {
+			ehea_error("query_ehea_qp failed (1)");
+			goto out;
+		}
+
+		cb0->qp_ctl_reg = (cb0->qp_ctl_reg & H_QP_CR_RES_STATE) << 8;
+		cb0->qp_ctl_reg |= H_QP_CR_ENABLED;
+
+		hret = ehea_h_modify_ehea_qp(adapter->handle, 0, qp->fw_handle,
+					     EHEA_BMASK_SET(H_QPCB0_QP_CTL_REG,
+							    1), cb0, &dummy64,
+					     &dummy64, &dummy16, &dummy16);
+		if (hret != H_SUCCESS) {
+			ehea_error("modify_ehea_qp failed (1)");
+			goto out;
+		}
+
+		hret = ehea_h_query_ehea_qp(adapter->handle, 0, qp->fw_handle,
+					    EHEA_BMASK_SET(H_QPCB0_ALL, 0xFFFF),
+					    cb0);
+		if (hret != H_SUCCESS) {
+			ehea_error("query_ehea_qp failed (2)");
+			goto out;
+		}
+
+		/* refill entire queue */
+		ehea_refill_rq1(pr, pr->rq1_skba.index, 0);
+		ehea_refill_rq2(pr, 0);
+		ehea_refill_rq3(pr, 0);
+	}
+out:
+	kfree(cb0);
+
+	return ret;
+}
+
 static void ehea_reset_port(struct work_struct *work)
 {
 	int ret;
@@ -2395,6 +2608,8 @@ static void ehea_reset_port(struct work_struct *work)
 	if (ret)
 		goto out;
 
+	ehea_set_multicast_list(dev);
+
 	if (netif_msg_timer(port))
 		ehea_info("Device %s resetted successfully", dev->name);
 
@@ -2411,6 +2626,7 @@ static void ehea_rereg_mrs(struct work_struct *work)
 	int ret, i;
 	struct ehea_adapter *adapter;
 
+	down(&dlpar_mem_lock);
 	ehea_info("LPAR memory enlarged - re-initializing driver");
 
 	list_for_each_entry(adapter, &adapter_list, list)
@@ -2423,14 +2639,14 @@ static void ehea_rereg_mrs(struct work_struct *work)
 					struct net_device *dev = port->netdev;
 
 					if (dev->flags & IFF_UP) {
-						ehea_info("stopping %s",
-							  dev->name);
 						down(&port->port_lock);
 						netif_stop_queue(dev);
-
+						ret = ehea_stop_qps(dev);
+						if (ret) {
+							up(&port->port_lock);
+							goto out;
+						}
 						port_napi_disable(port);
-
-						ehea_down(dev);
 						up(&port->port_lock);
 					}
 				}
@@ -2446,10 +2662,11 @@ static void ehea_rereg_mrs(struct work_struct *work)
 		}
 
 	ehea_destroy_busmap();
-
 	ret = ehea_create_busmap();
-	if (ret)
+	if (ret) {
+		ehea_error("creating ehea busmap failed");
 		goto out;
+	}
 
 	clear_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
 
@@ -2471,21 +2688,18 @@ static void ehea_rereg_mrs(struct work_struct *work)
 					struct net_device *dev = port->netdev;
 
 					if (dev->flags & IFF_UP) {
-						ehea_info("restarting %s",
-							  dev->name);
 						down(&port->port_lock);
-
-						ret = ehea_up(dev);
-						if (!ret) {
-							port_napi_enable(port);
+						port_napi_enable(port);
+						ret = ehea_restart_qps(dev);
+						if (!ret)
 							netif_wake_queue(dev);
-						}
-
 						up(&port->port_lock);
 					}
 				}
 			}
 		}
+       up(&dlpar_mem_lock);
+       ehea_info("re-initializing driver complete");
 out:
 	return;
 }
@@ -2494,7 +2708,8 @@ static void ehea_tx_watchdog(struct net_device *dev)
 {
 	struct ehea_port *port = netdev_priv(dev);
 
-	if (netif_carrier_ok(dev))
+	if (netif_carrier_ok(dev) &&
+	    !test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))
 		queue_work(port->adapter->ehea_wq, &port->reset_task);
 }
 
@@ -3139,6 +3354,7 @@ int __init ehea_module_init(void)
 	ehea_driver_wq = create_workqueue("ehea_driver_wq");
 
 	INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs);
+	sema_init(&dlpar_mem_lock, 1);
 
 	ret = check_module_parm();
 	if (ret)
diff --git a/drivers/net/ehea/ehea_phyp.h b/drivers/net/ehea/ehea_phyp.h
index 89b6353..faa191d 100644
--- a/drivers/net/ehea/ehea_phyp.h
+++ b/drivers/net/ehea/ehea_phyp.h
@@ -126,6 +126,7 @@ struct hcp_modify_qp_cb0 {
 #define H_QP_CR_STATE_RDY2RCV	    0x0000030000000000ULL /*  Ready to recv */
 #define H_QP_CR_STATE_RDY2SND	    0x0000050000000000ULL /*  Ready to send */
 #define H_QP_CR_STATE_ERROR	    0x0000800000000000ULL /*  Error */
+#define H_QP_CR_RES_STATE 	    0x0000007F00000000ULL /* Resultant state */
 
 struct hcp_modify_qp_cb1 {
 	u32 qpn;		/* 00 */
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index c82e245..329a252 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -563,8 +563,7 @@ int ehea_destroy_qp(struct ehea_qp *qp)
 int ehea_create_busmap( void )
 {
 	u64 vaddr = EHEA_BUSMAP_START;
-	unsigned long abs_max_pfn = 0;
-	unsigned long sec_max_pfn;
+	unsigned long high_section_index = 0;
 	int i;
 
 	/*
@@ -574,14 +573,10 @@ int ehea_create_busmap( void )
 	ehea_bmap.valid_sections = 0;
 
 	for (i = 0; i < NR_MEM_SECTIONS; i++)
-		if (valid_section_nr(i)) {
-			sec_max_pfn = section_nr_to_pfn(i);
-			if (sec_max_pfn > abs_max_pfn)
-				abs_max_pfn = sec_max_pfn;
-			ehea_bmap.valid_sections++;
-		}
+		if (valid_section_nr(i))
+			high_section_index = i;
 
-	ehea_bmap.entries = abs_max_pfn / EHEA_PAGES_PER_SECTION + 1;
+	ehea_bmap.entries = high_section_index + 1;
 	ehea_bmap.vaddr = vmalloc(ehea_bmap.entries * sizeof(*ehea_bmap.vaddr));
 
 	if (!ehea_bmap.vaddr)
@@ -593,6 +588,7 @@ int ehea_create_busmap( void )
 		if (pfn_valid(pfn)) {
 			ehea_bmap.vaddr[i] = vaddr;
 			vaddr += EHEA_SECTSIZE;
+			ehea_bmap.valid_sections++;
 		} else
 			ehea_bmap.vaddr[i] = 0;
 	}
@@ -637,7 +633,7 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
 
 	mr_len = ehea_bmap.valid_sections * EHEA_SECTSIZE;
 
-	pt =  kzalloc(EHEA_MAX_RPAGE * sizeof(u64), GFP_KERNEL);
+	pt =  kzalloc(PAGE_SIZE, GFP_KERNEL);
 	if (!pt) {
 		ehea_error("no mem");
 		ret = -ENOMEM;
@@ -660,8 +656,8 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
 			void *sectbase = __va(i << SECTION_SIZE_BITS);
 			unsigned long k = 0;
 
-			for (j = 0; j < (PAGES_PER_SECTION / EHEA_MAX_RPAGE);
-			      j++) {
+			for (j = 0; j < (EHEA_PAGES_PER_SECTION /
+					 EHEA_MAX_RPAGE); j++) {
 
 				for (m = 0; m < EHEA_MAX_RPAGE; m++) {
 					pg = sectbase + ((k++) * EHEA_PAGESIZE);
diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h
index b71f845..562de0e 100644
--- a/drivers/net/ehea/ehea_qmr.h
+++ b/drivers/net/ehea/ehea_qmr.h
@@ -39,7 +39,7 @@
 #define EHEA_PAGESHIFT         12
 #define EHEA_PAGESIZE          (1UL << EHEA_PAGESHIFT)
 #define EHEA_SECTSIZE          (1UL << 24)
-#define EHEA_PAGES_PER_SECTION (EHEA_SECTSIZE >> PAGE_SHIFT)
+#define EHEA_PAGES_PER_SECTION (EHEA_SECTSIZE >> EHEA_PAGESHIFT)
 
 #if (1UL << SECTION_SIZE_BITS) < EHEA_SECTSIZE
 #error eHEA module can't work if kernel sectionsize < ehea sectionsize
@@ -145,7 +145,7 @@ struct ehea_rwqe {
 #define EHEA_CQE_VLAN_TAG_XTRACT   0x0400
 
 #define EHEA_CQE_TYPE_RQ           0x60
-#define EHEA_CQE_STAT_ERR_MASK     0x721F
+#define EHEA_CQE_STAT_ERR_MASK     0x720F
 #define EHEA_CQE_STAT_FAT_ERR_MASK 0x1F
 #define EHEA_CQE_STAT_ERR_TCP      0x4000
 #define EHEA_CQE_STAT_ERR_IP       0x2000
diff --git a/drivers/net/fs_enet/Kconfig b/drivers/net/fs_enet/Kconfig
index e27ee21..2765e49 100644
--- a/drivers/net/fs_enet/Kconfig
+++ b/drivers/net/fs_enet/Kconfig
@@ -11,6 +11,7 @@ config FS_ENET_HAS_SCC
 config FS_ENET_HAS_FCC
 	bool "Chip has an FCC usable for ethernet"
 	depends on FS_ENET && CPM2
+	select MDIO_BITBANG
 	default y
 
 config FS_ENET_HAS_FEC
diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c
index ebdcf3f..04c6fae 100644
--- a/drivers/net/fs_enet/fs_enet-main.c
+++ b/drivers/net/fs_enet/fs_enet-main.c
@@ -42,19 +42,25 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_platform.h>
+#endif
+
 #include "fs_enet.h"
 
 /*************************************************/
 
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
 static char version[] __devinitdata =
     DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")" "\n";
+#endif
 
 MODULE_AUTHOR("Pantelis Antoniou <panto@intracom.gr>");
 MODULE_DESCRIPTION("Freescale Ethernet Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
-int fs_enet_debug = -1;		/* -1 == use FS_ENET_DEF_MSG_ENABLE as value */
+static int fs_enet_debug = -1; /* -1 == use FS_ENET_DEF_MSG_ENABLE as value */
 module_param(fs_enet_debug, int, 0);
 MODULE_PARM_DESC(fs_enet_debug,
 		 "Freescale bitmapped debugging message enable value");
@@ -70,13 +76,21 @@ static void fs_set_multicast_list(struct net_device *dev)
 	(*fep->ops->set_multicast_list)(dev);
 }
 
+static void skb_align(struct sk_buff *skb, int align)
+{
+	int off = ((unsigned long)skb->data) & (align - 1);
+
+	if (off)
+		skb_reserve(skb, align - off);
+}
+
 /* NAPI receive function */
 static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
 {
-	struct fs_enet_private *fep = container_of(napi, struct fec_enet_private, napi);
-	struct net_device *dev = fep->dev;
+	struct fs_enet_private *fep = container_of(napi, struct fs_enet_private, napi);
+	struct net_device *dev = to_net_dev(fep->dev);
 	const struct fs_platform_info *fpi = fep->fpi;
-	cbd_t *bdp;
+	cbd_t __iomem *bdp;
 	struct sk_buff *skb, *skbn, *skbt;
 	int received = 0;
 	u16 pkt_len, sc;
@@ -159,9 +173,13 @@ static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
 					skb = skbn;
 					skbn = skbt;
 				}
-			} else
+			} else {
 				skbn = dev_alloc_skb(ENET_RX_FRSIZE);
 
+				if (skbn)
+					skb_align(skbn, ENET_RX_ALIGN);
+			}
+
 			if (skbn != NULL) {
 				skb_put(skb, pkt_len);	/* Make room */
 				skb->protocol = eth_type_trans(skb, dev);
@@ -212,7 +230,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 	const struct fs_platform_info *fpi = fep->fpi;
-	cbd_t *bdp;
+	cbd_t __iomem *bdp;
 	struct sk_buff *skb, *skbn, *skbt;
 	int received = 0;
 	u16 pkt_len, sc;
@@ -290,9 +308,13 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
 					skb = skbn;
 					skbn = skbt;
 				}
-			} else
+			} else {
 				skbn = dev_alloc_skb(ENET_RX_FRSIZE);
 
+				if (skbn)
+					skb_align(skbn, ENET_RX_ALIGN);
+			}
+
 			if (skbn != NULL) {
 				skb_put(skb, pkt_len);	/* Make room */
 				skb->protocol = eth_type_trans(skb, dev);
@@ -333,7 +355,7 @@ static int fs_enet_rx_non_napi(struct net_device *dev)
 static void fs_enet_tx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	cbd_t *bdp;
+	cbd_t __iomem *bdp;
 	struct sk_buff *skb;
 	int dirtyidx, do_wake, do_restart;
 	u16 sc;
@@ -343,7 +365,6 @@ static void fs_enet_tx(struct net_device *dev)
 
 	do_wake = do_restart = 0;
 	while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
-
 		dirtyidx = bdp - fep->tx_bd_base;
 
 		if (fep->tx_free == fep->tx_ring)
@@ -444,7 +465,6 @@ fs_enet_interrupt(int irq, void *dev_id)
 
 	nr = 0;
 	while ((int_events = (*fep->ops->get_int_events)(dev)) != 0) {
-
 		nr++;
 
 		int_clr_events = int_events;
@@ -483,7 +503,7 @@ fs_enet_interrupt(int irq, void *dev_id)
 void fs_init_bds(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	cbd_t *bdp;
+	cbd_t __iomem *bdp;
 	struct sk_buff *skb;
 	int i;
 
@@ -504,6 +524,7 @@ void fs_init_bds(struct net_device *dev)
 			       dev->name);
 			break;
 		}
+		skb_align(skb, ENET_RX_ALIGN);
 		fep->rx_skbuff[i] = skb;
 		CBDW_BUFADDR(bdp,
 			dma_map_single(fep->dev, skb->data,
@@ -536,7 +557,7 @@ void fs_cleanup_bds(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 	struct sk_buff *skb;
-	cbd_t *bdp;
+	cbd_t __iomem *bdp;
 	int i;
 
 	/*
@@ -577,7 +598,7 @@ void fs_cleanup_bds(struct net_device *dev)
 static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	cbd_t *bdp;
+	cbd_t __iomem *bdp;
 	int curidx;
 	u16 sc;
 	unsigned long flags;
@@ -700,45 +721,43 @@ static void fs_timeout(struct net_device *dev)
  *-----------------------------------------------------------------------------*/
 static void generic_adjust_link(struct  net_device *dev)
 {
-       struct fs_enet_private *fep = netdev_priv(dev);
-       struct phy_device *phydev = fep->phydev;
-       int new_state = 0;
-
-       if (phydev->link) {
-
-               /* adjust to duplex mode */
-               if (phydev->duplex != fep->oldduplex){
-                       new_state = 1;
-                       fep->oldduplex = phydev->duplex;
-               }
-
-               if (phydev->speed != fep->oldspeed) {
-                       new_state = 1;
-                       fep->oldspeed = phydev->speed;
-               }
-
-               if (!fep->oldlink) {
-                       new_state = 1;
-                       fep->oldlink = 1;
-                       netif_schedule(dev);
-                       netif_carrier_on(dev);
-                       netif_start_queue(dev);
-               }
-
-               if (new_state)
-                       fep->ops->restart(dev);
-
-       } else if (fep->oldlink) {
-               new_state = 1;
-               fep->oldlink = 0;
-               fep->oldspeed = 0;
-               fep->oldduplex = -1;
-               netif_carrier_off(dev);
-               netif_stop_queue(dev);
-       }
-
-       if (new_state && netif_msg_link(fep))
-               phy_print_status(phydev);
+	struct fs_enet_private *fep = netdev_priv(dev);
+	struct phy_device *phydev = fep->phydev;
+	int new_state = 0;
+
+	if (phydev->link) {
+		/* adjust to duplex mode */
+		if (phydev->duplex != fep->oldduplex) {
+			new_state = 1;
+			fep->oldduplex = phydev->duplex;
+		}
+
+		if (phydev->speed != fep->oldspeed) {
+			new_state = 1;
+			fep->oldspeed = phydev->speed;
+		}
+
+		if (!fep->oldlink) {
+			new_state = 1;
+			fep->oldlink = 1;
+			netif_schedule(dev);
+			netif_carrier_on(dev);
+			netif_start_queue(dev);
+		}
+
+		if (new_state)
+			fep->ops->restart(dev);
+	} else if (fep->oldlink) {
+		new_state = 1;
+		fep->oldlink = 0;
+		fep->oldspeed = 0;
+		fep->oldduplex = -1;
+		netif_carrier_off(dev);
+		netif_stop_queue(dev);
+	}
+
+	if (new_state && netif_msg_link(fep))
+		phy_print_status(phydev);
 }
 
 
@@ -782,7 +801,6 @@ static int fs_init_phy(struct net_device *dev)
 	return 0;
 }
 
-
 static int fs_enet_open(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
@@ -936,6 +954,7 @@ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 extern int fs_mii_connect(struct net_device *dev);
 extern void fs_mii_disconnect(struct net_device *dev);
 
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
 static struct net_device *fs_init_instance(struct device *dev,
 		struct fs_platform_info *fpi)
 {
@@ -971,7 +990,7 @@ static struct net_device *fs_init_instance(struct device *dev,
 #endif
 
 #ifdef CONFIG_FS_ENET_HAS_SCC
-	if (fs_get_scc_index(fpi->fs_no) >=0 )
+	if (fs_get_scc_index(fpi->fs_no) >=0)
 		fep->ops = &fs_scc_ops;
 #endif
 
@@ -1066,9 +1085,8 @@ static struct net_device *fs_init_instance(struct device *dev,
 
 	return ndev;
 
-      err:
+err:
 	if (ndev != NULL) {
-
 		if (registered)
 			unregister_netdev(ndev);
 
@@ -1103,7 +1121,7 @@ static int fs_cleanup_instance(struct net_device *ndev)
 	unregister_netdev(ndev);
 
 	dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
-			  fep->ring_base, fep->ring_mem_addr);
+			  (void __force *)fep->ring_base, fep->ring_mem_addr);
 
 	/* reset it */
 	(*fep->ops->cleanup_data)(ndev);
@@ -1118,43 +1136,259 @@ static int fs_cleanup_instance(struct net_device *ndev)
 
 	return 0;
 }
+#endif
 
 /**************************************************************************************/
 
 /* handy pointer to the immap */
-void *fs_enet_immap = NULL;
+void __iomem *fs_enet_immap = NULL;
 
 static int setup_immap(void)
 {
-	phys_addr_t paddr = 0;
-	unsigned long size = 0;
-
 #ifdef CONFIG_CPM1
-	paddr = IMAP_ADDR;
-	size = 0x10000;	/* map 64K */
-#endif
-
-#ifdef CONFIG_CPM2
-	paddr = CPM_MAP_ADDR;
-	size = 0x40000;	/* map 256 K */
+	fs_enet_immap = ioremap(IMAP_ADDR, 0x4000);
+	WARN_ON(!fs_enet_immap);
+#elif defined(CONFIG_CPM2)
+	fs_enet_immap = cpm2_immr;
 #endif
-	fs_enet_immap = ioremap(paddr, size);
-	if (fs_enet_immap == NULL)
-		return -EBADF;	/* XXX ahem; maybe just BUG_ON? */
 
 	return 0;
 }
 
 static void cleanup_immap(void)
 {
-	if (fs_enet_immap != NULL) {
-		iounmap(fs_enet_immap);
-		fs_enet_immap = NULL;
-	}
+#if defined(CONFIG_CPM1)
+	iounmap(fs_enet_immap);
+#endif
 }
 
 /**************************************************************************************/
 
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+static int __devinit find_phy(struct device_node *np,
+                              struct fs_platform_info *fpi)
+{
+	struct device_node *phynode, *mdionode;
+	struct resource res;
+	int ret = 0, len;
+
+	const u32 *data = of_get_property(np, "phy-handle", &len);
+	if (!data || len != 4)
+		return -EINVAL;
+
+	phynode = of_find_node_by_phandle(*data);
+	if (!phynode)
+		return -EINVAL;
+
+	mdionode = of_get_parent(phynode);
+	if (!mdionode)
+		goto out_put_phy;
+
+	ret = of_address_to_resource(mdionode, 0, &res);
+	if (ret)
+		goto out_put_mdio;
+
+	data = of_get_property(phynode, "reg", &len);
+	if (!data || len != 4)
+		goto out_put_mdio;
+
+	snprintf(fpi->bus_id, 16, PHY_ID_FMT, res.start, *data);
+
+out_put_mdio:
+	of_node_put(mdionode);
+out_put_phy:
+	of_node_put(phynode);
+	return ret;
+}
+
+#ifdef CONFIG_FS_ENET_HAS_FEC
+#define IS_FEC(match) ((match)->data == &fs_fec_ops)
+#else
+#define IS_FEC(match) 0
+#endif
+
+static int __devinit fs_enet_probe(struct of_device *ofdev,
+                                   const struct of_device_id *match)
+{
+	struct net_device *ndev;
+	struct fs_enet_private *fep;
+	struct fs_platform_info *fpi;
+	const u32 *data;
+	const u8 *mac_addr;
+	int privsize, len, ret = -ENODEV;
+
+	fpi = kzalloc(sizeof(*fpi), GFP_KERNEL);
+	if (!fpi)
+		return -ENOMEM;
+
+	if (!IS_FEC(match)) {
+		data = of_get_property(ofdev->node, "fsl,cpm-command", &len);
+		if (!data || len != 4)
+			goto out_free_fpi;
+
+		fpi->cp_command = *data;
+	}
+
+	fpi->rx_ring = 32;
+	fpi->tx_ring = 32;
+	fpi->rx_copybreak = 240;
+	fpi->use_napi = 0;
+	fpi->napi_weight = 17;
+
+	ret = find_phy(ofdev->node, fpi);
+	if (ret)
+		goto out_free_fpi;
+
+	privsize = sizeof(*fep) +
+	           sizeof(struct sk_buff **) *
+	           (fpi->rx_ring + fpi->tx_ring);
+
+	ndev = alloc_etherdev(privsize);
+	if (!ndev) {
+		ret = -ENOMEM;
+		goto out_free_fpi;
+	}
+
+	SET_MODULE_OWNER(ndev);
+	dev_set_drvdata(&ofdev->dev, ndev);
+
+	fep = netdev_priv(ndev);
+	fep->dev = &ofdev->dev;
+	fep->fpi = fpi;
+	fep->ops = match->data;
+
+	ret = fep->ops->setup_data(ndev);
+	if (ret)
+		goto out_free_dev;
+
+	fep->rx_skbuff = (struct sk_buff **)&fep[1];
+	fep->tx_skbuff = fep->rx_skbuff + fpi->rx_ring;
+
+	spin_lock_init(&fep->lock);
+	spin_lock_init(&fep->tx_lock);
+
+	mac_addr = of_get_mac_address(ofdev->node);
+	if (mac_addr)
+		memcpy(ndev->dev_addr, mac_addr, 6);
+
+	ret = fep->ops->allocate_bd(ndev);
+	if (ret)
+		goto out_cleanup_data;
+
+	fep->rx_bd_base = fep->ring_base;
+	fep->tx_bd_base = fep->rx_bd_base + fpi->rx_ring;
+
+	fep->tx_ring = fpi->tx_ring;
+	fep->rx_ring = fpi->rx_ring;
+
+	ndev->open = fs_enet_open;
+	ndev->hard_start_xmit = fs_enet_start_xmit;
+	ndev->tx_timeout = fs_timeout;
+	ndev->watchdog_timeo = 2 * HZ;
+	ndev->stop = fs_enet_close;
+	ndev->get_stats = fs_enet_get_stats;
+	ndev->set_multicast_list = fs_set_multicast_list;
+	if (fpi->use_napi) {
+		ndev->poll = fs_enet_rx_napi;
+		ndev->weight = fpi->napi_weight;
+	}
+	ndev->ethtool_ops = &fs_ethtool_ops;
+	ndev->do_ioctl = fs_ioctl;
+
+	init_timer(&fep->phy_timer_list);
+
+	netif_carrier_off(ndev);
+
+	ret = register_netdev(ndev);
+	if (ret)
+		goto out_free_bd;
+
+	printk(KERN_INFO "%s: fs_enet: %02x:%02x:%02x:%02x:%02x:%02x\n",
+	       ndev->name,
+	       ndev->dev_addr[0], ndev->dev_addr[1], ndev->dev_addr[2],
+	       ndev->dev_addr[3], ndev->dev_addr[4], ndev->dev_addr[5]);
+
+	return 0;
+
+out_free_bd:
+	fep->ops->free_bd(ndev);
+out_cleanup_data:
+	fep->ops->cleanup_data(ndev);
+out_free_dev:
+	free_netdev(ndev);
+	dev_set_drvdata(&ofdev->dev, NULL);
+out_free_fpi:
+	kfree(fpi);
+	return ret;
+}
+
+static int fs_enet_remove(struct of_device *ofdev)
+{
+	struct net_device *ndev = dev_get_drvdata(&ofdev->dev);
+	struct fs_enet_private *fep = netdev_priv(ndev);
+
+	unregister_netdev(ndev);
+
+	fep->ops->free_bd(ndev);
+	fep->ops->cleanup_data(ndev);
+	dev_set_drvdata(fep->dev, NULL);
+
+	free_netdev(ndev);
+	return 0;
+}
+
+static struct of_device_id fs_enet_match[] = {
+#ifdef CONFIG_FS_ENET_HAS_SCC
+	{
+		.compatible = "fsl,cpm1-scc-enet",
+		.data = (void *)&fs_scc_ops,
+	},
+#endif
+#ifdef CONFIG_FS_ENET_HAS_FCC
+	{
+		.compatible = "fsl,cpm2-fcc-enet",
+		.data = (void *)&fs_fcc_ops,
+	},
+#endif
+#ifdef CONFIG_FS_ENET_HAS_FEC
+	{
+		.compatible = "fsl,pq1-fec-enet",
+		.data = (void *)&fs_fec_ops,
+	},
+#endif
+	{}
+};
+
+static struct of_platform_driver fs_enet_driver = {
+	.name	= "fs_enet",
+	.match_table = fs_enet_match,
+	.probe = fs_enet_probe,
+	.remove = fs_enet_remove,
+};
+
+static int __init fs_init(void)
+{
+	int r = setup_immap();
+	if (r != 0)
+		return r;
+
+	r = of_register_platform_driver(&fs_enet_driver);
+	if (r != 0)
+		goto out;
+
+	return 0;
+
+out:
+	cleanup_immap();
+	return r;
+}
+
+static void __exit fs_cleanup(void)
+{
+	of_unregister_platform_driver(&fs_enet_driver);
+	cleanup_immap();
+}
+#else
 static int __devinit fs_enet_probe(struct device *dev)
 {
 	struct net_device *ndev;
@@ -1259,7 +1493,6 @@ static int __init fs_init(void)
 err:
 	cleanup_immap();
 	return r;
-
 }
 
 static void __exit fs_cleanup(void)
@@ -1269,6 +1502,7 @@ static void __exit fs_cleanup(void)
 	driver_unregister(&fs_enet_scc_driver);
 	cleanup_immap();
 }
+#endif
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void fs_enet_netpoll(struct net_device *dev)
diff --git a/drivers/net/fs_enet/fs_enet.h b/drivers/net/fs_enet/fs_enet.h
index 46d0606..baf6477 100644
--- a/drivers/net/fs_enet/fs_enet.h
+++ b/drivers/net/fs_enet/fs_enet.h
@@ -15,8 +15,8 @@
 #include <asm/commproc.h>
 
 struct fec_info {
-        fec_t*  fecp;
-	u32     mii_speed;
+	fec_t __iomem *fecp;
+	u32 mii_speed;
 };
 #endif
 
@@ -24,19 +24,6 @@ struct fec_info {
 #include <asm/cpm2.h>
 #endif
 
-/* This is used to operate with pins.
-  Note that the actual port size may
-    be different; cpm(s) handle it OK  */
-struct bb_info {
-	u8 mdio_dat_msk;
-	u8 mdio_dir_msk;
-	u8 *mdio_dir;
-	u8 *mdio_dat;
-	u8 mdc_msk;
-	u8 *mdc_dat;
-	int delay;
-};
-
 /* hw driver ops */
 struct fs_ops {
 	int (*setup_data)(struct net_device *dev);
@@ -82,61 +69,26 @@ struct phy_info {
 /* Must be a multiple of 32 (to cover both FEC & FCC) */
 #define PKT_MAXBLR_SIZE		((PKT_MAXBUF_SIZE + 31) & ~31)
 /* This is needed so that invalidate_xxx wont invalidate too much */
-#define ENET_RX_FRSIZE		L1_CACHE_ALIGN(PKT_MAXBUF_SIZE)
-
-struct fs_enet_mii_bus {
-	struct list_head list;
-	spinlock_t mii_lock;
-	const struct fs_mii_bus_info *bus_info;
-	int refs;
-	u32 usage_map;
-
-	int (*mii_read)(struct fs_enet_mii_bus *bus,
-			int phy_id, int location);
-
-	void (*mii_write)(struct fs_enet_mii_bus *bus,
-			int phy_id, int location, int value);
-
-	union {
-		struct {
-			unsigned int mii_speed;
-			void *fecp;
-		} fec;
-
-		struct {
-			/* note that the actual port size may */
-			/* be different; cpm(s) handle it OK  */
-			u8 mdio_msk;
-			u8 *mdio_dir;
-			u8 *mdio_dat;
-			u8 mdc_msk;
-			u8 *mdc_dir;
-			u8 *mdc_dat;
-		} bitbang;
-
-		struct {
-			u16 lpa;
-		} fixed;
-	};
-};
+#define ENET_RX_ALIGN  16
+#define ENET_RX_FRSIZE L1_CACHE_ALIGN(PKT_MAXBUF_SIZE + ENET_RX_ALIGN - 1)
 
 struct fs_enet_private {
 	struct napi_struct napi;
 	struct device *dev;	/* pointer back to the device (must be initialized first) */
 	spinlock_t lock;	/* during all ops except TX pckt processing */
 	spinlock_t tx_lock;	/* during fs_start_xmit and fs_tx         */
-	const struct fs_platform_info *fpi;
+	struct fs_platform_info *fpi;
 	const struct fs_ops *ops;
 	int rx_ring, tx_ring;
 	dma_addr_t ring_mem_addr;
-	void *ring_base;
+	void __iomem *ring_base;
 	struct sk_buff **rx_skbuff;
 	struct sk_buff **tx_skbuff;
-	cbd_t *rx_bd_base;	/* Address of Rx and Tx buffers.    */
-	cbd_t *tx_bd_base;
-	cbd_t *dirty_tx;	/* ring entries to be free()ed.     */
-	cbd_t *cur_rx;
-	cbd_t *cur_tx;
+	cbd_t __iomem *rx_bd_base;	/* Address of Rx and Tx buffers.    */
+	cbd_t __iomem *tx_bd_base;
+	cbd_t __iomem *dirty_tx;	/* ring entries to be free()ed.     */
+	cbd_t __iomem *cur_rx;
+	cbd_t __iomem *cur_tx;
 	int tx_free;
 	struct net_device_stats stats;
 	struct timer_list phy_timer_list;
@@ -144,7 +96,6 @@ struct fs_enet_private {
 	u32 msg_enable;
 	struct mii_if_info mii_if;
 	unsigned int last_mii_status;
-	struct fs_enet_mii_bus *mii_bus;
 	int interrupt;
 
 	struct phy_device *phydev;
@@ -162,23 +113,23 @@ struct fs_enet_private {
 	union {
 		struct {
 			int idx;		/* FEC1 = 0, FEC2 = 1  */
-			void *fecp;		/* hw registers        */
+			void __iomem *fecp;	/* hw registers        */
 			u32 hthi, htlo;		/* state for multicast */
 		} fec;
 
 		struct {
 			int idx;		/* FCC1-3 = 0-2	       */
-			void *fccp;		/* hw registers	       */
-			void *ep;		/* parameter ram       */
-			void *fcccp;		/* hw registers cont.  */
-			void *mem;		/* FCC DPRAM */
+			void __iomem *fccp;	/* hw registers	       */
+			void __iomem *ep;	/* parameter ram       */
+			void __iomem *fcccp;	/* hw registers cont.  */
+			void __iomem *mem;	/* FCC DPRAM */
 			u32 gaddrh, gaddrl;	/* group address       */
 		} fcc;
 
 		struct {
 			int idx;		/* FEC1 = 0, FEC2 = 1  */
-			void *sccp;		/* hw registers        */
-			void *ep;		/* parameter ram       */
+			void __iomem *sccp;	/* hw registers        */
+			void __iomem *ep;	/* parameter ram       */
 			u32 hthi, htlo;		/* state for multicast */
 		} scc;
 
@@ -186,9 +137,10 @@ struct fs_enet_private {
 };
 
 /***************************************************************************/
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
 int fs_enet_mdio_bb_init(void);
-int fs_mii_fixed_init(struct fs_enet_mii_bus *bus);
 int fs_enet_mdio_fec_init(void);
+#endif
 
 void fs_init_bds(struct net_device *dev);
 void fs_cleanup_bds(struct net_device *dev);
@@ -248,7 +200,7 @@ extern const struct fs_ops fs_scc_ops;
 /*******************************************************************/
 
 /* handy pointer to the immap */
-extern void *fs_enet_immap;
+extern void __iomem *fs_enet_immap;
 
 /*******************************************************************/
 
diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c
index 6407151..da4efbc 100644
--- a/drivers/net/fs_enet/mac-fcc.c
+++ b/drivers/net/fs_enet/mac-fcc.c
@@ -42,34 +42,29 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_device.h>
+#endif
+
 #include "fs_enet.h"
 
 /*************************************************/
 
 /* FCC access macros */
 
-#define __fcc_out32(addr, x)	out_be32((unsigned *)addr, x)
-#define __fcc_out16(addr, x)	out_be16((unsigned short *)addr, x)
-#define __fcc_out8(addr, x)	out_8((unsigned char *)addr, x)
-#define __fcc_in32(addr)	in_be32((unsigned *)addr)
-#define __fcc_in16(addr)	in_be16((unsigned short *)addr)
-#define __fcc_in8(addr)		in_8((unsigned char *)addr)
-
-/* parameter space */
-
 /* write, read, set bits, clear bits */
-#define W32(_p, _m, _v)	__fcc_out32(&(_p)->_m, (_v))
-#define R32(_p, _m)	__fcc_in32(&(_p)->_m)
+#define W32(_p, _m, _v)	out_be32(&(_p)->_m, (_v))
+#define R32(_p, _m)	in_be32(&(_p)->_m)
 #define S32(_p, _m, _v)	W32(_p, _m, R32(_p, _m) | (_v))
 #define C32(_p, _m, _v)	W32(_p, _m, R32(_p, _m) & ~(_v))
 
-#define W16(_p, _m, _v)	__fcc_out16(&(_p)->_m, (_v))
-#define R16(_p, _m)	__fcc_in16(&(_p)->_m)
+#define W16(_p, _m, _v)	out_be16(&(_p)->_m, (_v))
+#define R16(_p, _m)	in_be16(&(_p)->_m)
 #define S16(_p, _m, _v)	W16(_p, _m, R16(_p, _m) | (_v))
 #define C16(_p, _m, _v)	W16(_p, _m, R16(_p, _m) & ~(_v))
 
-#define W8(_p, _m, _v)	__fcc_out8(&(_p)->_m, (_v))
-#define R8(_p, _m)	__fcc_in8(&(_p)->_m)
+#define W8(_p, _m, _v)	out_8(&(_p)->_m, (_v))
+#define R8(_p, _m)	in_8(&(_p)->_m)
 #define S8(_p, _m, _v)	W8(_p, _m, R8(_p, _m) | (_v))
 #define C8(_p, _m, _v)	W8(_p, _m, R8(_p, _m) & ~(_v))
 
@@ -83,34 +78,62 @@
 
 #define MAX_CR_CMD_LOOPS	10000
 
-static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 mcn, u32 op)
+static inline int fcc_cr_cmd(struct fs_enet_private *fep, u32 op)
 {
 	const struct fs_platform_info *fpi = fep->fpi;
-
-	cpm2_map_t *immap = fs_enet_immap;
-	cpm_cpm2_t *cpmp = &immap->im_cpm;
-	u32 v;
 	int i;
 
-	/* Currently I don't know what feature call will look like. But
-	   I guess there'd be something like do_cpm_cmd() which will require page & sblock */
-	v = mk_cr_cmd(fpi->cp_page, fpi->cp_block, mcn, op);
-	W32(cpmp, cp_cpcr, v | CPM_CR_FLG);
+	W32(cpmp, cp_cpcr, fpi->cp_command | op | CPM_CR_FLG);
 	for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
 		if ((R32(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
-			break;
+			return 0;
 
-	if (i >= MAX_CR_CMD_LOOPS) {
-		printk(KERN_ERR "%s(): Not able to issue CPM command\n",
-		       __FUNCTION__);
-		return 1;
-	}
-
-	return 0;
+	printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+	       __FUNCTION__);
+	return 1;
 }
 
 static int do_pd_setup(struct fs_enet_private *fep)
 {
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+	struct of_device *ofdev = to_of_device(fep->dev);
+	struct fs_platform_info *fpi = fep->fpi;
+	int ret = -EINVAL;
+
+	fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
+	if (fep->interrupt == NO_IRQ)
+		goto out;
+
+	fep->fcc.fccp = of_iomap(ofdev->node, 0);
+	if (!fep->fcc.fccp)
+		goto out;
+
+	fep->fcc.ep = of_iomap(ofdev->node, 1);
+	if (!fep->fcc.ep)
+		goto out_fccp;
+
+	fep->fcc.fcccp = of_iomap(ofdev->node, 2);
+	if (!fep->fcc.fcccp)
+		goto out_ep;
+
+	fep->fcc.mem = (void __iomem *)cpm2_immr;
+	fpi->dpram_offset = cpm_dpalloc(128, 8);
+	if (IS_ERR_VALUE(fpi->dpram_offset)) {
+		ret = fpi->dpram_offset;
+		goto out_fcccp;
+	}
+
+	return 0;
+
+out_fcccp:
+	iounmap(fep->fcc.fcccp);
+out_ep:
+	iounmap(fep->fcc.ep);
+out_fccp:
+	iounmap(fep->fcc.fccp);
+out:
+	return ret;
+#else
 	struct platform_device *pdev = to_platform_device(fep->dev);
 	struct resource *r;
 
@@ -121,33 +144,33 @@ static int do_pd_setup(struct fs_enet_private *fep)
 
 	/* Attach the memory for the FCC Parameter RAM */
 	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_pram");
-	fep->fcc.ep = (void *)ioremap(r->start, r->end - r->start + 1);
+	fep->fcc.ep = ioremap(r->start, r->end - r->start + 1);
 	if (fep->fcc.ep == NULL)
 		return -EINVAL;
 
 	r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fcc_regs");
-	fep->fcc.fccp = (void *)ioremap(r->start, r->end - r->start + 1);
+	fep->fcc.fccp = ioremap(r->start, r->end - r->start + 1);
 	if (fep->fcc.fccp == NULL)
 		return -EINVAL;
 
 	if (fep->fpi->fcc_regs_c) {
-
-		fep->fcc.fcccp = (void *)fep->fpi->fcc_regs_c;
+		fep->fcc.fcccp = (void __iomem *)fep->fpi->fcc_regs_c;
 	} else {
 		r = platform_get_resource_byname(pdev, IORESOURCE_MEM,
 				"fcc_regs_c");
-		fep->fcc.fcccp = (void *)ioremap(r->start,
+		fep->fcc.fcccp = ioremap(r->start,
 				r->end - r->start + 1);
 	}
 
 	if (fep->fcc.fcccp == NULL)
 		return -EINVAL;
 
-	fep->fcc.mem = (void *)fep->fpi->mem_offset;
+	fep->fcc.mem = (void __iomem *)fep->fpi->mem_offset;
 	if (fep->fcc.mem == NULL)
 		return -EINVAL;
 
 	return 0;
+#endif
 }
 
 #define FCC_NAPI_RX_EVENT_MSK	(FCC_ENET_RXF | FCC_ENET_RXB)
@@ -158,11 +181,17 @@ static int do_pd_setup(struct fs_enet_private *fep)
 static int setup_data(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	const struct fs_platform_info *fpi = fep->fpi;
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
+	struct fs_platform_info *fpi = fep->fpi;
+
+	fpi->cp_command = (fpi->cp_page << 26) |
+	                  (fpi->cp_block << 21) |
+	                  (12 << 6);
 
 	fep->fcc.idx = fs_get_fcc_index(fpi->fs_no);
 	if ((unsigned int)fep->fcc.idx >= 3)	/* max 3 FCCs */
 		return -EINVAL;
+#endif
 
 	if (do_pd_setup(fep) != 0)
 		return -EINVAL;
@@ -180,7 +209,7 @@ static int allocate_bd(struct net_device *dev)
 	struct fs_enet_private *fep = netdev_priv(dev);
 	const struct fs_platform_info *fpi = fep->fpi;
 
-	fep->ring_base = dma_alloc_coherent(fep->dev,
+	fep->ring_base = (void __iomem __force *)dma_alloc_coherent(fep->dev,
 					    (fpi->tx_ring + fpi->rx_ring) *
 					    sizeof(cbd_t), &fep->ring_mem_addr,
 					    GFP_KERNEL);
@@ -198,7 +227,7 @@ static void free_bd(struct net_device *dev)
 	if (fep->ring_base)
 		dma_free_coherent(fep->dev,
 			(fpi->tx_ring + fpi->rx_ring) * sizeof(cbd_t),
-			fep->ring_base, fep->ring_mem_addr);
+			(void __force *)fep->ring_base, fep->ring_mem_addr);
 }
 
 static void cleanup_data(struct net_device *dev)
@@ -209,7 +238,7 @@ static void cleanup_data(struct net_device *dev)
 static void set_promiscuous_mode(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_t *fccp = fep->fcc.fccp;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
 
 	S32(fccp, fcc_fpsmr, FCC_PSMR_PRO);
 }
@@ -217,7 +246,7 @@ static void set_promiscuous_mode(struct net_device *dev)
 static void set_multicast_start(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_enet_t *ep = fep->fcc.ep;
+	fcc_enet_t __iomem *ep = fep->fcc.ep;
 
 	W32(ep, fen_gaddrh, 0);
 	W32(ep, fen_gaddrl, 0);
@@ -226,7 +255,7 @@ static void set_multicast_start(struct net_device *dev)
 static void set_multicast_one(struct net_device *dev, const u8 *mac)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_enet_t *ep = fep->fcc.ep;
+	fcc_enet_t __iomem *ep = fep->fcc.ep;
 	u16 taddrh, taddrm, taddrl;
 
 	taddrh = ((u16)mac[5] << 8) | mac[4];
@@ -236,14 +265,14 @@ static void set_multicast_one(struct net_device *dev, const u8 *mac)
 	W16(ep, fen_taddrh, taddrh);
 	W16(ep, fen_taddrm, taddrm);
 	W16(ep, fen_taddrl, taddrl);
-	fcc_cr_cmd(fep, 0x0C, CPM_CR_SET_GADDR);
+	fcc_cr_cmd(fep, CPM_CR_SET_GADDR);
 }
 
 static void set_multicast_finish(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_t *fccp = fep->fcc.fccp;
-	fcc_enet_t *ep = fep->fcc.ep;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
+	fcc_enet_t __iomem *ep = fep->fcc.ep;
 
 	/* clear promiscuous always */
 	C32(fccp, fcc_fpsmr, FCC_PSMR_PRO);
@@ -278,12 +307,14 @@ static void restart(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 	const struct fs_platform_info *fpi = fep->fpi;
-	fcc_t *fccp = fep->fcc.fccp;
-	fcc_c_t *fcccp = fep->fcc.fcccp;
-	fcc_enet_t *ep = fep->fcc.ep;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
+	fcc_c_t __iomem *fcccp = fep->fcc.fcccp;
+	fcc_enet_t __iomem *ep = fep->fcc.ep;
 	dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
 	u16 paddrh, paddrm, paddrl;
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
 	u16 mem_addr;
+#endif
 	const unsigned char *mac;
 	int i;
 
@@ -291,7 +322,7 @@ static void restart(struct net_device *dev)
 
 	/* clear everything (slow & steady does it) */
 	for (i = 0; i < sizeof(*ep); i++)
-		__fcc_out8((char *)ep + i, 0);
+		out_8((u8 __iomem *)ep + i, 0);
 
 	/* get physical address */
 	rx_bd_base_phys = fep->ring_mem_addr;
@@ -315,14 +346,22 @@ static void restart(struct net_device *dev)
 	 * this area.
 	 */
 
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+	W16(ep, fen_genfcc.fcc_riptr, fpi->dpram_offset);
+	W16(ep, fen_genfcc.fcc_tiptr, fpi->dpram_offset + 32);
+
+	W16(ep, fen_padptr, fpi->dpram_offset + 64);
+#else
 	mem_addr = (u32) fep->fcc.mem;	/* de-fixup dpram offset */
 
 	W16(ep, fen_genfcc.fcc_riptr, (mem_addr & 0xffff));
 	W16(ep, fen_genfcc.fcc_tiptr, ((mem_addr + 32) & 0xffff));
+
 	W16(ep, fen_padptr, mem_addr + 64);
+#endif
 
 	/* fill with special symbol...  */
-	memset(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32);
+	memset_io(fep->fcc.mem + fpi->dpram_offset + 64, 0x88, 32);
 
 	W32(ep, fen_genfcc.fcc_rbptr, 0);
 	W32(ep, fen_genfcc.fcc_tbptr, 0);
@@ -407,7 +446,7 @@ static void restart(struct net_device *dev)
 			S8(fcccp, fcc_gfemr, 0x20);
 	}
 
-	fcc_cr_cmd(fep, 0x0c, CPM_CR_INIT_TRX);
+	fcc_cr_cmd(fep, CPM_CR_INIT_TRX);
 
 	/* clear events */
 	W16(fccp, fcc_fcce, 0xffff);
@@ -438,7 +477,7 @@ static void restart(struct net_device *dev)
 static void stop(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_t *fccp = fep->fcc.fccp;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
 
 	/* stop ethernet */
 	C32(fccp, fcc_gfmr, FCC_GFMR_ENR | FCC_GFMR_ENT);
@@ -465,7 +504,7 @@ static void post_free_irq(struct net_device *dev, int irq)
 static void napi_clear_rx_event(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_t *fccp = fep->fcc.fccp;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
 
 	W16(fccp, fcc_fcce, FCC_NAPI_RX_EVENT_MSK);
 }
@@ -473,7 +512,7 @@ static void napi_clear_rx_event(struct net_device *dev)
 static void napi_enable_rx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_t *fccp = fep->fcc.fccp;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
 
 	S16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
 }
@@ -481,7 +520,7 @@ static void napi_enable_rx(struct net_device *dev)
 static void napi_disable_rx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_t *fccp = fep->fcc.fccp;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
 
 	C16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
 }
@@ -494,15 +533,15 @@ static void rx_bd_done(struct net_device *dev)
 static void tx_kickstart(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_t *fccp = fep->fcc.fccp;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
 
-	S32(fccp, fcc_ftodr, 0x80);
+	S16(fccp, fcc_ftodr, 0x8000);
 }
 
 static u32 get_int_events(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_t *fccp = fep->fcc.fccp;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
 
 	return (u32)R16(fccp, fcc_fcce);
 }
@@ -510,7 +549,7 @@ static u32 get_int_events(struct net_device *dev)
 static void clear_int_events(struct net_device *dev, u32 int_events)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_t *fccp = fep->fcc.fccp;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
 
 	W16(fccp, fcc_fcce, int_events & 0xffff);
 }
@@ -521,27 +560,26 @@ static void ev_error(struct net_device *dev, u32 int_events)
 	       ": %s FS_ENET ERROR(s) 0x%x\n", dev->name, int_events);
 }
 
-int get_regs(struct net_device *dev, void *p, int *sizep)
+static int get_regs(struct net_device *dev, void *p, int *sizep)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 
-	if (*sizep < sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t))
+	if (*sizep < sizeof(fcc_t) + sizeof(fcc_enet_t) + 1)
 		return -EINVAL;
 
 	memcpy_fromio(p, fep->fcc.fccp, sizeof(fcc_t));
 	p = (char *)p + sizeof(fcc_t);
 
-	memcpy_fromio(p, fep->fcc.fcccp, sizeof(fcc_c_t));
-	p = (char *)p + sizeof(fcc_c_t);
-
 	memcpy_fromio(p, fep->fcc.ep, sizeof(fcc_enet_t));
+	p = (char *)p + sizeof(fcc_enet_t);
 
+	memcpy_fromio(p, fep->fcc.fcccp, 1);
 	return 0;
 }
 
-int get_regs_len(struct net_device *dev)
+static int get_regs_len(struct net_device *dev)
 {
-	return sizeof(fcc_t) + sizeof(fcc_c_t) + sizeof(fcc_enet_t);
+	return sizeof(fcc_t) + sizeof(fcc_enet_t) + 1;
 }
 
 /* Some transmit errors cause the transmitter to shut
@@ -552,16 +590,16 @@ int get_regs_len(struct net_device *dev)
  * CPM37, we must disable and then re-enable the transmitter
  * following a Late Collision, Underrun, or Retry Limit error.
  */
-void tx_restart(struct net_device *dev)
+static void tx_restart(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fcc_t *fccp = fep->fcc.fccp;
+	fcc_t __iomem *fccp = fep->fcc.fccp;
 
 	C32(fccp, fcc_gfmr, FCC_GFMR_ENT);
 	udelay(10);
 	S32(fccp, fcc_gfmr, FCC_GFMR_ENT);
 
-	fcc_cr_cmd(fep, 0x0C, CPM_CR_RESTART_TX);
+	fcc_cr_cmd(fep, CPM_CR_RESTART_TX);
 }
 
 /*************************************************************************/
diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c
index cbdc17b..c1fee48 100644
--- a/drivers/net/fs_enet/mac-fec.c
+++ b/drivers/net/fs_enet/mac-fec.c
@@ -43,6 +43,10 @@
 #include <asm/commproc.h>
 #endif
 
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_device.h>
+#endif
+
 #include "fs_enet.h"
 #include "fec.h"
 
@@ -79,7 +83,7 @@
  */
 #define FEC_RESET_DELAY		50
 
-static int whack_reset(fec_t * fecp)
+static int whack_reset(fec_t __iomem *fecp)
 {
 	int i;
 
@@ -95,6 +99,19 @@ static int whack_reset(fec_t * fecp)
 
 static int do_pd_setup(struct fs_enet_private *fep)
 {
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+	struct of_device *ofdev = to_of_device(fep->dev);
+
+	fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
+	if (fep->interrupt == NO_IRQ)
+		return -EINVAL;
+
+	fep->fec.fecp = of_iomap(ofdev->node, 0);
+	if (!fep->fcc.fccp)
+		return -EINVAL;
+
+	return 0;
+#else
 	struct platform_device *pdev = to_platform_device(fep->dev);
 	struct resource	*r;
 
@@ -110,7 +127,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
 		return -EINVAL;
 
 	return 0;
-
+#endif
 }
 
 #define FEC_NAPI_RX_EVENT_MSK	(FEC_ENET_RXF | FEC_ENET_RXB)
@@ -142,7 +159,7 @@ static int allocate_bd(struct net_device *dev)
 	struct fs_enet_private *fep = netdev_priv(dev);
 	const struct fs_platform_info *fpi = fep->fpi;
 
-	fep->ring_base = dma_alloc_coherent(fep->dev,
+	fep->ring_base = (void __force __iomem *)dma_alloc_coherent(fep->dev,
 					    (fpi->tx_ring + fpi->rx_ring) *
 					    sizeof(cbd_t), &fep->ring_mem_addr,
 					    GFP_KERNEL);
@@ -160,7 +177,7 @@ static void free_bd(struct net_device *dev)
 	if(fep->ring_base)
 		dma_free_coherent(fep->dev, (fpi->tx_ring + fpi->rx_ring)
 					* sizeof(cbd_t),
-					fep->ring_base,
+					(void __force *)fep->ring_base,
 					fep->ring_mem_addr);
 }
 
@@ -172,7 +189,7 @@ static void cleanup_data(struct net_device *dev)
 static void set_promiscuous_mode(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 
 	FS(fecp, r_cntrl, FEC_RCNTRL_PROM);
 }
@@ -220,7 +237,7 @@ static void set_multicast_one(struct net_device *dev, const u8 *mac)
 static void set_multicast_finish(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 
 	/* if all multi or too many multicasts; just enable all */
 	if ((dev->flags & IFF_ALLMULTI) != 0 ||
@@ -254,7 +271,7 @@ static void restart(struct net_device *dev)
 	u32 cptr;
 #endif
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 	const struct fs_platform_info *fpi = fep->fpi;
 	dma_addr_t rx_bd_base_phys, tx_bd_base_phys;
 	int r;
@@ -382,7 +399,7 @@ static void stop(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 	const struct fs_platform_info *fpi = fep->fpi;
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 
 	struct fec_info* feci= fep->phydev->bus->priv;
 
@@ -444,7 +461,7 @@ static void post_free_irq(struct net_device *dev, int irq)
 static void napi_clear_rx_event(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 
 	FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
 }
@@ -452,7 +469,7 @@ static void napi_clear_rx_event(struct net_device *dev)
 static void napi_enable_rx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 
 	FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
 }
@@ -460,7 +477,7 @@ static void napi_enable_rx(struct net_device *dev)
 static void napi_disable_rx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 
 	FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
 }
@@ -468,7 +485,7 @@ static void napi_disable_rx(struct net_device *dev)
 static void rx_bd_done(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 
 	FW(fecp, r_des_active, 0x01000000);
 }
@@ -476,7 +493,7 @@ static void rx_bd_done(struct net_device *dev)
 static void tx_kickstart(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 
 	FW(fecp, x_des_active, 0x01000000);
 }
@@ -484,7 +501,7 @@ static void tx_kickstart(struct net_device *dev)
 static u32 get_int_events(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 
 	return FR(fecp, ievent) & FR(fecp, imask);
 }
@@ -492,7 +509,7 @@ static u32 get_int_events(struct net_device *dev)
 static void clear_int_events(struct net_device *dev, u32 int_events)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	fec_t *fecp = fep->fec.fecp;
+	fec_t __iomem *fecp = fep->fec.fecp;
 
 	FW(fecp, ievent, int_events);
 }
@@ -503,7 +520,7 @@ static void ev_error(struct net_device *dev, u32 int_events)
 	       ": %s FEC ERROR(s) 0x%x\n", dev->name, int_events);
 }
 
-int get_regs(struct net_device *dev, void *p, int *sizep)
+static int get_regs(struct net_device *dev, void *p, int *sizep)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 
@@ -515,12 +532,12 @@ int get_regs(struct net_device *dev, void *p, int *sizep)
 	return 0;
 }
 
-int get_regs_len(struct net_device *dev)
+static int get_regs_len(struct net_device *dev)
 {
 	return sizeof(fec_t);
 }
 
-void tx_restart(struct net_device *dev)
+static void tx_restart(struct net_device *dev)
 {
 	/* nothing */
 }
diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c
index 6f32674..03134f4 100644
--- a/drivers/net/fs_enet/mac-scc.c
+++ b/drivers/net/fs_enet/mac-scc.c
@@ -43,6 +43,10 @@
 #include <asm/commproc.h>
 #endif
 
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_platform.h>
+#endif
+
 #include "fs_enet.h"
 
 /*************************************************/
@@ -89,27 +93,38 @@
 
 static inline int scc_cr_cmd(struct fs_enet_private *fep, u32 op)
 {
-	cpm8xx_t *cpmp = &((immap_t *)fs_enet_immap)->im_cpm;
-	u32 v, ch;
-	int i = 0;
+	const struct fs_platform_info *fpi = fep->fpi;
+	int i;
 
-	ch = fep->scc.idx << 2;
-	v = mk_cr_cmd(ch, op);
-	W16(cpmp, cp_cpcr, v | CPM_CR_FLG);
+	W16(cpmp, cp_cpcr, fpi->cp_command | CPM_CR_FLG | (op << 8));
 	for (i = 0; i < MAX_CR_CMD_LOOPS; i++)
 		if ((R16(cpmp, cp_cpcr) & CPM_CR_FLG) == 0)
-			break;
+			return 0;
 
-	if (i >= MAX_CR_CMD_LOOPS) {
-		printk(KERN_ERR "%s(): Not able to issue CPM command\n",
-			__FUNCTION__);
-		return 1;
-	}
-	return 0;
+	printk(KERN_ERR "%s(): Not able to issue CPM command\n",
+		__FUNCTION__);
+	return 1;
 }
 
 static int do_pd_setup(struct fs_enet_private *fep)
 {
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+	struct of_device *ofdev = to_of_device(fep->dev);
+
+	fep->interrupt = of_irq_to_resource(ofdev->node, 0, NULL);
+	if (fep->interrupt == NO_IRQ)
+		return -EINVAL;
+
+	fep->scc.sccp = of_iomap(ofdev->node, 0);
+	if (!fep->scc.sccp)
+		return -EINVAL;
+
+	fep->scc.ep = of_iomap(ofdev->node, 1);
+	if (!fep->scc.ep) {
+		iounmap(fep->scc.sccp);
+		return -EINVAL;
+	}
+#else
 	struct platform_device *pdev = to_platform_device(fep->dev);
 	struct resource *r;
 
@@ -129,6 +144,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
 
 	if (fep->scc.ep == NULL)
 		return -EINVAL;
+#endif
 
 	return 0;
 }
@@ -141,12 +157,17 @@ static int do_pd_setup(struct fs_enet_private *fep)
 static int setup_data(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	const struct fs_platform_info *fpi = fep->fpi;
+
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+	struct fs_platform_info *fpi = fep->fpi;
 
 	fep->scc.idx = fs_get_scc_index(fpi->fs_no);
-	if ((unsigned int)fep->fcc.idx > 4)	/* max 4 SCCs */
+	if ((unsigned int)fep->fcc.idx >= 4) /* max 4 SCCs */
 		return -EINVAL;
 
+	fpi->cp_command = fep->fcc.idx << 6;
+#endif
+
 	do_pd_setup(fep);
 
 	fep->scc.hthi = 0;
@@ -154,7 +175,7 @@ static int setup_data(struct net_device *dev)
 
 	fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK;
 	fep->ev_rx = SCC_RX_EVENT;
-	fep->ev_tx = SCC_TX_EVENT;
+	fep->ev_tx = SCC_TX_EVENT | SCCE_ENET_TXE;
 	fep->ev_err = SCC_ERR_EVENT_MSK;
 
 	return 0;
@@ -170,7 +191,8 @@ static int allocate_bd(struct net_device *dev)
 	if (IS_ERR_VALUE(fep->ring_mem_addr))
 		return -ENOMEM;
 
-	fep->ring_base = cpm_dpram_addr(fep->ring_mem_addr);
+	fep->ring_base = (void __iomem __force*)
+		cpm_dpram_addr(fep->ring_mem_addr);
 
 	return 0;
 }
@@ -191,7 +213,7 @@ static void cleanup_data(struct net_device *dev)
 static void set_promiscuous_mode(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_t *sccp = fep->scc.sccp;
+	scc_t __iomem *sccp = fep->scc.sccp;
 
 	S16(sccp, scc_psmr, SCC_PSMR_PRO);
 }
@@ -199,7 +221,7 @@ static void set_promiscuous_mode(struct net_device *dev)
 static void set_multicast_start(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_enet_t *ep = fep->scc.ep;
+	scc_enet_t __iomem *ep = fep->scc.ep;
 
 	W16(ep, sen_gaddr1, 0);
 	W16(ep, sen_gaddr2, 0);
@@ -210,7 +232,7 @@ static void set_multicast_start(struct net_device *dev)
 static void set_multicast_one(struct net_device *dev, const u8 * mac)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_enet_t *ep = fep->scc.ep;
+	scc_enet_t __iomem *ep = fep->scc.ep;
 	u16 taddrh, taddrm, taddrl;
 
 	taddrh = ((u16) mac[5] << 8) | mac[4];
@@ -226,8 +248,8 @@ static void set_multicast_one(struct net_device *dev, const u8 * mac)
 static void set_multicast_finish(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_t *sccp = fep->scc.sccp;
-	scc_enet_t *ep = fep->scc.ep;
+	scc_t __iomem *sccp = fep->scc.sccp;
+	scc_enet_t __iomem *ep = fep->scc.ep;
 
 	/* clear promiscuous always */
 	C16(sccp, scc_psmr, SCC_PSMR_PRO);
@@ -264,8 +286,8 @@ static void set_multicast_list(struct net_device *dev)
 static void restart(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_t *sccp = fep->scc.sccp;
-	scc_enet_t *ep = fep->scc.ep;
+	scc_t __iomem *sccp = fep->scc.sccp;
+	scc_enet_t __iomem *ep = fep->scc.ep;
 	const struct fs_platform_info *fpi = fep->fpi;
 	u16 paddrh, paddrm, paddrl;
 	const unsigned char *mac;
@@ -275,7 +297,7 @@ static void restart(struct net_device *dev)
 
 	/* clear everything (slow & steady does it) */
 	for (i = 0; i < sizeof(*ep); i++)
-		__fs_out8((char *)ep + i, 0);
+		__fs_out8((u8 __iomem *)ep + i, 0);
 
 	/* point to bds */
 	W16(ep, sen_genscc.scc_rbase, fep->ring_mem_addr);
@@ -376,7 +398,7 @@ static void restart(struct net_device *dev)
 static void stop(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_t *sccp = fep->scc.sccp;
+	scc_t __iomem *sccp = fep->scc.sccp;
 	int i;
 
 	for (i = 0; (R16(sccp, scc_sccm) == 0) && i < SCC_RESET_DELAY; i++)
@@ -420,7 +442,7 @@ static void post_free_irq(struct net_device *dev, int irq)
 static void napi_clear_rx_event(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_t *sccp = fep->scc.sccp;
+	scc_t __iomem *sccp = fep->scc.sccp;
 
 	W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK);
 }
@@ -428,7 +450,7 @@ static void napi_clear_rx_event(struct net_device *dev)
 static void napi_enable_rx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_t *sccp = fep->scc.sccp;
+	scc_t __iomem *sccp = fep->scc.sccp;
 
 	S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
 }
@@ -436,7 +458,7 @@ static void napi_enable_rx(struct net_device *dev)
 static void napi_disable_rx(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_t *sccp = fep->scc.sccp;
+	scc_t __iomem *sccp = fep->scc.sccp;
 
 	C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
 }
@@ -454,7 +476,7 @@ static void tx_kickstart(struct net_device *dev)
 static u32 get_int_events(struct net_device *dev)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_t *sccp = fep->scc.sccp;
+	scc_t __iomem *sccp = fep->scc.sccp;
 
 	return (u32) R16(sccp, scc_scce);
 }
@@ -462,7 +484,7 @@ static u32 get_int_events(struct net_device *dev)
 static void clear_int_events(struct net_device *dev, u32 int_events)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
-	scc_t *sccp = fep->scc.sccp;
+	scc_t __iomem *sccp = fep->scc.sccp;
 
 	W16(sccp, scc_scce, int_events & 0xffff);
 }
@@ -477,20 +499,20 @@ static int get_regs(struct net_device *dev, void *p, int *sizep)
 {
 	struct fs_enet_private *fep = netdev_priv(dev);
 
-	if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t))
+	if (*sizep < sizeof(scc_t) + sizeof(scc_enet_t __iomem *))
 		return -EINVAL;
 
 	memcpy_fromio(p, fep->scc.sccp, sizeof(scc_t));
 	p = (char *)p + sizeof(scc_t);
 
-	memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t));
+	memcpy_fromio(p, fep->scc.ep, sizeof(scc_enet_t __iomem *));
 
 	return 0;
 }
 
 static int get_regs_len(struct net_device *dev)
 {
-	return sizeof(scc_t) + sizeof(scc_enet_t);
+	return sizeof(scc_t) + sizeof(scc_enet_t __iomem *);
 }
 
 static void tx_restart(struct net_device *dev)
diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c
index 1a41ea6..b8e4a73 100644
--- a/drivers/net/fs_enet/mii-bitbang.c
+++ b/drivers/net/fs_enet/mii-bitbang.c
@@ -12,303 +12,277 @@
  * kind, whether express or implied.
  */
 
-
 #include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/ptrace.h>
-#include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
-#include <linux/interrupt.h>
 #include <linux/init.h>
-#include <linux/delay.h>
+#include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/spinlock.h>
 #include <linux/mii.h>
-#include <linux/ethtool.h>
-#include <linux/bitops.h>
 #include <linux/platform_device.h>
+#include <linux/mdio-bitbang.h>
 
-#include <asm/pgtable.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <linux/of_platform.h>
+#endif
 
 #include "fs_enet.h"
 
-static int bitbang_prep_bit(u8 **datp, u8 *mskp,
-		struct fs_mii_bit *mii_bit)
-{
-	void *dat;
-	int adv;
-	u8 msk;
-
-	dat = (void*) mii_bit->offset;
-
-	adv = mii_bit->bit >> 3;
-	dat = (char *)dat + adv;
-
-	msk = 1 << (7 - (mii_bit->bit & 7));
-
-	*datp = dat;
-	*mskp = msk;
-
-	return 0;
-}
+struct bb_info {
+	struct mdiobb_ctrl ctrl;
+	__be32 __iomem *dir;
+	__be32 __iomem *dat;
+	u32 mdio_msk;
+	u32 mdc_msk;
+};
 
-static inline void bb_set(u8 *p, u8 m)
+/* FIXME: If any other users of GPIO crop up, then these will have to
+ * have some sort of global synchronization to avoid races with other
+ * pins on the same port.  The ideal solution would probably be to
+ * bind the ports to a GPIO driver, and have this be a client of it.
+ */
+static inline void bb_set(u32 __iomem *p, u32 m)
 {
-	out_8(p, in_8(p) | m);
+	out_be32(p, in_be32(p) | m);
 }
 
-static inline void bb_clr(u8 *p, u8 m)
+static inline void bb_clr(u32 __iomem *p, u32 m)
 {
-	out_8(p, in_8(p) & ~m);
+	out_be32(p, in_be32(p) & ~m);
 }
 
-static inline int bb_read(u8 *p, u8 m)
+static inline int bb_read(u32 __iomem *p, u32 m)
 {
-	return (in_8(p) & m) != 0;
+	return (in_be32(p) & m) != 0;
 }
 
-static inline void mdio_active(struct bb_info *bitbang)
+static inline void mdio_dir(struct mdiobb_ctrl *ctrl, int dir)
 {
-	bb_set(bitbang->mdio_dir, bitbang->mdio_dir_msk);
-}
+	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
 
-static inline void mdio_tristate(struct bb_info *bitbang )
-{
-	bb_clr(bitbang->mdio_dir, bitbang->mdio_dir_msk);
+	if (dir)
+		bb_set(bitbang->dir, bitbang->mdio_msk);
+	else
+		bb_clr(bitbang->dir, bitbang->mdio_msk);
+
+	/* Read back to flush the write. */
+	in_be32(bitbang->dir);
 }
 
-static inline int mdio_read(struct bb_info *bitbang )
+static inline int mdio_read(struct mdiobb_ctrl *ctrl)
 {
-	return bb_read(bitbang->mdio_dat, bitbang->mdio_dat_msk);
+	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+	return bb_read(bitbang->dat, bitbang->mdio_msk);
 }
 
-static inline void mdio(struct bb_info *bitbang , int what)
+static inline void mdio(struct mdiobb_ctrl *ctrl, int what)
 {
+	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
 	if (what)
-		bb_set(bitbang->mdio_dat, bitbang->mdio_dat_msk);
+		bb_set(bitbang->dat, bitbang->mdio_msk);
 	else
-		bb_clr(bitbang->mdio_dat, bitbang->mdio_dat_msk);
+		bb_clr(bitbang->dat, bitbang->mdio_msk);
+
+	/* Read back to flush the write. */
+	in_be32(bitbang->dat);
 }
 
-static inline void mdc(struct bb_info *bitbang , int what)
+static inline void mdc(struct mdiobb_ctrl *ctrl, int what)
 {
+	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
 	if (what)
-		bb_set(bitbang->mdc_dat, bitbang->mdc_msk);
+		bb_set(bitbang->dat, bitbang->mdc_msk);
 	else
-		bb_clr(bitbang->mdc_dat, bitbang->mdc_msk);
+		bb_clr(bitbang->dat, bitbang->mdc_msk);
+
+	/* Read back to flush the write. */
+	in_be32(bitbang->dat);
 }
 
-static inline void mii_delay(struct bb_info *bitbang )
+static struct mdiobb_ops bb_ops = {
+	.owner = THIS_MODULE,
+	.set_mdc = mdc,
+	.set_mdio_dir = mdio_dir,
+	.set_mdio_data = mdio,
+	.get_mdio_data = mdio_read,
+};
+
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+static int __devinit fs_mii_bitbang_init(struct mii_bus *bus,
+                                         struct device_node *np)
 {
-	udelay(bitbang->delay);
+	struct resource res;
+	const u32 *data;
+	int mdio_pin, mdc_pin, len;
+	struct bb_info *bitbang = bus->priv;
+
+	int ret = of_address_to_resource(np, 0, &res);
+	if (ret)
+		return ret;
+
+	if (res.end - res.start < 13)
+		return -ENODEV;
+
+	/* This should really encode the pin number as well, but all
+	 * we get is an int, and the odds of multiple bitbang mdio buses
+	 * is low enough that it's not worth going too crazy.
+	 */
+	bus->id = res.start;
+
+	data = of_get_property(np, "fsl,mdio-pin", &len);
+	if (!data || len != 4)
+		return -ENODEV;
+	mdio_pin = *data;
+
+	data = of_get_property(np, "fsl,mdc-pin", &len);
+	if (!data || len != 4)
+		return -ENODEV;
+	mdc_pin = *data;
+
+	bitbang->dir = ioremap(res.start, res.end - res.start + 1);
+	if (!bitbang->dir)
+		return -ENOMEM;
+
+	bitbang->dat = bitbang->dir + 4;
+	bitbang->mdio_msk = 1 << (31 - mdio_pin);
+	bitbang->mdc_msk = 1 << (31 - mdc_pin);
+
+	return 0;
 }
 
-/* Utility to send the preamble, address, and register (common to read and write). */
-static void bitbang_pre(struct bb_info *bitbang , int read, u8 addr, u8 reg)
+static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
 {
-	int j;
-
-	/*
-	 * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
-	 * The IEEE spec says this is a PHY optional requirement.  The AMD
-	 * 79C874 requires one after power up and one after a MII communications
-	 * error.  This means that we are doing more preambles than we need,
-	 * but it is safer and will be much more robust.
-	 */
+	const u32 *data;
+	int len, id, irq;
 
-	mdio_active(bitbang);
-	mdio(bitbang, 1);
-	for (j = 0; j < 32; j++) {
-		mdc(bitbang, 0);
-		mii_delay(bitbang);
-		mdc(bitbang, 1);
-		mii_delay(bitbang);
-	}
+	data = of_get_property(np, "reg", &len);
+	if (!data || len != 4)
+		return;
 
-	/* send the start bit (01) and the read opcode (10) or write (10) */
-	mdc(bitbang, 0);
-	mdio(bitbang, 0);
-	mii_delay(bitbang);
-	mdc(bitbang, 1);
-	mii_delay(bitbang);
-	mdc(bitbang, 0);
-	mdio(bitbang, 1);
-	mii_delay(bitbang);
-	mdc(bitbang, 1);
-	mii_delay(bitbang);
-	mdc(bitbang, 0);
-	mdio(bitbang, read);
-	mii_delay(bitbang);
-	mdc(bitbang, 1);
-	mii_delay(bitbang);
-	mdc(bitbang, 0);
-	mdio(bitbang, !read);
-	mii_delay(bitbang);
-	mdc(bitbang, 1);
-	mii_delay(bitbang);
-
-	/* send the PHY address */
-	for (j = 0; j < 5; j++) {
-		mdc(bitbang, 0);
-		mdio(bitbang, (addr & 0x10) != 0);
-		mii_delay(bitbang);
-		mdc(bitbang, 1);
-		mii_delay(bitbang);
-		addr <<= 1;
-	}
+	id = *data;
+	bus->phy_mask &= ~(1 << id);
 
-	/* send the register address */
-	for (j = 0; j < 5; j++) {
-		mdc(bitbang, 0);
-		mdio(bitbang, (reg & 0x10) != 0);
-		mii_delay(bitbang);
-		mdc(bitbang, 1);
-		mii_delay(bitbang);
-		reg <<= 1;
-	}
+	irq = of_irq_to_resource(np, 0, NULL);
+	if (irq != NO_IRQ)
+		bus->irq[id] = irq;
 }
 
-static int fs_enet_mii_bb_read(struct mii_bus *bus , int phy_id, int location)
+static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
+                                        const struct of_device_id *match)
 {
-	u16 rdreg;
-	int ret, j;
-	u8 addr = phy_id & 0xff;
-	u8 reg = location & 0xff;
-	struct bb_info* bitbang = bus->priv;
-
-	bitbang_pre(bitbang, 1, addr, reg);
-
-	/* tri-state our MDIO I/O pin so we can read */
-	mdc(bitbang, 0);
-	mdio_tristate(bitbang);
-	mii_delay(bitbang);
-	mdc(bitbang, 1);
-	mii_delay(bitbang);
-
-	/* check the turnaround bit: the PHY should be driving it to zero */
-	if (mdio_read(bitbang) != 0) {
-		/* PHY didn't drive TA low */
-		for (j = 0; j < 32; j++) {
-			mdc(bitbang, 0);
-			mii_delay(bitbang);
-			mdc(bitbang, 1);
-			mii_delay(bitbang);
-		}
-		ret = -1;
+	struct device_node *np = NULL;
+	struct mii_bus *new_bus;
+	struct bb_info *bitbang;
+	int ret = -ENOMEM;
+	int i;
+
+	bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
+	if (!bitbang)
 		goto out;
-	}
 
-	mdc(bitbang, 0);
-	mii_delay(bitbang);
-
-	/* read 16 bits of register data, MSB first */
-	rdreg = 0;
-	for (j = 0; j < 16; j++) {
-		mdc(bitbang, 1);
-		mii_delay(bitbang);
-		rdreg <<= 1;
-		rdreg |= mdio_read(bitbang);
-		mdc(bitbang, 0);
-		mii_delay(bitbang);
-	}
+	bitbang->ctrl.ops = &bb_ops;
+
+	new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
+	if (!new_bus)
+		goto out_free_priv;
+
+	new_bus->name = "CPM2 Bitbanged MII",
+
+	ret = fs_mii_bitbang_init(new_bus, ofdev->node);
+	if (ret)
+		goto out_free_bus;
+
+	new_bus->phy_mask = ~0;
+	new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+	if (!new_bus->irq)
+		goto out_unmap_regs;
+
+	for (i = 0; i < PHY_MAX_ADDR; i++)
+		new_bus->irq[i] = -1;
+
+	while ((np = of_get_next_child(ofdev->node, np)))
+		if (!strcmp(np->type, "ethernet-phy"))
+			add_phy(new_bus, np);
+
+	new_bus->dev = &ofdev->dev;
+	dev_set_drvdata(&ofdev->dev, new_bus);
+
+	ret = mdiobus_register(new_bus);
+	if (ret)
+		goto out_free_irqs;
 
-	mdc(bitbang, 1);
-	mii_delay(bitbang);
-	mdc(bitbang, 0);
-	mii_delay(bitbang);
-	mdc(bitbang, 1);
-	mii_delay(bitbang);
+	return 0;
 
-	ret = rdreg;
+out_free_irqs:
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(new_bus->irq);
+out_unmap_regs:
+	iounmap(bitbang->dir);
+out_free_bus:
+	kfree(new_bus);
+out_free_priv:
+	free_mdio_bitbang(new_bus);
 out:
 	return ret;
 }
 
-static int fs_enet_mii_bb_write(struct mii_bus *bus, int phy_id, int location, u16 val)
+static int fs_enet_mdio_remove(struct of_device *ofdev)
 {
-	int j;
-	struct bb_info* bitbang = bus->priv;
-
-	u8 addr = phy_id & 0xff;
-	u8 reg = location & 0xff;
-	u16 value = val & 0xffff;
-
-	bitbang_pre(bitbang, 0, addr, reg);
-
-	/* send the turnaround (10) */
-	mdc(bitbang, 0);
-	mdio(bitbang, 1);
-	mii_delay(bitbang);
-	mdc(bitbang, 1);
-	mii_delay(bitbang);
-	mdc(bitbang, 0);
-	mdio(bitbang, 0);
-	mii_delay(bitbang);
-	mdc(bitbang, 1);
-	mii_delay(bitbang);
-
-	/* write 16 bits of register data, MSB first */
-	for (j = 0; j < 16; j++) {
-		mdc(bitbang, 0);
-		mdio(bitbang, (value & 0x8000) != 0);
-		mii_delay(bitbang);
-		mdc(bitbang, 1);
-		mii_delay(bitbang);
-		value <<= 1;
-	}
+	struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
+	struct bb_info *bitbang = bus->priv;
 
-	/*
-	 * Tri-state the MDIO line.
-	 */
-	mdio_tristate(bitbang);
-	mdc(bitbang, 0);
-	mii_delay(bitbang);
-	mdc(bitbang, 1);
-	mii_delay(bitbang);
-	return 0;
-}
+	mdiobus_unregister(bus);
+	free_mdio_bitbang(bus);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(bus->irq);
+	iounmap(bitbang->dir);
+	kfree(bitbang);
+	kfree(bus);
 
-static int fs_enet_mii_bb_reset(struct mii_bus *bus)
-{
-	/*nothing here - dunno how to reset it*/
 	return 0;
 }
 
-static int fs_mii_bitbang_init(struct bb_info *bitbang, struct fs_mii_bb_platform_info* fmpi)
-{
-	int r;
+static struct of_device_id fs_enet_mdio_bb_match[] = {
+	{
+		.compatible = "fsl,cpm2-mdio-bitbang",
+	},
+	{},
+};
 
-	bitbang->delay = fmpi->delay;
+static struct of_platform_driver fs_enet_bb_mdio_driver = {
+	.name = "fsl-bb-mdio",
+	.match_table = fs_enet_mdio_bb_match,
+	.probe = fs_enet_mdio_probe,
+	.remove = fs_enet_mdio_remove,
+};
 
-	r = bitbang_prep_bit(&bitbang->mdio_dir,
-			 &bitbang->mdio_dir_msk,
-			 &fmpi->mdio_dir);
-	if (r != 0)
-		return r;
+static int fs_enet_mdio_bb_init(void)
+{
+	return of_register_platform_driver(&fs_enet_bb_mdio_driver);
+}
 
-	r = bitbang_prep_bit(&bitbang->mdio_dat,
-			 &bitbang->mdio_dat_msk,
-			 &fmpi->mdio_dat);
-	if (r != 0)
-		return r;
+static void fs_enet_mdio_bb_exit(void)
+{
+	of_unregister_platform_driver(&fs_enet_bb_mdio_driver);
+}
 
-	r = bitbang_prep_bit(&bitbang->mdc_dat,
-			 &bitbang->mdc_msk,
-			 &fmpi->mdc_dat);
-	if (r != 0)
-		return r;
+module_init(fs_enet_mdio_bb_init);
+module_exit(fs_enet_mdio_bb_exit);
+#else
+static int __devinit fs_mii_bitbang_init(struct bb_info *bitbang,
+                                         struct fs_mii_bb_platform_info *fmpi)
+{
+	bitbang->dir = (u32 __iomem *)fmpi->mdio_dir.offset;
+	bitbang->dat = (u32 __iomem *)fmpi->mdio_dat.offset;
+	bitbang->mdio_msk = 1U << (31 - fmpi->mdio_dat.bit);
+	bitbang->mdc_msk = 1U << (31 - fmpi->mdc_dat.bit);
 
 	return 0;
 }
 
-
 static int __devinit fs_enet_mdio_probe(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -320,20 +294,19 @@ static int __devinit fs_enet_mdio_probe(struct device *dev)
 	if (NULL == dev)
 		return -EINVAL;
 
-	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+	bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
 
-	if (NULL == new_bus)
+	if (NULL == bitbang)
 		return -ENOMEM;
 
-	bitbang = kzalloc(sizeof(struct bb_info), GFP_KERNEL);
+	bitbang->ctrl.ops = &bb_ops;
 
-	if (NULL == bitbang)
+	new_bus = alloc_mdio_bitbang(&bitbang->ctrl);
+
+	if (NULL == new_bus)
 		return -ENOMEM;
 
 	new_bus->name = "BB MII Bus",
-	new_bus->read = &fs_enet_mii_bb_read,
-	new_bus->write = &fs_enet_mii_bb_write,
-	new_bus->reset = &fs_enet_mii_bb_reset,
 	new_bus->id = pdev->id;
 
 	new_bus->phy_mask = ~0x9;
@@ -365,13 +338,12 @@ static int __devinit fs_enet_mdio_probe(struct device *dev)
 	return 0;
 
 bus_register_fail:
+	free_mdio_bitbang(new_bus);
 	kfree(bitbang);
-	kfree(new_bus);
 
 	return err;
 }
 
-
 static int fs_enet_mdio_remove(struct device *dev)
 {
 	struct mii_bus *bus = dev_get_drvdata(dev);
@@ -380,9 +352,7 @@ static int fs_enet_mdio_remove(struct device *dev)
 
 	dev_set_drvdata(dev, NULL);
 
-	iounmap((void *) (&bus->priv));
-	bus->priv = NULL;
-	kfree(bus);
+	free_mdio_bitbang(bus);
 
 	return 0;
 }
@@ -403,4 +373,4 @@ void fs_enet_mdio_bb_exit(void)
 {
 	driver_unregister(&fs_enet_bb_mdio_driver);
 }
-
+#endif
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 0a563a8..a89cf15 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -36,6 +36,10 @@
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+#include <asm/of_platform.h>
+#endif
+
 #include "fs_enet.h"
 #include "fec.h"
 
@@ -47,6 +51,7 @@
 
 #define FEC_MII_LOOPS	10000
 
+#ifndef CONFIG_PPC_CPM_NEW_BINDING
 static int match_has_phy (struct device *dev, void* data)
 {
 	struct platform_device* pdev = container_of(dev, struct platform_device, dev);
@@ -65,7 +70,7 @@ static int match_has_phy (struct device *dev, void* data)
 static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info *fmpi)
 {
 	struct resource *r;
-	fec_t *fecp;
+	fec_t __iomem *fecp;
 	char* name = "fsl-cpm-fec";
 
 	/* we need fec in order to be useful */
@@ -80,7 +85,7 @@ static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info
 
 	r = platform_get_resource_byname(fec_pdev, IORESOURCE_MEM, "regs");
 
-	fec->fecp = fecp = (fec_t*)ioremap(r->start,sizeof(fec_t));
+	fec->fecp = fecp = ioremap(r->start,sizeof(fec_t));
 	fec->mii_speed = fmpi->mii_speed;
 
 	setbits32(&fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);	/* MII enable */
@@ -90,11 +95,12 @@ static int fs_mii_fec_init(struct fec_info* fec, struct fs_mii_fec_platform_info
 
 	return 0;
 }
+#endif
 
 static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
 {
 	struct fec_info* fec = bus->priv;
-	fec_t *fecp = fec->fecp;
+	fec_t __iomem *fecp = fec->fecp;
 	int i, ret = -1;
 
 	if ((in_be32(&fecp->fec_r_cntrl) & FEC_RCNTRL_MII_MODE) == 0)
@@ -113,13 +119,12 @@ static int fs_enet_fec_mii_read(struct mii_bus *bus , int phy_id, int location)
 	}
 
 	return ret;
-
 }
 
 static int fs_enet_fec_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
 {
 	struct fec_info* fec = bus->priv;
-	fec_t *fecp = fec->fecp;
+	fec_t __iomem *fecp = fec->fecp;
 	int i;
 
 	/* this must never happen */
@@ -146,6 +151,141 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
 	return 0;
 }
 
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+static void __devinit add_phy(struct mii_bus *bus, struct device_node *np)
+{
+	const u32 *data;
+	int len, id, irq;
+
+	data = of_get_property(np, "reg", &len);
+	if (!data || len != 4)
+		return;
+
+	id = *data;
+	bus->phy_mask &= ~(1 << id);
+
+	irq = of_irq_to_resource(np, 0, NULL);
+	if (irq != NO_IRQ)
+		bus->irq[id] = irq;
+}
+
+static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
+                                        const struct of_device_id *match)
+{
+	struct device_node *np = NULL;
+	struct resource res;
+	struct mii_bus *new_bus;
+	struct fec_info *fec;
+	int ret = -ENOMEM, i;
+
+	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+	if (!new_bus)
+		goto out;
+
+	fec = kzalloc(sizeof(struct fec_info), GFP_KERNEL);
+	if (!fec)
+		goto out_mii;
+
+	new_bus->priv = fec;
+	new_bus->name = "FEC MII Bus";
+	new_bus->read = &fs_enet_fec_mii_read;
+	new_bus->write = &fs_enet_fec_mii_write;
+	new_bus->reset = &fs_enet_fec_mii_reset;
+
+	ret = of_address_to_resource(ofdev->node, 0, &res);
+	if (ret)
+		return ret;
+
+	new_bus->id = res.start;
+
+	fec->fecp = ioremap(res.start, res.end - res.start + 1);
+	if (!fec->fecp)
+		goto out_fec;
+
+	fec->mii_speed = ((ppc_proc_freq + 4999999) / 5000000) << 1;
+
+	setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
+	setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX |
+	                                  FEC_ECNTRL_ETHER_EN);
+	out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII);
+	out_be32(&fec->fecp->fec_mii_speed, fec->mii_speed);
+
+	new_bus->phy_mask = ~0;
+	new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
+	if (!new_bus->irq)
+		goto out_unmap_regs;
+
+	for (i = 0; i < PHY_MAX_ADDR; i++)
+		new_bus->irq[i] = -1;
+
+	while ((np = of_get_next_child(ofdev->node, np)))
+		if (!strcmp(np->type, "ethernet-phy"))
+			add_phy(new_bus, np);
+
+	new_bus->dev = &ofdev->dev;
+	dev_set_drvdata(&ofdev->dev, new_bus);
+
+	ret = mdiobus_register(new_bus);
+	if (ret)
+		goto out_free_irqs;
+
+	return 0;
+
+out_free_irqs:
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(new_bus->irq);
+out_unmap_regs:
+	iounmap(fec->fecp);
+out_fec:
+	kfree(fec);
+out_mii:
+	kfree(new_bus);
+out:
+	return ret;
+}
+
+static int fs_enet_mdio_remove(struct of_device *ofdev)
+{
+	struct mii_bus *bus = dev_get_drvdata(&ofdev->dev);
+	struct fec_info *fec = bus->priv;
+
+	mdiobus_unregister(bus);
+	dev_set_drvdata(&ofdev->dev, NULL);
+	kfree(bus->irq);
+	iounmap(fec->fecp);
+	kfree(fec);
+	kfree(bus);
+
+	return 0;
+}
+
+static struct of_device_id fs_enet_mdio_fec_match[] = {
+	{
+		.compatible = "fsl,pq1-fec-mdio",
+	},
+	{},
+};
+
+static struct of_platform_driver fs_enet_fec_mdio_driver = {
+	.name = "fsl-fec-mdio",
+	.match_table = fs_enet_mdio_fec_match,
+	.probe = fs_enet_mdio_probe,
+	.remove = fs_enet_mdio_remove,
+};
+
+static int fs_enet_mdio_fec_init(void)
+{
+	return of_register_platform_driver(&fs_enet_fec_mdio_driver);
+}
+
+static void fs_enet_mdio_fec_exit(void)
+{
+	of_unregister_platform_driver(&fs_enet_fec_mdio_driver);
+}
+
+module_init(fs_enet_mdio_fec_init);
+module_exit(fs_enet_mdio_fec_exit);
+#else
 static int __devinit fs_enet_fec_mdio_probe(struct device *dev)
 {
 	struct platform_device *pdev = to_platform_device(dev);
@@ -236,4 +376,4 @@ void fs_enet_mdio_fec_exit(void)
 {
 	driver_unregister(&fs_enet_fec_mdio_driver);
 }
-
+#endif
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index c28a0a4..047ea7b 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -492,7 +492,7 @@ static int macb_poll(struct napi_struct *napi, int budget)
 	}
 
 	dev_dbg(&bp->pdev->dev, "poll: status = %08lx, budget = %d\n",
-		(unsigned long)status, *budget);
+		(unsigned long)status, budget);
 
 	if (!(status & MACB_BIT(REC))) {
 		dev_warn(&bp->pdev->dev,
@@ -503,7 +503,7 @@ static int macb_poll(struct napi_struct *napi, int budget)
 	}
 
 	work_done = macb_rx(bp, budget);
-	if (work_done < orig_budget)
+	if (work_done < budget)
 		netif_rx_complete(dev, napi);
 
 	/*
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index de59313..4bba884 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -772,6 +772,7 @@ static struct pcmcia_device_id axnet_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1106),
 	PCMCIA_DEVICE_MANF_CARD(0x8a01, 0xc1ab),
 	PCMCIA_DEVICE_MANF_CARD(0x021b, 0x0202), 
+	PCMCIA_DEVICE_MANF_CARD(0xffff, 0x1090), 
 	PCMCIA_DEVICE_PROD_ID12("AmbiCom,Inc.", "Fast Ethernet PC Card(AMB8110)", 0x49b020a7, 0x119cc9fc),
 	PCMCIA_DEVICE_PROD_ID124("Fast Ethernet", "16-bit PC Card", "AX88190", 0xb4be14e3, 0x9a12eb6a, 0xab9be5ef),
 	PCMCIA_DEVICE_PROD_ID12("ASIX", "AX88190", 0x0959823b, 0xab9be5ef),
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 6a64751..9d45e96 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1662,6 +1662,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
 	PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDF", 0x1b7827b2, 0xfec71e40),
 	PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDL/T", 0x1b7827b2, 0x79fba4f7),
 	PCMCIA_DEVICE_PROD_ID12("Laneed", "LD-CDS", 0x1b7827b2, 0x931afaab),
+	PCMCIA_DEVICE_PROD_ID12("LEMEL", "LM-N89TX PRO", 0xbbefb52f, 0xd2897a97),
 	PCMCIA_DEVICE_PROD_ID12("Linksys", "Combo PCMCIA EthernetCard (EC2T)", 0x0733cc81, 0x32ee8c78),
 	PCMCIA_DEVICE_PROD_ID12("LINKSYS", "E-CARD", 0xf7cb0b07, 0x6701da11),
 	PCMCIA_DEVICE_PROD_ID12("Linksys", "EtherFast 10/100 Integrated PC Card (PCM100)", 0x0733cc81, 0x453c3f9d),
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index 432c210..54b2ba9 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -90,4 +90,13 @@ config FIXED_MII_AMNT
         This control will have specified number allocated for each fixed
         PHY type enabled.
 
+config MDIO_BITBANG
+	tristate "Support for bitbanged MDIO buses"
+	help
+	  This module implements the MDIO bus protocol in software,
+	  for use by low level drivers that export the ability to
+	  drive the relevant pins.
+
+	  If in doubt, say N.
+
 endif # PHYLIB
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile
index 8885650..3d6cc7b 100644
--- a/drivers/net/phy/Makefile
+++ b/drivers/net/phy/Makefile
@@ -13,3 +13,4 @@ obj-$(CONFIG_VITESSE_PHY)	+= vitesse.o
 obj-$(CONFIG_BROADCOM_PHY)	+= broadcom.o
 obj-$(CONFIG_ICPLUS_PHY)	+= icplus.o
 obj-$(CONFIG_FIXED_PHY)		+= fixed.o
+obj-$(CONFIG_MDIO_BITBANG)	+= mdio-bitbang.o
diff --git a/drivers/net/phy/mdio-bitbang.c b/drivers/net/phy/mdio-bitbang.c
new file mode 100644
index 0000000..8cd243d
--- /dev/null
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -0,0 +1,187 @@
+/*
+ * Bitbanged MDIO support.
+ *
+ * Author: Scott Wood <scottwood@freescale.com>
+ * Copyright (c) 2007 Freescale Semiconductor
+ *
+ * Based on CPM2 MDIO code which is:
+ *
+ * Copyright (c) 2003 Intracom S.A.
+ *  by Pantelis Antoniou <panto@intracom.gr>
+ *
+ * 2005 (c) MontaVista Software, Inc.
+ * Vitaly Bordug <vbordug@ru.mvista.com>
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/module.h>
+#include <linux/mdio-bitbang.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+
+#define MDIO_READ 1
+#define MDIO_WRITE 0
+
+#define MDIO_SETUP_TIME 10
+#define MDIO_HOLD_TIME 10
+
+/* Minimum MDC period is 400 ns, plus some margin for error.  MDIO_DELAY
+ * is done twice per period.
+ */
+#define MDIO_DELAY 250
+
+/* The PHY may take up to 300 ns to produce data, plus some margin
+ * for error.
+ */
+#define MDIO_READ_DELAY 350
+
+/* MDIO must already be configured as output. */
+static void mdiobb_send_bit(struct mdiobb_ctrl *ctrl, int val)
+{
+	const struct mdiobb_ops *ops = ctrl->ops;
+
+	ops->set_mdio_data(ctrl, val);
+	ndelay(MDIO_DELAY);
+	ops->set_mdc(ctrl, 1);
+	ndelay(MDIO_DELAY);
+	ops->set_mdc(ctrl, 0);
+}
+
+/* MDIO must already be configured as input. */
+static int mdiobb_get_bit(struct mdiobb_ctrl *ctrl)
+{
+	const struct mdiobb_ops *ops = ctrl->ops;
+
+	ndelay(MDIO_DELAY);
+	ops->set_mdc(ctrl, 1);
+	ndelay(MDIO_READ_DELAY);
+	ops->set_mdc(ctrl, 0);
+
+	return ops->get_mdio_data(ctrl);
+}
+
+/* MDIO must already be configured as output. */
+static void mdiobb_send_num(struct mdiobb_ctrl *ctrl, u16 val, int bits)
+{
+	int i;
+
+	for (i = bits - 1; i >= 0; i--)
+		mdiobb_send_bit(ctrl, (val >> i) & 1);
+}
+
+/* MDIO must already be configured as input. */
+static u16 mdiobb_get_num(struct mdiobb_ctrl *ctrl, int bits)
+{
+	int i;
+	u16 ret = 0;
+
+	for (i = bits - 1; i >= 0; i--) {
+		ret <<= 1;
+		ret |= mdiobb_get_bit(ctrl);
+	}
+
+	return ret;
+}
+
+/* Utility to send the preamble, address, and
+ * register (common to read and write).
+ */
+static void mdiobb_cmd(struct mdiobb_ctrl *ctrl, int read, u8 phy, u8 reg)
+{
+	const struct mdiobb_ops *ops = ctrl->ops;
+	int i;
+
+	ops->set_mdio_dir(ctrl, 1);
+
+	/*
+	 * Send a 32 bit preamble ('1's) with an extra '1' bit for good
+	 * measure.  The IEEE spec says this is a PHY optional
+	 * requirement.  The AMD 79C874 requires one after power up and
+	 * one after a MII communications error.  This means that we are
+	 * doing more preambles than we need, but it is safer and will be
+	 * much more robust.
+	 */
+
+	for (i = 0; i < 32; i++)
+		mdiobb_send_bit(ctrl, 1);
+
+	/* send the start bit (01) and the read opcode (10) or write (10) */
+	mdiobb_send_bit(ctrl, 0);
+	mdiobb_send_bit(ctrl, 1);
+	mdiobb_send_bit(ctrl, read);
+	mdiobb_send_bit(ctrl, !read);
+
+	mdiobb_send_num(ctrl, phy, 5);
+	mdiobb_send_num(ctrl, reg, 5);
+}
+
+
+static int mdiobb_read(struct mii_bus *bus, int phy, int reg)
+{
+	struct mdiobb_ctrl *ctrl = bus->priv;
+	int ret, i;
+
+	mdiobb_cmd(ctrl, MDIO_READ, phy, reg);
+	ctrl->ops->set_mdio_dir(ctrl, 0);
+
+	/* check the turnaround bit: the PHY should be driving it to zero */
+	if (mdiobb_get_bit(ctrl) != 0) {
+		/* PHY didn't drive TA low -- flush any bits it
+		 * may be trying to send.
+		 */
+		for (i = 0; i < 32; i++)
+			mdiobb_get_bit(ctrl);
+
+		return 0xffff;
+	}
+
+	ret = mdiobb_get_num(ctrl, 16);
+	mdiobb_get_bit(ctrl);
+	return ret;
+}
+
+static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
+{
+	struct mdiobb_ctrl *ctrl = bus->priv;
+
+	mdiobb_cmd(ctrl, MDIO_WRITE, phy, reg);
+
+	/* send the turnaround (10) */
+	mdiobb_send_bit(ctrl, 1);
+	mdiobb_send_bit(ctrl, 0);
+
+	mdiobb_send_num(ctrl, val, 16);
+
+	ctrl->ops->set_mdio_dir(ctrl, 0);
+	mdiobb_get_bit(ctrl);
+	return 0;
+}
+
+struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl)
+{
+	struct mii_bus *bus;
+
+	bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
+	if (!bus)
+		return NULL;
+
+	__module_get(ctrl->ops->owner);
+
+	bus->read = mdiobb_read;
+	bus->write = mdiobb_write;
+	bus->priv = ctrl;
+
+	return bus;
+}
+
+void free_mdio_bitbang(struct mii_bus *bus)
+{
+	struct mdiobb_ctrl *ctrl = bus->priv;
+
+	module_put(ctrl->ops->owner);
+	kfree(bus);
+}
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index c0276c0..7c60df4 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -2063,7 +2063,7 @@ static int __init smc911x_probe(struct net_device *dev, unsigned long ioaddr)
 
 	/* Grab the IRQ */
 	retval = request_irq(dev->irq, &smc911x_interrupt,
-			IRQF_SHARED | IRQF_TRIGGER_FALLING, dev->name, dev);
+			IRQF_SHARED | SMC_IRQ_SENSE, dev->name, dev);
 	if (retval)
 		goto err_out;
 
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
index 962a710..16a0edc 100644
--- a/drivers/net/smc911x.h
+++ b/drivers/net/smc911x.h
@@ -36,6 +36,12 @@
   #define SMC_USE_PXA_DMA	1
   #define SMC_USE_16BIT		0
   #define SMC_USE_32BIT		1
+  #define SMC_IRQ_SENSE		IRQF_TRIGGER_FALLING
+#elif CONFIG_SH_MAGIC_PANEL_R2
+  #define SMC_USE_SH_DMA	0
+  #define SMC_USE_16BIT		0
+  #define SMC_USE_32BIT		1
+  #define SMC_IRQ_SENSE		IRQF_TRIGGER_LOW
 #endif
 
 
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 6ff3a16..af9e6bf 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -284,6 +284,7 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 #elif   defined(CONFIG_SUPERH)
 
 #ifdef CONFIG_SOLUTION_ENGINE
+#define SMC_IRQ_FLAGS		(0)
 #define SMC_CAN_USE_8BIT       0
 #define SMC_CAN_USE_16BIT      1
 #define SMC_CAN_USE_32BIT      0
diff --git a/include/linux/fs_enet_pd.h b/include/linux/fs_enet_pd.h
index 543cd3c..9bc045b 100644
--- a/include/linux/fs_enet_pd.h
+++ b/include/linux/fs_enet_pd.h
@@ -16,6 +16,7 @@
 #ifndef FS_ENET_PD_H
 #define FS_ENET_PD_H
 
+#include <linux/string.h>
 #include <asm/types.h>
 
 #define FS_ENET_NAME	"fs_enet"
@@ -119,6 +120,7 @@ struct fs_platform_info {
 
 	u32 cp_page;		/* CPM page */
 	u32 cp_block;		/* CPM sblock */
+	u32 cp_command;		/* CPM page/sblock/mcn */
 
 	u32 clk_trx;		/* some stuff for pins & mux configuration*/
 	u32 clk_rx;
@@ -133,7 +135,11 @@ struct fs_platform_info {
 	u32 device_flags;
 
 	int phy_addr;		/* the phy address (-1 no phy) */
+#ifdef CONFIG_PPC_CPM_NEW_BINDING
+	char bus_id[16];
+#else
 	const char*	bus_id;
+#endif
 	int phy_irq;		/* the phy irq (if it exists)  */
 
 	const struct fs_mii_bus_info *bus_info;
diff --git a/include/linux/mdio-bitbang.h b/include/linux/mdio-bitbang.h
new file mode 100644
index 0000000..8ea9a42
--- /dev/null
+++ b/include/linux/mdio-bitbang.h
@@ -0,0 +1,42 @@
+#ifndef __LINUX_MDIO_BITBANG_H
+#define __LINUX_MDIO_BITBANG_H
+
+#include <linux/phy.h>
+#include <linux/module.h>
+
+struct mdiobb_ctrl;
+
+struct mdiobb_ops {
+	struct module *owner;
+
+	/* Set the Management Data Clock high if level is one,
+	 * low if level is zero.
+	 */
+	void (*set_mdc)(struct mdiobb_ctrl *ctrl, int level);
+
+	/* Configure the Management Data I/O pin as an input if
+	 * "output" is zero, or an output if "output" is one.
+	 */
+	void (*set_mdio_dir)(struct mdiobb_ctrl *ctrl, int output);
+
+	/* Set the Management Data I/O pin high if value is one,
+	 * low if "value" is zero.  This may only be called
+	 * when the MDIO pin is configured as an output.
+	 */
+	void (*set_mdio_data)(struct mdiobb_ctrl *ctrl, int value);
+
+	/* Retrieve the state Management Data I/O pin. */
+	int (*get_mdio_data)(struct mdiobb_ctrl *ctrl);
+};
+
+struct mdiobb_ctrl {
+	const struct mdiobb_ops *ops;
+};
+
+/* The returned bus is not yet registered with the phy layer. */
+struct mii_bus *alloc_mdio_bitbang(struct mdiobb_ctrl *ctrl);
+
+/* The bus must already have been unregistered. */
+void free_mdio_bitbang(struct mii_bus *bus);
+
+#endif

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-09-29  6:08 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2007-09-29  6:08 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, LKML


Please pull from the 'upstream' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream

to receive the following changes:

Adrian Bunk (1):
      drivers/net/cxgb3/xgmac.c: remove dead code

Chris Snook (1):
      atl1: explain 32-bit DMA restriction

Ed Swierk (1):
      forcedeth: "no link" is informational

Jeff Garzik (1):
      [netdrvr] sundance: fix phy scanning on IP100A

Jesper Juhl (1):
      Avoid possible NULL pointer deref in 3c359 driver

Krishna Kumar (1):
      e1000e: Do not allow requeue of freed skb

Maciej W. Rozycki (5):
      sb1250-mac.c: De-typedef, de-volatile, de-etc...
      sb1250-mac: Driver model & phylib update
      PHYLIB: Spinlock fixes for softirqs
      PHYLIB: IRQ event workqueue handling fixes
      PHYLIB: fix an interrupt loop potential when halting

Magnus Damm (1):
      ax88796: add 93cx6 eeprom support

Mariusz Kozlowski (1):
      skge: remove broken and unused PHY_M_PC_MDI_XMODE macro

Micah Gruber (1):
      Fix a potential NULL pointer dereference in uli526x_interrupt() in drivers/net/tulip/uli526x.c

Nathanael Nerode (1):
      dgrs: remove from build, config, and maintainer list

Olof Johansson (4):
      pasemi_mac: set interface speed correctly on XAUI ports
      pasemi_mac: flags as passed to spin_*_irqsave() should be unsigned long
      pasemi_mac: don't enable rx before there are buffers on the ring
      pasemi_mac: pass in count of buffers to replenish rx ring with

Peter Oruba (1):
      PCI-X/PCI-Express read control interfaces: use them in e1000

Roy Zang (1):
      Clean up redundant PHY write line for ULi526x Ethernet driver

Stephen Hemminger (2):
      via-velocity: use standard VLAN interface (resend)
      via-velocity: more cleanup

Vitaly Bordug (1):
      PHY fixed driver: rework release path and update phy_id notation

 Documentation/networking/dgrs.txt |   52 
 MAINTAINERS                       |    6 
 drivers/net/Kconfig               |   23 
 drivers/net/Makefile              |    1 
 drivers/net/atl1/atl1_main.c      |   10 
 drivers/net/ax88796.c             |   49 
 drivers/net/cxgb3/xgmac.c         |    5 
 drivers/net/dgrs.c                | 1593 ------
 drivers/net/dgrs.h                |   38 
 drivers/net/dgrs_asstruct.h       |   37 
 drivers/net/dgrs_bcomm.h          |  148 
 drivers/net/dgrs_es4h.h           |  183 
 drivers/net/dgrs_ether.h          |  135 
 drivers/net/dgrs_firmware.c       | 9966 --------------------------------------
 drivers/net/dgrs_i82596.h         |  473 -
 drivers/net/dgrs_plx9060.h        |  175 
 drivers/net/e1000/e1000_hw.c      |   25 
 drivers/net/e1000/e1000_hw.h      |    2 
 drivers/net/e1000/e1000_main.c    |   14 
 drivers/net/e1000e/netdev.c       |    2 
 drivers/net/forcedeth.c           |    2 
 drivers/net/pasemi_mac.c          |   43 
 drivers/net/phy/Kconfig           |   14 
 drivers/net/phy/fixed.c           |  310 -
 drivers/net/phy/phy.c             |   52 
 drivers/net/phy/phy_device.c      |    4 
 drivers/net/sb1250-mac.c          | 1367 ++---
 drivers/net/skge.h                |    2 
 drivers/net/sundance.c            |   14 
 drivers/net/tokenring/3c359.c     |    5 
 drivers/net/tulip/uli526x.c       |    6 
 drivers/net/via-velocity.c        |  247 
 drivers/net/via-velocity.h        |  207 
 include/linux/eeprom_93cx6.h      |    3 
 include/linux/phy.h               |    3 
 include/linux/phy_fixed.h         |   38 
 include/net/ax88796.h             |    1 
 37 files changed, 1233 insertions(+), 14022 deletions(-)

diff --git a/Documentation/networking/dgrs.txt b/Documentation/networking/dgrs.txt
deleted file mode 100644
index 1aa1bb3..0000000
--- a/Documentation/networking/dgrs.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-    The Digi International RightSwitch SE-X (dgrs) Device Driver
-
-This is a Linux driver for the Digi International RightSwitch SE-X
-EISA and PCI boards.  These are 4 (EISA) or 6 (PCI) port Ethernet
-switches and a NIC combined into a single board.  This driver can
-be compiled into the kernel statically or as a loadable module.
-
-There is also a companion management tool, called "xrightswitch".
-The management tool lets you watch the performance graphically,
-as well as set the SNMP agent IP and IPX addresses, IEEE Spanning
-Tree, and Aging time.  These can also be set from the command line
-when the driver is loaded.  The driver command line options are:
-
-	debug=NNN		Debug printing level
-	dma=0/1			Disable/Enable DMA on PCI card
-	spantree=0/1		Disable/Enable IEEE spanning tree
-	hashexpire=NNN		Change address aging time (default 300 seconds)
-	ipaddr=A,B,C,D		Set SNMP agent IP address i.e. 199,86,8,221
-	iptrap=A,B,C,D		Set SNMP agent IP trap address i.e. 199,86,8,221
-	ipxnet=NNN		Set SNMP agent IPX network number
-	nicmode=0/1		Disable/Enable multiple NIC mode
-
-There is also a tool for setting up input and output packet filters
-on each port, called "dgrsfilt".
-
-Both the management tool and the filtering tool are available
-separately from the following FTP site:
-
-	ftp://ftp.dgii.com/drivers/rightswitch/linux/
-
-When nicmode=1, the board and driver operate as 4 or 6 individual
-NIC ports (eth0...eth5) instead of as a switch.  All switching
-functions are disabled.  In the future, the board firmware may include
-a routing cache when in this mode.
-
-Copyright 1995-1996 Digi International Inc.
-
-This software may be used and distributed according to the terms
-of the GNU General Public License, incorporated herein by reference.
-
-For information on purchasing a RightSwitch SE-4 or SE-6
-board, please contact Digi's sales department at 1-612-912-3444
-or 1-800-DIGIBRD.  Outside the U.S., please check our Web page at:
-
-	http://www.dgii.com
-
-for sales offices worldwide.  Tech support is also available through
-the channels listed on the Web site, although as long as I am
-employed on networking products at Digi I will be happy to provide
-any bug fixes that may be needed.
-
--Rick Richardson, rick@dgii.com
diff --git a/MAINTAINERS b/MAINTAINERS
index 27e1110..1664680 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1274,12 +1274,6 @@ L:	Eng.Linux@digi.com
 W:	http://www.digi.com
 S:	Orphaned
 
-DIGI RIGHTSWITCH NETWORK DRIVER
-P:	Rick Richardson
-L:	netdev@vger.kernel.org
-W:	http://www.digi.com
-S:	Orphaned
-
 DIRECTORY NOTIFICATION
 P:	Stephen Rothwell
 M:	sfr@canb.auug.org.au
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 467532c..45f6cf5 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -240,6 +240,13 @@ config AX88796
 	  AX88796 driver, using platform bus to provide
 	  chip detection and resources
 
+config AX88796_93CX6
+	bool "ASIX AX88796 external 93CX6 eeprom support"
+	depends on AX88796
+	select EEPROM_93CX6
+	help
+	  Select this if your platform comes with an external 93CX6 eeprom.
+
 config MACE
 	tristate "MACE (Power Mac ethernet) support"
 	depends on PPC_PMAC && PPC32
@@ -1459,21 +1466,6 @@ config TC35815
 	depends on NET_PCI && PCI && MIPS
 	select MII
 
-config DGRS
-	tristate "Digi Intl. RightSwitch SE-X support"
-	depends on NET_PCI && (PCI || EISA)
-	---help---
-	  This is support for the Digi International RightSwitch series of
-	  PCI/EISA Ethernet switch cards. These include the SE-4 and the SE-6
-	  models.  If you have a network card of this type, say Y and read the
-	  Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.  More specific
-	  information is contained in <file:Documentation/networking/dgrs.txt>.
-
-	  To compile this driver as a module, choose M here and read
-	  <file:Documentation/networking/net-modules.txt>.  The module
-	  will be called dgrs.
-
 config EEPRO100
 	tristate "EtherExpressPro/100 support (eepro100, original Becker driver)"
 	depends on NET_PCI && PCI
@@ -2126,6 +2118,7 @@ config R8169_VLAN
 config SB1250_MAC
 	tristate "SB1250 Gigabit Ethernet support"
 	depends on SIBYTE_SB1xxx_SOC
+	select PHYLIB
 	---help---
 	  This driver supports Gigabit Ethernet interfaces based on the
 	  Broadcom SiByte family of System-On-a-Chip parts.  They include
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 6220c50..eb5c655 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -44,7 +44,6 @@ obj-$(CONFIG_SUNVNET) += sunvnet.o
 obj-$(CONFIG_MACE) += mace.o
 obj-$(CONFIG_BMAC) += bmac.o
 
-obj-$(CONFIG_DGRS) += dgrs.o
 obj-$(CONFIG_VORTEX) += 3c59x.o
 obj-$(CONFIG_TYPHOON) += typhoon.o
 obj-$(CONFIG_NE2K_PCI) += ne2k-pci.o 8390.o
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index e1a9223..4c728f1 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -2209,8 +2209,14 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 		return err;
 
 	/*
-	 * 64-bit DMA currently has data corruption problems, so let's just
-	 * use 32-bit DMA for now.  This is a big hack that is probably wrong.
+	 * The atl1 chip can DMA to 64-bit addresses, but it uses a single
+	 * shared register for the high 32 bits, so only a single, aligned,
+	 * 4 GB physical address range can be used at a time.
+	 *
+	 * Supporting 64-bit DMA on this hardware is more trouble than it's
+	 * worth.  It is far easier to limit to 32-bit DMA than update
+	 * various kernel subsystems to support the mechanics required by a
+	 * fixed-high-32-bit system.
 	 */
 	err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 	if (err) {
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
index 90e0734..9fe0517 100644
--- a/drivers/net/ax88796.c
+++ b/drivers/net/ax88796.c
@@ -24,6 +24,7 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/mii.h>
+#include <linux/eeprom_93cx6.h>
 
 #include <net/ax88796.h>
 
@@ -582,6 +583,37 @@ static const struct ethtool_ops ax_ethtool_ops = {
 	.get_link		= ax_get_link,
 };
 
+#ifdef CONFIG_AX88796_93CX6
+static void ax_eeprom_register_read(struct eeprom_93cx6 *eeprom)
+{
+	struct ei_device *ei_local = eeprom->data;
+	u8 reg = ei_inb(ei_local->mem + AX_MEMR);
+
+	eeprom->reg_data_in = reg & AX_MEMR_EEI;
+	eeprom->reg_data_out = reg & AX_MEMR_EEO; /* Input pin */
+	eeprom->reg_data_clock = reg & AX_MEMR_EECLK;
+	eeprom->reg_chip_select = reg & AX_MEMR_EECS;
+}
+
+static void ax_eeprom_register_write(struct eeprom_93cx6 *eeprom)
+{
+	struct ei_device *ei_local = eeprom->data;
+	u8 reg = ei_inb(ei_local->mem + AX_MEMR);
+
+	reg &= ~(AX_MEMR_EEI | AX_MEMR_EECLK | AX_MEMR_EECS);
+
+	if (eeprom->reg_data_in)
+		reg |= AX_MEMR_EEI;
+	if (eeprom->reg_data_clock)
+		reg |= AX_MEMR_EECLK;
+	if (eeprom->reg_chip_select)
+		reg |= AX_MEMR_EECS;
+
+	ei_outb(reg, ei_local->mem + AX_MEMR);
+	udelay(10);
+}
+#endif
+
 /* setup code */
 
 static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
@@ -640,6 +672,23 @@ static int ax_init_dev(struct net_device *dev, int first_init)
 		memcpy(dev->dev_addr,  SA_prom, 6);
 	}
 
+#ifdef CONFIG_AX88796_93CX6
+	if (first_init && ax->plat->flags & AXFLG_HAS_93CX6) {
+		unsigned char mac_addr[6];
+		struct eeprom_93cx6 eeprom;
+
+		eeprom.data = ei_local;
+		eeprom.register_read = ax_eeprom_register_read;
+		eeprom.register_write = ax_eeprom_register_write;
+		eeprom.width = PCI_EEPROM_WIDTH_93C56;
+
+		eeprom_93cx6_multiread(&eeprom, 0,
+				       (__le16 __force *)mac_addr,
+				       sizeof(mac_addr) >> 1);
+
+		memcpy(dev->dev_addr,  mac_addr, 6);
+	}
+#endif
 	if (ax->plat->wordlength == 2) {
 		/* We must set the 8390 for word mode. */
 		ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG);
diff --git a/drivers/net/cxgb3/xgmac.c b/drivers/net/cxgb3/xgmac.c
index ff9e9dc..bcb5bc4 100644
--- a/drivers/net/cxgb3/xgmac.c
+++ b/drivers/net/cxgb3/xgmac.c
@@ -522,10 +522,7 @@ int t3b2_mac_watchdog_task(struct cmac *mac)
 		goto rxcheck;
 	}
 
-	if (((tx_tcnt != mac->tx_tcnt) &&
-	     (tx_xcnt == 0) && (mac->tx_xcnt == 0)) ||
-	    ((mac->tx_mcnt == tx_mcnt) &&
-	     (tx_xcnt != 0) && (mac->tx_xcnt != 0))) {
+	if ((tx_tcnt != mac->tx_tcnt) && (mac->tx_xcnt == 0))  {
 		if (mac->toggle_cnt > 4) {
 			status = 2;
 			goto out;
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
deleted file mode 100644
index 054f2ba..0000000
--- a/drivers/net/dgrs.c
+++ /dev/null

[SNIPPED AS OBVIOUS, for file size reasons]

diff --git a/drivers/net/dgrs.h b/drivers/net/dgrs.h
deleted file mode 100644
index 6058d53..0000000
--- a/drivers/net/dgrs.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- *	ioctl's for the Digi Intl. RightSwitch
- *
- *	These network driver ioctl's are a bit obtuse compared to the usual
- *	ioctl's for a "normal" device driver.  Hey, I didn't invent it.
- *
- *	Typical use:
- *
- *	struct ifreq	ifr;
- *	DGRS_IOCTL	ioc;
- *	int		x;
- *
- *	strcpy(ifr.ifr_name, "eth1");
- *	ifr.ifr_data = (caddr_t) &ioc;
- *	ioc.cmd = DGRS_GETMEM;
- *	ioc.len = sizeof(x);
- *	ioc.data = (caddr_t) &x;
- *	rc = ioctl(fd, DGRSIOCTL, &ifr);
- *	printf("rc=%d mem=%x\n", rc, x);
- *
- */
-#include <linux/sockios.h>
-
-#define DGRSIOCTL      SIOCDEVPRIVATE
-
-typedef struct dgrs_ioctl {
-	unsigned short cmd;	/* Command to run */
-	unsigned short len;	/* Length of the data buffer */
-	unsigned char  __user *data;	/* Pointer to the data buffer */
-	unsigned short	port;	/* port number for command, if needed */
-	unsigned short	filter;	/* filter number for command, if needed */
-} DGRS_IOCTL;
-
-/*
- *	Commands for the driver
- */
-#define	DGRS_GETMEM		0x01	/* Get the dual port memory address */
-#define	DGRS_SETFILTER		0x02	/* Set a filter */
diff --git a/drivers/net/dgrs_asstruct.h b/drivers/net/dgrs_asstruct.h
deleted file mode 100644
index f0e2121..0000000
--- a/drivers/net/dgrs_asstruct.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- *	For declaring structures shared with assembly routines
- *
- *	$Id: asstruct.h,v 1.1.1.1 1994/10/23 05:08:32 rick Exp $
- */
-
-#ifdef ASSEMBLER
-
-#	define MO(t,a)		(a)
-#	define VMO(t,a)		(a)
-
-#	define	BEGIN_STRUCT(x)	_Off=0
-#	define	S1A(t,x,n)	_Off=(_Off+0)&~0; x=_Off; _Off=_Off+(1*n)
-#	define	S2A(t,x,n)	_Off=(_Off+1)&~1; x=_Off; _Off=_Off+(2*n)
-#	define	S4A(t,x,n)	_Off=(_Off+3)&~3; x=_Off; _Off=_Off+(4*n)
-#	define	WORD(x)		_Off=(_Off+3)&~3; x=_Off; _Off=_Off+4
-#	define	WORDA(x,n)	_Off=(_Off+3)&~3; x=_Off; _Off=_Off+(4*n)
-#	define	VWORD(x)	_Off=(_Off+3)&~3; x=_Off; _Off=_Off+4
-#	define	S1(t,x)		_Off=(_Off+0)&~0; x=_Off; _Off=_Off+1
-#	define	S2(t,x)		_Off=(_Off+1)&~1; x=_Off; _Off=_Off+2
-#	define	S4(t,x)		_Off=(_Off+3)&~3; x=_Off; _Off=_Off+4
-#	define	END_STRUCT(x)	_Off=(_Off+3)&~3; x=_Off
-
-#else	/* C */
-
-#define VMO(t,a)        (*(volatile t *)(a))
-
-#	define BEGIN_STRUCT(x) struct x {
-#	define S1(t,x)         t x ;
-#	define S1A(t,x,n)      t x[n] ;
-#	define S2(t,x)         t x ;
-#	define S2A(t,x,n)      t x[n] ;
-#	define S4(t,x)         t x ;
-#	define S4A(t,x,n)      t x[n] ;
-#	define END_STRUCT(x)   } ;
-
-#endif
diff --git a/drivers/net/dgrs_bcomm.h b/drivers/net/dgrs_bcomm.h
deleted file mode 100644
index 5e9c252..0000000
--- a/drivers/net/dgrs_bcomm.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * The bios low-memory structure
- *
- * Some of the variables in here can be used to set parameters that
- * are stored in NVRAM and will retain their old values the next time
- * the card is brought up.  To use the values stored in NVRAM, the
- * parameter should be set to "all ones".  This tells the firmware to
- * use the NVRAM value or a suitable default.  The value that is used
- * will be stored back into this structure by the firmware.  If the
- * value of the variable is not "all ones", then that value will be
- * used and will be stored into NVRAM if it isn't already there.
- * The variables this applies to are the following:
- *	Variable	Set to:		Gets default of:
- *	bc_hashexpire	-1		300	(5 minutes)
- *	bc_spantree	-1		1	(spanning tree on)
- *	bc_ipaddr	FF:FF:FF:FF	0	(no SNMP IP address)
- *	bc_ipxnet	FF:FF:FF:FF	0	(no SNMP IPX net)
- *	bc_iptrap	FF:FF:FF:FF	0	(no SNMP IP trap address)
- *
- * Some variables MUST have their value set after the firmware
- * is loaded onto the board, but before the processor is released.
- * These are:
- *	bc_host		0 means no host "port", run as standalone switch.
- *			1 means run as a switch, with a host port. (normal)
- *			2 means run as multiple NICs, not as a switch.
- *			-1 means run in diagnostics mode.
- *	bc_nowait
- *	bc_hostarea_len
- *	bc_filter_len
- *
- */
-BEGIN_STRUCT(bios_comm)
-	S4(ulong, bc_intflag)	/* Count of all interrupts */
-	S4(ulong, bc_lbolt)	/* Count of timer interrupts */
-	S4(ulong, bc_maincnt)	/* Count of main loops */
-	S4(ulong, bc_hashcnt)	/* Count of entries in hash table */
-	S4A(ulong, bc_cnt, 8)	/* Misc counters, for debugging */
-	S4A(ulong, bc_flag, 8)	/* Misc flags, for debugging */
-	S4(ulong, bc_memsize)	/* Size of memory */
-	S4(ulong, bc_dcache)	/* Size of working dcache */
-	S4(ulong, bc_icache)	/* Size of working icache */
-	S4(long, bc_status)	/* Firmware status */
-	S1A(char, bc_file, 8)	/* File name of assertion failure */
-	S4(ulong, bc_line)	/* Line # of assertion failure */
-	S4(uchar *, bc_ramstart)
-	S4(uchar *, bc_ramend)
-	S4(uchar *, bc_heapstart) /* Start of heap (end of loaded memory) */
-	S4(uchar *, bc_heapend)	/* End of heap */
-
-	/* Configurable Parameters */
-	S4(long, bc_host)	/* 1=Host Port, 0=No Host Port, -1=Test Mode */
-	S4(long, bc_nowait)	/* Don't wait for 2host circ buffer to empty*/
-	S4(long, bc_150ohm)	/* 0 == 100 ohm UTP, 1 == 150 ohm STP */
-	S4(long, bc_squelch)	/* 0 == normal squelch, 1 == reduced squelch */
-	S4(ulong, bc_hashexpire) /* Expiry time in seconds for hash table */
-	S4(long, bc_spantree)	/* 1 == enable IEEE spanning tree */
-
-	S2A(ushort, bc_eaddr, 3) /* New ether address */
-	S2(ushort, bc_dummy1)	/* padding for DOS compilers */
-
-	/* Various debugging aids */
-	S4(long, bc_debug)	/* Debugging is turned on */
-	S4(long, bc_spew)	/* Spew data on port 4 for bs_spew seconds */
-	S4(long, bc_spewlen)	/* Length of spewed data packets */
-	S4(long, bc_maxrfd)	/* If != 0, max number of RFD's to allocate */
-	S4(long, bc_maxrbd)	/* If != 0, max number of RBD's to allocate */
-
-	/* Circular buffers for messages to/from host */
-	S4(ulong, bc_2host_head)
-	S4(ulong, bc_2host_tail)
-	S4(ulong, bc_2host_mask)
-	S1A(char, bc_2host, 0x200)	/* Circ buff to host */
-
-	S4(ulong, bc_2idt_head)
-	S4(ulong, bc_2idt_tail)
-	S4(ulong, bc_2idt_mask)
-	S1A(char, bc_2idt, 0x200)	/* Circ buff to idt */
-
-	/* Pointers to structures for driver access */
-	S4(uchar *, bc_port)	/* pointer to Port[] structures */
-	S4(long, bc_nports)	/* Number of ports */
-	S4(long, bc_portlen)	/* sizeof(PORT) */
-	S4(uchar *, bc_hash)	/* Pointer to hash table */
-	S4(long, bc_hashlen)	/* sizeof(Table) */
-
-	/* SNMP agent addresses */
-	S1A(uchar, bc_ipaddr, 4) /* IP address for SNMP */
-	S1A(uchar, bc_ipxnet, 4) /* IPX net address for SNMP */
-
-	S4(long, bc_nohostintr) /* Do not cause periodic host interrupts */
-
-	S4(uchar *, bc_dmaaddr) /* Physical addr of host DMA buf for diags */
-	S4(ulong, bc_dmalen)	/* Length of DMA buffer 0..2048 */
-
-	/*
-	 *	Board memory allocated on startup for use by host, usually
-	 *	for the purposes of creating DMA chain descriptors.  The
-	 *	"len" must be set before the processor is released.  The
-	 *	address of the area is returned in bc_hostarea.  The area
-	 *	is guaranteed to be aligned on a 16 byte boundary.
-	 */
-	S4(ulong, bc_hostarea_len)	/* RW: Number of bytes to allocate */
-	S4(uchar *, bc_hostarea)	/* RO: Address of allocated memory */
-
-	/*
-	 *	Variables for communicating filters into the board
-	 */
-	S4(ulong *, bc_filter_area)	/* RO: Space to put filter into */
-	S4(ulong, bc_filter_area_len)	/* RO: Length of area, in bytes */
-	S4(long, bc_filter_cmd)		/* RW: Filter command, see below */
-	S4(ulong, bc_filter_len)	/* RW: Actual length of filter */
-	S4(ulong, bc_filter_port)	/* RW: Port # for filter 0..6 */
-	S4(ulong, bc_filter_num)	/* RW: Filter #, 0=input, 1=output */
-
-	/* more SNMP agent addresses */
-	S1A(uchar, bc_iptrap, 4) /* IP address for SNMP */
-
-	S4A(long, bc_spare, 2)	/* spares */
-END_STRUCT(bios_comm)
-
-#define	bc	VMO(struct bios_comm, 0xa3000100)
-
-/*
- *	bc_status values
- */
-#define	BC_INIT	0
-#define	BC_RUN	100
-
-/*
- *	bc_host values
- */
-#define	BC_DIAGS	-1
-#define BC_SASWITCH	0
-#define	BC_SWITCH	1
-#define	BC_MULTINIC	2
-
-/*
- *	Values for spew (debugging)
- */
-#define	BC_SPEW_ENABLE	0x80000000
-
-/*
- *	filter commands
- */
-#define	BC_FILTER_ERR	-1
-#define	BC_FILTER_OK	0
-#define	BC_FILTER_SET	1
-#define	BC_FILTER_CLR	2
diff --git a/drivers/net/dgrs_es4h.h b/drivers/net/dgrs_es4h.h
deleted file mode 100644
index 5518fba..0000000
--- a/drivers/net/dgrs_es4h.h
+++ /dev/null
@@ -1,183 +0,0 @@
-/************************************************************************/
-/*									*/
-/*	es4h.h:	Hardware definition of the ES/4h Ethernet Switch, from	*/
-/*		both the host and the 3051's point of view.		*/
-/*		NOTE: this name is a misnomer now that there is a PCI	*/
-/*		board.  Everything that says "es4h" should really be	*/
-/*		"se4".  But we'll keep the old name for now.		*/
-/*									*/
-/*	$Id: es4h.h,v 1.10 1996/08/22 17:16:53 rick Exp $		*/
-/*									*/
-/************************************************************************/
-
-/************************************************************************/
-/*									*/
-/*	EISA I/O Registers.  These are located at 0x1000 * slot-number	*/
-/*	plus the indicated address.  I.E. 0x4000-0x4009 for slot 4.	*/
-/*									*/
-/************************************************************************/
-
-#define	ES4H_MANUFmsb	0x00		/* Read-only */
-#define	ES4H_MANUFlsb	0x01		/* Read-only */
-#	define ES4H_MANUF_CODE		0x1049	/* = "DBI" */
-
-#define	ES4H_PRODUCT	0x02		/* Read-only */
-#	define ES4H_PRODUCT_CODE	0x0A
-#	define EPC_PRODUCT_CODE		0x03
-
-#define	ES4H_REVISION	0x03		/* Read-only */
-#	define ES4H_REVISION_CODE	0x01
-
-#define	ES4H_EC		0x04		/* EISA Control */
-#	define ES4H_EC_RESET		0x04	/* WO, EISA reset */
-#	define ES4H_EC_ENABLE		0x01	/* RW, EISA enable - set to */
-						/* 1 before memory enable */
-#define	ES4H_PC		0x05		/* Processor Control */
-#	define ES4H_PC_RESET		0x04	/* RW, 3051 reset */
-#	define ES4H_PC_INT		0x08	/* WO, assert 3051 intr. 3 */
-
-#define	ES4H_MW		0x06		/* Memory Window select and enable */
-#	define ES4H_MW_ENABLE		0x80	/* WO, enable memory */
-#	define ES4H_MW_SELECT_MASK	0x1f	/* WO, 32k window selected */
-
-#define	ES4H_IS		0x07		/* Interrupt, addr select */
-#	define ES4H_IS_INTMASK		0x07	/* WO, interrupt select */
-#	define ES4H_IS_INTOFF		0x00		/* No IRQ */
-#	define ES4H_IS_INT3		0x03		/* IRQ 3 */
-#	define ES4H_IS_INT5		0x02		/* IRQ 5 */
-#	define ES4H_IS_INT7		0x01		/* IRQ 7 */
-#	define ES4H_IS_INT10		0x04		/* IRQ 10 */
-#	define ES4H_IS_INT11		0x05		/* IRQ 11 */
-#	define ES4H_IS_INT12		0x06		/* IRQ 12 */
-#	define ES4H_IS_INT15		0x07		/* IRQ 15 */
-#	define ES4H_IS_INTACK		0x10	/* WO, interrupt ack */
-#	define ES4H_IS_INTPEND		0x10	/* RO, interrupt pending */
-#	define ES4H_IS_LINEAR		0x40	/* WO, no memory windowing */
-#	define ES4H_IS_AS15		0x80	/* RW, address select bit 15 */
-
-#define	ES4H_AS_23_16	0x08		/* Address select bits 23-16 */
-#define	ES4H_AS_31_24	0x09		/* Address select bits 31-24 */
-
-#define ES4H_IO_MAX		0x09		/* Size of I/O space */
-
-/*
- * PCI
- */
-#define SE6_RESET		PLX_USEROUT
-
-/************************************************************************/
-/*									*/
-/*	3051 Memory Map							*/
-/*									*/
-/*	Note: 3051 has 4K I-cache, 2K D-cache.  1 cycle is 50 nsec.	*/
-/*									*/
-/************************************************************************/
-#define	SE4_NPORTS		4		/* # of ethernet ports */
-#define	SE6_NPORTS		6		/* # of ethernet ports */
-#define	SE_NPORTS		6		/* Max # of ethernet ports */
-
-#define	ES4H_RAM_BASE		0x83000000	/* Base address of RAM */
-#define	ES4H_RAM_SIZE		0x00200000	/* Size of RAM (2MB) */
-#define	ES4H_RAM_INTBASE	0x83800000	/* Base of int-on-write RAM */
-						/* a.k.a. PKT RAM */
-
-						/* Ethernet controllers */
-						/* See: i82596.h */
-#define	ES4H_ETHER0_PORT	0xA2000000
-#define	ES4H_ETHER0_CMD		0xA2000100
-#define	ES4H_ETHER1_PORT	0xA2000200
-#define	ES4H_ETHER1_CMD		0xA2000300
-#define	ES4H_ETHER2_PORT	0xA2000400
-#define	ES4H_ETHER2_CMD		0xA2000500
-#define	ES4H_ETHER3_PORT	0xA2000600
-#define	ES4H_ETHER3_CMD		0xA2000700
-#define	ES4H_ETHER4_PORT	0xA2000800	/* RS SE-6 only */
-#define	ES4H_ETHER4_CMD		0xA2000900	/* RS SE-6 only */
-#define	ES4H_ETHER5_PORT	0xA2000A00	/* RS SE-6 only */
-#define	ES4H_ETHER5_CMD		0xA2000B00	/* RS SE-6 only */
-
-#define	ES4H_I8254		0xA2040000	/* 82C54 timers */
-						/* See: i8254.h */
-
-#define	SE4_I8254_HZ		(23000000/4)	/* EISA clock input freq. */
-#define	SE4_IDT_HZ		(46000000)	/* EISA CPU freq. */
-#define	SE6_I8254_HZ		(20000000/4)	/* PCI clock input freq. */
-#define	SE6_IDT_HZ		(50000000)	/* PCI CPU freq. */
-#define	ES4H_I8254_HZ		(23000000/4)	/* EISA clock input freq. */
-
-#define	ES4H_GPP		0xA2050000	/* General purpose port */
-	/*
-	 * SE-4 (EISA) GPP bits
-	 */
-#	define ES4H_GPP_C0_100		0x0001	/* WO, Chan 0: 100 ohm TP */
-#	define ES4H_GPP_C0_SQE		0x0002	/* WO, Chan 0: normal squelch */
-#	define ES4H_GPP_C1_100		0x0004	/* WO, Chan 1: 100 ohm TP */
-#	define ES4H_GPP_C1_SQE		0x0008	/* WO, Chan 1: normal squelch */
-#	define ES4H_GPP_C2_100		0x0010	/* WO, Chan 2: 100 ohm TP */
-#	define ES4H_GPP_C2_SQE		0x0020	/* WO, Chan 2: normal squelch */
-#	define ES4H_GPP_C3_100		0x0040	/* WO, Chan 3: 100 ohm TP */
-#	define ES4H_GPP_C3_SQE		0x0080	/* WO, Chan 3: normal squelch */
-#	define ES4H_GPP_SQE		0x00AA	/* WO, All: normal squelch */
-#	define ES4H_GPP_100		0x0055	/* WO, All: 100 ohm TP */
-#	define ES4H_GPP_HOSTINT		0x0100	/* RO, cause intr. to host */
-						/* Hold high > 250 nsec */
-#	define SE4_GPP_EED		0x0200	/* RW, EEPROM data bit */
-#	define SE4_GPP_EECS		0x0400	/* RW, EEPROM chip select */
-#	define SE4_GPP_EECK		0x0800	/* RW, EEPROM clock */
-
-	/*
-	 * SE-6 (PCI) GPP bits
-	 */
-#	define SE6_GPP_EED		0x0001	/* RW, EEPROM data bit */
-#	define SE6_GPP_EECS		0x0002	/* RW, EEPROM chip select */
-#	define SE6_GPP_EECK		0x0004	/* RW, EEPROM clock */
-#	define SE6_GPP_LINK		0x00fc	/* R, Link status LEDs */
-
-#define	ES4H_INTVEC		0xA2060000	/* RO: Interrupt Vector */
-#	define ES4H_IV_DMA0		0x01	/* Chan 0 DMA interrupt */
-#	define ES4H_IV_PKT0		0x02	/* Chan 0 PKT interrupt */
-#	define ES4H_IV_DMA1		0x04	/* Chan 1 DMA interrupt */
-#	define ES4H_IV_PKT1		0x08	/* Chan 1 PKT interrupt */
-#	define ES4H_IV_DMA2		0x10	/* Chan 2 DMA interrupt */
-#	define ES4H_IV_PKT2		0x20	/* Chan 2 PKT interrupt */
-#	define ES4H_IV_DMA3		0x40	/* Chan 3 DMA interrupt */
-#	define ES4H_IV_PKT3		0x80	/* Chan 3 PKT interrupt */
-
-#define	ES4H_INTACK		0xA2060000	/* WO: Interrupt Ack */
-#	define ES4H_INTACK_8254		0x01	/* Real Time Clock (int 0) */
-#	define ES4H_INTACK_HOST		0x02	/* Host (int 1) */
-#	define ES4H_INTACK_PKT0		0x04	/* Chan 0 Pkt (int 2) */
-#	define ES4H_INTACK_PKT1		0x08	/* Chan 1 Pkt (int 3) */
-#	define ES4H_INTACK_PKT2		0x10	/* Chan 2 Pkt (int 4) */
-#	define ES4H_INTACK_PKT3		0x20	/* Chan 3 Pkt (int 5) */
-
-#define	SE6_PLX			0xA2070000	/* PLX 9060, SE-6 (PCI) only */
-						/* see plx9060.h */
-
-#define	SE6_PCI_VENDOR_ID	0x114F		/* Digi PCI vendor ID */
-#define	SE6_PCI_DEVICE_ID	0x0003		/* RS SE-6 device ID */
-#define	SE6_PCI_ID		((SE6_PCI_DEVICE_ID<<16) | SE6_PCI_VENDOR_ID)
-
-/*
- *	IDT Interrupts
- */
-#define	ES4H_INT_8254		IDT_INT0
-#define	ES4H_INT_HOST		IDT_INT1
-#define	ES4H_INT_ETHER0		IDT_INT2
-#define	ES4H_INT_ETHER1		IDT_INT3
-#define	ES4H_INT_ETHER2		IDT_INT4
-#define	ES4H_INT_ETHER3		IDT_INT5
-
-/*
- *	Because there are differences between the SE-4 and the SE-6,
- *	we assume that the following globals will be set up at init
- *	time in main.c to containt the appropriate constants from above
- */
-extern ushort	Gpp;		/* Softcopy of GPP register */
-extern ushort	EEck;		/* Clock bit */
-extern ushort	EEcs;		/* CS bit */
-extern ushort	EEd;		/* Data bit */
-extern ulong	I8254_Hz;	/* i8254 input frequency */
-extern ulong	IDT_Hz;		/* IDT CPU frequency */
-extern int	Nports;		/* Number of ethernet controllers */
-extern int	Nchan;		/* Nports+1 */
diff --git a/drivers/net/dgrs_ether.h b/drivers/net/dgrs_ether.h
deleted file mode 100644
index 7539b59..0000000
--- a/drivers/net/dgrs_ether.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- *	A filtering function.  There are two filters/port.  Filter "0"
- *	is the input filter, and filter "1" is the output filter.
- */
-typedef int (FILTER_FUNC)(uchar *pktp, int pktlen, ulong *scratch, int port);
-#define	NFILTERS	2
-
-/*
- *	The per port structure
- */
-typedef struct
-{
-	int		chan;		/* Channel number (0-3) */
-	ulong		portaddr;	/* address of 596 port register */
-	volatile ulong	*ca;		/* address of 596 chan attention */
-	ulong		intmask;	/* Interrupt mask for this port */
-	ulong		intack;		/* Ack bit for this port */
-
-	uchar		ethaddr[6];	/* Ethernet address of this port */
-	int		is_promisc;	/* Port is promiscuous */
-
-	int		debug;		/* Debugging turned on */
-
-	I596_ISCP	*iscpp;		/* Uncached ISCP pointer */
-	I596_SCP	*scpp;		/* Uncached SCP pointer */
-	I596_SCB	*scbp;		/* Uncached SCB pointer */
-
-	I596_ISCP	iscp;
-	I596_SCB	scb;
-
-	/* Command Queue */
-	I596_CB		*cb0;
-	I596_CB		*cbN;
-	I596_CB		*cb_head;
-	I596_CB		*cb_tail;
-
-	/* Receive Queue */
-	I596_RFD	*rfd0;
-	I596_RFD	*rfdN;
-	I596_RFD	*rfd_head;
-	I596_RFD	*rfd_tail;
-
-	/* Receive Buffers */
-	I596_RBD	*rbd0;
-	I596_RBD	*rbdN;
-	I596_RBD	*rbd_head;
-	I596_RBD	*rbd_tail;
-	int		buf_size;	/* Size of an RBD buffer */
-	int		buf_cnt;	/* Total RBD's allocated */
-
-	/* Rx Statistics */
-	ulong		cnt_rx_cnt;	/* Total packets rcvd, good and bad */
-	ulong		cnt_rx_good;	/* Total good packets rcvd */
-	ulong		cnt_rx_bad;	/* Total of all bad packets rcvd */
-					/* Subtotals can be gotten from SCB */
-	ulong		cnt_rx_nores;	/* No resources */
-	ulong		cnt_rx_bytes;	/* Total bytes rcvd */
-
-	/* Tx Statistics */
-	ulong		cnt_tx_queued;
-	ulong		cnt_tx_done;
-	ulong		cnt_tx_freed;
-	ulong		cnt_tx_nores;	/* No resources */
-
-	ulong		cnt_tx_bad;
-	ulong		cnt_tx_err_late;
-	ulong		cnt_tx_err_nocrs;
-	ulong		cnt_tx_err_nocts;
-	ulong		cnt_tx_err_under;
-	ulong		cnt_tx_err_maxcol;
-	ulong		cnt_tx_collisions;
-
-	/* Special stuff for host */
-#	define		rfd_freed	cnt_rx_cnt
-	ulong		rbd_freed;
-	int		host_timer;
-
-	/* Added after first beta */
-	ulong		cnt_tx_races;	/* Counts race conditions */
-	int		spanstate;
-	ulong		cnt_st_tx;	/* send span tree pkts */
-	ulong		cnt_st_fail_tx;	/* Failures to send span tree pkts */
-	ulong		cnt_st_fail_rbd;/* Failures to send span tree pkts */
-	ulong		cnt_st_rx;	/* rcv span tree pkts */
-	ulong		cnt_st_rx_bad;	/* bogus st packets rcvd */
-	ulong		cnt_rx_fwd;	/* Rcvd packets that were forwarded */
-
-	ulong		cnt_rx_mcast;	/* Multicast pkts received */
-	ulong		cnt_tx_mcast;	/* Multicast pkts transmitted */
-	ulong		cnt_tx_bytes;	/* Bytes transmitted */
-
-	/*
-	 *	Packet filtering
-	 *	Filter 0: input filter
-	 *	Filter 1: output filter
-	 */
-
-	ulong		*filter_space[NFILTERS];
-	FILTER_FUNC	*filter_func[NFILTERS];
-	ulong		filter_cnt[NFILTERS];
-	ulong		filter_len[NFILTERS];
-
-	ulong		pad[ (512-300) / 4];
-} PORT;
-
-/*
- *	Port[0]			is host interface
- *	Port[1..SE_NPORTS]	are external 10 Base T ports.  Fewer may be in
- *				use, depending on whether this is an SE-4 or
- *				an SE-6.
- *	Port[SE_NPORTS]		Pseudo-port for Spanning tree and SNMP
- */
-extern PORT	Port[1+SE_NPORTS+1];
-
-extern int	Nports;		/* Number of genuine ethernet controllers */
-extern int	Nchan;		/* ... plus one for host interface */
-
-extern int	FirstChan;	/* 0 or 1, depedning on whether host is used */
-extern int	NumChan;	/* 4 or 5 */
-
-/*
- *	A few globals
- */
-extern int	IsPromisc;
-extern int	MultiNicMode;
-
-/*
- *	Functions
- */
-extern void	eth_xmit_spew_on(PORT *p, int cnt);
-extern void	eth_xmit_spew_off(PORT *p);
-
-extern I596_RBD	*alloc_rbds(PORT *p, int num);
-
-extern I596_CB * eth_cb_alloc(PORT *p);
diff --git a/drivers/net/dgrs_firmware.c b/drivers/net/dgrs_firmware.c
deleted file mode 100644
index 8c20d4c..0000000
--- a/drivers/net/dgrs_firmware.c
+++ /dev/null

[SNIPPED AS OBVIOUS, for file size reasons]

diff --git a/drivers/net/dgrs_i82596.h b/drivers/net/dgrs_i82596.h
deleted file mode 100644
index ac9217a..0000000
--- a/drivers/net/dgrs_i82596.h
+++ /dev/null

[SNIPPED AS OBVIOUS, for file size reasons]

diff --git a/drivers/net/dgrs_plx9060.h b/drivers/net/dgrs_plx9060.h
deleted file mode 100644
index 6888ae0..0000000
--- a/drivers/net/dgrs_plx9060.h
+++ /dev/null

[SNIPPED AS OBVIOUS, for file size reasons]

diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index ba120f7..6c3b85a 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -870,10 +870,6 @@ e1000_init_hw(struct e1000_hw *hw)
     uint32_t ctrl;
     uint32_t i;
     int32_t ret_val;
-    uint16_t pcix_cmd_word;
-    uint16_t pcix_stat_hi_word;
-    uint16_t cmd_mmrbc;
-    uint16_t stat_mmrbc;
     uint32_t mta_size;
     uint32_t reg_data;
     uint32_t ctrl_ext;
@@ -963,24 +959,9 @@ e1000_init_hw(struct e1000_hw *hw)
         break;
     default:
         /* Workaround for PCI-X problem when BIOS sets MMRBC incorrectly. */
-        if (hw->bus_type == e1000_bus_type_pcix) {
-            e1000_read_pci_cfg(hw, PCIX_COMMAND_REGISTER, &pcix_cmd_word);
-            e1000_read_pci_cfg(hw, PCIX_STATUS_REGISTER_HI,
-                &pcix_stat_hi_word);
-            cmd_mmrbc = (pcix_cmd_word & PCIX_COMMAND_MMRBC_MASK) >>
-                PCIX_COMMAND_MMRBC_SHIFT;
-            stat_mmrbc = (pcix_stat_hi_word & PCIX_STATUS_HI_MMRBC_MASK) >>
-                PCIX_STATUS_HI_MMRBC_SHIFT;
-            if (stat_mmrbc == PCIX_STATUS_HI_MMRBC_4K)
-                stat_mmrbc = PCIX_STATUS_HI_MMRBC_2K;
-            if (cmd_mmrbc > stat_mmrbc) {
-                pcix_cmd_word &= ~PCIX_COMMAND_MMRBC_MASK;
-                pcix_cmd_word |= stat_mmrbc << PCIX_COMMAND_MMRBC_SHIFT;
-                e1000_write_pci_cfg(hw, PCIX_COMMAND_REGISTER,
-                    &pcix_cmd_word);
-            }
-        }
-        break;
+	if (hw->bus_type == e1000_bus_type_pcix && e1000_pcix_get_mmrbc(hw) > 2048)
+		e1000_pcix_set_mmrbc(hw, 2048);
+	break;
     }
 
     /* More time needed for PHY to initialize */
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index fe87146..1084c17 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -424,6 +424,8 @@ void e1000_pci_clear_mwi(struct e1000_hw *hw);
 void e1000_read_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
 void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
 int32_t e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value);
+void e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc);
+int e1000_pcix_get_mmrbc(struct e1000_hw *hw);
 /* Port I/O is only supported on 82544 and newer */
 void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
 int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index cbd64ce..ce24b48 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -4901,6 +4901,20 @@ e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
 	pci_write_config_word(adapter->pdev, reg, *value);
 }
 
+int
+e1000_pcix_get_mmrbc(struct e1000_hw *hw)
+{
+	struct e1000_adapter *adapter = hw->back;
+	return pcix_get_mmrbc(adapter->pdev);
+}
+
+void
+e1000_pcix_set_mmrbc(struct e1000_hw *hw, int mmrbc)
+{
+	struct e1000_adapter *adapter = hw->back;
+	pcix_set_mmrbc(adapter->pdev, mmrbc);
+}
+
 int32_t
 e1000_read_pcie_cap_reg(struct e1000_hw *hw, uint32_t reg, uint16_t *value)
 {
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 885d946..4a21d7d 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -3531,7 +3531,7 @@ static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		/* handle pci_map_single() error in e1000_tx_map */
 		dev_kfree_skb_any(skb);
 		spin_unlock_irqrestore(&adapter->tx_queue_lock, irq_flags);
-		return NETDEV_TX_BUSY;
+		return NETDEV_TX_OK;
 	}
 
 	e1000_tx_queue(adapter, tx_flags, count);
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 666de42..dae30b7 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -4917,7 +4917,7 @@ static int nv_open(struct net_device *dev)
 	if (ret) {
 		netif_carrier_on(dev);
 	} else {
-		printk("%s: no link during initialization.\n", dev->name);
+		printk(KERN_INFO "%s: no link during initialization.\n", dev->name);
 		netif_carrier_off(dev);
 	}
 	if (oom)
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 912bc5d..c2d34a8 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -370,23 +370,18 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev)
 	mac->rx = NULL;
 }
 
-static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
+static void pasemi_mac_replenish_rx_ring(struct net_device *dev, int limit)
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
 	unsigned int i;
 	int start = mac->rx->next_to_fill;
-	unsigned int limit, count;
-
-	limit = RING_AVAIL(mac->rx);
-	/* Check to see if we're doing first-time setup */
-	if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
-		limit = RX_RING_SIZE;
+	int count;
 
 	if (limit <= 0)
 		return;
 
 	i = start;
-	for (count = limit; count; count--) {
+	for (count = 0; count < limit; count++) {
 		struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i);
 		u64 *buff = &RX_BUFF(mac, i);
 		struct sk_buff *skb;
@@ -417,10 +412,10 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
 
 	wmb();
 
-	write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), limit - count);
-	write_dma_reg(mac, PAS_DMA_RXINT_INCR(mac->dma_if), limit - count);
+	write_dma_reg(mac, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), count);
+	write_dma_reg(mac, PAS_DMA_RXINT_INCR(mac->dma_if), count);
 
-	mac->rx->next_to_fill += limit - count;
+	mac->rx->next_to_fill += count;
 }
 
 static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
@@ -538,7 +533,7 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 	}
 
 	mac->rx->next_to_clean += limit - count;
-	pasemi_mac_replenish_rx_ring(mac->netdev);
+	pasemi_mac_replenish_rx_ring(mac->netdev, limit-count);
 
 	spin_unlock(&mac->rx->lock);
 
@@ -552,7 +547,7 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
 	struct pas_dma_xct_descr *dp;
 	unsigned int start, count, limit;
 	unsigned int total_count;
-	int flags;
+	unsigned long flags;
 	struct sk_buff *skbs[32];
 	dma_addr_t dmas[32];
 
@@ -786,11 +781,6 @@ static int pasemi_mac_open(struct net_device *dev)
 
 	write_mac_reg(mac, PAS_MAC_CFG_TXP, flags);
 
-	flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE |
-		PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE;
-
-	flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
-
 	write_iob_reg(mac, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
 			   PAS_IOB_DMA_RXCH_CFG_CNTTH(0));
 
@@ -805,8 +795,6 @@ static int pasemi_mac_open(struct net_device *dev)
 	write_iob_reg(mac, PAS_IOB_DMA_COM_TIMEOUTCFG,
 			   PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff));
 
-	write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
-
 	ret = pasemi_mac_setup_rx_resources(dev);
 	if (ret)
 		goto out_rx_resources;
@@ -832,7 +820,18 @@ static int pasemi_mac_open(struct net_device *dev)
 	write_dma_reg(mac, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
 			   PAS_DMA_TXCHAN_TCMDSTA_EN);
 
-	pasemi_mac_replenish_rx_ring(dev);
+	pasemi_mac_replenish_rx_ring(dev, RX_RING_SIZE);
+
+	flags = PAS_MAC_CFG_PCFG_S1 | PAS_MAC_CFG_PCFG_PE |
+		PAS_MAC_CFG_PCFG_PR | PAS_MAC_CFG_PCFG_CE;
+
+	if (mac->type == MAC_TYPE_GMAC)
+		flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
+	else
+		flags |= PAS_MAC_CFG_PCFG_TSR_10G | PAS_MAC_CFG_PCFG_SPD_10G;
+
+	/* Enable interface in MAC */
+	write_mac_reg(mac, PAS_MAC_CFG_PCFG, flags);
 
 	ret = pasemi_mac_phy_init(dev);
 	/* Some configs don't have PHYs (XAUI etc), so don't complain about
@@ -970,7 +969,7 @@ static int pasemi_mac_start_tx(struct sk_buff *skb, struct net_device *dev)
 	struct pas_dma_xct_descr *dp;
 	u64 dflags, mactx, ptr;
 	dma_addr_t map;
-	int flags;
+	unsigned long flags;
 
 	dflags = XCT_MACTX_O | XCT_MACTX_ST | XCT_MACTX_SS | XCT_MACTX_CRC_PAD;
 
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index dd09011..432c210 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -76,4 +76,18 @@ config FIXED_MII_100_FDX
 	bool "Emulation for 100M Fdx fixed PHY behavior"
 	depends on FIXED_PHY
 
+config FIXED_MII_1000_FDX
+	bool "Emulation for 1000M Fdx fixed PHY behavior"
+	depends on FIXED_PHY
+
+config FIXED_MII_AMNT
+        int "Number of emulated PHYs to allocate "
+        depends on FIXED_PHY
+        default "1"
+        ---help---
+        Sometimes it is required to have several independent emulated
+        PHYs on the bus (in case of multi-eth but phy-less HW for instance).
+        This control will have specified number allocated for each fixed
+        PHY type enabled.
+
 endif # PHYLIB
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index bb96691..5619182 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -30,53 +30,31 @@
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/phy.h>
+#include <linux/phy_fixed.h>
 
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
 
-#define MII_REGS_NUM	7
-
-/*
-    The idea is to emulate normal phy behavior by responding with
-    pre-defined values to mii BMCR read, so that read_status hook could
-    take all the needed info.
-*/
-
-struct fixed_phy_status {
-	u8 	link;
-	u16	speed;
-	u8 	duplex;
-};
-
-/*-----------------------------------------------------------------------------
- *  Private information hoder for mii_bus
- *-----------------------------------------------------------------------------*/
-struct fixed_info {
-	u16 *regs;
-	u8 regs_num;
-	struct fixed_phy_status phy_status;
-	struct phy_device *phydev; /* pointer to the container */
-	/* link & speed cb */
-	int(*link_update)(struct net_device*, struct fixed_phy_status*);
-
-};
+/* we need to track the allocated pointers in order to free them on exit */
+static struct fixed_info *fixed_phy_ptrs[CONFIG_FIXED_MII_AMNT*MAX_PHY_AMNT];
 
 /*-----------------------------------------------------------------------------
  *  If something weird is required to be done with link/speed,
  * network driver is able to assign a function to implement this.
  * May be useful for PHY's that need to be software-driven.
  *-----------------------------------------------------------------------------*/
-int fixed_mdio_set_link_update(struct phy_device* phydev,
-		int(*link_update)(struct net_device*, struct fixed_phy_status*))
+int fixed_mdio_set_link_update(struct phy_device *phydev,
+			       int (*link_update) (struct net_device *,
+						   struct fixed_phy_status *))
 {
 	struct fixed_info *fixed;
 
-	if(link_update == NULL)
+	if (link_update == NULL)
 		return -EINVAL;
 
-	if(phydev) {
-		if(phydev->bus)	{
+	if (phydev) {
+		if (phydev->bus) {
 			fixed = phydev->bus->priv;
 			fixed->link_update = link_update;
 			return 0;
@@ -84,54 +62,64 @@ int fixed_mdio_set_link_update(struct phy_device* phydev,
 	}
 	return -EINVAL;
 }
+
 EXPORT_SYMBOL(fixed_mdio_set_link_update);
 
+struct fixed_info *fixed_mdio_get_phydev (int phydev_ind)
+{
+	if (phydev_ind >= MAX_PHY_AMNT)
+		return NULL;
+	return fixed_phy_ptrs[phydev_ind];
+}
+
+EXPORT_SYMBOL(fixed_mdio_get_phydev);
+
 /*-----------------------------------------------------------------------------
  *  This is used for updating internal mii regs from the status
  *-----------------------------------------------------------------------------*/
-#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX)
+#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX)
 static int fixed_mdio_update_regs(struct fixed_info *fixed)
 {
 	u16 *regs = fixed->regs;
 	u16 bmsr = 0;
 	u16 bmcr = 0;
 
-	if(!regs) {
+	if (!regs) {
 		printk(KERN_ERR "%s: regs not set up", __FUNCTION__);
 		return -EINVAL;
 	}
 
-	if(fixed->phy_status.link)
+	if (fixed->phy_status.link)
 		bmsr |= BMSR_LSTATUS;
 
-	if(fixed->phy_status.duplex) {
+	if (fixed->phy_status.duplex) {
 		bmcr |= BMCR_FULLDPLX;
 
-		switch ( fixed->phy_status.speed ) {
+		switch (fixed->phy_status.speed) {
 		case 100:
 			bmsr |= BMSR_100FULL;
 			bmcr |= BMCR_SPEED100;
-		break;
+			break;
 
 		case 10:
 			bmsr |= BMSR_10FULL;
-		break;
+			break;
 		}
 	} else {
-		switch ( fixed->phy_status.speed ) {
+		switch (fixed->phy_status.speed) {
 		case 100:
 			bmsr |= BMSR_100HALF;
 			bmcr |= BMCR_SPEED100;
-		break;
+			break;
 
 		case 10:
 			bmsr |= BMSR_100HALF;
-		break;
+			break;
 		}
 	}
 
-	regs[MII_BMCR] =  bmcr;
-	regs[MII_BMSR] =  bmsr | 0x800; /*we are always capable of 10 hdx*/
+	regs[MII_BMCR] = bmcr;
+	regs[MII_BMSR] = bmsr | 0x800;	/*we are always capable of 10 hdx */
 
 	return 0;
 }
@@ -141,29 +129,30 @@ static int fixed_mii_read(struct mii_bus *bus, int phy_id, int location)
 	struct fixed_info *fixed = bus->priv;
 
 	/* if user has registered link update callback, use it */
-	if(fixed->phydev)
-		if(fixed->phydev->attached_dev) {
-			if(fixed->link_update) {
+	if (fixed->phydev)
+		if (fixed->phydev->attached_dev) {
+			if (fixed->link_update) {
 				fixed->link_update(fixed->phydev->attached_dev,
-						&fixed->phy_status);
+						   &fixed->phy_status);
 				fixed_mdio_update_regs(fixed);
 			}
-	}
+		}
 
 	if ((unsigned int)location >= fixed->regs_num)
 		return -1;
 	return fixed->regs[location];
 }
 
-static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location, u16 val)
+static int fixed_mii_write(struct mii_bus *bus, int phy_id, int location,
+			   u16 val)
 {
-	/* do nothing for now*/
+	/* do nothing for now */
 	return 0;
 }
 
 static int fixed_mii_reset(struct mii_bus *bus)
 {
-	/*nothing here - no way/need to reset it*/
+	/*nothing here - no way/need to reset it */
 	return 0;
 }
 #endif
@@ -171,8 +160,8 @@ static int fixed_mii_reset(struct mii_bus *bus)
 static int fixed_config_aneg(struct phy_device *phydev)
 {
 	/* :TODO:03/13/2006 09:45:37 PM::
-	 The full autoneg funcionality can be emulated,
-	 but no need to have anything here for now
+	   The full autoneg funcionality can be emulated,
+	   but no need to have anything here for now
 	 */
 	return 0;
 }
@@ -182,59 +171,79 @@ static int fixed_config_aneg(struct phy_device *phydev)
  * match will never return true...
  *-----------------------------------------------------------------------------*/
 static struct phy_driver fixed_mdio_driver = {
-	.name		= "Fixed PHY",
-	.features	= PHY_BASIC_FEATURES,
-	.config_aneg	= fixed_config_aneg,
-	.read_status	= genphy_read_status,
-	.driver 	= { .owner = THIS_MODULE,},
+	.name = "Fixed PHY",
+#ifdef CONFIG_FIXED_MII_1000_FDX
+	.features = PHY_GBIT_FEATURES,
+#else
+	.features = PHY_BASIC_FEATURES,
+#endif
+	.config_aneg = fixed_config_aneg,
+	.read_status = genphy_read_status,
+	.driver = { .owner = THIS_MODULE, },
 };
 
+static void fixed_mdio_release(struct device *dev)
+{
+	struct phy_device *phydev = container_of(dev, struct phy_device, dev);
+	struct mii_bus *bus = phydev->bus;
+	struct fixed_info *fixed = bus->priv;
+
+	kfree(phydev);
+	kfree(bus->dev);
+	kfree(bus);
+	kfree(fixed->regs);
+	kfree(fixed);
+}
+
 /*-----------------------------------------------------------------------------
  *  This func is used to create all the necessary stuff, bind
  * the fixed phy driver and register all it on the mdio_bus_type.
- * speed is either 10 or 100, duplex is boolean.
+ * speed is either 10 or 100 or 1000, duplex is boolean.
  * number is used to create multiple fixed PHYs, so that several devices can
  * utilize them simultaneously.
+ *
+ * The device on mdio bus will look like [bus_id]:[phy_id],
+ * bus_id = number
+ * phy_id = speed+duplex.
  *-----------------------------------------------------------------------------*/
-#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX)
-static int fixed_mdio_register_device(int number, int speed, int duplex)
+#if defined(CONFIG_FIXED_MII_100_FDX) || defined(CONFIG_FIXED_MII_10_FDX) || defined(CONFIG_FIXED_MII_1000_FDX)
+struct fixed_info *fixed_mdio_register_device(
+	int bus_id, int speed, int duplex, u8 phy_id)
 {
 	struct mii_bus *new_bus;
 	struct fixed_info *fixed;
 	struct phy_device *phydev;
-	int err = 0;
+	int err;
 
-	struct device* dev = kzalloc(sizeof(struct device), GFP_KERNEL);
+	struct device *dev = kzalloc(sizeof(struct device), GFP_KERNEL);
 
-	if (NULL == dev)
-		return -ENOMEM;
+	if (dev == NULL)
+		goto err_dev_alloc;
 
 	new_bus = kzalloc(sizeof(struct mii_bus), GFP_KERNEL);
 
-	if (NULL == new_bus) {
-		kfree(dev);
-		return -ENOMEM;
-	}
+	if (new_bus == NULL)
+		goto err_bus_alloc;
+
 	fixed = kzalloc(sizeof(struct fixed_info), GFP_KERNEL);
 
-	if (NULL == fixed) {
-		kfree(dev);
-		kfree(new_bus);
-		return -ENOMEM;
-	}
+	if (fixed == NULL)
+		goto err_fixed_alloc;
+
+	fixed->regs = kzalloc(MII_REGS_NUM * sizeof(int), GFP_KERNEL);
+	if (NULL == fixed->regs)
+		goto err_fixed_regs_alloc;
 
-	fixed->regs = kzalloc(MII_REGS_NUM*sizeof(int), GFP_KERNEL);
 	fixed->regs_num = MII_REGS_NUM;
 	fixed->phy_status.speed = speed;
 	fixed->phy_status.duplex = duplex;
 	fixed->phy_status.link = 1;
 
-	new_bus->name = "Fixed MII Bus",
-	new_bus->read = &fixed_mii_read,
-	new_bus->write = &fixed_mii_write,
-	new_bus->reset = &fixed_mii_reset,
-
-	/*set up workspace*/
+	new_bus->name = "Fixed MII Bus";
+	new_bus->read = &fixed_mii_read;
+	new_bus->write = &fixed_mii_write;
+	new_bus->reset = &fixed_mii_reset;
+	/*set up workspace */
 	fixed_mdio_update_regs(fixed);
 	new_bus->priv = fixed;
 
@@ -243,119 +252,110 @@ static int fixed_mdio_register_device(int number, int speed, int duplex)
 
 	/* create phy_device and register it on the mdio bus */
 	phydev = phy_device_create(new_bus, 0, 0);
+	if (phydev == NULL)
+		goto err_phy_dev_create;
 
 	/*
-	 Put the phydev pointer into the fixed pack so that bus read/write code could
-	 be able to access for instance attached netdev. Well it doesn't have to do
-	 so, only in case of utilizing user-specified link-update...
+	 * Put the phydev pointer into the fixed pack so that bus read/write
+	 * code could be able to access for instance attached netdev. Well it
+	 * doesn't have to do so, only in case of utilizing user-specified
+	 * link-update...
 	 */
-	fixed->phydev = phydev;
 
-	if(NULL == phydev) {
-		err = -ENOMEM;
-		goto device_create_fail;
-	}
+	fixed->phydev = phydev;
+	phydev->speed = speed;
+	phydev->duplex = duplex;
 
 	phydev->irq = PHY_IGNORE_INTERRUPT;
 	phydev->dev.bus = &mdio_bus_type;
 
-	if(number)
-		snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
-				"fixed_%d@%d:%d", number, speed, duplex);
-	else
-		snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
-				"fixed@%d:%d", speed, duplex);
-	phydev->bus = new_bus;
+	snprintf(phydev->dev.bus_id, BUS_ID_SIZE,
+		 PHY_ID_FMT, bus_id, phy_id);
 
-	err = device_register(&phydev->dev);
-	if(err) {
-		printk(KERN_ERR "Phy %s failed to register\n",
-				phydev->dev.bus_id);
-		goto bus_register_fail;
-	}
+	phydev->bus = new_bus;
 
-	/*
-	   the mdio bus has phy_id match... In order not to do it
-	   artificially, we are binding the driver here by hand;
-	   it will be the same for all the fixed phys anyway.
-	 */
 	phydev->dev.driver = &fixed_mdio_driver.driver;
-
+	phydev->dev.release = fixed_mdio_release;
 	err = phydev->dev.driver->probe(&phydev->dev);
-	if(err < 0) {
-		printk(KERN_ERR "Phy %s: problems with fixed driver\n",phydev->dev.bus_id);
-		goto probe_fail;
+	if (err < 0) {
+		printk(KERN_ERR "Phy %s: problems with fixed driver\n",
+		       phydev->dev.bus_id);
+		goto err_out;
 	}
+	err = device_register(&phydev->dev);
+	if (err) {
+		printk(KERN_ERR "Phy %s failed to register\n",
+		       phydev->dev.bus_id);
+		goto err_out;
+	}
+	//phydev->state = PHY_RUNNING; /* make phy go up quick, but in 10Mbit/HDX
+	return fixed;
 
-	err = device_bind_driver(&phydev->dev);
-	if (err)
-		goto probe_fail;
-
-	return 0;
-
-probe_fail:
-	device_unregister(&phydev->dev);
-bus_register_fail:
+err_out:
 	kfree(phydev);
-device_create_fail:
-	kfree(dev);
-	kfree(new_bus);
+err_phy_dev_create:
+	kfree(fixed->regs);
+err_fixed_regs_alloc:
 	kfree(fixed);
+err_fixed_alloc:
+	kfree(new_bus);
+err_bus_alloc:
+	kfree(dev);
+err_dev_alloc:
+
+	return NULL;
 
-	return err;
 }
 #endif
 
-
 MODULE_DESCRIPTION("Fixed PHY device & driver for PAL");
 MODULE_AUTHOR("Vitaly Bordug");
 MODULE_LICENSE("GPL");
 
 static int __init fixed_init(void)
 {
-#if 0
-	int ret;
-	int duplex = 0;
-#endif
-
-	/* register on the bus... Not expected to be matched with anything there... */
+	int cnt = 0;
+	int i;
+/* register on the bus... Not expected to be matched
+ * with anything there...
+ *
+ */
 	phy_driver_register(&fixed_mdio_driver);
 
-	/* So let the fun begin...
-	   We will create several mdio devices here, and will bound the upper
-	   driver to them.
-
-	   Then the external software can lookup the phy bus by searching
-	   fixed@speed:duplex, e.g. fixed@100:1, to be connected to the
-	   virtual 100M Fdx phy.
-
-	   In case several virtual PHYs required, the bus_id will be in form
-	   fixed_<num>@<speed>:<duplex>, which make it able even to define
-	   driver-specific link control callback, if for instance PHY is completely
-	   SW-driven.
-
-	*/
-
-#ifdef CONFIG_FIXED_MII_DUPLEX
-#if 0
-	duplex = 1;
-#endif
+/* We will create several mdio devices here, and will bound the upper
+ * driver to them.
+ *
+ * Then the external software can lookup the phy bus by searching
+ * for 0:101, to be connected to the virtual 100M Fdx phy.
+ *
+ * In case several virtual PHYs required, the bus_id will be in form
+ * [num]:[duplex]+[speed], which make it able even to define
+ * driver-specific link control callback, if for instance PHY is
+ * completely SW-driven.
+ */
+	for (i=1; i <= CONFIG_FIXED_MII_AMNT; i++) {
+#ifdef CONFIG_FIXED_MII_1000_FDX
+		fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(0, 1000, 1, i);
 #endif
-
 #ifdef CONFIG_FIXED_MII_100_FDX
-	fixed_mdio_register_device(0, 100, 1);
+		fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(1, 100, 1, i);
 #endif
-
 #ifdef CONFIG_FIXED_MII_10_FDX
-	fixed_mdio_register_device(0, 10, 1);
+		fixed_phy_ptrs[cnt++] = fixed_mdio_register_device(2, 10, 1, i);
 #endif
+	}
+
 	return 0;
 }
 
 static void __exit fixed_exit(void)
 {
+	int i;
+
 	phy_driver_unregister(&fixed_mdio_driver);
-	/* :WARNING:02/18/2006 04:32:40 AM:: Cleanup all the created stuff */
+	for (i=0; i < MAX_PHY_AMNT; i++)
+		if ( fixed_phy_ptrs[i] )
+			device_unregister(&fixed_phy_ptrs[i]->phydev->dev);
 }
 
 module_init(fixed_init);
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 17c1e15..9bc1177 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -7,7 +7,7 @@
  * Author: Andy Fleming
  *
  * Copyright (c) 2004 Freescale Semiconductor, Inc.
- * Copyright (c) 2006  Maciej W. Rozycki
+ * Copyright (c) 2006, 2007  Maciej W. Rozycki
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -35,6 +35,7 @@
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 
+#include <asm/atomic.h>
 #include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/uaccess.h>
@@ -424,7 +425,7 @@ int phy_start_aneg(struct phy_device *phydev)
 {
 	int err;
 
-	spin_lock(&phydev->lock);
+	spin_lock_bh(&phydev->lock);
 
 	if (AUTONEG_DISABLE == phydev->autoneg)
 		phy_sanitize_settings(phydev);
@@ -445,7 +446,7 @@ int phy_start_aneg(struct phy_device *phydev)
 	}
 
 out_unlock:
-	spin_unlock(&phydev->lock);
+	spin_unlock_bh(&phydev->lock);
 	return err;
 }
 EXPORT_SYMBOL(phy_start_aneg);
@@ -490,10 +491,10 @@ void phy_stop_machine(struct phy_device *phydev)
 {
 	del_timer_sync(&phydev->phy_timer);
 
-	spin_lock(&phydev->lock);
+	spin_lock_bh(&phydev->lock);
 	if (phydev->state > PHY_UP)
 		phydev->state = PHY_UP;
-	spin_unlock(&phydev->lock);
+	spin_unlock_bh(&phydev->lock);
 
 	phydev->adjust_state = NULL;
 }
@@ -537,9 +538,9 @@ static void phy_force_reduction(struct phy_device *phydev)
  */
 void phy_error(struct phy_device *phydev)
 {
-	spin_lock(&phydev->lock);
+	spin_lock_bh(&phydev->lock);
 	phydev->state = PHY_HALTED;
-	spin_unlock(&phydev->lock);
+	spin_unlock_bh(&phydev->lock);
 }
 
 /**
@@ -562,6 +563,7 @@ static irqreturn_t phy_interrupt(int irq, void *phy_dat)
 	 * queue will write the PHY to disable and clear the
 	 * interrupt, and then reenable the irq line. */
 	disable_irq_nosync(irq);
+	atomic_inc(&phydev->irq_disable);
 
 	schedule_work(&phydev->phy_queue);
 
@@ -632,6 +634,7 @@ int phy_start_interrupts(struct phy_device *phydev)
 
 	INIT_WORK(&phydev->phy_queue, phy_change);
 
+	atomic_set(&phydev->irq_disable, 0);
 	if (request_irq(phydev->irq, phy_interrupt,
 				IRQF_SHARED,
 				"phy_interrupt",
@@ -662,13 +665,22 @@ int phy_stop_interrupts(struct phy_device *phydev)
 	if (err)
 		phy_error(phydev);
 
+	free_irq(phydev->irq, phydev);
+
 	/*
-	 * Finish any pending work; we might have been scheduled to be called
-	 * from keventd ourselves, but cancel_work_sync() handles that.
+	 * Cannot call flush_scheduled_work() here as desired because
+	 * of rtnl_lock(), but we do not really care about what would
+	 * be done, except from enable_irq(), so cancel any work
+	 * possibly pending and take care of the matter below.
 	 */
 	cancel_work_sync(&phydev->phy_queue);
-
-	free_irq(phydev->irq, phydev);
+	/*
+	 * If work indeed has been cancelled, disable_irq() will have
+	 * been left unbalanced from phy_interrupt() and enable_irq()
+	 * has to be called so that other devices on the line work.
+	 */
+	while (atomic_dec_return(&phydev->irq_disable) >= 0)
+		enable_irq(phydev->irq);
 
 	return err;
 }
@@ -690,11 +702,12 @@ static void phy_change(struct work_struct *work)
 	if (err)
 		goto phy_err;
 
-	spin_lock(&phydev->lock);
+	spin_lock_bh(&phydev->lock);
 	if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state))
 		phydev->state = PHY_CHANGELINK;
-	spin_unlock(&phydev->lock);
+	spin_unlock_bh(&phydev->lock);
 
+	atomic_dec(&phydev->irq_disable);
 	enable_irq(phydev->irq);
 
 	/* Reenable interrupts */
@@ -708,6 +721,7 @@ static void phy_change(struct work_struct *work)
 
 irq_enable_err:
 	disable_irq(phydev->irq);
+	atomic_inc(&phydev->irq_disable);
 phy_err:
 	phy_error(phydev);
 }
@@ -718,13 +732,11 @@ phy_err:
  */
 void phy_stop(struct phy_device *phydev)
 {
-	spin_lock(&phydev->lock);
+	spin_lock_bh(&phydev->lock);
 
 	if (PHY_HALTED == phydev->state)
 		goto out_unlock;
 
-	phydev->state = PHY_HALTED;
-
 	if (phydev->irq != PHY_POLL) {
 		/* Disable PHY Interrupts */
 		phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED);
@@ -733,8 +745,10 @@ void phy_stop(struct phy_device *phydev)
 		phy_clear_interrupt(phydev);
 	}
 
+	phydev->state = PHY_HALTED;
+
 out_unlock:
-	spin_unlock(&phydev->lock);
+	spin_unlock_bh(&phydev->lock);
 
 	/*
 	 * Cannot call flush_scheduled_work() here as desired because
@@ -782,7 +796,7 @@ static void phy_timer(unsigned long data)
 	int needs_aneg = 0;
 	int err = 0;
 
-	spin_lock(&phydev->lock);
+	spin_lock_bh(&phydev->lock);
 
 	if (phydev->adjust_state)
 		phydev->adjust_state(phydev->attached_dev);
@@ -948,7 +962,7 @@ static void phy_timer(unsigned long data)
 			break;
 	}
 
-	spin_unlock(&phydev->lock);
+	spin_unlock_bh(&phydev->lock);
 
 	if (needs_aneg)
 		err = phy_start_aneg(phydev);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 49328e0..c046121 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -670,9 +670,9 @@ static int phy_remove(struct device *dev)
 
 	phydev = to_phy_device(dev);
 
-	spin_lock(&phydev->lock);
+	spin_lock_bh(&phydev->lock);
 	phydev->state = PHY_DOWN;
-	spin_unlock(&phydev->lock);
+	spin_unlock_bh(&phydev->lock);
 
 	if (phydev->drv->remove)
 		phydev->drv->remove(phydev);
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 6001ab4..7b53d65 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2001,2002,2003,2004 Broadcom Corporation
+ * Copyright (c) 2006, 2007  Maciej W. Rozycki
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -18,7 +19,12 @@
  *
  * This driver is designed for the Broadcom SiByte SOC built-in
  * Ethernet controllers. Written by Mitch Lichtenberg at Broadcom Corp.
+ *
+ * Updated to the driver model and the PHY abstraction layer
+ * by Maciej W. Rozycki.
  */
+
+#include <linux/bug.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
@@ -32,9 +38,15 @@
 #include <linux/skbuff.h>
 #include <linux/init.h>
 #include <linux/bitops.h>
-#include <asm/processor.h>		/* Processor type for cache alignment. */
-#include <asm/io.h>
+#include <linux/err.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+
 #include <asm/cache.h>
+#include <asm/io.h>
+#include <asm/processor.h>	/* Processor type for cache alignment. */
 
 /* This is only here until the firmware is ready.  In that case,
    the firmware leaves the ethernet address in the register for us. */
@@ -48,7 +60,7 @@
 
 /* These identify the driver base version and may not be removed. */
 #if 0
-static char version1[] __devinitdata =
+static char version1[] __initdata =
 "sb1250-mac.c:1.00 1/11/2001 Written by Mitch Lichtenberg\n";
 #endif
 
@@ -57,8 +69,6 @@ static char version1[] __devinitdata =
 
 #define CONFIG_SBMAC_COALESCE
 
-#define MAX_UNITS 4		/* More are supported, limit only on options */
-
 /* Time in jiffies before concluding the transmitter is hung. */
 #define TX_TIMEOUT  (2*HZ)
 
@@ -74,26 +84,6 @@ static int debug = 1;
 module_param(debug, int, S_IRUGO);
 MODULE_PARM_DESC(debug, "Debug messages");
 
-/* mii status msgs */
-static int noisy_mii = 1;
-module_param(noisy_mii, int, S_IRUGO);
-MODULE_PARM_DESC(noisy_mii, "MII status messages");
-
-/* Used to pass the media type, etc.
-   Both 'options[]' and 'full_duplex[]' should exist for driver
-   interoperability.
-   The media type is usually passed in 'options[]'.
-*/
-#ifdef MODULE
-static int options[MAX_UNITS] = {-1, -1, -1, -1};
-module_param_array(options, int, NULL, S_IRUGO);
-MODULE_PARM_DESC(options, "1-" __MODULE_STRING(MAX_UNITS));
-
-static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1};
-module_param_array(full_duplex, int, NULL, S_IRUGO);
-MODULE_PARM_DESC(full_duplex, "1-" __MODULE_STRING(MAX_UNITS));
-#endif
-
 #ifdef CONFIG_SBMAC_COALESCE
 static int int_pktcnt_tx = 255;
 module_param(int_pktcnt_tx, int, S_IRUGO);
@@ -112,6 +102,7 @@ module_param(int_timeout_rx, int, S_IRUGO);
 MODULE_PARM_DESC(int_timeout_rx, "RX timeout value");
 #endif
 
+#include <asm/sibyte/board.h>
 #include <asm/sibyte/sb1250.h>
 #if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80)
 #include <asm/sibyte/bcm1480_regs.h>
@@ -135,22 +126,43 @@ MODULE_PARM_DESC(int_timeout_rx, "RX timeout value");
 #error invalid SiByte MAC configuation
 #endif
 
+#ifdef K_INT_PHY
+#define SBMAC_PHY_INT			K_INT_PHY
+#else
+#define SBMAC_PHY_INT			PHY_POLL
+#endif
+
 /**********************************************************************
  *  Simple types
  ********************************************************************* */
 
+enum sbmac_speed {
+	sbmac_speed_none = 0,
+	sbmac_speed_10 = SPEED_10,
+	sbmac_speed_100 = SPEED_100,
+	sbmac_speed_1000 = SPEED_1000,
+};
 
-typedef enum { sbmac_speed_auto, sbmac_speed_10,
-	       sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t;
-
-typedef enum { sbmac_duplex_auto, sbmac_duplex_half,
-	       sbmac_duplex_full } sbmac_duplex_t;
+enum sbmac_duplex {
+	sbmac_duplex_none = -1,
+	sbmac_duplex_half = DUPLEX_HALF,
+	sbmac_duplex_full = DUPLEX_FULL,
+};
 
-typedef enum { sbmac_fc_auto, sbmac_fc_disabled, sbmac_fc_frame,
-	       sbmac_fc_collision, sbmac_fc_carrier } sbmac_fc_t;
+enum sbmac_fc {
+	sbmac_fc_none,
+	sbmac_fc_disabled,
+	sbmac_fc_frame,
+	sbmac_fc_collision,
+	sbmac_fc_carrier,
+};
 
-typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
-	       sbmac_state_broken } sbmac_state_t;
+enum sbmac_state {
+	sbmac_state_uninit,
+	sbmac_state_off,
+	sbmac_state_on,
+	sbmac_state_broken,
+};
 
 
 /**********************************************************************
@@ -176,55 +188,61 @@ typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
  *  DMA Descriptor structure
  ********************************************************************* */
 
-typedef struct sbdmadscr_s {
+struct sbdmadscr {
 	uint64_t  dscr_a;
 	uint64_t  dscr_b;
-} sbdmadscr_t;
-
-typedef unsigned long paddr_t;
+};
 
 /**********************************************************************
  *  DMA Controller structure
  ********************************************************************* */
 
-typedef struct sbmacdma_s {
+struct sbmacdma {
 
 	/*
 	 * This stuff is used to identify the channel and the registers
 	 * associated with it.
 	 */
-
-	struct sbmac_softc *sbdma_eth;	    /* back pointer to associated MAC */
-	int              sbdma_channel;	    /* channel number */
-	int		 sbdma_txdir;       /* direction (1=transmit) */
-	int		 sbdma_maxdescr;    /* total # of descriptors in ring */
+	struct sbmac_softc	*sbdma_eth;	/* back pointer to associated
+						   MAC */
+	int			sbdma_channel;	/* channel number */
+	int			sbdma_txdir;	/* direction (1=transmit) */
+	int			sbdma_maxdescr;	/* total # of descriptors
+						   in ring */
 #ifdef CONFIG_SBMAC_COALESCE
-	int		 sbdma_int_pktcnt;  /* # descriptors rx/tx before interrupt*/
-	int		 sbdma_int_timeout; /* # usec rx/tx interrupt */
+	int			sbdma_int_pktcnt;
+						/* # descriptors rx/tx
+						   before interrupt */
+	int			sbdma_int_timeout;
+						/* # usec rx/tx interrupt */
 #endif
-
-	volatile void __iomem *sbdma_config0;	/* DMA config register 0 */
-	volatile void __iomem *sbdma_config1;	/* DMA config register 1 */
-	volatile void __iomem *sbdma_dscrbase;	/* Descriptor base address */
-	volatile void __iomem *sbdma_dscrcnt;   /* Descriptor count register */
-	volatile void __iomem *sbdma_curdscr;	/* current descriptor address */
-	volatile void __iomem *sbdma_oodpktlost;/* pkt drop (rx only) */
-
+	void __iomem		*sbdma_config0;	/* DMA config register 0 */
+	void __iomem		*sbdma_config1;	/* DMA config register 1 */
+	void __iomem		*sbdma_dscrbase;
+						/* descriptor base address */
+	void __iomem		*sbdma_dscrcnt;	/* descriptor count register */
+	void __iomem		*sbdma_curdscr;	/* current descriptor
+						   address */
+	void __iomem		*sbdma_oodpktlost;
+						/* pkt drop (rx only) */
 
 	/*
 	 * This stuff is for maintenance of the ring
 	 */
-
-	sbdmadscr_t     *sbdma_dscrtable_unaligned;
-	sbdmadscr_t     *sbdma_dscrtable;	/* base of descriptor table */
-	sbdmadscr_t     *sbdma_dscrtable_end; /* end of descriptor table */
-
-	struct sk_buff **sbdma_ctxtable;    /* context table, one per descr */
-
-	paddr_t          sbdma_dscrtable_phys; /* and also the phys addr */
-	sbdmadscr_t     *sbdma_addptr;	/* next dscr for sw to add */
-	sbdmadscr_t     *sbdma_remptr;	/* next dscr for sw to remove */
-} sbmacdma_t;
+	void			*sbdma_dscrtable_unaligned;
+	struct sbdmadscr	*sbdma_dscrtable;
+						/* base of descriptor table */
+	struct sbdmadscr	*sbdma_dscrtable_end;
+						/* end of descriptor table */
+	struct sk_buff		**sbdma_ctxtable;
+						/* context table, one
+						   per descr */
+	dma_addr_t		sbdma_dscrtable_phys;
+						/* and also the phys addr */
+	struct sbdmadscr	*sbdma_addptr;	/* next dscr for sw to add */
+	struct sbdmadscr	*sbdma_remptr;	/* next dscr for sw
+						   to remove */
+};
 
 
 /**********************************************************************
@@ -236,47 +254,43 @@ struct sbmac_softc {
 	/*
 	 * Linux-specific things
 	 */
+	struct net_device	*sbm_dev;	/* pointer to linux device */
+	struct napi_struct	napi;
+	struct phy_device	*phy_dev;	/* the associated PHY device */
+	struct mii_bus		mii_bus;	/* the MII bus */
+	int			phy_irq[PHY_MAX_ADDR];
+	spinlock_t		sbm_lock;	/* spin lock */
+	int			sbm_devflags;	/* current device flags */
 
-	struct net_device *sbm_dev;		/* pointer to linux device */
-	struct napi_struct napi;
-	spinlock_t sbm_lock;		/* spin lock */
-	struct timer_list sbm_timer;     	/* for monitoring MII */
-	int sbm_devflags;			/* current device flags */
-
-	int	     sbm_phy_oldbmsr;
-	int	     sbm_phy_oldanlpar;
-	int	     sbm_phy_oldk1stsr;
-	int	     sbm_phy_oldlinkstat;
-	int sbm_buffersize;
-
-	unsigned char sbm_phys[2];
+	int			sbm_buffersize;
 
 	/*
 	 * Controller-specific things
 	 */
-
-	void __iomem		*sbm_base;          /* MAC's base address */
-	sbmac_state_t    sbm_state;         /* current state */
-
-	volatile void __iomem	*sbm_macenable;	/* MAC Enable Register */
-	volatile void __iomem	*sbm_maccfg;	/* MAC Configuration Register */
-	volatile void __iomem	*sbm_fifocfg;	/* FIFO configuration register */
-	volatile void __iomem	*sbm_framecfg;	/* Frame configuration register */
-	volatile void __iomem	*sbm_rxfilter;	/* receive filter register */
-	volatile void __iomem	*sbm_isr;	/* Interrupt status register */
-	volatile void __iomem	*sbm_imr;	/* Interrupt mask register */
-	volatile void __iomem	*sbm_mdio;	/* MDIO register */
-
-	sbmac_speed_t    sbm_speed;		/* current speed */
-	sbmac_duplex_t   sbm_duplex;	/* current duplex */
-	sbmac_fc_t       sbm_fc;		/* current flow control setting */
-
-	unsigned char    sbm_hwaddr[ETHER_ADDR_LEN];
-
-	sbmacdma_t       sbm_txdma;		/* for now, only use channel 0 */
-	sbmacdma_t       sbm_rxdma;
-	int              rx_hw_checksum;
-	int 		 sbe_idx;
+	void __iomem		*sbm_base;	/* MAC's base address */
+	enum sbmac_state	sbm_state;	/* current state */
+
+	void __iomem		*sbm_macenable;	/* MAC Enable Register */
+	void __iomem		*sbm_maccfg;	/* MAC Config Register */
+	void __iomem		*sbm_fifocfg;	/* FIFO Config Register */
+	void __iomem		*sbm_framecfg;	/* Frame Config Register */
+	void __iomem		*sbm_rxfilter;	/* Receive Filter Register */
+	void __iomem		*sbm_isr;	/* Interrupt Status Register */
+	void __iomem		*sbm_imr;	/* Interrupt Mask Register */
+	void __iomem		*sbm_mdio;	/* MDIO Register */
+
+	enum sbmac_speed	sbm_speed;	/* current speed */
+	enum sbmac_duplex	sbm_duplex;	/* current duplex */
+	enum sbmac_fc		sbm_fc;		/* cur. flow control setting */
+	int			sbm_pause;	/* current pause setting */
+	int			sbm_link;	/* current link state */
+
+	unsigned char		sbm_hwaddr[ETHER_ADDR_LEN];
+
+	struct sbmacdma		sbm_txdma;	/* only channel 0 for now */
+	struct sbmacdma		sbm_rxdma;
+	int			rx_hw_checksum;
+	int			sbe_idx;
 };
 
 
@@ -288,54 +302,58 @@ struct sbmac_softc {
  *  Prototypes
  ********************************************************************* */
 
-static void sbdma_initctx(sbmacdma_t *d,
-			  struct sbmac_softc *s,
-			  int chan,
-			  int txrx,
-			  int maxdescr);
-static void sbdma_channel_start(sbmacdma_t *d, int rxtx);
-static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *m);
-static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *m);
-static void sbdma_emptyring(sbmacdma_t *d);
-static void sbdma_fillring(sbmacdma_t *d);
-static int sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d, int work_to_do, int poll);
-static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll);
+static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan,
+			  int txrx, int maxdescr);
+static void sbdma_channel_start(struct sbmacdma *d, int rxtx);
+static int sbdma_add_rcvbuffer(struct sbmacdma *d, struct sk_buff *m);
+static int sbdma_add_txbuffer(struct sbmacdma *d, struct sk_buff *m);
+static void sbdma_emptyring(struct sbmacdma *d);
+static void sbdma_fillring(struct sbmacdma *d);
+static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d,
+			    int work_to_do, int poll);
+static void sbdma_tx_process(struct sbmac_softc *sc, struct sbmacdma *d,
+			     int poll);
 static int sbmac_initctx(struct sbmac_softc *s);
 static void sbmac_channel_start(struct sbmac_softc *s);
 static void sbmac_channel_stop(struct sbmac_softc *s);
-static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *,sbmac_state_t);
-static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff);
+static enum sbmac_state sbmac_set_channel_state(struct sbmac_softc *,
+						enum sbmac_state);
+static void sbmac_promiscuous_mode(struct sbmac_softc *sc, int onoff);
 static uint64_t sbmac_addr2reg(unsigned char *ptr);
-static irqreturn_t sbmac_intr(int irq,void *dev_instance);
+static irqreturn_t sbmac_intr(int irq, void *dev_instance);
 static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev);
 static void sbmac_setmulti(struct sbmac_softc *sc);
-static int sbmac_init(struct net_device *dev, int idx);
-static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed);
-static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc_t fc);
+static int sbmac_init(struct platform_device *pldev, long long base);
+static int sbmac_set_speed(struct sbmac_softc *s, enum sbmac_speed speed);
+static int sbmac_set_duplex(struct sbmac_softc *s, enum sbmac_duplex duplex,
+			    enum sbmac_fc fc);
 
 static int sbmac_open(struct net_device *dev);
-static void sbmac_timer(unsigned long data);
 static void sbmac_tx_timeout (struct net_device *dev);
 static void sbmac_set_rx_mode(struct net_device *dev);
 static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int sbmac_close(struct net_device *dev);
 static int sbmac_poll(struct napi_struct *napi, int budget);
 
-static int sbmac_mii_poll(struct sbmac_softc *s,int noisy);
+static void sbmac_mii_poll(struct net_device *dev);
 static int sbmac_mii_probe(struct net_device *dev);
 
-static void sbmac_mii_sync(struct sbmac_softc *s);
-static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitcnt);
-static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx);
-static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
-			    unsigned int regval);
+static void sbmac_mii_sync(void __iomem *sbm_mdio);
+static void sbmac_mii_senddata(void __iomem *sbm_mdio, unsigned int data,
+			       int bitcnt);
+static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int regidx);
+static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
+			   u16 val);
 
 
 /**********************************************************************
  *  Globals
  ********************************************************************* */
 
-static uint64_t sbmac_orig_hwaddr[MAX_UNITS];
+static char sbmac_string[] = "sb1250-mac";
+static char sbmac_pretty[] = "SB1250 MAC";
+
+static char sbmac_mdio_string[] = "sb1250-mac-mdio";
 
 
 /**********************************************************************
@@ -347,185 +365,66 @@ static uint64_t sbmac_orig_hwaddr[MAX_UNITS];
 #define	MII_COMMAND_WRITE	0x01
 #define	MII_COMMAND_ACK		0x02
 
-#define BMCR_RESET     0x8000
-#define BMCR_LOOPBACK  0x4000
-#define BMCR_SPEED0    0x2000
-#define BMCR_ANENABLE  0x1000
-#define BMCR_POWERDOWN 0x0800
-#define BMCR_ISOLATE   0x0400
-#define BMCR_RESTARTAN 0x0200
-#define BMCR_DUPLEX    0x0100
-#define BMCR_COLTEST   0x0080
-#define BMCR_SPEED1    0x0040
-#define BMCR_SPEED1000	BMCR_SPEED1
-#define BMCR_SPEED100	BMCR_SPEED0
-#define BMCR_SPEED10 	0
-
-#define BMSR_100BT4	0x8000
-#define BMSR_100BT_FDX	0x4000
-#define BMSR_100BT_HDX  0x2000
-#define BMSR_10BT_FDX   0x1000
-#define BMSR_10BT_HDX   0x0800
-#define BMSR_100BT2_FDX 0x0400
-#define BMSR_100BT2_HDX 0x0200
-#define BMSR_1000BT_XSR	0x0100
-#define BMSR_PRESUP	0x0040
-#define BMSR_ANCOMPLT	0x0020
-#define BMSR_REMFAULT	0x0010
-#define BMSR_AUTONEG	0x0008
-#define BMSR_LINKSTAT	0x0004
-#define BMSR_JABDETECT	0x0002
-#define BMSR_EXTCAPAB	0x0001
-
-#define PHYIDR1 	0x2000
-#define PHYIDR2		0x5C60
-
-#define ANAR_NP		0x8000
-#define ANAR_RF		0x2000
-#define ANAR_ASYPAUSE	0x0800
-#define ANAR_PAUSE	0x0400
-#define ANAR_T4		0x0200
-#define ANAR_TXFD	0x0100
-#define ANAR_TXHD	0x0080
-#define ANAR_10FD	0x0040
-#define ANAR_10HD	0x0020
-#define ANAR_PSB	0x0001
-
-#define ANLPAR_NP	0x8000
-#define ANLPAR_ACK	0x4000
-#define ANLPAR_RF	0x2000
-#define ANLPAR_ASYPAUSE	0x0800
-#define ANLPAR_PAUSE	0x0400
-#define ANLPAR_T4	0x0200
-#define ANLPAR_TXFD	0x0100
-#define ANLPAR_TXHD	0x0080
-#define ANLPAR_10FD	0x0040
-#define ANLPAR_10HD	0x0020
-#define ANLPAR_PSB	0x0001	/* 802.3 */
-
-#define ANER_PDF	0x0010
-#define ANER_LPNPABLE	0x0008
-#define ANER_NPABLE	0x0004
-#define ANER_PAGERX	0x0002
-#define ANER_LPANABLE	0x0001
-
-#define ANNPTR_NP	0x8000
-#define ANNPTR_MP	0x2000
-#define ANNPTR_ACK2	0x1000
-#define ANNPTR_TOGTX	0x0800
-#define ANNPTR_CODE	0x0008
-
-#define ANNPRR_NP	0x8000
-#define ANNPRR_MP	0x2000
-#define ANNPRR_ACK3	0x1000
-#define ANNPRR_TOGTX	0x0800
-#define ANNPRR_CODE	0x0008
-
-#define K1TCR_TESTMODE	0x0000
-#define K1TCR_MSMCE	0x1000
-#define K1TCR_MSCV	0x0800
-#define K1TCR_RPTR	0x0400
-#define K1TCR_1000BT_FDX 0x200
-#define K1TCR_1000BT_HDX 0x100
-
-#define K1STSR_MSMCFLT	0x8000
-#define K1STSR_MSCFGRES	0x4000
-#define K1STSR_LRSTAT	0x2000
-#define K1STSR_RRSTAT	0x1000
-#define K1STSR_LP1KFD	0x0800
-#define K1STSR_LP1KHD   0x0400
-#define K1STSR_LPASMDIR	0x0200
-
-#define K1SCR_1KX_FDX	0x8000
-#define K1SCR_1KX_HDX	0x4000
-#define K1SCR_1KT_FDX	0x2000
-#define K1SCR_1KT_HDX	0x1000
-
-#define STRAP_PHY1	0x0800
-#define STRAP_NCMODE	0x0400
-#define STRAP_MANMSCFG	0x0200
-#define STRAP_ANENABLE	0x0100
-#define STRAP_MSVAL	0x0080
-#define STRAP_1KHDXADV	0x0010
-#define STRAP_1KFDXADV	0x0008
-#define STRAP_100ADV	0x0004
-#define STRAP_SPEEDSEL	0x0000
-#define STRAP_SPEED100	0x0001
-
-#define PHYSUP_SPEED1000 0x10
-#define PHYSUP_SPEED100  0x08
-#define PHYSUP_SPEED10   0x00
-#define PHYSUP_LINKUP	 0x04
-#define PHYSUP_FDX       0x02
-
-#define	MII_BMCR	0x00 	/* Basic mode control register (rw) */
-#define	MII_BMSR	0x01	/* Basic mode status register (ro) */
-#define	MII_PHYIDR1	0x02
-#define	MII_PHYIDR2	0x03
-
-#define MII_K1STSR	0x0A	/* 1K Status Register (ro) */
-#define	MII_ANLPAR	0x05	/* Autonegotiation lnk partner abilities (rw) */
-
-
 #define M_MAC_MDIO_DIR_OUTPUT	0		/* for clarity */
 
 #define ENABLE 		1
 #define DISABLE		0
 
 /**********************************************************************
- *  SBMAC_MII_SYNC(s)
+ *  SBMAC_MII_SYNC(sbm_mdio)
  *
  *  Synchronize with the MII - send a pattern of bits to the MII
  *  that will guarantee that it is ready to accept a command.
  *
  *  Input parameters:
- *  	   s - sbmac structure
+ *  	   sbm_mdio - address of the MAC's MDIO register
  *
  *  Return value:
  *  	   nothing
  ********************************************************************* */
 
-static void sbmac_mii_sync(struct sbmac_softc *s)
+static void sbmac_mii_sync(void __iomem *sbm_mdio)
 {
 	int cnt;
 	uint64_t bits;
 	int mac_mdio_genc;
 
-	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+	mac_mdio_genc = __raw_readq(sbm_mdio) & M_MAC_GENC;
 
 	bits = M_MAC_MDIO_DIR_OUTPUT | M_MAC_MDIO_OUT;
 
-	__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+	__raw_writeq(bits | mac_mdio_genc, sbm_mdio);
 
 	for (cnt = 0; cnt < 32; cnt++) {
-		__raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
-		__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+		__raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, sbm_mdio);
+		__raw_writeq(bits | mac_mdio_genc, sbm_mdio);
 	}
 }
 
 /**********************************************************************
- *  SBMAC_MII_SENDDATA(s,data,bitcnt)
+ *  SBMAC_MII_SENDDATA(sbm_mdio, data, bitcnt)
  *
  *  Send some bits to the MII.  The bits to be sent are right-
  *  justified in the 'data' parameter.
  *
  *  Input parameters:
- *  	   s - sbmac structure
- *  	   data - data to send
- *  	   bitcnt - number of bits to send
+ *  	   sbm_mdio - address of the MAC's MDIO register
+ *  	   data     - data to send
+ *  	   bitcnt   - number of bits to send
  ********************************************************************* */
 
-static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitcnt)
+static void sbmac_mii_senddata(void __iomem *sbm_mdio, unsigned int data,
+			       int bitcnt)
 {
 	int i;
 	uint64_t bits;
 	unsigned int curmask;
 	int mac_mdio_genc;
 
-	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+	mac_mdio_genc = __raw_readq(sbm_mdio) & M_MAC_GENC;
 
 	bits = M_MAC_MDIO_DIR_OUTPUT;
-	__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+	__raw_writeq(bits | mac_mdio_genc, sbm_mdio);
 
 	curmask = 1 << (bitcnt - 1);
 
@@ -533,9 +432,9 @@ static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitc
 		if (data & curmask)
 			bits |= M_MAC_MDIO_OUT;
 		else bits &= ~M_MAC_MDIO_OUT;
-		__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
-		__raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
-		__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+		__raw_writeq(bits | mac_mdio_genc, sbm_mdio);
+		__raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, sbm_mdio);
+		__raw_writeq(bits | mac_mdio_genc, sbm_mdio);
 		curmask >>= 1;
 	}
 }
@@ -543,21 +442,22 @@ static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitc
 
 
 /**********************************************************************
- *  SBMAC_MII_READ(s,phyaddr,regidx)
- *
+ *  SBMAC_MII_READ(bus, phyaddr, regidx)
  *  Read a PHY register.
  *
  *  Input parameters:
- *  	   s - sbmac structure
+ *  	   bus     - MDIO bus handle
  *  	   phyaddr - PHY's address
- *  	   regidx = index of register to read
+ *  	   regnum  - index of register to read
  *
  *  Return value:
- *  	   value read, or 0 if an error occurred.
+ *  	   value read, or 0xffff if an error occurred.
  ********************************************************************* */
 
-static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
+static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
 {
+	struct sbmac_softc *sc = (struct sbmac_softc *)bus->priv;
+	void __iomem *sbm_mdio = sc->sbm_mdio;
 	int idx;
 	int error;
 	int regval;
@@ -567,8 +467,7 @@ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
 	 * Synchronize ourselves so that the PHY knows the next
 	 * thing coming down is a command
 	 */
-
-	sbmac_mii_sync(s);
+	sbmac_mii_sync(sbm_mdio);
 
 	/*
 	 * Send the data to the PHY.  The sequence is
@@ -577,37 +476,37 @@ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
 	 * the PHY addr (5 bits)
 	 * the register index (5 bits)
 	 */
+	sbmac_mii_senddata(sbm_mdio, MII_COMMAND_START, 2);
+	sbmac_mii_senddata(sbm_mdio, MII_COMMAND_READ, 2);
+	sbmac_mii_senddata(sbm_mdio, phyaddr, 5);
+	sbmac_mii_senddata(sbm_mdio, regidx, 5);
 
-	sbmac_mii_senddata(s,MII_COMMAND_START, 2);
-	sbmac_mii_senddata(s,MII_COMMAND_READ, 2);
-	sbmac_mii_senddata(s,phyaddr, 5);
-	sbmac_mii_senddata(s,regidx, 5);
-
-	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+	mac_mdio_genc = __raw_readq(sbm_mdio) & M_MAC_GENC;
 
 	/*
 	 * Switch the port around without a clock transition.
 	 */
-	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, sbm_mdio);
 
 	/*
 	 * Send out a clock pulse to signal we want the status
 	 */
-
-	__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
-	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+	__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc,
+		     sbm_mdio);
+	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, sbm_mdio);
 
 	/*
 	 * If an error occurred, the PHY will signal '1' back
 	 */
-	error = __raw_readq(s->sbm_mdio) & M_MAC_MDIO_IN;
+	error = __raw_readq(sbm_mdio) & M_MAC_MDIO_IN;
 
 	/*
 	 * Issue an 'idle' clock pulse, but keep the direction
 	 * the same.
 	 */
-	__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
-	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+	__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc,
+		     sbm_mdio);
+	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, sbm_mdio);
 
 	regval = 0;
 
@@ -615,55 +514,60 @@ static unsigned int sbmac_mii_read(struct sbmac_softc *s,int phyaddr,int regidx)
 		regval <<= 1;
 
 		if (error == 0) {
-			if (__raw_readq(s->sbm_mdio) & M_MAC_MDIO_IN)
+			if (__raw_readq(sbm_mdio) & M_MAC_MDIO_IN)
 				regval |= 1;
 		}
 
-		__raw_writeq(M_MAC_MDIO_DIR_INPUT|M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
-		__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
+		__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc,
+			     sbm_mdio);
+		__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, sbm_mdio);
 	}
 
 	/* Switch back to output */
-	__raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, s->sbm_mdio);
+	__raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, sbm_mdio);
 
 	if (error == 0)
 		return regval;
-	return 0;
+	return 0xffff;
 }
 
 
 /**********************************************************************
- *  SBMAC_MII_WRITE(s,phyaddr,regidx,regval)
+ *  SBMAC_MII_WRITE(bus, phyaddr, regidx, regval)
  *
  *  Write a value to a PHY register.
  *
  *  Input parameters:
- *  	   s - sbmac structure
+ *  	   bus     - MDIO bus handle
  *  	   phyaddr - PHY to use
- *  	   regidx - register within the PHY
- *  	   regval - data to write to register
+ *  	   regidx  - register within the PHY
+ *  	   regval  - data to write to register
  *
  *  Return value:
- *  	   nothing
+ *  	   0 for success
  ********************************************************************* */
 
-static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
-			    unsigned int regval)
+static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
+			   u16 regval)
 {
+	struct sbmac_softc *sc = (struct sbmac_softc *)bus->priv;
+	void __iomem *sbm_mdio = sc->sbm_mdio;
 	int mac_mdio_genc;
 
-	sbmac_mii_sync(s);
+	sbmac_mii_sync(sbm_mdio);
+
+	sbmac_mii_senddata(sbm_mdio, MII_COMMAND_START, 2);
+	sbmac_mii_senddata(sbm_mdio, MII_COMMAND_WRITE, 2);
+	sbmac_mii_senddata(sbm_mdio, phyaddr, 5);
+	sbmac_mii_senddata(sbm_mdio, regidx, 5);
+	sbmac_mii_senddata(sbm_mdio, MII_COMMAND_ACK, 2);
+	sbmac_mii_senddata(sbm_mdio, regval, 16);
 
-	sbmac_mii_senddata(s,MII_COMMAND_START,2);
-	sbmac_mii_senddata(s,MII_COMMAND_WRITE,2);
-	sbmac_mii_senddata(s,phyaddr, 5);
-	sbmac_mii_senddata(s,regidx, 5);
-	sbmac_mii_senddata(s,MII_COMMAND_ACK,2);
-	sbmac_mii_senddata(s,regval,16);
+	mac_mdio_genc = __raw_readq(sbm_mdio) & M_MAC_GENC;
 
-	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
+	__raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, sbm_mdio);
 
-	__raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, s->sbm_mdio);
+	return 0;
 }
 
 
@@ -676,8 +580,8 @@ static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
  *  way.
  *
  *  Input parameters:
- *  	   d - sbmacdma_t structure (DMA channel context)
- *  	   s - sbmac_softc structure (pointer to a MAC)
+ *  	   d - struct sbmacdma (DMA channel context)
+ *  	   s - struct sbmac_softc (pointer to a MAC)
  *  	   chan - channel number (0..1 right now)
  *  	   txrx - Identifies DMA_TX or DMA_RX for channel direction
  *      maxdescr - number of descriptors
@@ -686,11 +590,8 @@ static void sbmac_mii_write(struct sbmac_softc *s,int phyaddr,int regidx,
  *  	   nothing
  ********************************************************************* */
 
-static void sbdma_initctx(sbmacdma_t *d,
-			  struct sbmac_softc *s,
-			  int chan,
-			  int txrx,
-			  int maxdescr)
+static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan,
+			  int txrx, int maxdescr)
 {
 #ifdef CONFIG_SBMAC_COALESCE
 	int int_pktcnt, int_timeout;
@@ -709,27 +610,27 @@ static void sbdma_initctx(sbmacdma_t *d,
 	s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING;
 #endif
 
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)));
-	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)));
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_BYTES);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_COLLISIONS);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_LATE_COL);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_EX_COL);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_FCS_ERROR);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_ABORT);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_BAD);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_GOOD);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_RUNT);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_OVERSIZE);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_BYTES);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_MCAST);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_BCAST);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_BAD);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_GOOD);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_RUNT);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_OVERSIZE);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_FCS_ERROR);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_LENGTH_ERROR);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_CODE_ERROR);
+	__raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_ALIGN_ERROR);
 
 	/*
 	 * initialize register pointers
@@ -757,18 +658,17 @@ static void sbdma_initctx(sbmacdma_t *d,
 
 	d->sbdma_maxdescr = maxdescr;
 
-	d->sbdma_dscrtable_unaligned =
-	d->sbdma_dscrtable = (sbdmadscr_t *)
-		kmalloc((d->sbdma_maxdescr+1)*sizeof(sbdmadscr_t), GFP_KERNEL);
+	d->sbdma_dscrtable_unaligned = kcalloc(d->sbdma_maxdescr + 1,
+					       sizeof(*d->sbdma_dscrtable),
+					       GFP_KERNEL);
 
 	/*
 	 * The descriptor table must be aligned to at least 16 bytes or the
 	 * MAC will corrupt it.
 	 */
-	d->sbdma_dscrtable = (sbdmadscr_t *)
-		ALIGN((unsigned long)d->sbdma_dscrtable, sizeof(sbdmadscr_t));
-
-	memset(d->sbdma_dscrtable,0,d->sbdma_maxdescr*sizeof(sbdmadscr_t));
+	d->sbdma_dscrtable = (struct sbdmadscr *)
+			     ALIGN((unsigned long)d->sbdma_dscrtable_unaligned,
+				   sizeof(*d->sbdma_dscrtable));
 
 	d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr;
 
@@ -779,7 +679,7 @@ static void sbdma_initctx(sbmacdma_t *d,
 	 */
 
 	d->sbdma_ctxtable = kcalloc(d->sbdma_maxdescr,
-				    sizeof(struct sk_buff *), GFP_KERNEL);
+				    sizeof(*d->sbdma_ctxtable), GFP_KERNEL);
 
 #ifdef CONFIG_SBMAC_COALESCE
 	/*
@@ -816,7 +716,7 @@ static void sbdma_initctx(sbmacdma_t *d,
  *  	   nothing
  ********************************************************************* */
 
-static void sbdma_channel_start(sbmacdma_t *d, int rxtx )
+static void sbdma_channel_start(struct sbmacdma *d, int rxtx)
 {
 	/*
 	 * Turn on the DMA channel
@@ -857,7 +757,7 @@ static void sbdma_channel_start(sbmacdma_t *d, int rxtx )
  *  	   nothing
  ********************************************************************* */
 
-static void sbdma_channel_stop(sbmacdma_t *d)
+static void sbdma_channel_stop(struct sbmacdma *d)
 {
 	/*
 	 * Turn off the DMA channel
@@ -906,10 +806,10 @@ static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset)
  ********************************************************************* */
 
 
-static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
+static int sbdma_add_rcvbuffer(struct sbmacdma *d, struct sk_buff *sb)
 {
-	sbdmadscr_t *dsc;
-	sbdmadscr_t *nextdsc;
+	struct sbdmadscr *dsc;
+	struct sbdmadscr *nextdsc;
 	struct sk_buff *sb_new = NULL;
 	int pktsize = ENET_PACKET_SIZE;
 
@@ -950,7 +850,7 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
 	if (sb == NULL) {
 		sb_new = dev_alloc_skb(ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + ETHER_ALIGN);
 		if (sb_new == NULL) {
-			printk(KERN_INFO "%s: sk_buff allocation failed\n",
+			pr_info("%s: sk_buff allocation failed\n",
 			       d->sbdma_eth->sbm_dev->name);
 			return -ENOBUFS;
 		}
@@ -1021,10 +921,10 @@ static int sbdma_add_rcvbuffer(sbmacdma_t *d,struct sk_buff *sb)
  ********************************************************************* */
 
 
-static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *sb)
+static int sbdma_add_txbuffer(struct sbmacdma *d, struct sk_buff *sb)
 {
-	sbdmadscr_t *dsc;
-	sbdmadscr_t *nextdsc;
+	struct sbdmadscr *dsc;
+	struct sbdmadscr *nextdsc;
 	uint64_t phys;
 	uint64_t ncb;
 	int length;
@@ -1110,7 +1010,7 @@ static int sbdma_add_txbuffer(sbmacdma_t *d,struct sk_buff *sb)
  *  	   nothing
  ********************************************************************* */
 
-static void sbdma_emptyring(sbmacdma_t *d)
+static void sbdma_emptyring(struct sbmacdma *d)
 {
 	int idx;
 	struct sk_buff *sb;
@@ -1138,7 +1038,7 @@ static void sbdma_emptyring(sbmacdma_t *d)
  *  	   nothing
  ********************************************************************* */
 
-static void sbdma_fillring(sbmacdma_t *d)
+static void sbdma_fillring(struct sbmacdma *d)
 {
 	int idx;
 
@@ -1185,13 +1085,13 @@ static void sbmac_netpoll(struct net_device *netdev)
  *  	   nothing
  ********************************************************************* */
 
-static int sbdma_rx_process(struct sbmac_softc *sc,sbmacdma_t *d,
-                             int work_to_do, int poll)
+static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d,
+			    int work_to_do, int poll)
 {
 	struct net_device *dev = sc->sbm_dev;
 	int curidx;
 	int hwidx;
-	sbdmadscr_t *dsc;
+	struct sbdmadscr *dsc;
 	struct sk_buff *sb;
 	int len;
 	int work_done = 0;
@@ -1223,8 +1123,9 @@ again:
 		prefetch(dsc);
 		prefetch(&d->sbdma_ctxtable[curidx]);
 
-		hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
-				d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
+		hwidx = ((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+			 d->sbdma_dscrtable_phys) /
+			sizeof(*d->sbdma_dscrtable);
 
 		/*
 		 * If they're the same, that means we've processed all
@@ -1348,12 +1249,13 @@ done:
  *  	   nothing
  ********************************************************************* */
 
-static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll)
+static void sbdma_tx_process(struct sbmac_softc *sc, struct sbmacdma *d,
+			     int poll)
 {
 	struct net_device *dev = sc->sbm_dev;
 	int curidx;
 	int hwidx;
-	sbdmadscr_t *dsc;
+	struct sbdmadscr *dsc;
 	struct sk_buff *sb;
 	unsigned long flags;
 	int packets_handled = 0;
@@ -1363,8 +1265,8 @@ static void sbdma_tx_process(struct sbmac_softc *sc,sbmacdma_t *d, int poll)
 	if (d->sbdma_remptr == d->sbdma_addptr)
 	  goto end_unlock;
 
-	hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
-			d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
+	hwidx = ((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+		 d->sbdma_dscrtable_phys) / sizeof(*d->sbdma_dscrtable);
 
 	for (;;) {
 		/*
@@ -1467,14 +1369,6 @@ static int sbmac_initctx(struct sbmac_softc *s)
 	s->sbm_imr       = s->sbm_base + R_MAC_INT_MASK;
 	s->sbm_mdio      = s->sbm_base + R_MAC_MDIO;
 
-	s->sbm_phys[0]   = 1;
-	s->sbm_phys[1]   = 0;
-
-	s->sbm_phy_oldbmsr = 0;
-	s->sbm_phy_oldanlpar = 0;
-	s->sbm_phy_oldk1stsr = 0;
-	s->sbm_phy_oldlinkstat = 0;
-
 	/*
 	 * Initialize the DMA channels.  Right now, only one per MAC is used
 	 * Note: Only do this _once_, as it allocates memory from the kernel!
@@ -1489,19 +1383,11 @@ static int sbmac_initctx(struct sbmac_softc *s)
 
 	s->sbm_state = sbmac_state_off;
 
-	/*
-	 * Initial speed is (XXX TEMP) 10MBit/s HDX no FC
-	 */
-
-	s->sbm_speed = sbmac_speed_10;
-	s->sbm_duplex = sbmac_duplex_half;
-	s->sbm_fc = sbmac_fc_disabled;
-
 	return 0;
 }
 
 
-static void sbdma_uninitctx(struct sbmacdma_s *d)
+static void sbdma_uninitctx(struct sbmacdma *d)
 {
 	if (d->sbdma_dscrtable_unaligned) {
 		kfree(d->sbdma_dscrtable_unaligned);
@@ -1537,7 +1423,7 @@ static void sbmac_uninitctx(struct sbmac_softc *sc)
 static void sbmac_channel_start(struct sbmac_softc *s)
 {
 	uint64_t reg;
-	volatile void __iomem *port;
+	void __iomem *port;
 	uint64_t cfg,fifo,framecfg;
 	int idx, th_value;
 
@@ -1800,10 +1686,10 @@ static void sbmac_channel_stop(struct sbmac_softc *s)
  *  Return value:
  *  	   old state
  ********************************************************************* */
-static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *sc,
-					     sbmac_state_t state)
+static enum sbmac_state sbmac_set_channel_state(struct sbmac_softc *sc,
+						enum sbmac_state state)
 {
-	sbmac_state_t oldstate = sc->sbm_state;
+	enum sbmac_state oldstate = sc->sbm_state;
 
 	/*
 	 * If same as previous state, return
@@ -1938,14 +1824,14 @@ static uint64_t sbmac_addr2reg(unsigned char *ptr)
  *
  *  Input parameters:
  *  	   s - sbmac structure
- *  	   speed - speed to set MAC to (see sbmac_speed_t enum)
+ *  	   speed - speed to set MAC to (see enum sbmac_speed)
  *
  *  Return value:
  *  	   1 if successful
  *      0 indicates invalid parameters
  ********************************************************************* */
 
-static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
+static int sbmac_set_speed(struct sbmac_softc *s, enum sbmac_speed speed)
 {
 	uint64_t cfg;
 	uint64_t framecfg;
@@ -2003,8 +1889,6 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
 		cfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN;
 		break;
 
-	case sbmac_speed_auto:		/* XXX not implemented */
-		/* fall through */
 	default:
 		return 0;
 	}
@@ -2027,15 +1911,16 @@ static int sbmac_set_speed(struct sbmac_softc *s,sbmac_speed_t speed)
  *
  *  Input parameters:
  *  	   s - sbmac structure
- *  	   duplex - duplex setting (see sbmac_duplex_t)
- *  	   fc - flow control setting (see sbmac_fc_t)
+ *  	   duplex - duplex setting (see enum sbmac_duplex)
+ *  	   fc - flow control setting (see enum sbmac_fc)
  *
  *  Return value:
  *  	   1 if ok
  *  	   0 if an invalid parameter combination was specified
  ********************************************************************* */
 
-static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc_t fc)
+static int sbmac_set_duplex(struct sbmac_softc *s, enum sbmac_duplex duplex,
+			    enum sbmac_fc fc)
 {
 	uint64_t cfg;
 
@@ -2077,8 +1962,6 @@ static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc
 			cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR;
 			break;
 
-		case sbmac_fc_auto:		/* XXX not implemented */
-			/* fall through */
 		case sbmac_fc_frame:		/* not valid in half duplex */
 		default:			/* invalid selection */
 			return 0;
@@ -2097,15 +1980,12 @@ static int sbmac_set_duplex(struct sbmac_softc *s,sbmac_duplex_t duplex,sbmac_fc
 
 		case sbmac_fc_collision:	/* not valid in full duplex */
 		case sbmac_fc_carrier:		/* not valid in full duplex */
-		case sbmac_fc_auto:		/* XXX not implemented */
-			/* fall through */
 		default:
 			return 0;
 		}
 		break;
-	case sbmac_duplex_auto:
-		/* XXX not implemented */
-		break;
+	default:
+		return 0;
 	}
 
 	/*
@@ -2228,7 +2108,7 @@ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev)
 static void sbmac_setmulti(struct sbmac_softc *sc)
 {
 	uint64_t reg;
-	volatile void __iomem *port;
+	void __iomem *port;
 	int idx;
 	struct dev_mc_list *mclist;
 	struct net_device *dev = sc->sbm_dev;
@@ -2384,7 +2264,7 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
 	if (new_mtu >  ENET_PACKET_SIZE)
 		return -EINVAL;
 	_dev->mtu = new_mtu;
-	printk(KERN_INFO "changing the mtu to %d\n", new_mtu);
+	pr_info("changing the mtu to %d\n", new_mtu);
 	return 0;
 }
 
@@ -2400,20 +2280,17 @@ static int sb1250_change_mtu(struct net_device *_dev, int new_mtu)
  *  	   status
  ********************************************************************* */
 
-static int sbmac_init(struct net_device *dev, int idx)
+static int sbmac_init(struct platform_device *pldev, long long base)
 {
-	struct sbmac_softc *sc;
+	struct net_device *dev = pldev->dev.driver_data;
+	int idx = pldev->id;
+	struct sbmac_softc *sc = netdev_priv(dev);
 	unsigned char *eaddr;
 	uint64_t ea_reg;
 	int i;
 	int err;
 	DECLARE_MAC_BUF(mac);
 
-	sc = netdev_priv(dev);
-
-	/* Determine controller base address */
-
-	sc->sbm_base = IOADDR(dev->base_addr);
 	sc->sbm_dev = dev;
 	sc->sbe_idx = idx;
 
@@ -2470,43 +2347,55 @@ static int sbmac_init(struct net_device *dev, int idx)
 	dev->poll_controller = sbmac_netpoll;
 #endif
 
+	dev->irq		= UNIT_INT(idx);
+
 	/* This is needed for PASS2 for Rx H/W checksum feature */
 	sbmac_set_iphdr_offset(sc);
 
 	err = register_netdev(dev);
-	if (err)
-		goto out_uninit;
-
-	if (sc->rx_hw_checksum == ENABLE) {
-		printk(KERN_INFO "%s: enabling TCP rcv checksum\n",
-			sc->sbm_dev->name);
+	if (err) {
+		printk(KERN_ERR "%s.%d: unable to register netdev\n",
+		       sbmac_string, idx);
+		sbmac_uninitctx(sc);
+		return err;
 	}
 
+	pr_info("%s.%d: registered as %s\n", sbmac_string, idx, dev->name);
+
+	if (sc->rx_hw_checksum == ENABLE)
+		pr_info("%s: enabling TCP rcv checksum\n", dev->name);
+
 	/*
 	 * Display Ethernet address (this is called during the config
 	 * process so we need to finish off the config message that
 	 * was being displayed)
 	 */
-	printk(KERN_INFO
-	       "%s: SiByte Ethernet at 0x%08lX, address: %s\n",
-	       dev->name, dev->base_addr, print_mac(mac, eaddr));
+	pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %s\n",
+	       dev->name, base, print_mac(mac, eaddr));
 
-	return 0;
+	sc->mii_bus.name = sbmac_mdio_string;
+	sc->mii_bus.id = idx;
+	sc->mii_bus.priv = sc;
+	sc->mii_bus.read = sbmac_mii_read;
+	sc->mii_bus.write = sbmac_mii_write;
+	sc->mii_bus.irq = sc->phy_irq;
+	for (i = 0; i < PHY_MAX_ADDR; ++i)
+		sc->mii_bus.irq[i] = SBMAC_PHY_INT;
 
-out_uninit:
-	sbmac_uninitctx(sc);
+	sc->mii_bus.dev = &pldev->dev;
+	dev_set_drvdata(&pldev->dev, &sc->mii_bus);
 
-	return err;
+	return 0;
 }
 
 
 static int sbmac_open(struct net_device *dev)
 {
 	struct sbmac_softc *sc = netdev_priv(dev);
+	int err;
 
-	if (debug > 1) {
-		printk(KERN_DEBUG "%s: sbmac_open() irq %d.\n", dev->name, dev->irq);
-	}
+	if (debug > 1)
+		pr_debug("%s: sbmac_open() irq %d.\n", dev->name, dev->irq);
 
 	/*
 	 * map/route interrupt (clear status first, in case something
@@ -2515,25 +2404,35 @@ static int sbmac_open(struct net_device *dev)
 	 */
 
 	__raw_readq(sc->sbm_isr);
-	if (request_irq(dev->irq, &sbmac_intr, IRQF_SHARED, dev->name, dev))
-		return -EBUSY;
+	err = request_irq(dev->irq, &sbmac_intr, IRQF_SHARED, dev->name, dev);
+	if (err) {
+		printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name,
+		       dev->irq);
+		goto out_err;
+	}
 
 	/*
-	 * Probe phy address
+	 * Probe PHY address
 	 */
-
-	if(sbmac_mii_probe(dev) == -1) {
-		printk("%s: failed to probe PHY.\n", dev->name);
-		return -EINVAL;
+	err = mdiobus_register(&sc->mii_bus);
+	if (err) {
+		printk(KERN_ERR "%s: unable to register MDIO bus\n",
+		       dev->name);
+		goto out_unirq;
 	}
 
-	napi_enable(&sc->napi);
+	sc->sbm_speed = sbmac_speed_none;
+	sc->sbm_duplex = sbmac_duplex_none;
+	sc->sbm_fc = sbmac_fc_none;
+	sc->sbm_pause = -1;
+	sc->sbm_link = 0;
 
 	/*
-	 * Configure default speed
+	 * Attach to the PHY
 	 */
-
-	sbmac_mii_poll(sc,noisy_mii);
+	err = sbmac_mii_probe(dev);
+	if (err)
+		goto out_unregister;
 
 	/*
 	 * Turn on the channel
@@ -2541,200 +2440,133 @@ static int sbmac_open(struct net_device *dev)
 
 	sbmac_set_channel_state(sc,sbmac_state_on);
 
-	/*
-	 * XXX Station address is in dev->dev_addr
-	 */
-
-	if (dev->if_port == 0)
-		dev->if_port = 0;
-
 	netif_start_queue(dev);
 
 	sbmac_set_rx_mode(dev);
 
-	/* Set the timer to check for link beat. */
-	init_timer(&sc->sbm_timer);
-	sc->sbm_timer.expires = jiffies + 2 * HZ/100;
-	sc->sbm_timer.data = (unsigned long)dev;
-	sc->sbm_timer.function = &sbmac_timer;
-	add_timer(&sc->sbm_timer);
+	phy_start(sc->phy_dev);
+
+	napi_enable(&sc->napi);
 
 	return 0;
+
+out_unregister:
+	mdiobus_unregister(&sc->mii_bus);
+
+out_unirq:
+	free_irq(dev->irq, dev);
+
+out_err:
+	return err;
 }
 
 static int sbmac_mii_probe(struct net_device *dev)
 {
+	struct sbmac_softc *sc = netdev_priv(dev);
+	struct phy_device *phy_dev;
 	int i;
-	struct sbmac_softc *s = netdev_priv(dev);
-	u16 bmsr, id1, id2;
-	u32 vendor, device;
-
-	for (i=1; i<31; i++) {
-	bmsr = sbmac_mii_read(s, i, MII_BMSR);
-		if (bmsr != 0) {
-			s->sbm_phys[0] = i;
-			id1 = sbmac_mii_read(s, i, MII_PHYIDR1);
-			id2 = sbmac_mii_read(s, i, MII_PHYIDR2);
-			vendor = ((u32)id1 << 6) | ((id2 >> 10) & 0x3f);
-			device = (id2 >> 4) & 0x3f;
-
-			printk(KERN_INFO "%s: found phy %d, vendor %06x part %02x\n",
-				dev->name, i, vendor, device);
-			return i;
-		}
-	}
-	return -1;
-}
 
-
-static int sbmac_mii_poll(struct sbmac_softc *s,int noisy)
-{
-    int bmsr,bmcr,k1stsr,anlpar;
-    int chg;
-    char buffer[100];
-    char *p = buffer;
-
-    /* Read the mode status and mode control registers. */
-    bmsr = sbmac_mii_read(s,s->sbm_phys[0],MII_BMSR);
-    bmcr = sbmac_mii_read(s,s->sbm_phys[0],MII_BMCR);
-
-    /* get the link partner status */
-    anlpar = sbmac_mii_read(s,s->sbm_phys[0],MII_ANLPAR);
-
-    /* if supported, read the 1000baseT register */
-    if (bmsr & BMSR_1000BT_XSR) {
-	k1stsr = sbmac_mii_read(s,s->sbm_phys[0],MII_K1STSR);
-	}
-    else {
-	k1stsr = 0;
+	for (i = 0; i < PHY_MAX_ADDR; i++) {
+		phy_dev = sc->mii_bus.phy_map[i];
+		if (phy_dev)
+			break;
 	}
-
-    chg = 0;
-
-    if ((bmsr & BMSR_LINKSTAT) == 0) {
-	/*
-	 * If link status is down, clear out old info so that when
-	 * it comes back up it will force us to reconfigure speed
-	 */
-	s->sbm_phy_oldbmsr = 0;
-	s->sbm_phy_oldanlpar = 0;
-	s->sbm_phy_oldk1stsr = 0;
-	return 0;
+	if (!phy_dev) {
+		printk(KERN_ERR "%s: no PHY found\n", dev->name);
+		return -ENXIO;
 	}
 
-    if ((s->sbm_phy_oldbmsr != bmsr) ||
-	(s->sbm_phy_oldanlpar != anlpar) ||
-	(s->sbm_phy_oldk1stsr != k1stsr)) {
-	if (debug > 1) {
-	    printk(KERN_DEBUG "%s: bmsr:%x/%x anlpar:%x/%x  k1stsr:%x/%x\n",
-	       s->sbm_dev->name,
-	       s->sbm_phy_oldbmsr,bmsr,
-	       s->sbm_phy_oldanlpar,anlpar,
-	       s->sbm_phy_oldk1stsr,k1stsr);
-	    }
-	s->sbm_phy_oldbmsr = bmsr;
-	s->sbm_phy_oldanlpar = anlpar;
-	s->sbm_phy_oldk1stsr = k1stsr;
-	chg = 1;
+	phy_dev = phy_connect(dev, phy_dev->dev.bus_id, &sbmac_mii_poll, 0,
+			      PHY_INTERFACE_MODE_GMII);
+	if (IS_ERR(phy_dev)) {
+		printk(KERN_ERR "%s: could not attach to PHY\n", dev->name);
+		return PTR_ERR(phy_dev);
 	}
 
-    if (chg == 0)
-	    return 0;
+	/* Remove any features not supported by the controller */
+	phy_dev->supported &= SUPPORTED_10baseT_Half |
+			      SUPPORTED_10baseT_Full |
+			      SUPPORTED_100baseT_Half |
+			      SUPPORTED_100baseT_Full |
+			      SUPPORTED_1000baseT_Half |
+			      SUPPORTED_1000baseT_Full |
+			      SUPPORTED_Autoneg |
+			      SUPPORTED_MII |
+			      SUPPORTED_Pause |
+			      SUPPORTED_Asym_Pause;
+	phy_dev->advertising = phy_dev->supported;
+
+	pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
+		dev->name, phy_dev->drv->name,
+		phy_dev->dev.bus_id, phy_dev->irq);
+
+	sc->phy_dev = phy_dev;
 
-    p += sprintf(p,"Link speed: ");
-
-    if (k1stsr & K1STSR_LP1KFD) {
-	s->sbm_speed = sbmac_speed_1000;
-	s->sbm_duplex = sbmac_duplex_full;
-	s->sbm_fc = sbmac_fc_frame;
-	p += sprintf(p,"1000BaseT FDX");
-	}
-    else if (k1stsr & K1STSR_LP1KHD) {
-	s->sbm_speed = sbmac_speed_1000;
-	s->sbm_duplex = sbmac_duplex_half;
-	s->sbm_fc = sbmac_fc_disabled;
-	p += sprintf(p,"1000BaseT HDX");
-	}
-    else if (anlpar & ANLPAR_TXFD) {
-	s->sbm_speed = sbmac_speed_100;
-	s->sbm_duplex = sbmac_duplex_full;
-	s->sbm_fc = (anlpar & ANLPAR_PAUSE) ? sbmac_fc_frame : sbmac_fc_disabled;
-	p += sprintf(p,"100BaseT FDX");
-	}
-    else if (anlpar & ANLPAR_TXHD) {
-	s->sbm_speed = sbmac_speed_100;
-	s->sbm_duplex = sbmac_duplex_half;
-	s->sbm_fc = sbmac_fc_disabled;
-	p += sprintf(p,"100BaseT HDX");
-	}
-    else if (anlpar & ANLPAR_10FD) {
-	s->sbm_speed = sbmac_speed_10;
-	s->sbm_duplex = sbmac_duplex_full;
-	s->sbm_fc = sbmac_fc_frame;
-	p += sprintf(p,"10BaseT FDX");
-	}
-    else if (anlpar & ANLPAR_10HD) {
-	s->sbm_speed = sbmac_speed_10;
-	s->sbm_duplex = sbmac_duplex_half;
-	s->sbm_fc = sbmac_fc_collision;
-	p += sprintf(p,"10BaseT HDX");
-	}
-    else {
-	p += sprintf(p,"Unknown");
-	}
-
-    if (noisy) {
-	    printk(KERN_INFO "%s: %s\n",s->sbm_dev->name,buffer);
-	    }
-
-    return 1;
+	return 0;
 }
 
 
-static void sbmac_timer(unsigned long data)
+static void sbmac_mii_poll(struct net_device *dev)
 {
-	struct net_device *dev = (struct net_device *)data;
 	struct sbmac_softc *sc = netdev_priv(dev);
-	int next_tick = HZ;
-	int mii_status;
+	struct phy_device *phy_dev = sc->phy_dev;
+	unsigned long flags;
+	enum sbmac_fc fc;
+	int link_chg, speed_chg, duplex_chg, pause_chg, fc_chg;
+
+	link_chg = (sc->sbm_link != phy_dev->link);
+	speed_chg = (sc->sbm_speed != phy_dev->speed);
+	duplex_chg = (sc->sbm_duplex != phy_dev->duplex);
+	pause_chg = (sc->sbm_pause != phy_dev->pause);
+
+	if (!link_chg && !speed_chg && !duplex_chg && !pause_chg)
+		return;					/* Hmmm... */
+
+	if (!phy_dev->link) {
+		if (link_chg) {
+			sc->sbm_link = phy_dev->link;
+			sc->sbm_speed = sbmac_speed_none;
+			sc->sbm_duplex = sbmac_duplex_none;
+			sc->sbm_fc = sbmac_fc_disabled;
+			sc->sbm_pause = -1;
+			pr_info("%s: link unavailable\n", dev->name);
+		}
+		return;
+	}
 
-	spin_lock_irq (&sc->sbm_lock);
+	if (phy_dev->duplex == DUPLEX_FULL) {
+		if (phy_dev->pause)
+			fc = sbmac_fc_frame;
+		else
+			fc = sbmac_fc_disabled;
+	} else
+		fc = sbmac_fc_collision;
+	fc_chg = (sc->sbm_fc != fc);
 
-	/* make IFF_RUNNING follow the MII status bit "Link established" */
-	mii_status = sbmac_mii_read(sc, sc->sbm_phys[0], MII_BMSR);
+	pr_info("%s: link available: %dbase-%cD\n", dev->name, phy_dev->speed,
+		phy_dev->duplex == DUPLEX_FULL ? 'F' : 'H');
 
-	if ( (mii_status & BMSR_LINKSTAT) != (sc->sbm_phy_oldlinkstat) ) {
-    	        sc->sbm_phy_oldlinkstat = mii_status & BMSR_LINKSTAT;
-		if (mii_status & BMSR_LINKSTAT) {
-			netif_carrier_on(dev);
-		}
-		else {
-			netif_carrier_off(dev);
-		}
-	}
+	spin_lock_irqsave(&sc->sbm_lock, flags);
 
-	/*
-	 * Poll the PHY to see what speed we should be running at
-	 */
+	sc->sbm_speed = phy_dev->speed;
+	sc->sbm_duplex = phy_dev->duplex;
+	sc->sbm_fc = fc;
+	sc->sbm_pause = phy_dev->pause;
+	sc->sbm_link = phy_dev->link;
 
-	if (sbmac_mii_poll(sc,noisy_mii)) {
-		if (sc->sbm_state != sbmac_state_off) {
-			/*
-			 * something changed, restart the channel
-			 */
-			if (debug > 1) {
-				printk("%s: restarting channel because speed changed\n",
-				       sc->sbm_dev->name);
-			}
-			sbmac_channel_stop(sc);
-			sbmac_channel_start(sc);
-		}
+	if ((speed_chg || duplex_chg || fc_chg) &&
+	    sc->sbm_state != sbmac_state_off) {
+		/*
+		 * something changed, restart the channel
+		 */
+		if (debug > 1)
+			pr_debug("%s: restarting channel "
+				 "because PHY state changed\n", dev->name);
+		sbmac_channel_stop(sc);
+		sbmac_channel_start(sc);
 	}
 
-	spin_unlock_irq (&sc->sbm_lock);
-
-	sc->sbm_timer.expires = jiffies + next_tick;
-	add_timer(&sc->sbm_timer);
+	spin_unlock_irqrestore(&sc->sbm_lock, flags);
 }
 
 
@@ -2787,64 +2619,34 @@ static void sbmac_set_rx_mode(struct net_device *dev)
 static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct sbmac_softc *sc = netdev_priv(dev);
-	u16 *data = (u16 *)&rq->ifr_ifru;
-	unsigned long flags;
-	int retval;
 
-	spin_lock_irqsave(&sc->sbm_lock, flags);
-	retval = 0;
-
-	switch(cmd) {
-	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
-		data[0] = sc->sbm_phys[0] & 0x1f;
-		/* Fall Through */
-	case SIOCDEVPRIVATE+1:		/* Read the specified MII register. */
-		data[3] = sbmac_mii_read(sc, data[0] & 0x1f, data[1] & 0x1f);
-		break;
-	case SIOCDEVPRIVATE+2:		/* Write the specified MII register */
-		if (!capable(CAP_NET_ADMIN)) {
-			retval = -EPERM;
-			break;
-		}
-		if (debug > 1) {
-		    printk(KERN_DEBUG "%s: sbmac_mii_ioctl: write %02X %02X %02X\n",dev->name,
-		       data[0],data[1],data[2]);
-		    }
-		sbmac_mii_write(sc, data[0] & 0x1f, data[1] & 0x1f, data[2]);
-		break;
-	default:
-		retval = -EOPNOTSUPP;
-	}
+	if (!netif_running(dev) || !sc->phy_dev)
+		return -EINVAL;
 
-	spin_unlock_irqrestore(&sc->sbm_lock, flags);
-	return retval;
+	return phy_mii_ioctl(sc->phy_dev, if_mii(rq), cmd);
 }
 
 static int sbmac_close(struct net_device *dev)
 {
 	struct sbmac_softc *sc = netdev_priv(dev);
-	unsigned long flags;
-	int irq;
 
 	napi_disable(&sc->napi);
 
-	sbmac_set_channel_state(sc,sbmac_state_off);
+	phy_stop(sc->phy_dev);
 
-	del_timer_sync(&sc->sbm_timer);
-
-	spin_lock_irqsave(&sc->sbm_lock, flags);
+	sbmac_set_channel_state(sc, sbmac_state_off);
 
 	netif_stop_queue(dev);
 
-	if (debug > 1) {
-		printk(KERN_DEBUG "%s: Shutting down ethercard\n",dev->name);
-	}
+	if (debug > 1)
+		pr_debug("%s: Shutting down ethercard\n", dev->name);
 
-	spin_unlock_irqrestore(&sc->sbm_lock, flags);
+	phy_disconnect(sc->phy_dev);
+	sc->phy_dev = NULL;
 
-	irq = dev->irq;
-	synchronize_irq(irq);
-	free_irq(irq, dev);
+	mdiobus_unregister(&sc->mii_bus);
+
+	free_irq(dev->irq, dev);
 
 	sbdma_emptyring(&(sc->sbm_txdma));
 	sbdma_emptyring(&(sc->sbm_rxdma));
@@ -2877,54 +2679,195 @@ static int sbmac_poll(struct napi_struct *napi, int budget)
 	return work_done;
 }
 
+
+static int __init sbmac_probe(struct platform_device *pldev)
+{
+	struct net_device *dev;
+	struct sbmac_softc *sc;
+	void __iomem *sbm_base;
+	struct resource *res;
+	u64 sbmac_orig_hwaddr;
+	int err;
+
+	res = platform_get_resource(pldev, IORESOURCE_MEM, 0);
+	BUG_ON(!res);
+	sbm_base = ioremap_nocache(res->start, res->end - res->start + 1);
+	if (!sbm_base) {
+		printk(KERN_ERR "%s: unable to map device registers\n",
+		       pldev->dev.bus_id);
+		err = -ENOMEM;
+		goto out_out;
+	}
+
+	/*
+	 * The R_MAC_ETHERNET_ADDR register will be set to some nonzero
+	 * value for us by the firmware if we're going to use this MAC.
+	 * If we find a zero, skip this MAC.
+	 */
+	sbmac_orig_hwaddr = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR);
+	pr_debug("%s: %sconfiguring MAC at 0x%08Lx\n", pldev->dev.bus_id,
+		 sbmac_orig_hwaddr ? "" : "not ", (long long)res->start);
+	if (sbmac_orig_hwaddr == 0) {
+		err = 0;
+		goto out_unmap;
+	}
+
+	/*
+	 * Okay, cool.  Initialize this MAC.
+	 */
+	dev = alloc_etherdev(sizeof(struct sbmac_softc));
+	if (!dev) {
+		printk(KERN_ERR "%s: unable to allocate etherdev\n",
+		       pldev->dev.bus_id);
+		err = -ENOMEM;
+		goto out_unmap;
+	}
+
+	pldev->dev.driver_data = dev;
+	SET_NETDEV_DEV(dev, &pldev->dev);
+
+	sc = netdev_priv(dev);
+	sc->sbm_base = sbm_base;
+
+	err = sbmac_init(pldev, res->start);
+	if (err)
+		goto out_kfree;
+
+	return 0;
+
+out_kfree:
+	free_netdev(dev);
+	__raw_writeq(sbmac_orig_hwaddr, sbm_base + R_MAC_ETHERNET_ADDR);
+
+out_unmap:
+	iounmap(sbm_base);
+
+out_out:
+	return err;
+}
+
+static int __exit sbmac_remove(struct platform_device *pldev)
+{
+	struct net_device *dev = pldev->dev.driver_data;
+	struct sbmac_softc *sc = netdev_priv(dev);
+
+	unregister_netdev(dev);
+	sbmac_uninitctx(sc);
+	iounmap(sc->sbm_base);
+	free_netdev(dev);
+
+	return 0;
+}
+
+
+static struct platform_device **sbmac_pldev;
+static int sbmac_max_units;
+
 #if defined(SBMAC_ETH0_HWADDR) || defined(SBMAC_ETH1_HWADDR) || defined(SBMAC_ETH2_HWADDR) || defined(SBMAC_ETH3_HWADDR)
-static void
-sbmac_setup_hwaddr(int chan,char *addr)
+static void __init sbmac_setup_hwaddr(int idx, char *addr)
 {
+	void __iomem *sbm_base;
+	unsigned long start, end;
 	uint8_t eaddr[6];
 	uint64_t val;
-	unsigned long port;
 
-	port = A_MAC_CHANNEL_BASE(chan);
-	sbmac_parse_hwaddr(addr,eaddr);
+	if (idx >= sbmac_max_units)
+		return;
+
+	start = A_MAC_CHANNEL_BASE(idx);
+	end = A_MAC_CHANNEL_BASE(idx + 1) - 1;
+
+	sbm_base = ioremap_nocache(start, end - start + 1);
+	if (!sbm_base) {
+		printk(KERN_ERR "%s: unable to map device registers\n",
+		       sbmac_string);
+		return;
+	}
+
+	sbmac_parse_hwaddr(addr, eaddr);
 	val = sbmac_addr2reg(eaddr);
-	__raw_writeq(val, IOADDR(port+R_MAC_ETHERNET_ADDR));
-	val = __raw_readq(IOADDR(port+R_MAC_ETHERNET_ADDR));
+	__raw_writeq(val, sbm_base + R_MAC_ETHERNET_ADDR);
+	val = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR);
+
+	iounmap(sbm_base);
 }
 #endif
 
-static struct net_device *dev_sbmac[MAX_UNITS];
+static int __init sbmac_platform_probe_one(int idx)
+{
+	struct platform_device *pldev;
+	struct {
+		struct resource r;
+		char name[strlen(sbmac_pretty) + 4];
+	} *res;
+	int err;
+
+	res = kzalloc(sizeof(*res), GFP_KERNEL);
+	if (!res) {
+		printk(KERN_ERR "%s.%d: unable to allocate memory\n",
+		       sbmac_string, idx);
+		err = -ENOMEM;
+		goto out_err;
+	}
+
+	/*
+	 * This is the base address of the MAC.
+	 */
+	snprintf(res->name, sizeof(res->name), "%s %d", sbmac_pretty, idx);
+	res->r.name = res->name;
+	res->r.flags = IORESOURCE_MEM;
+	res->r.start = A_MAC_CHANNEL_BASE(idx);
+	res->r.end = A_MAC_CHANNEL_BASE(idx + 1) - 1;
+
+	pldev = platform_device_register_simple(sbmac_string, idx, &res->r, 1);
+	if (IS_ERR(pldev)) {
+		printk(KERN_ERR "%s.%d: unable to register platform device\n",
+		       sbmac_string, idx);
+		err = PTR_ERR(pldev);
+		goto out_kfree;
+	}
+
+	if (!pldev->dev.driver) {
+		err = 0;		/* No hardware at this address. */
+		goto out_unregister;
+	}
+
+	sbmac_pldev[idx] = pldev;
+	return 0;
 
-static int __init
-sbmac_init_module(void)
+out_unregister:
+	platform_device_unregister(pldev);
+
+out_kfree:
+	kfree(res);
+
+out_err:
+	return err;
+}
+
+static void __init sbmac_platform_probe(void)
 {
-	int idx;
-	struct net_device *dev;
-	unsigned long port;
-	int chip_max_units;
+	int i;
 
 	/* Set the number of available units based on the SOC type.  */
 	switch (soc_type) {
 	case K_SYS_SOC_TYPE_BCM1250:
 	case K_SYS_SOC_TYPE_BCM1250_ALT:
-		chip_max_units = 3;
+		sbmac_max_units = 3;
 		break;
 	case K_SYS_SOC_TYPE_BCM1120:
 	case K_SYS_SOC_TYPE_BCM1125:
 	case K_SYS_SOC_TYPE_BCM1125H:
-	case K_SYS_SOC_TYPE_BCM1250_ALT2: /* Hybrid */
-		chip_max_units = 2;
+	case K_SYS_SOC_TYPE_BCM1250_ALT2:	/* Hybrid */
+		sbmac_max_units = 2;
 		break;
 	case K_SYS_SOC_TYPE_BCM1x55:
 	case K_SYS_SOC_TYPE_BCM1x80:
-		chip_max_units = 4;
+		sbmac_max_units = 4;
 		break;
 	default:
-		chip_max_units = 0;
-		break;
+		return;				/* none */
 	}
-	if (chip_max_units > MAX_UNITS)
-		chip_max_units = MAX_UNITS;
 
 	/*
 	 * For bringup when not using the firmware, we can pre-fill
@@ -2932,89 +2875,71 @@ sbmac_init_module(void)
 	 * specified in this file (or maybe from the config file?)
 	 */
 #ifdef SBMAC_ETH0_HWADDR
-	if (chip_max_units > 0)
-	  sbmac_setup_hwaddr(0,SBMAC_ETH0_HWADDR);
+	sbmac_setup_hwaddr(0, SBMAC_ETH0_HWADDR);
 #endif
 #ifdef SBMAC_ETH1_HWADDR
-	if (chip_max_units > 1)
-	  sbmac_setup_hwaddr(1,SBMAC_ETH1_HWADDR);
+	sbmac_setup_hwaddr(1, SBMAC_ETH1_HWADDR);
 #endif
 #ifdef SBMAC_ETH2_HWADDR
-	if (chip_max_units > 2)
-	  sbmac_setup_hwaddr(2,SBMAC_ETH2_HWADDR);
+	sbmac_setup_hwaddr(2, SBMAC_ETH2_HWADDR);
 #endif
 #ifdef SBMAC_ETH3_HWADDR
-	if (chip_max_units > 3)
-	  sbmac_setup_hwaddr(3,SBMAC_ETH3_HWADDR);
+	sbmac_setup_hwaddr(3, SBMAC_ETH3_HWADDR);
 #endif
 
+	sbmac_pldev = kcalloc(sbmac_max_units, sizeof(*sbmac_pldev),
+			      GFP_KERNEL);
+	if (!sbmac_pldev) {
+		printk(KERN_ERR "%s: unable to allocate memory\n",
+		       sbmac_string);
+		return;
+	}
+
 	/*
 	 * Walk through the Ethernet controllers and find
 	 * those who have their MAC addresses set.
 	 */
-	for (idx = 0; idx < chip_max_units; idx++) {
+	for (i = 0; i < sbmac_max_units; i++)
+		if (sbmac_platform_probe_one(i))
+			break;
+}
 
-	        /*
-	         * This is the base address of the MAC.
-		 */
 
-	        port = A_MAC_CHANNEL_BASE(idx);
+static void __exit sbmac_platform_cleanup(void)
+{
+	int i;
 
-		/*
-		 * The R_MAC_ETHERNET_ADDR register will be set to some nonzero
-		 * value for us by the firmware if we are going to use this MAC.
-		 * If we find a zero, skip this MAC.
-		 */
+	for (i = 0; i < sbmac_max_units; i++)
+		platform_device_unregister(sbmac_pldev[i]);
+	kfree(sbmac_pldev);
+}
 
-		sbmac_orig_hwaddr[idx] = __raw_readq(IOADDR(port+R_MAC_ETHERNET_ADDR));
-		if (sbmac_orig_hwaddr[idx] == 0) {
-			printk(KERN_DEBUG "sbmac: not configuring MAC at "
-			       "%lx\n", port);
-		    continue;
-		}
 
-		/*
-		 * Okay, cool.  Initialize this MAC.
-		 */
+static struct platform_driver sbmac_driver = {
+	.probe = sbmac_probe,
+	.remove = __exit_p(sbmac_remove),
+	.driver = {
+		.name = sbmac_string,
+	},
+};
 
-		dev = alloc_etherdev(sizeof(struct sbmac_softc));
-		if (!dev)
-			return -ENOMEM;
+static int __init sbmac_init_module(void)
+{
+	int err;
 
-		printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);
+	err = platform_driver_register(&sbmac_driver);
+	if (err)
+		return err;
 
-		dev->irq = UNIT_INT(idx);
-		dev->base_addr = port;
-		dev->mem_end = 0;
-		if (sbmac_init(dev, idx)) {
-			port = A_MAC_CHANNEL_BASE(idx);
-			__raw_writeq(sbmac_orig_hwaddr[idx], IOADDR(port+R_MAC_ETHERNET_ADDR));
-			free_netdev(dev);
-			continue;
-		}
-		dev_sbmac[idx] = dev;
-	}
-	return 0;
-}
+	sbmac_platform_probe();
 
+	return err;
+}
 
-static void __exit
-sbmac_cleanup_module(void)
+static void __exit sbmac_cleanup_module(void)
 {
-	struct net_device *dev;
-	int idx;
-
-	for (idx = 0; idx < MAX_UNITS; idx++) {
-		struct sbmac_softc *sc;
-		dev = dev_sbmac[idx];
-		if (!dev)
-			continue;
-
-		sc = netdev_priv(dev);
-		unregister_netdev(dev);
-		sbmac_uninitctx(sc);
-		free_netdev(dev);
-	}
+	sbmac_platform_cleanup();
+	platform_driver_unregister(&sbmac_driver);
 }
 
 module_init(sbmac_init_module);
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index dd0fd45..1a57bdd 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -1351,8 +1351,6 @@ enum {
 	PHY_M_PC_EN_DET_PLUS	= 3<<8, /* Energy Detect Plus (Mode 2) */
 };
 
-#define PHY_M_PC_MDI_XMODE(x)	((((u16)(x)<<5) & PHY_M_PC_MDIX_MSK)
-
 enum {
 	PHY_M_PC_MAN_MDI	= 0, /* 00 = Manual MDI configuration */
 	PHY_M_PC_MAN_MDIX	= 1, /* 01 = Manual MDIX configuration */
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index a37637e..ff98f5d 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -466,7 +466,7 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
 #else
 	int bar = 1;
 #endif
-	int phy, phy_idx = 0;
+	int phy, phy_end, phy_idx = 0;
 	DECLARE_MAC_BUF(mac);
 
 /* when built into the kernel, we only print version if device is found */
@@ -552,11 +552,19 @@ static int __devinit sundance_probe1 (struct pci_dev *pdev,
 
 	np->phys[0] = 1;		/* Default setting */
 	np->mii_preamble_required++;
+
 	/*
 	 * It seems some phys doesn't deal well with address 0 being accessed
-	 * first, so leave address zero to the end of the loop (32 & 31).
+	 * first
 	 */
-	for (phy = 1; phy <= 32 && phy_idx < MII_CNT; phy++) {
+	if (sundance_pci_tbl[np->chip_id].device == 0x0200) {
+		phy = 0;
+		phy_end = 31;
+	} else {
+		phy = 1;
+		phy_end = 32;	/* wraps to zero, due to 'phy & 0x1f' */
+	}
+	for (; phy <= phy_end && phy_idx < MII_CNT; phy++) {
 		int phyx = phy & 0x1f;
 		int mii_status = mdio_read(dev, phyx, MII_BMSR);
 		if (mii_status != 0xffff  &&  mii_status != 0x0000) {
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index 88d03c0..7224d36 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -1045,11 +1045,6 @@ static irqreturn_t xl_interrupt(int irq, void *dev_id)
 	u8 __iomem * xl_mmio = xl_priv->xl_mmio ; 
 	u16 intstatus, macstatus  ;
 
-	if (!dev) { 
-		printk(KERN_WARNING "Device structure dead, aaahhhh !\n") ;
-		return IRQ_NONE; 
-	}
-
 	intstatus = readw(xl_mmio + MMIO_INTSTATUS) ;  
 
 	if (!(intstatus & 1)) /* We didn't generate the interrupt */
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
index 53c7523..76e5561 100644
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -664,11 +664,6 @@ static irqreturn_t uli526x_interrupt(int irq, void *dev_id)
 	unsigned long ioaddr = dev->base_addr;
 	unsigned long flags;
 
-	if (!dev) {
-		ULI526X_DBUG(1, "uli526x_interrupt() without DEVICE arg", 0);
-		return IRQ_NONE;
-	}
-
 	spin_lock_irqsave(&db->lock, flags);
 	outl(0, ioaddr + DCR7);
 
@@ -1604,7 +1599,6 @@ static void uli526x_process_mode(struct uli526x_board_info *db)
 			case ULI526X_100MFD: phy_reg = 0x2100; break;
 			}
 			phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id);
-       			phy_write(db->ioaddr, db->phy_addr, 0, phy_reg, db->chip_id);
 		}
 	}
 }
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 511a74c..4ae0579 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -72,6 +72,7 @@
 #include <linux/mii.h>
 #include <linux/in.h>
 #include <linux/if_arp.h>
+#include <linux/if_vlan.h>
 #include <linux/ip.h>
 #include <linux/tcp.h>
 #include <linux/udp.h>
@@ -84,6 +85,163 @@
 static int velocity_nics = 0;
 static int msglevel = MSG_LEVEL_INFO;
 
+/**
+ *	mac_get_cam_mask	-	Read a CAM mask
+ *	@regs: register block for this velocity
+ *	@mask: buffer to store mask
+ *
+ *	Fetch the mask bits of the selected CAM and store them into the
+ *	provided mask buffer.
+ */
+
+static void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
+{
+	int i;
+
+	/* Select CAM mask */
+	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+
+	writeb(0, &regs->CAMADDR);
+
+	/* read mask */
+	for (i = 0; i < 8; i++)
+		*mask++ = readb(&(regs->MARCAM[i]));
+
+	/* disable CAMEN */
+	writeb(0, &regs->CAMADDR);
+
+	/* Select mar */
+	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+
+}
+
+
+/**
+ *	mac_set_cam_mask	-	Set a CAM mask
+ *	@regs: register block for this velocity
+ *	@mask: CAM mask to load
+ *
+ *	Store a new mask into a CAM
+ */
+
+static void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
+{
+	int i;
+	/* Select CAM mask */
+	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+
+	writeb(CAMADDR_CAMEN, &regs->CAMADDR);
+
+	for (i = 0; i < 8; i++) {
+		writeb(*mask++, &(regs->MARCAM[i]));
+	}
+	/* disable CAMEN */
+	writeb(0, &regs->CAMADDR);
+
+	/* Select mar */
+	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+}
+
+static void mac_set_vlan_cam_mask(struct mac_regs __iomem * regs, u8 * mask)
+{
+	int i;
+	/* Select CAM mask */
+	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+
+	writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, &regs->CAMADDR);
+
+	for (i = 0; i < 8; i++) {
+		writeb(*mask++, &(regs->MARCAM[i]));
+	}
+	/* disable CAMEN */
+	writeb(0, &regs->CAMADDR);
+
+	/* Select mar */
+	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+}
+
+/**
+ *	mac_set_cam	-	set CAM data
+ *	@regs: register block of this velocity
+ *	@idx: Cam index
+ *	@addr: 2 or 6 bytes of CAM data
+ *
+ *	Load an address or vlan tag into a CAM
+ */
+
+static void mac_set_cam(struct mac_regs __iomem * regs, int idx, const u8 *addr)
+{
+	int i;
+
+	/* Select CAM mask */
+	BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+
+	idx &= (64 - 1);
+
+	writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);
+
+	for (i = 0; i < 6; i++) {
+		writeb(*addr++, &(regs->MARCAM[i]));
+	}
+	BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
+
+	udelay(10);
+
+	writeb(0, &regs->CAMADDR);
+
+	/* Select mar */
+	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+}
+
+static void mac_set_vlan_cam(struct mac_regs __iomem * regs, int idx,
+			     const u8 *addr)
+{
+
+	/* Select CAM mask */
+	BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+
+	idx &= (64 - 1);
+
+	writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, &regs->CAMADDR);
+	writew(*((u16 *) addr), &regs->MARCAM[0]);
+
+	BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
+
+	udelay(10);
+
+	writeb(0, &regs->CAMADDR);
+
+	/* Select mar */
+	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+}
+
+
+/**
+ *	mac_wol_reset	-	reset WOL after exiting low power
+ *	@regs: register block of this velocity
+ *
+ *	Called after we drop out of wake on lan mode in order to
+ *	reset the Wake on lan features. This function doesn't restore
+ *	the rest of the logic from the result of sleep/wakeup
+ */
+
+static void mac_wol_reset(struct mac_regs __iomem * regs)
+{
+
+	/* Turn off SWPTAG right after leaving power mode */
+	BYTE_REG_BITS_OFF(STICKHW_SWPTAG, &regs->STICKHW);
+	/* clear sticky bits */
+	BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);
+
+	BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, &regs->CHIPGCR);
+	BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
+	/* disable force PME-enable */
+	writeb(WOLCFG_PMEOVR, &regs->WOLCFGClr);
+	/* disable power-event config bit */
+	writew(0xFFFF, &regs->WOLCRClr);
+	/* clear power status */
+	writew(0xFFFF, &regs->WOLSRClr);
+}
 
 static int velocity_mii_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 static const struct ethtool_ops velocity_ethtool_ops;
@@ -111,15 +269,6 @@ VELOCITY_PARAM(RxDescriptors, "Number of receive descriptors");
 #define TX_DESC_DEF     64
 VELOCITY_PARAM(TxDescriptors, "Number of transmit descriptors");
 
-#define VLAN_ID_MIN     0
-#define VLAN_ID_MAX     4095
-#define VLAN_ID_DEF     0
-/* VID_setting[] is used for setting the VID of NIC.
-   0: default VID.
-   1-4094: other VIDs.
-*/
-VELOCITY_PARAM(VID_setting, "802.1Q VLAN ID");
-
 #define RX_THRESH_MIN   0
 #define RX_THRESH_MAX   3
 #define RX_THRESH_DEF   0
@@ -147,13 +296,6 @@ VELOCITY_PARAM(rx_thresh, "Receive fifo threshold");
 */
 VELOCITY_PARAM(DMA_length, "DMA length");
 
-#define TAGGING_DEF     0
-/* enable_tagging[] is used for enabling 802.1Q VID tagging.
-   0: disable VID seeting(default).
-   1: enable VID setting.
-*/
-VELOCITY_PARAM(enable_tagging, "Enable 802.1Q tagging");
-
 #define IP_ALIG_DEF     0
 /* IP_byte_align[] is used for IP header DWORD byte aligned
    0: indicate the IP header won't be DWORD byte aligned.(Default) .
@@ -324,7 +466,7 @@ MODULE_DEVICE_TABLE(pci, velocity_id_table);
  *	a pointer a static string valid while the driver is loaded.
  */
 
-static char __devinit *get_chip_name(enum chip_type chip_id)
+static const char __devinit *get_chip_name(enum chip_type chip_id)
 {
 	int i;
 	for (i = 0; chip_info_table[i].name != NULL; i++)
@@ -442,8 +584,7 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index,
 	velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname);
 	velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname);
 	velocity_set_int_opt(&opts->numtx, TxDescriptors[index], TX_DESC_MIN, TX_DESC_MAX, TX_DESC_DEF, "TxDescriptors", devname);
-	velocity_set_int_opt(&opts->vid, VID_setting[index], VLAN_ID_MIN, VLAN_ID_MAX, VLAN_ID_DEF, "VID_setting", devname);
-	velocity_set_bool_opt(&opts->flags, enable_tagging[index], TAGGING_DEF, VELOCITY_FLAGS_TAGGING, "enable_tagging", devname);
+
 	velocity_set_bool_opt(&opts->flags, txcsum_offload[index], TX_CSUM_DEF, VELOCITY_FLAGS_TX_CSUM, "txcsum_offload", devname);
 	velocity_set_int_opt(&opts->flow_cntl, flow_control[index], FLOW_CNTL_MIN, FLOW_CNTL_MAX, FLOW_CNTL_DEF, "flow_control", devname);
 	velocity_set_bool_opt(&opts->flags, IP_byte_align[index], IP_ALIG_DEF, VELOCITY_FLAGS_IP_ALIGN, "IP_byte_align", devname);
@@ -465,6 +606,7 @@ static void __devinit velocity_get_options(struct velocity_opt *opts, int index,
 static void velocity_init_cam_filter(struct velocity_info *vptr)
 {
 	struct mac_regs __iomem * regs = vptr->mac_regs;
+	unsigned short vid;
 
 	/* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
 	WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
@@ -473,27 +615,52 @@ static void velocity_init_cam_filter(struct velocity_info *vptr)
 	/* Disable all CAMs */
 	memset(vptr->vCAMmask, 0, sizeof(u8) * 8);
 	memset(vptr->mCAMmask, 0, sizeof(u8) * 8);
-	mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
-	mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
+	mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
+	mac_set_cam_mask(regs, vptr->mCAMmask);
 
 	/* Enable first VCAM */
-	if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
-		/* If Tagging option is enabled and VLAN ID is not zero, then
-		   turn on MCFG_RTGOPT also */
-		if (vptr->options.vid != 0)
-			WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
-
-		mac_set_cam(regs, 0, (u8 *) & (vptr->options.vid), VELOCITY_VLAN_ID_CAM);
+	if (vptr->vlgrp) {
+		for (vid = 0; vid < VLAN_VID_MASK; vid++) {
+			if (vlan_group_get_device(vptr->vlgrp, vid)) {
+				/* If Tagging option is enabled and
+				   VLAN ID is not zero, then
+				   turn on MCFG_RTGOPT also */
+				if (vid != 0)
+					WORD_REG_BITS_ON(MCFG_RTGOPT, &regs->MCFG);
+
+				mac_set_vlan_cam(regs, 0, (u8 *) &vid);
+			}
+		}
 		vptr->vCAMmask[0] |= 1;
-		mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM);
+		mac_set_vlan_cam_mask(regs, vptr->vCAMmask);
 	} else {
 		u16 temp = 0;
-		mac_set_cam(regs, 0, (u8 *) &temp, VELOCITY_VLAN_ID_CAM);
+		mac_set_vlan_cam(regs, 0, (u8 *) &temp);
 		temp = 1;
-		mac_set_cam_mask(regs, (u8 *) &temp, VELOCITY_VLAN_ID_CAM);
+		mac_set_vlan_cam_mask(regs, (u8 *) &temp);
 	}
 }
 
+static void velocity_vlan_rx_add_vid(struct net_device *dev, unsigned short vid)
+{
+	struct velocity_info *vptr = netdev_priv(dev);
+
+        spin_lock_irq(&vptr->lock);
+	velocity_init_cam_filter(vptr);
+        spin_unlock_irq(&vptr->lock);
+}
+
+static void velocity_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
+{
+	struct velocity_info *vptr = netdev_priv(dev);
+
+        spin_lock_irq(&vptr->lock);
+	vlan_group_set_device(vptr->vlgrp, vid, NULL);
+	velocity_init_cam_filter(vptr);
+        spin_unlock_irq(&vptr->lock);
+}
+
+
 /**
  *	velocity_rx_reset	-	handle a receive reset
  *	@vptr: velocity we are resetting
@@ -790,13 +957,17 @@ static int __devinit velocity_found1(struct pci_dev *pdev, const struct pci_devi
 	dev->do_ioctl = velocity_ioctl;
 	dev->ethtool_ops = &velocity_ethtool_ops;
 	dev->change_mtu = velocity_change_mtu;
+
+	dev->vlan_rx_add_vid = velocity_vlan_rx_add_vid;
+	dev->vlan_rx_kill_vid = velocity_vlan_rx_kill_vid;
+
 #ifdef  VELOCITY_ZERO_COPY_SUPPORT
 	dev->features |= NETIF_F_SG;
 #endif
+	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_FILTER;
 
-	if (vptr->flags & VELOCITY_FLAGS_TX_CSUM) {
+	if (vptr->flags & VELOCITY_FLAGS_TX_CSUM)
 		dev->features |= NETIF_F_IP_CSUM;
-	}
 
 	ret = register_netdev(dev);
 	if (ret < 0)
@@ -1989,8 +2160,8 @@ static int velocity_xmit(struct sk_buff *skb, struct net_device *dev)
 		td_ptr->tdesc1.CMDZ = 2;
 	}
 
-	if (vptr->flags & VELOCITY_FLAGS_TAGGING) {
-		td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff);
+	if (vptr->vlgrp && vlan_tx_tag_present(skb)) {
+		td_ptr->tdesc1.pqinf.VID = vlan_tx_tag_get(skb);
 		td_ptr->tdesc1.pqinf.priority = 0;
 		td_ptr->tdesc1.pqinf.CFI = 0;
 		td_ptr->tdesc1.TCR |= TCR0_VETAG;
@@ -2116,14 +2287,14 @@ static void velocity_set_multi(struct net_device *dev)
 		rx_mode = (RCR_AM | RCR_AB);
 	} else {
 		int offset = MCAM_SIZE - vptr->multicast_limit;
-		mac_get_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
+		mac_get_cam_mask(regs, vptr->mCAMmask);
 
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; i++, mclist = mclist->next) {
-			mac_set_cam(regs, i + offset, mclist->dmi_addr, VELOCITY_MULTICAST_CAM);
+			mac_set_cam(regs, i + offset, mclist->dmi_addr);
 			vptr->mCAMmask[(offset + i) / 8] |= 1 << ((offset + i) & 7);
 		}
 
-		mac_set_cam_mask(regs, vptr->mCAMmask, VELOCITY_MULTICAST_CAM);
+		mac_set_cam_mask(regs, vptr->mCAMmask);
 		rx_mode = (RCR_AM | RCR_AB);
 	}
 	if (dev->mtu > 1500)
diff --git a/drivers/net/via-velocity.h b/drivers/net/via-velocity.h
index b9e114d..aa91796 100644
--- a/drivers/net/via-velocity.h
+++ b/drivers/net/via-velocity.h
@@ -1173,7 +1173,7 @@ enum chip_type {
 
 struct velocity_info_tbl {
 	enum chip_type chip_id;
-	char *name;
+	const char *name;
 	int txqueue;
 	u32 flags;
 };
@@ -1194,14 +1194,6 @@ struct velocity_info_tbl {
 #define mac_disable_int(regs)       	writel(CR0_GINTMSK1,&((regs)->CR0Clr))
 #define mac_enable_int(regs)    	writel(CR0_GINTMSK1,&((regs)->CR0Set))
 
-#define mac_hw_mibs_read(regs, MIBs) {\
-	int i;\
-	BYTE_REG_BITS_ON(MIBCR_MPTRINI,&((regs)->MIBCR));\
-	for (i=0;i<HW_MIB_SIZE;i++) {\
-		(MIBs)[i]=readl(&((regs)->MIBData));\
-	}\
-}
-
 #define mac_set_dma_length(regs, n) {\
 	BYTE_REG_BITS_SET((n),0x07,&((regs)->DCFG));\
 }
@@ -1226,195 +1218,17 @@ struct velocity_info_tbl {
 	writew(TRDCSR_WAK<<(n*4),&((regs)->TDCSRSet));\
 }
 
-#define mac_eeprom_reload(regs) {\
-	int i=0;\
-	BYTE_REG_BITS_ON(EECSR_RELOAD,&((regs)->EECSR));\
-	do {\
-		udelay(10);\
-		if (i++>0x1000) {\
-			break;\
-		}\
-	}while (BYTE_REG_BITS_IS_ON(EECSR_RELOAD,&((regs)->EECSR)));\
-}
-
-enum velocity_cam_type {
-	VELOCITY_VLAN_ID_CAM = 0,
-	VELOCITY_MULTICAST_CAM
-};
-
-/**
- *	mac_get_cam_mask	-	Read a CAM mask
- *	@regs: register block for this velocity
- *	@mask: buffer to store mask
- *	@cam_type: CAM to fetch
- *
- *	Fetch the mask bits of the selected CAM and store them into the
- *	provided mask buffer.
- */
-
-static inline void mac_get_cam_mask(struct mac_regs __iomem * regs, u8 * mask, enum velocity_cam_type cam_type)
-{
-	int i;
-	/* Select CAM mask */
-	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-
-	if (cam_type == VELOCITY_VLAN_ID_CAM)
-		writeb(CAMADDR_VCAMSL, &regs->CAMADDR);
-	else
-		writeb(0, &regs->CAMADDR);
-
-	/* read mask */
-	for (i = 0; i < 8; i++)
-		*mask++ = readb(&(regs->MARCAM[i]));
-
-	/* disable CAMEN */
-	writeb(0, &regs->CAMADDR);
-
-	/* Select mar */
-	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
+static inline void mac_eeprom_reload(struct mac_regs __iomem * regs) {
+	int i=0;
 
+	BYTE_REG_BITS_ON(EECSR_RELOAD,&(regs->EECSR));
+	do {
+		udelay(10);
+		if (i++>0x1000)
+			break;
+	} while (BYTE_REG_BITS_IS_ON(EECSR_RELOAD,&(regs->EECSR)));
 }
 
-/**
- *	mac_set_cam_mask	-	Set a CAM mask
- *	@regs: register block for this velocity
- *	@mask: CAM mask to load
- *	@cam_type: CAM to store
- *
- *	Store a new mask into a CAM
- */
-
-static inline void mac_set_cam_mask(struct mac_regs __iomem * regs, u8 * mask, enum velocity_cam_type cam_type)
-{
-	int i;
-	/* Select CAM mask */
-	BYTE_REG_BITS_SET(CAMCR_PS_CAM_MASK, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-
-	if (cam_type == VELOCITY_VLAN_ID_CAM)
-		writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL, &regs->CAMADDR);
-	else
-		writeb(CAMADDR_CAMEN, &regs->CAMADDR);
-
-	for (i = 0; i < 8; i++) {
-		writeb(*mask++, &(regs->MARCAM[i]));
-	}
-	/* disable CAMEN */
-	writeb(0, &regs->CAMADDR);
-
-	/* Select mar */
-	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-}
-
-/**
- *	mac_set_cam	-	set CAM data
- *	@regs: register block of this velocity
- *	@idx: Cam index
- *	@addr: 2 or 6 bytes of CAM data
- *	@cam_type: CAM to load
- *
- *	Load an address or vlan tag into a CAM
- */
-
-static inline void mac_set_cam(struct mac_regs __iomem * regs, int idx, u8 *addr, enum velocity_cam_type cam_type)
-{
-	int i;
-
-	/* Select CAM mask */
-	BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-
-	idx &= (64 - 1);
-
-	if (cam_type == VELOCITY_VLAN_ID_CAM)
-		writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, &regs->CAMADDR);
-	else
-		writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);
-
-	if (cam_type == VELOCITY_VLAN_ID_CAM)
-		writew(*((u16 *) addr), &regs->MARCAM[0]);
-	else {
-		for (i = 0; i < 6; i++) {
-			writeb(*addr++, &(regs->MARCAM[i]));
-		}
-	}
-	BYTE_REG_BITS_ON(CAMCR_CAMWR, &regs->CAMCR);
-
-	udelay(10);
-
-	writeb(0, &regs->CAMADDR);
-
-	/* Select mar */
-	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-}
-
-/**
- *	mac_get_cam	-	fetch CAM data
- *	@regs: register block of this velocity
- *	@idx: Cam index
- *	@addr: buffer to hold up to 6 bytes of CAM data
- *	@cam_type: CAM to load
- *
- *	Load an address or vlan tag from a CAM into the buffer provided by
- *	the caller. VLAN tags are 2 bytes the address cam entries are 6.
- */
-
-static inline void mac_get_cam(struct mac_regs __iomem * regs, int idx, u8 *addr, enum velocity_cam_type cam_type)
-{
-	int i;
-
-	/* Select CAM mask */
-	BYTE_REG_BITS_SET(CAMCR_PS_CAM_DATA, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-
-	idx &= (64 - 1);
-
-	if (cam_type == VELOCITY_VLAN_ID_CAM)
-		writeb(CAMADDR_CAMEN | CAMADDR_VCAMSL | idx, &regs->CAMADDR);
-	else
-		writeb(CAMADDR_CAMEN | idx, &regs->CAMADDR);
-
-	BYTE_REG_BITS_ON(CAMCR_CAMRD, &regs->CAMCR);
-
-	udelay(10);
-
-	if (cam_type == VELOCITY_VLAN_ID_CAM)
-		*((u16 *) addr) = readw(&(regs->MARCAM[0]));
-	else
-		for (i = 0; i < 6; i++, addr++)
-			*((u8 *) addr) = readb(&(regs->MARCAM[i]));
-
-	writeb(0, &regs->CAMADDR);
-
-	/* Select mar */
-	BYTE_REG_BITS_SET(CAMCR_PS_MAR, CAMCR_PS1 | CAMCR_PS0, &regs->CAMCR);
-}
-
-/**
- *	mac_wol_reset	-	reset WOL after exiting low power
- *	@regs: register block of this velocity
- *
- *	Called after we drop out of wake on lan mode in order to
- *	reset the Wake on lan features. This function doesn't restore
- *	the rest of the logic from the result of sleep/wakeup
- */
-
-static inline void mac_wol_reset(struct mac_regs __iomem * regs)
-{
-
-	/* Turn off SWPTAG right after leaving power mode */
-	BYTE_REG_BITS_OFF(STICKHW_SWPTAG, &regs->STICKHW);
-	/* clear sticky bits */
-	BYTE_REG_BITS_OFF((STICKHW_DS1 | STICKHW_DS0), &regs->STICKHW);
-
-	BYTE_REG_BITS_OFF(CHIPGCR_FCGMII, &regs->CHIPGCR);
-	BYTE_REG_BITS_OFF(CHIPGCR_FCMODE, &regs->CHIPGCR);
-	/* disable force PME-enable */
-	writeb(WOLCFG_PMEOVR, &regs->WOLCFGClr);
-	/* disable power-event config bit */
-	writew(0xFFFF, &regs->WOLCRClr);
-	/* clear power status */
-	writew(0xFFFF, &regs->WOLSRClr);
-}
-
-
 /*
  * Header for WOL definitions. Used to compute hashes
  */
@@ -1701,7 +1515,7 @@ struct velocity_opt {
 	int numrx;			/* Number of RX descriptors */
 	int numtx;			/* Number of TX descriptors */
 	enum speed_opt spd_dpx;		/* Media link mode */
-	int vid;			/* vlan id */
+
 	int DMA_length;			/* DMA length */
 	int rx_thresh;			/* RX_THRESH */
 	int flow_cntl;
@@ -1727,6 +1541,7 @@ struct velocity_info {
 	dma_addr_t tx_bufs_dma;
 	u8 *tx_bufs;
 
+	struct vlan_group    *vlgrp;
 	u8 ip_addr[4];
 	enum chip_type chip_id;
 
diff --git a/include/linux/eeprom_93cx6.h b/include/linux/eeprom_93cx6.h
index d774b77..a55c873 100644
--- a/include/linux/eeprom_93cx6.h
+++ b/include/linux/eeprom_93cx6.h
@@ -21,13 +21,14 @@
 /*
 	Module: eeprom_93cx6
 	Abstract: EEPROM reader datastructures for 93cx6 chipsets.
-	Supported chipsets: 93c46 & 93c66.
+	Supported chipsets: 93c46, 93c56 and 93c66.
  */
 
 /*
  * EEPROM operation defines.
  */
 #define PCI_EEPROM_WIDTH_93C46	6
+#define PCI_EEPROM_WIDTH_93C56	8
 #define PCI_EEPROM_WIDTH_93C66	8
 #define PCI_EEPROM_WIDTH_OPCODE	3
 #define PCI_EEPROM_WRITE_OPCODE	0x05
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 2a65978..f0742b6 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -25,6 +25,8 @@
 #include <linux/timer.h>
 #include <linux/workqueue.h>
 
+#include <asm/atomic.h>
+
 #define PHY_BASIC_FEATURES	(SUPPORTED_10baseT_Half | \
 				 SUPPORTED_10baseT_Full | \
 				 SUPPORTED_100baseT_Half | \
@@ -281,6 +283,7 @@ struct phy_device {
 	/* Interrupt and Polling infrastructure */
 	struct work_struct phy_queue;
 	struct timer_list phy_timer;
+	atomic_t irq_disable;
 
 	spinlock_t lock;
 
diff --git a/include/linux/phy_fixed.h b/include/linux/phy_fixed.h
new file mode 100644
index 0000000..04ba70d
--- /dev/null
+++ b/include/linux/phy_fixed.h
@@ -0,0 +1,38 @@
+#ifndef __PHY_FIXED_H
+#define __PHY_FIXED_H
+
+#define MII_REGS_NUM	29
+
+/* max number of virtual phy stuff */
+#define MAX_PHY_AMNT	10
+/*
+    The idea is to emulate normal phy behavior by responding with
+    pre-defined values to mii BMCR read, so that read_status hook could
+    take all the needed info.
+*/
+
+struct fixed_phy_status {
+	u8 link;
+	u16 speed;
+	u8 duplex;
+};
+
+/*-----------------------------------------------------------------------------
+ *  Private information hoder for mii_bus
+ *-----------------------------------------------------------------------------*/
+struct fixed_info {
+	u16 *regs;
+	u8 regs_num;
+	struct fixed_phy_status phy_status;
+	struct phy_device *phydev;	/* pointer to the container */
+	/* link & speed cb */
+	int (*link_update) (struct net_device *, struct fixed_phy_status *);
+
+};
+
+
+int fixed_mdio_set_link_update(struct phy_device *,
+       int (*link_update) (struct net_device *, struct fixed_phy_status *));
+struct fixed_info *fixed_mdio_get_phydev (int phydev_ind);
+
+#endif /* __PHY_FIXED_H */
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
index ee786a0..51329da 100644
--- a/include/net/ax88796.h
+++ b/include/net/ax88796.h
@@ -14,6 +14,7 @@
 
 #define AXFLG_HAS_EEPROM		(1<<0)
 #define AXFLG_MAC_FROMDEV		(1<<1)	/* device already has MAC */
+#define AXFLG_HAS_93CX6			(1<<2)	/* use eeprom_93cx6 driver */
 
 struct ax_plat_data {
 	unsigned int	 flags;

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-09-20  7:26 Jeff Garzik
@ 2007-09-20 18:42 ` David Miller
  0 siblings, 0 replies; 101+ messages in thread
From: David Miller @ 2007-09-20 18:42 UTC (permalink / raw)
  To: jeff; +Cc: netdev, linux-kernel

From: Jeff Garzik <jeff@garzik.org>
Date: Thu, 20 Sep 2007 03:26:10 -0400

> Please pull from the 'upstream' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream
> 
> to receive the following changes:

Pulled into net-2.6.24 and pushed out, thanks Jeff!

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-09-20  7:26 Jeff Garzik
  2007-09-20 18:42 ` David Miller
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2007-09-20  7:26 UTC (permalink / raw)
  To: netdev; +Cc: LKML


[this, sans patch which was too big for netdev, was just sent upstream.
 the patch can be recreated via 'git diff net-2.6.24..upstream']



NOTE that sky2 will also be going upstream for 2.6.23-rc, as just posted
on netdev.

Please pull from the 'upstream' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream

to receive the following changes:

Al Viro (20):
      8139cp: trivial endianness annotations
      endianness annotations drivers/net/bonding/
      fix vlan in 8139cp on big-endian
      3c59x: trivial endianness annotations, NULL noise removal
      amd8111e: trivial endianness annotations, NULL noise removal
      amd8111e big-endian fix
      arcnet endianness annotations
      tulip: endianness annotations
      typhoon: trivial endianness annotations
      pcnet32: endianness
      ixgb: endianness
      drivers/net/irda: endianness, NULL noise
      starfire: trivial endianness annotations
      r8169: endianness
      via-rhine: endianness
      pppoe: endianness
      tms380tr: trivial endianness annotations
      drivers/net/appletalk: endianness
      3c509: endianness
      cxgb3: trivial endianness annotations

Alex Landau (1):
      Blackfin EMAC driver: add function to change the MAC address

Bryan Wu (3):
      Blackfin EMAC driver: add power management interface and change the bf537mac_reset to bf537mac_disable
      Blackfin EMAC driver: Add phy abstraction layer supporting in bfin_emac driver
      Blackfin EMAC driver: add a select for the PHYLIB of this driver

David Gibson (1):
      Device tree aware EMAC driver

Dhananjay Phadke (1):
      netxen: ethtool fixes

Jeff Garzik (1):
      [netdrvr] Stop using legacy hooks ->self_test_count, ->get_stats_count

Maciej W. Rozycki (3):
      sb1250-mac.c: Fix "stats" references
      NET_SB1250_MAC: Update Kconfig entry
      NET_SB1250_MAC: Rename to SB1250_MAC

Sivakumar Subramani (4):
      S2io: Change kmalloc+memset to k[zc]alloc
      S2io: Removed unused feature - bimodal interrupts
      S2io: Added support set_mac_address driver entry point
      S2io: Updating transceiver information in ethtool function

Stephen Hemminger (3):
      sky2: fix VLAN receive processing (resend)
      sky2: ethtool speed report bug
      sky2: version 1.18

Ursula Braun (1):
      s390 networking MAINTAINERS

Vitaly Bordug (2):
      FS_ENET: TX stuff should use fep->tx_lock, instead of fep->lock.
      FS_ENET: Add polling support

 Documentation/powerpc/booting-without-of.txt |  156 +
 MAINTAINERS                                  |   12 
 arch/mips/configs/bigsur_defconfig           |    2 
 arch/mips/configs/sb1250-swarm_defconfig     |    2 
 arch/powerpc/platforms/44x/Kconfig           |    3 
 arch/powerpc/platforms/cell/Kconfig          |    4 
 drivers/net/3c509.c                          |    4 
 drivers/net/3c59x.c                          |   39 
 drivers/net/8139cp.c                         |   59 
 drivers/net/8139too.c                        |   11 
 drivers/net/Kconfig                          |   89 
 drivers/net/Makefile                         |    3 
 drivers/net/amd8111e.c                       |    9 
 drivers/net/amd8111e.h                       |   24 
 drivers/net/appletalk/ipddp.c                |    2 
 drivers/net/appletalk/ipddp.h                |    2 
 drivers/net/arcnet/rfc1051.c                 |    4 
 drivers/net/arcnet/rfc1201.c                 |    6 
 drivers/net/atl1/atl1_ethtool.c              |   11 
 drivers/net/b44.c                            |   11 
 drivers/net/bfin_mac.c                       |  347 ++-
 drivers/net/bfin_mac.h                       |   53 
 drivers/net/bnx2.c                           |   20 
 drivers/net/bonding/bond_3ad.c               |   42 
 drivers/net/bonding/bond_3ad.h               |   20 
 drivers/net/bonding/bond_alb.c               |   19 
 drivers/net/bonding/bond_alb.h               |    4 
 drivers/net/bonding/bond_main.c              |   22 
 drivers/net/bonding/bond_sysfs.c             |    8 
 drivers/net/bonding/bonding.h                |    6 
 drivers/net/cassini.c                        |   11 
 drivers/net/chelsio/cxgb2.c                  |   11 
 drivers/net/cxgb3/common.h                   |    4 
 drivers/net/cxgb3/cxgb3_main.c               |   11 
 drivers/net/cxgb3/sge.c                      |    6 
 drivers/net/e100.c                           |   19 
 drivers/net/e1000/e1000_ethtool.c            |   22 
 drivers/net/e1000e/ethtool.c                 |   21 
 drivers/net/ehea/ehea_ethtool.c              |   13 
 drivers/net/forcedeth.c                      |   45 
 drivers/net/fs_enet/fs_enet-main.c           |   77 
 drivers/net/fs_enet/mac-fcc.c                |   12 
 drivers/net/fs_enet/mac-fec.c                |   30 
 drivers/net/fs_enet/mac-scc.c                |   20 
 drivers/net/fs_enet/mii-bitbang.c            |   10 
 drivers/net/gianfar_ethtool.c                |   20 
 drivers/net/ibm_emac/Kconfig                 |   70 
 drivers/net/ibm_emac/ibm_emac_core.c         |   12 
 drivers/net/ibm_newemac/Kconfig              |   63 
 drivers/net/ibm_newemac/Makefile             |   11 
 drivers/net/ibm_newemac/core.c               | 2907 +++++++++++++++++++++++++++
 drivers/net/ibm_newemac/core.h               |  355 +++
 drivers/net/ibm_newemac/debug.c              |  238 ++
 drivers/net/ibm_newemac/debug.h              |   78 
 drivers/net/ibm_newemac/emac.h               |  268 ++
 drivers/net/ibm_newemac/mal.c                |  728 ++++++
 drivers/net/ibm_newemac/mal.h                |  276 ++
 drivers/net/ibm_newemac/phy.c                |  373 +++
 drivers/net/ibm_newemac/phy.h                |   80 
 drivers/net/ibm_newemac/rgmii.c              |  323 +++
 drivers/net/ibm_newemac/rgmii.h              |   76 
 drivers/net/ibm_newemac/tah.c                |  173 +
 drivers/net/ibm_newemac/tah.h                |   90 
 drivers/net/ibm_newemac/zmii.c               |  322 ++
 drivers/net/ibm_newemac/zmii.h               |   73 
 drivers/net/ibmveth.c                        |   11 
 drivers/net/irda/mcs7780.c                   |    2 
 drivers/net/irda/sir_dev.c                   |    2 
 drivers/net/irda/stir4200.c                  |    2 
 drivers/net/irda/vlsi_ir.h                   |    6 
 drivers/net/ixgb/ixgb_ee.c                   |   16 
 drivers/net/ixgb/ixgb_ee.h                   |   28 
 drivers/net/ixgb/ixgb_ethtool.c              |   15 
 drivers/net/ixgb/ixgb_hw.h                   |    4 
 drivers/net/ixgbe/ixgbe_ethtool.c            |   11 
 drivers/net/mv643xx_eth.c                    |   12 
 drivers/net/myri10ge/myri10ge.c              |   11 
 drivers/net/netxen/netxen_nic.h              |    2 
 drivers/net/netxen/netxen_nic_ethtool.c      |   48 
 drivers/net/netxen/netxen_nic_init.c         |    7 
 drivers/net/netxen/netxen_nic_main.c         |    1 
 drivers/net/pcnet32.c                        |  109 -
 drivers/net/pppoe.c                          |   18 
 drivers/net/qla3xxx.c                        |    2 
 drivers/net/r8169.c                          |   37 
 drivers/net/s2io.c                           |  404 +--
 drivers/net/s2io.h                           |    3 
 drivers/net/sb1250-mac.c                     |    2 
 drivers/net/sc92031.c                        |   11 
 drivers/net/skge.c                           |   11 
 drivers/net/sky2.c                           |   34 
 drivers/net/sky2.h                           |    2 
 drivers/net/spider_net_ethtool.c             |   11 
 drivers/net/starfire.c                       |   88 
 drivers/net/tc35815.c                        |   12 
 drivers/net/tg3.c                            |   19 
 drivers/net/tokenring/tms380tr.c             |    4 
 drivers/net/tokenring/tms380tr.h             |   18 
 drivers/net/tulip/de2104x.c                  |   12 
 drivers/net/tulip/de4x5.c                    |   10 
 drivers/net/tulip/tulip.h                    |   16 
 drivers/net/tulip/tulip_core.c               |   10 
 drivers/net/tulip/uli526x.c                  |    6 
 drivers/net/tulip/winbond-840.c              |    2 
 drivers/net/typhoon.c                        |   36 
 drivers/net/typhoon.h                        |  190 -
 drivers/net/ucc_geth_ethtool.c               |   26 
 drivers/net/veth.c                           |   11 
 drivers/net/via-rhine.c                      |   16 
 drivers/net/wireless/libertas/ethtool.c      |   72 
 include/linux/arcdevice.h                    |    4 
 include/linux/if_arcnet.h                    |    2 
 include/linux/if_pppox.h                     |   12 
 113 files changed, 7993 insertions(+), 1237 deletions(-)


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-07-24 20:55 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2007-07-24 20:55 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML


Mostly fixes or a few minor cleanups.  I did permit ethtool support
addition to ucc_geth, since it's nice to be able to control your own
NICs using standard software.

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 drivers/net/82596.c                  |    1 +
 drivers/net/Makefile                 |    2 +-
 drivers/net/acenic.c                 |    6 -
 drivers/net/atl1/atl1_hw.h           |    9 +-
 drivers/net/atl1/atl1_main.c         |   28 ++-
 drivers/net/defxx.c                  |   17 +-
 drivers/net/ehea/ehea.h              |    2 +-
 drivers/net/ehea/ehea_main.c         |   22 ++-
 drivers/net/forcedeth.c              |   16 ++
 drivers/net/netxen/netxen_nic.h      |    3 +-
 drivers/net/netxen/netxen_nic_main.c |   48 ++--
 drivers/net/phy/vitesse.c            |    2 +-
 drivers/net/ps3_gelic_net.c          |  215 +++++++++++--------
 drivers/net/ps3_gelic_net.h          |   24 +--
 drivers/net/ucc_geth.c               |  334 +++++++++++++++++------------
 drivers/net/ucc_geth.h               |    6 +
 drivers/net/ucc_geth_ethtool.c       |  388 ++++++++++++++++++++++++++++++++++
 drivers/net/ucc_geth_mii.c           |    6 +-
 include/linux/pci_ids.h              |    4 +
 19 files changed, 824 insertions(+), 309 deletions(-)
 create mode 100644 drivers/net/ucc_geth_ethtool.c

Adrian Bunk (1):
      drivers/net/acenic.c: fix check-after-use

Andy Fleming (1):
      Fix error checking in Vitesse IRQ config

Ayaz Abdulla (2):
      forcedeth: new device ids in pci_ids.h
      forcedeth: mcp73 device addition

Chris Snook (1):
      atl1: make atl1_init_ring_ptrs static

Geert Uytterhoeven (1):
      netdev: i82596 Ethernet needs <asm/cacheflush.h>

Jan-Bernd Themann (1):
      eHEA: net_poll support

Jay Cliburn (5):
      atl1: change tpd_avail function name
      atl1: fix typo in DMA engine setup
      atl1: change cmb write threshold
      atl1: fix typo in dma_req_block
      atl1: use kernel provided ethernet length constants

Li Yang (2):
      ucc_geth: add ethtool support
      ucc_geth: add support to netif message level

Maciej W. Rozycki (1):
      defxx: Use __maybe_unused rather than a local hack

Masakazu Mokuno (10):
      ps3: fix wrong calculation of rx descriptor address
      ps3: some minor cleanups
      ps3: tx descriptor handling cleanup
      ps3: removed defines no longer used
      ps3: removed conditional ethtool support
      ps3: use net_device_stats of net_device structure
      ps3: use ethX as the name of irq
      ps3: removed calling netif_poll_enable() in open()
      ps3: fix rare issue that reenabling rx DMA fails
      ps3: reduce allocation size of rx skb buffers

dhananjay@netxen.com (1):
      netxen: Load firmware during probe, dma watchdog fix.

diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index 3ff1155..d915837 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -57,6 +57,7 @@
 #include <asm/io.h>
 #include <asm/dma.h>
 #include <asm/pgtable.h>
+#include <asm/cacheflush.h>
 
 static char version[] __initdata =
 	"82596.c $Revision: 1.5 $\n";
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 336af06..94b78cc 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -18,7 +18,7 @@ gianfar_driver-objs := gianfar.o \
 		gianfar_sysfs.o
 
 obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
-ucc_geth_driver-objs := ucc_geth.o ucc_geth_mii.o
+ucc_geth_driver-objs := ucc_geth.o ucc_geth_mii.o ucc_geth_ethtool.o
 
 #
 # link order important here
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index b78a4e5..62e660a 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -3128,12 +3128,6 @@ static int __devinit read_eeprom_byte(struct net_device *dev,
 	int result = 0;
 	short i;
 
-	if (!dev) {
-		printk(KERN_ERR "No device!\n");
-		result = -ENODEV;
-		goto out;
-	}
-
 	/*
 	 * Don't take interrupts on this CPU will bit banging
 	 * the %#%#@$ I2C device
diff --git a/drivers/net/atl1/atl1_hw.h b/drivers/net/atl1/atl1_hw.h
index 100c09c..939aa0f 100644
--- a/drivers/net/atl1/atl1_hw.h
+++ b/drivers/net/atl1/atl1_hw.h
@@ -680,11 +680,6 @@ void atl1_check_options(struct atl1_adapter *adapter);
 #define AUTONEG_ADVERTISE_10_100_ALL	0x000F	/* All 10/100 speeds */
 #define AUTONEG_ADVERTISE_10_ALL	0x0003	/* 10Mbps Full & Half speeds */
 
-/* The size (in bytes) of a ethernet packet */
-#define ENET_HEADER_SIZE		14
-#define MAXIMUM_ETHERNET_FRAME_SIZE	1518	/* with FCS */
-#define MINIMUM_ETHERNET_FRAME_SIZE	64	/* with FCS */
-#define ETHERNET_FCS_SIZE		4
 #define MAX_JUMBO_FRAME_SIZE		0x2800
 
 #define PHY_AUTO_NEG_TIME	45	/* 4.5 Seconds */
@@ -929,8 +924,8 @@ enum atl1_dma_req_block {
 	atl1_dma_req_128 = 0,
 	atl1_dma_req_256 = 1,
 	atl1_dma_req_512 = 2,
-	atl1_dam_req_1024 = 3,
-	atl1_dam_req_2048 = 4,
+	atl1_dma_req_1024 = 3,
+	atl1_dma_req_2048 = 4,
 	atl1_dma_req_4096 = 5
 };
 
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index fd1e156..56f6389 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -59,6 +59,7 @@
 #include <linux/skbuff.h>
 #include <linux/etherdevice.h>
 #include <linux/if_vlan.h>
+#include <linux/if_ether.h>
 #include <linux/irqreturn.h>
 #include <linux/workqueue.h>
 #include <linux/timer.h>
@@ -120,8 +121,8 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
 	struct atl1_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
 
-	hw->max_frame_size = netdev->mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
-	hw->min_frame_size = MINIMUM_ETHERNET_FRAME_SIZE;
+	hw->max_frame_size = netdev->mtu + ETH_HLEN + ETH_FCS_LEN;
+	hw->min_frame_size = ETH_ZLEN + ETH_FCS_LEN;
 
 	adapter->wol = 0;
 	adapter->rx_buffer_len = (hw->max_frame_size + 7) & ~7;
@@ -314,7 +315,7 @@ err_nomem:
 	return -ENOMEM;
 }
 
-void atl1_init_ring_ptrs(struct atl1_adapter *adapter)
+static void atl1_init_ring_ptrs(struct atl1_adapter *adapter)
 {
 	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
 	struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
@@ -688,9 +689,9 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
 {
 	struct atl1_adapter *adapter = netdev_priv(netdev);
 	int old_mtu = netdev->mtu;
-	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
+	int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
 
-	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
+	if ((max_frame < ETH_ZLEN + ETH_FCS_LEN) ||
 	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
 		dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
 		return -EINVAL;
@@ -908,8 +909,8 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
 	/* config DMA Engine */
 	value = ((((u32) hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
 		<< DMA_CTRL_DMAR_BURST_LEN_SHIFT) |
-		((((u32) hw->dmaw_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
-		<< DMA_CTRL_DMAR_BURST_LEN_SHIFT) | DMA_CTRL_DMAR_EN |
+		((((u32) hw->dmaw_block) & DMA_CTRL_DMAW_BURST_LEN_MASK)
+		<< DMA_CTRL_DMAW_BURST_LEN_SHIFT) | DMA_CTRL_DMAR_EN |
 		DMA_CTRL_DMAW_EN;
 	value |= (u32) hw->dma_ord;
 	if (atl1_rcb_128 == hw->rcb_value)
@@ -917,7 +918,10 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
 	iowrite32(value, hw->hw_addr + REG_DMA_CTRL);
 
 	/* config CMB / SMB */
-	value = hw->cmb_rrd | ((u32) hw->cmb_tpd << 16);
+	value = (hw->cmb_tpd > adapter->tpd_ring.count) ?
+		hw->cmb_tpd : adapter->tpd_ring.count;
+	value <<= 16;
+	value |= hw->cmb_rrd;
 	iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TH);
 	value = hw->cmb_rx_timer | ((u32) hw->cmb_tx_timer << 16);
 	iowrite32(value, hw->hw_addr + REG_CMB_WRITE_TIMER);
@@ -1334,7 +1338,7 @@ rrd_ok:
 		skb = buffer_info->skb;
 		length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size);
 
-		skb_put(skb, length - ETHERNET_FCS_SIZE);
+		skb_put(skb, length - ETH_FCS_LEN);
 
 		/* Receive Checksum Offload */
 		atl1_rx_checksum(adapter, rrd, skb);
@@ -1422,7 +1426,7 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
 		netif_wake_queue(adapter->netdev);
 }
 
-static u16 tpd_avail(struct atl1_tpd_ring *tpd_ring)
+static u16 atl1_tpd_avail(struct atl1_tpd_ring *tpd_ring)
 {
 	u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
 	u16 next_to_use = atomic_read(&tpd_ring->next_to_use);
@@ -1453,7 +1457,7 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
 			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
 				iph->daddr, 0, IPPROTO_TCP, 0);
 			ipofst = skb_network_offset(skb);
-			if (ipofst != ENET_HEADER_SIZE) /* 802.3 frame */
+			if (ipofst != ETH_HLEN) /* 802.3 frame */
 				tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT;
 
 			tso->tsopl |= (iph->ihl &
@@ -1708,7 +1712,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		return NETDEV_TX_LOCKED;
 	}
 
-	if (tpd_avail(&adapter->tpd_ring) < count) {
+	if (atl1_tpd_avail(&adapter->tpd_ring) < count) {
 		/* not enough descriptors */
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&adapter->lock, flags);
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index 7df23dc..9c8e3f9 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -200,6 +200,7 @@
 
 /* Include files */
 #include <linux/bitops.h>
+#include <linux/compiler.h>
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
 #include <linux/eisa.h>
@@ -240,8 +241,6 @@ static char version[] __devinitdata =
  */
 #define NEW_SKB_SIZE (PI_RCV_DATA_K_SIZE_MAX+128)
 
-#define __unused __attribute__ ((unused))
-
 #ifdef CONFIG_PCI
 #define DFX_BUS_PCI(dev) (dev->bus == &pci_bus_type)
 #else
@@ -375,7 +374,7 @@ static inline void dfx_outl(DFX_board_t *bp, int offset, u32 data)
 
 static void dfx_port_write_long(DFX_board_t *bp, int offset, u32 data)
 {
-	struct device __unused *bdev = bp->bus_dev;
+	struct device __maybe_unused *bdev = bp->bus_dev;
 	int dfx_bus_tc = DFX_BUS_TC(bdev);
 	int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
 
@@ -399,7 +398,7 @@ static inline void dfx_inl(DFX_board_t *bp, int offset, u32 *data)
 
 static void dfx_port_read_long(DFX_board_t *bp, int offset, u32 *data)
 {
-	struct device __unused *bdev = bp->bus_dev;
+	struct device __maybe_unused *bdev = bp->bus_dev;
 	int dfx_bus_tc = DFX_BUS_TC(bdev);
 	int dfx_use_mmio = DFX_MMIO || dfx_bus_tc;
 
@@ -866,7 +865,7 @@ static void __devinit dfx_bus_uninit(struct net_device *dev)
 
 static void __devinit dfx_bus_config_check(DFX_board_t *bp)
 {
-	struct device __unused *bdev = bp->bus_dev;
+	struct device __maybe_unused *bdev = bp->bus_dev;
 	int dfx_bus_eisa = DFX_BUS_EISA(bdev);
 	int	status;				/* return code from adapter port control call */
 	u32	host_data;			/* LW data returned from port control call */
@@ -3624,8 +3623,8 @@ static void __devexit dfx_unregister(struct device *bdev)
 }
 
 
-static int __devinit __unused dfx_dev_register(struct device *);
-static int __devexit __unused dfx_dev_unregister(struct device *);
+static int __devinit __maybe_unused dfx_dev_register(struct device *);
+static int __devexit __maybe_unused dfx_dev_unregister(struct device *);
 
 #ifdef CONFIG_PCI
 static int __devinit dfx_pci_register(struct pci_dev *,
@@ -3699,7 +3698,7 @@ static struct tc_driver dfx_tc_driver = {
 };
 #endif /* CONFIG_TC */
 
-static int __devinit __unused dfx_dev_register(struct device *dev)
+static int __devinit __maybe_unused dfx_dev_register(struct device *dev)
 {
 	int status;
 
@@ -3709,7 +3708,7 @@ static int __devinit __unused dfx_dev_register(struct device *dev)
 	return status;
 }
 
-static int __devexit __unused dfx_dev_unregister(struct device *dev)
+static int __devexit __maybe_unused dfx_dev_unregister(struct device *dev)
 {
 	put_device(dev);
 	dfx_unregister(dev);
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 489c8b2..8ee2c2c 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0071"
+#define DRV_VERSION	"EHEA_0072"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 4c70a93..58702f5 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -589,6 +589,23 @@ static int ehea_poll(struct net_device *dev, int *budget)
 	return 1;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void ehea_netpoll(struct net_device *dev)
+{
+	struct ehea_port *port = netdev_priv(dev);
+
+	netif_rx_schedule(port->port_res[0].d_netdev);
+}
+#endif
+
+static int ehea_poll_firstqueue(struct net_device *dev, int *budget)
+{
+	struct ehea_port *port = netdev_priv(dev);
+	struct net_device *d_dev = port->port_res[0].d_netdev;
+
+	return ehea_poll(d_dev, budget);
+}
+
 static irqreturn_t ehea_recv_irq_handler(int irq, void *param)
 {
 	struct ehea_port_res *pr = param;
@@ -2626,7 +2643,10 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 	memcpy(dev->dev_addr, &port->mac_addr, ETH_ALEN);
 
 	dev->open = ehea_open;
-	dev->poll = ehea_poll;
+	dev->poll = ehea_poll_firstqueue;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = ehea_netpoll;
+#endif
 	dev->weight = 64;
 	dev->stop = ehea_stop;
 	dev->hard_start_xmit = ehea_start_xmit;
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 6d1d50a..661c747 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -5546,6 +5546,22 @@ static struct pci_device_id pci_tbl[] = {
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_27),
 		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
 	},
+	{	/* MCP73 Ethernet Controller */
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_28),
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+	},
+	{	/* MCP73 Ethernet Controller */
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_29),
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+	},
+	{	/* MCP73 Ethernet Controller */
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_30),
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+	},
+	{	/* MCP73 Ethernet Controller */
+		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+	},
 	{0,},
 };
 
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 325269d..d4c92cc 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1179,8 +1179,7 @@ dma_watchdog_shutdown_poll_result(struct netxen_adapter *adapter)
 	    NETXEN_CAM_RAM(NETXEN_CAM_RAM_DMA_WATCHDOG_CTRL), &ctrl, 4))
 		printk(KERN_ERR "failed to read dma watchdog status\n");
 
-	return ((netxen_get_dma_watchdog_enabled(ctrl) == 0) &&
-		(netxen_get_dma_watchdog_disabled(ctrl) == 0));
+	return (netxen_get_dma_watchdog_enabled(ctrl) == 0);
 }
 
 static inline int
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index b703ccf..19e2fa9 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -46,7 +46,7 @@ MODULE_DESCRIPTION("NetXen Multi port (1/10) Gigabit Network Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(NETXEN_NIC_LINUX_VERSIONID);
 
-char netxen_nic_driver_name[] = "netxen-nic";
+char netxen_nic_driver_name[] = "netxen_nic";
 static char netxen_nic_driver_string[] = "NetXen Network Driver version "
     NETXEN_NIC_LINUX_VERSIONID;
 
@@ -640,6 +640,10 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 			NETXEN_CRB_NORMALIZE(adapter,
 				NETXEN_ROMUSB_GLB_PEGTUNE_DONE));
 		/* Handshake with the card before we register the devices. */
+		writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
+		netxen_pinit_from_rom(adapter, 0);
+		msleep(1);
+		netxen_load_firmware(adapter);
 		netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
 	}
 
@@ -782,19 +786,18 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
 	if (adapter->portnum == 0) {
 		if (init_firmware_done) {
-			dma_watchdog_shutdown_request(adapter);
-			msleep(100);
 			i = 100;
-			while ((dma_watchdog_shutdown_poll_result(adapter) != 1) && i) {
-				printk(KERN_INFO "dma_watchdog_shutdown_poll still in progress\n");
+			do {
+				if (dma_watchdog_shutdown_request(adapter) == 1)
+					break;
 				msleep(100);
-				i--;
-			}
+				if (dma_watchdog_shutdown_poll_result(adapter) == 1)
+					break;
+			} while (--i);
 
-			if (i == 0) {
-				printk(KERN_ERR "dma_watchdog_shutdown_request failed\n");
-				return;
-			}
+			if (i == 0)
+				printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
+						netdev->name);
 
 			/* clear the register for future unloads/loads */
 			writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_CAM_RAM(0x1fc)));
@@ -803,11 +806,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 
 			/* leave the hw in the same state as reboot */
 			writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
-			if (netxen_pinit_from_rom(adapter, 0))
-				return;
+			netxen_pinit_from_rom(adapter, 0);
 			msleep(1);
-			if (netxen_load_firmware(adapter))
-				return;
+			netxen_load_firmware(adapter);
 			netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
 		}
 
@@ -816,22 +817,21 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
 		printk(KERN_INFO "State: 0x%0x\n",
 			readl(NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE)));
 
-		dma_watchdog_shutdown_request(adapter);
-		msleep(100);
 		i = 100;
-		while ((dma_watchdog_shutdown_poll_result(adapter) != 1) && i) {
-			printk(KERN_INFO "dma_watchdog_shutdown_poll still in progress\n");
+		do {
+			if (dma_watchdog_shutdown_request(adapter) == 1)
+				break;
 			msleep(100);
-			i--;
-		}
+			if (dma_watchdog_shutdown_poll_result(adapter) == 1)
+				break;
+		} while (--i);
 
 		if (i) {
 			netxen_free_adapter_offload(adapter);
 		} else {
-			printk(KERN_ERR "failed to dma shutdown\n");
-			return;
+			printk(KERN_ERR "%s: dma_watchdog_shutdown failed\n",
+					netdev->name);
 		}
-
 	}
 
 	iounmap(adapter->ahw.db_base);
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 6a53856..8874497 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -109,7 +109,7 @@ static int vsc824x_config_intr(struct phy_device *phydev)
 		 */
 		err = phy_read(phydev, MII_VSC8244_ISTAT);
 
-		if (err)
+		if (err < 0)
 			return err;
 
 		err = phy_write(phydev, MII_VSC8244_IMASK, 0);
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 08d2506..13d1c0a 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -290,7 +290,8 @@ static void gelic_net_release_rx_chain(struct gelic_net_card *card)
 			descr->buf_addr = 0;
 			dev_kfree_skb_any(descr->skb);
 			descr->skb = NULL;
-			descr->dmac_cmd_status = GELIC_NET_DESCR_NOT_IN_USE;
+			gelic_net_set_descr_status(descr,
+						   GELIC_NET_DESCR_NOT_IN_USE);
 		}
 		descr = descr->next;
 	} while (descr != card->rx_chain.head);
@@ -374,7 +375,7 @@ static void gelic_net_release_tx_descr(struct gelic_net_card *card,
 	descr->skb = NULL;
 
 	/* set descr status */
-	descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE;
+	gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
 }
 
 /**
@@ -403,26 +404,29 @@ static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
 					 "%s: forcing end of tx descriptor " \
 					 "with status %x\n",
 					 __func__, status);
-			card->netdev_stats.tx_dropped++;
+			card->netdev->stats.tx_dropped++;
 			break;
 
 		case GELIC_NET_DESCR_COMPLETE:
-			card->netdev_stats.tx_packets++;
-			card->netdev_stats.tx_bytes +=
-				tx_chain->tail->skb->len;
+			if (tx_chain->tail->skb) {
+				card->netdev->stats.tx_packets++;
+				card->netdev->stats.tx_bytes +=
+					tx_chain->tail->skb->len;
+			}
 			break;
 
 		case GELIC_NET_DESCR_CARDOWNED:
 			/* pending tx request */
 		default:
 			/* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
-			goto out;
+			if (!stop)
+				goto out;
 		}
 		gelic_net_release_tx_descr(card, tx_chain->tail);
-		release = 1;
+		release ++;
 	}
 out:
-	if (!stop && release)
+	if (!stop && (2 < release))
 		netif_wake_queue(card->netdev);
 }
 
@@ -659,19 +663,21 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
 {
 	dma_addr_t buf[2];
 	unsigned int vlan_len;
+	struct gelic_net_descr *sec_descr = descr->next;
 
 	if (skb->len < GELIC_NET_VLAN_POS)
 		return -EINVAL;
 
-	memcpy(&descr->vlan, skb->data, GELIC_NET_VLAN_POS);
+	vlan_len = GELIC_NET_VLAN_POS;
+	memcpy(&descr->vlan, skb->data, vlan_len);
 	if (card->vlan_index != -1) {
+		/* internal vlan tag used */
 		descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/
 		descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]);
-		vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */
-	} else
-		vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */
+		vlan_len += VLAN_HLEN; /* added for above two lines */
+	}
 
-	/* first descr */
+	/* map data area */
 	buf[0] = dma_map_single(ctodev(card), &descr->vlan,
 			     vlan_len, DMA_TO_DEVICE);
 
@@ -682,20 +688,6 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
 		return -ENOMEM;
 	}
 
-	descr->buf_addr = buf[0];
-	descr->buf_size = vlan_len;
-	descr->skb = skb; /* not used */
-	descr->data_status = 0;
-	gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */
-
-	/* second descr */
-	card->tx_chain.head = card->tx_chain.head->next;
-	descr->next_descr_addr = descr->next->bus_addr;
-	descr = descr->next;
-	if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE)
-		/* XXX will be removed */
-		dev_err(ctodev(card), "descr is not free!\n");
-
 	buf[1] = dma_map_single(ctodev(card), skb->data + GELIC_NET_VLAN_POS,
 			     skb->len - GELIC_NET_VLAN_POS,
 			     DMA_TO_DEVICE);
@@ -710,13 +702,24 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
 		return -ENOMEM;
 	}
 
-	descr->buf_addr = buf[1];
-	descr->buf_size = skb->len - GELIC_NET_VLAN_POS;
-	descr->skb = skb;
+	/* first descr */
+	descr->buf_addr = buf[0];
+	descr->buf_size = vlan_len;
+	descr->skb = NULL; /* not used */
 	descr->data_status = 0;
-	descr->next_descr_addr = 0; /* terminate hw descr */
-	gelic_net_set_txdescr_cmdstat(descr, skb, 0);
+	descr->next_descr_addr = descr->next->bus_addr;
+	gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */
 
+	/* second descr */
+	sec_descr->buf_addr = buf[1];
+	sec_descr->buf_size = skb->len - GELIC_NET_VLAN_POS;
+	sec_descr->skb = skb;
+	sec_descr->data_status = 0;
+	sec_descr->next_descr_addr = 0; /* terminate hw descr */
+	gelic_net_set_txdescr_cmdstat(sec_descr, skb, 0);
+
+	/* bump free descriptor pointer */
+	card->tx_chain.head = sec_descr->next;
 	return 0;
 }
 
@@ -729,7 +732,7 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
 static int gelic_net_kick_txdma(struct gelic_net_card *card,
 				struct gelic_net_descr *descr)
 {
-	int status = -ENXIO;
+	int status = 0;
 	int count = 10;
 
 	if (card->tx_dma_progress)
@@ -763,47 +766,62 @@ static int gelic_net_kick_txdma(struct gelic_net_card *card,
 static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct gelic_net_card *card = netdev_priv(netdev);
-	struct gelic_net_descr *descr = NULL;
+	struct gelic_net_descr *descr;
 	int result;
 	unsigned long flags;
 
 	spin_lock_irqsave(&card->tx_dma_lock, flags);
 
 	gelic_net_release_tx_chain(card, 0);
-	if (!skb)
-		goto kick;
+
 	descr = gelic_net_get_next_tx_descr(card);
 	if (!descr) {
+		/*
+		 * no more descriptors free
+		 */
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&card->tx_dma_lock, flags);
 		return NETDEV_TX_BUSY;
 	}
-	result = gelic_net_prepare_tx_descr_v(card, descr, skb);
-
-	if (result)
-		goto error;
 
-	card->tx_chain.head = card->tx_chain.head->next;
-
-	if (descr->prev)
-		descr->prev->next_descr_addr = descr->bus_addr;
-kick:
+	result = gelic_net_prepare_tx_descr_v(card, descr, skb);
+	if (result) {
+		/*
+		 * DMA map failed.  As chanses are that failure
+		 * would continue, just release skb and return
+		 */
+		card->netdev->stats.tx_dropped++;
+		dev_kfree_skb_any(skb);
+		spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+		return NETDEV_TX_OK;
+	}
+	/*
+	 * link this prepared descriptor to previous one
+	 * to achieve high performance
+	 */
+	descr->prev->next_descr_addr = descr->bus_addr;
 	/*
 	 * as hardware descriptor is modified in the above lines,
 	 * ensure that the hardware sees it
 	 */
 	wmb();
-	if (gelic_net_kick_txdma(card, card->tx_chain.tail))
-		goto error;
+	if (gelic_net_kick_txdma(card, descr)) {
+		/*
+		 * kick failed.
+		 * release descriptors which were just prepared
+		 */
+		card->netdev->stats.tx_dropped++;
+		gelic_net_release_tx_descr(card, descr);
+		gelic_net_release_tx_descr(card, descr->next);
+		card->tx_chain.tail = descr->next->next;
+		dev_info(ctodev(card), "%s: kick failure\n", __func__);
+	} else {
+		/* OK, DMA started/reserved */
+		netdev->trans_start = jiffies;
+	}
 
-	netdev->trans_start = jiffies;
 	spin_unlock_irqrestore(&card->tx_dma_lock, flags);
 	return NETDEV_TX_OK;
-
-error:
-	card->netdev_stats.tx_dropped++;
-	spin_unlock_irqrestore(&card->tx_dma_lock, flags);
-	return NETDEV_TX_LOCKED;
 }
 
 /**
@@ -854,8 +872,8 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
 		skb->ip_summed = CHECKSUM_NONE;
 
 	/* update netdevice statistics */
-	card->netdev_stats.rx_packets++;
-	card->netdev_stats.rx_bytes += skb->len;
+	card->netdev->stats.rx_packets++;
+	card->netdev->stats.rx_bytes += skb->len;
 
 	/* pass skb up to stack */
 	netif_receive_skb(skb);
@@ -895,38 +913,67 @@ static int gelic_net_decode_one_descr(struct gelic_net_card *card)
 	    (status == GELIC_NET_DESCR_FORCE_END)) {
 		dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
 			 status);
-		card->netdev_stats.rx_dropped++;
+		card->netdev->stats.rx_dropped++;
 		goto refill;
 	}
 
-	if ((status != GELIC_NET_DESCR_COMPLETE) &&
-	    (status != GELIC_NET_DESCR_FRAME_END)) {
+	if (status == GELIC_NET_DESCR_BUFFER_FULL) {
+		/*
+		 * Buffer full would occur if and only if
+		 * the frame length was longer than the size of this
+		 * descriptor's buffer.  If the frame length was equal
+		 * to or shorter than buffer'size, FRAME_END condition
+		 * would occur.
+		 * Anyway this frame was longer than the MTU,
+		 * just drop it.
+		 */
+		dev_info(ctodev(card), "overlength frame\n");
+		goto refill;
+	}
+	/*
+	 * descriptoers any other than FRAME_END here should
+	 * be treated as error.
+	 */
+	if (status != GELIC_NET_DESCR_FRAME_END) {
 		dev_dbg(ctodev(card), "RX descriptor with state %x\n",
 			status);
 		goto refill;
 	}
 
 	/* ok, we've got a packet in descr */
-	gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */
-
+	gelic_net_pass_skb_up(descr, card);
 refill:
-	descr->next_descr_addr = 0; /* unlink the descr */
+	/*
+	 * So that always DMAC can see the end
+	 * of the descriptor chain to avoid
+	 * from unwanted DMAC overrun.
+	 */
+	descr->next_descr_addr = 0;
 
 	/* change the descriptor state: */
 	gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
 
-	/* refill one desc
-	 * FIXME: this can fail, but for now, just leave this
-	 * descriptor without skb
+	/*
+	 * this call can fail, but for now, just leave this
+	 * decriptor without skb
 	 */
 	gelic_net_prepare_rx_descr(card, descr);
+
 	chain->head = descr;
 	chain->tail = descr->next;
+
+	/*
+	 * Set this descriptor the end of the chain.
+	 */
 	descr->prev->next_descr_addr = descr->bus_addr;
 
+	/*
+	 * If dmac chain was met, DMAC stopped.
+	 * thus re-enable it
+	 */
 	if (dmac_chain_ended) {
-		gelic_net_enable_rxdmac(card);
-		dev_dbg(ctodev(card), "reenable rx dma\n");
+		card->rx_dma_restart_required = 1;
+		dev_dbg(ctodev(card), "reenable rx dma scheduled\n");
 	}
 
 	return 1;
@@ -968,20 +1015,6 @@ static int gelic_net_poll(struct net_device *netdev, int *budget)
 	} else
 		return 1;
 }
-
-/**
- * gelic_net_get_stats - get interface statistics
- * @netdev: interface device structure
- *
- * returns the interface statistics residing in the gelic_net_card struct
- */
-static struct net_device_stats *gelic_net_get_stats(struct net_device *netdev)
-{
-	struct gelic_net_card *card = netdev_priv(netdev);
-
-	return &card->netdev_stats;
-}
-
 /**
  * gelic_net_change_mtu - changes the MTU of an interface
  * @netdev: interface device structure
@@ -1016,6 +1049,11 @@ static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
 	if (!status)
 		return IRQ_NONE;
 
+	if (card->rx_dma_restart_required) {
+		card->rx_dma_restart_required = 0;
+		gelic_net_enable_rxdmac(card);
+	}
+
 	if (status & GELIC_NET_RXINT) {
 		gelic_net_rx_irq_off(card);
 		netif_rx_schedule(netdev);
@@ -1024,9 +1062,10 @@ static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
 	if (status & GELIC_NET_TXINT) {
 		spin_lock_irqsave(&card->tx_dma_lock, flags);
 		card->tx_dma_progress = 0;
+		gelic_net_release_tx_chain(card, 0);
+		/* kick outstanding tx descriptor if any */
+		gelic_net_kick_txdma(card, card->tx_chain.tail);
 		spin_unlock_irqrestore(&card->tx_dma_lock, flags);
-		/* start pending DMA */
-		gelic_net_xmit(NULL, netdev);
 	}
 	return IRQ_HANDLED;
 }
@@ -1068,7 +1107,7 @@ static int gelic_net_open_device(struct gelic_net_card *card)
 	}
 
 	result = request_irq(card->netdev->irq, gelic_net_interrupt,
-			     IRQF_DISABLED, "gelic network", card->netdev);
+			     IRQF_DISABLED, card->netdev->name, card->netdev);
 
 	if (result) {
 		dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n",
@@ -1107,7 +1146,7 @@ static int gelic_net_open(struct net_device *netdev)
 			card->descr, GELIC_NET_TX_DESCRIPTORS))
 		goto alloc_tx_failed;
 	if (gelic_net_init_chain(card, &card->rx_chain,
-				 card->descr + GELIC_NET_RX_DESCRIPTORS,
+				 card->descr + GELIC_NET_TX_DESCRIPTORS,
 				 GELIC_NET_RX_DESCRIPTORS))
 		goto alloc_rx_failed;
 
@@ -1129,7 +1168,6 @@ static int gelic_net_open(struct net_device *netdev)
 
 	netif_start_queue(netdev);
 	netif_carrier_on(netdev);
-	netif_poll_enable(netdev);
 
 	return 0;
 
@@ -1141,7 +1179,6 @@ alloc_tx_failed:
 	return -ENOMEM;
 }
 
-#ifdef GELIC_NET_ETHTOOL
 static void gelic_net_get_drvinfo (struct net_device *netdev,
 				   struct ethtool_drvinfo *info)
 {
@@ -1261,7 +1298,6 @@ static struct ethtool_ops gelic_net_ethtool_ops = {
 	.get_rx_csum	= gelic_net_get_rx_csum,
 	.set_rx_csum	= gelic_net_set_rx_csum,
 };
-#endif
 
 /**
  * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout
@@ -1320,7 +1356,6 @@ static void gelic_net_setup_netdev_ops(struct net_device *netdev)
 	netdev->open = &gelic_net_open;
 	netdev->stop = &gelic_net_stop;
 	netdev->hard_start_xmit = &gelic_net_xmit;
-	netdev->get_stats = &gelic_net_get_stats;
 	netdev->set_multicast_list = &gelic_net_set_multi;
 	netdev->change_mtu = &gelic_net_change_mtu;
 	/* tx watchdog */
@@ -1329,9 +1364,7 @@ static void gelic_net_setup_netdev_ops(struct net_device *netdev)
 	/* NAPI */
 	netdev->poll = &gelic_net_poll;
 	netdev->weight = GELIC_NET_NAPI_WEIGHT;
-#ifdef GELIC_NET_ETHTOOL
 	netdev->ethtool_ops = &gelic_net_ethtool_ops;
-#endif
 }
 
 /**
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
index 5e1c286..a9c4c4f 100644
--- a/drivers/net/ps3_gelic_net.h
+++ b/drivers/net/ps3_gelic_net.h
@@ -28,21 +28,12 @@
 #ifndef _GELIC_NET_H
 #define _GELIC_NET_H
 
-#define GELIC_NET_DRV_NAME "Gelic Network Driver"
-#define GELIC_NET_DRV_VERSION "1.0"
-
-#define GELIC_NET_ETHTOOL               /* use ethtool */
-
-/* ioctl */
-#define GELIC_NET_GET_MODE              (SIOCDEVPRIVATE + 0)
-#define GELIC_NET_SET_MODE              (SIOCDEVPRIVATE + 1)
-
 /* descriptors */
 #define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
 #define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */
 
-#define GELIC_NET_MAX_MTU               2308
-#define GELIC_NET_MIN_MTU               64
+#define GELIC_NET_MAX_MTU               VLAN_ETH_FRAME_LEN
+#define GELIC_NET_MIN_MTU               VLAN_ETH_ZLEN
 #define GELIC_NET_RXBUF_ALIGN           128
 #define GELIC_NET_RX_CSUM_DEFAULT       1 /* hw chksum */
 #define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
@@ -90,7 +81,8 @@ enum gelic_net_int1_status {
 					    */
 #define GELIC_NET_RXVLNPKT	0x00200000 /* VLAN packet */
 /* bit 20..16 reserved */
-#define GELIC_NET_RXRECNUM	0x0000ff00 /* reception receipt number */
+#define GELIC_NET_RXRRECNUM	0x0000ff00 /* reception receipt number */
+#define GELIC_NET_RXRRECNUM_SHIFT	8
 /* bit 7..0 reserved */
 
 #define GELIC_NET_TXDESC_TAIL		0
@@ -133,19 +125,19 @@ enum gelic_net_int1_status {
 						      * interrupt status */
 
 #define GELIC_NET_DMAC_CMDSTAT_CHAIN_END  0x00000002 /* RXDCEIS:DMA stopped */
-#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000
 #define GELIC_NET_DESCR_IND_PROC_SHIFT    28
 #define GELIC_NET_DESCR_IND_PROC_MASKO    0x0fffffff
 
 
 enum gelic_net_descr_status {
-	GELIC_NET_DESCR_COMPLETE            = 0x00, /* used in rx and tx */
+	GELIC_NET_DESCR_COMPLETE            = 0x00, /* used in tx */
+	GELIC_NET_DESCR_BUFFER_FULL         = 0x00, /* used in rx */
 	GELIC_NET_DESCR_RESPONSE_ERROR      = 0x01, /* used in rx and tx */
 	GELIC_NET_DESCR_PROTECTION_ERROR    = 0x02, /* used in rx and tx */
 	GELIC_NET_DESCR_FRAME_END           = 0x04, /* used in rx */
 	GELIC_NET_DESCR_FORCE_END           = 0x05, /* used in rx and tx */
 	GELIC_NET_DESCR_CARDOWNED           = 0x0a, /* used in rx and tx */
-	GELIC_NET_DESCR_NOT_IN_USE                  /* any other value */
+	GELIC_NET_DESCR_NOT_IN_USE          = 0x0b  /* any other value */
 };
 /* for lv1_net_control */
 #define GELIC_NET_GET_MAC_ADDRESS               0x0000000000000001
@@ -216,10 +208,10 @@ struct gelic_net_card {
 
 	struct gelic_net_descr_chain tx_chain;
 	struct gelic_net_descr_chain rx_chain;
+	int rx_dma_restart_required;
 	/* gurad dmac descriptor chain*/
 	spinlock_t chain_lock;
 
-	struct net_device_stats netdev_stats;
 	int rx_csum;
 	/* guard tx_dma_progress */
 	spinlock_t tx_dma_lock;
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index e4736a3..12e01b2 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -43,10 +43,6 @@
 
 #undef DEBUG
 
-#define DRV_DESC "QE UCC Gigabit Ethernet Controller"
-#define DRV_NAME "ucc_geth"
-#define DRV_VERSION "1.1"
-
 #define ugeth_printk(level, format, arg...)  \
         printk(level format "\n", ## arg)
 
@@ -64,9 +60,19 @@
 #else
 #define ugeth_vdbg(fmt, args...) do { } while (0)
 #endif				/* UGETH_VERBOSE_DEBUG */
+#define UGETH_MSG_DEFAULT	(NETIF_MSG_IFUP << 1 ) - 1
 
+void uec_set_ethtool_ops(struct net_device *netdev);
+	
 static DEFINE_SPINLOCK(ugeth_lock);
 
+static struct {
+	u32 msg_enable;
+} debug = { -1 };
+
+module_param_named(debug, debug.msg_enable, int, 0);
+MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., 0xffff=all)");
+
 static struct ucc_geth_info ugeth_primary_info = {
 	.uf_info = {
 		    .bd_mem_part = MEM_PART_SYSTEM,
@@ -104,6 +110,7 @@ static struct ucc_geth_info ugeth_primary_info = {
 	.maxRetransmission = 0xf,
 	.collisionWindow = 0x37,
 	.receiveFlowControl = 1,
+	.transmitFlowControl = 1,
 	.maxGroupAddrInHash = 4,
 	.maxIndAddrInHash = 4,
 	.prel = 7,
@@ -139,7 +146,9 @@ static struct ucc_geth_info ugeth_primary_info = {
 	.numStationAddresses = UCC_GETH_NUM_OF_STATION_ADDRESSES_1,
 	.largestexternallookupkeysize =
 	    QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_NONE,
-	.statisticsMode = UCC_GETH_STATISTICS_GATHERING_MODE_NONE,
+	.statisticsMode = UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE |
+		UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX |
+		UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX,
 	.vlanOperationTagged = UCC_GETH_VLAN_OPERATION_TAGGED_NOP,
 	.vlanOperationNonTagged = UCC_GETH_VLAN_OPERATION_NON_TAGGED_NOP,
 	.rxQoSMode = UCC_GETH_QOS_MODE_DEFAULT,
@@ -281,7 +290,8 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
 
 	for (i = 0; i < num_entries; i++) {
 		if ((snum = qe_get_snum()) < 0) {
-			ugeth_err("fill_init_enet_entries: Can not get SNUM.");
+			if (netif_msg_ifup(ugeth))
+				ugeth_err("fill_init_enet_entries: Can not get SNUM.");
 			return snum;
 		}
 		if ((i == 0) && skip_page_for_first_entry)
@@ -291,8 +301,8 @@ static int fill_init_enet_entries(struct ucc_geth_private *ugeth,
 			init_enet_offset =
 			    qe_muram_alloc(thread_size, thread_alignment);
 			if (IS_ERR_VALUE(init_enet_offset)) {
-				ugeth_err
-		("fill_init_enet_entries: Can not allocate DPRAM memory.");
+				if (netif_msg_ifup(ugeth))
+					ugeth_err("fill_init_enet_entries: Can not allocate DPRAM memory.");
 				qe_put_snum((u8) snum);
 				return -ENOMEM;
 			}
@@ -1200,7 +1210,7 @@ static int init_inter_frame_gap_params(u8 non_btb_cs_ipg,
 	return 0;
 }
 
-static int init_flow_control_params(u32 automatic_flow_control_mode,
+int init_flow_control_params(u32 automatic_flow_control_mode,
 				    int rx_flow_control_enable,
 				    int tx_flow_control_enable,
 				    u16 pause_period,
@@ -1486,9 +1496,9 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
 
 	ret_val = init_preamble_length(ug_info->prel, &ug_regs->maccfg2);
 	if (ret_val != 0) {
-		ugeth_err
-		    ("%s: Preamble length must be between 3 and 7 inclusive.",
-		     __FUNCTION__);
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: Preamble length must be between 3 and 7 inclusive.",
+			     __FUNCTION__);
 		return ret_val;
 	}
 
@@ -1726,7 +1736,8 @@ static int ugeth_enable(struct ucc_geth_private *ugeth, enum comm_dir mode)
 
 	/* check if the UCC number is in range. */
 	if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
-		ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
 		return -EINVAL;
 	}
 
@@ -1754,7 +1765,8 @@ static int ugeth_disable(struct ucc_geth_private * ugeth, enum comm_dir mode)
 
 	/* check if the UCC number is in range. */
 	if (ugeth->ug_info->uf_info.ucc_num >= UCC_MAX_NUM) {
-		ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: ucc_num out of range.", __FUNCTION__);
 		return -EINVAL;
 	}
 
@@ -2306,7 +2318,9 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
 
 	if (!((uf_info->bd_mem_part == MEM_PART_SYSTEM) ||
 	      (uf_info->bd_mem_part == MEM_PART_MURAM))) {
-		ugeth_err("%s: Bad memory partition value.", __FUNCTION__);
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: Bad memory partition value.",
+					__FUNCTION__);
 		return -EINVAL;
 	}
 
@@ -2315,9 +2329,10 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
 		if ((ug_info->bdRingLenRx[i] < UCC_GETH_RX_BD_RING_SIZE_MIN) ||
 		    (ug_info->bdRingLenRx[i] %
 		     UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT)) {
-			ugeth_err
-			    ("%s: Rx BD ring length must be multiple of 4,"
-				" no smaller than 8.", __FUNCTION__);
+			if (netif_msg_probe(ugeth))
+				ugeth_err
+				    ("%s: Rx BD ring length must be multiple of 4, no smaller than 8.",
+					__FUNCTION__);
 			return -EINVAL;
 		}
 	}
@@ -2325,9 +2340,10 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
 	/* Tx BD lengths */
 	for (i = 0; i < ug_info->numQueuesTx; i++) {
 		if (ug_info->bdRingLenTx[i] < UCC_GETH_TX_BD_RING_SIZE_MIN) {
-			ugeth_err
-			    ("%s: Tx BD ring length must be no smaller than 2.",
-			     __FUNCTION__);
+			if (netif_msg_probe(ugeth))
+				ugeth_err
+				    ("%s: Tx BD ring length must be no smaller than 2.",
+				     __FUNCTION__);
 			return -EINVAL;
 		}
 	}
@@ -2335,31 +2351,35 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
 	/* mrblr */
 	if ((uf_info->max_rx_buf_length == 0) ||
 	    (uf_info->max_rx_buf_length % UCC_GETH_MRBLR_ALIGNMENT)) {
-		ugeth_err
-		    ("%s: max_rx_buf_length must be non-zero multiple of 128.",
-		     __FUNCTION__);
+		if (netif_msg_probe(ugeth))
+			ugeth_err
+			    ("%s: max_rx_buf_length must be non-zero multiple of 128.",
+			     __FUNCTION__);
 		return -EINVAL;
 	}
 
 	/* num Tx queues */
 	if (ug_info->numQueuesTx > NUM_TX_QUEUES) {
-		ugeth_err("%s: number of tx queues too large.", __FUNCTION__);
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: number of tx queues too large.", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	/* num Rx queues */
 	if (ug_info->numQueuesRx > NUM_RX_QUEUES) {
-		ugeth_err("%s: number of rx queues too large.", __FUNCTION__);
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: number of rx queues too large.", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	/* l2qt */
 	for (i = 0; i < UCC_GETH_VLAN_PRIORITY_MAX; i++) {
 		if (ug_info->l2qt[i] >= ug_info->numQueuesRx) {
-			ugeth_err
-			    ("%s: VLAN priority table entry must not be"
-				" larger than number of Rx queues.",
-			     __FUNCTION__);
+			if (netif_msg_probe(ugeth))
+				ugeth_err
+				    ("%s: VLAN priority table entry must not be"
+					" larger than number of Rx queues.",
+				     __FUNCTION__);
 			return -EINVAL;
 		}
 	}
@@ -2367,26 +2387,29 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
 	/* l3qt */
 	for (i = 0; i < UCC_GETH_IP_PRIORITY_MAX; i++) {
 		if (ug_info->l3qt[i] >= ug_info->numQueuesRx) {
-			ugeth_err
-			    ("%s: IP priority table entry must not be"
-				" larger than number of Rx queues.",
-			     __FUNCTION__);
+			if (netif_msg_probe(ugeth))
+				ugeth_err
+				    ("%s: IP priority table entry must not be"
+					" larger than number of Rx queues.",
+				     __FUNCTION__);
 			return -EINVAL;
 		}
 	}
 
 	if (ug_info->cam && !ug_info->ecamptr) {
-		ugeth_err("%s: If cam mode is chosen, must supply cam ptr.",
-			  __FUNCTION__);
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: If cam mode is chosen, must supply cam ptr.",
+				  __FUNCTION__);
 		return -EINVAL;
 	}
 
 	if ((ug_info->numStationAddresses !=
 	     UCC_GETH_NUM_OF_STATION_ADDRESSES_1)
 	    && ug_info->rxExtendedFiltering) {
-		ugeth_err("%s: Number of station addresses greater than 1 "
-			  "not allowed in extended parsing mode.",
-			  __FUNCTION__);
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: Number of station addresses greater than 1 "
+				  "not allowed in extended parsing mode.",
+				  __FUNCTION__);
 		return -EINVAL;
 	}
 
@@ -2399,7 +2422,8 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
 		uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i);
 	/* Initialize the general fast UCC block. */
 	if (ucc_fast_init(uf_info, &ugeth->uccf)) {
-		ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: Failed to init uccf.", __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -ENOMEM;
 	}
@@ -2452,7 +2476,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		numThreadsRxNumerical = 8;
 		break;
 	default:
-		ugeth_err("%s: Bad number of Rx threads value.", __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Bad number of Rx threads value.",
+				       	__FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -EINVAL;
 		break;
@@ -2475,7 +2501,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		numThreadsTxNumerical = 8;
 		break;
 	default:
-		ugeth_err("%s: Bad number of Tx threads value.", __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Bad number of Tx threads value.",
+				       	__FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -EINVAL;
 		break;
@@ -2507,7 +2535,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	/* For more details see the hardware spec.           */
 	init_flow_control_params(ug_info->aufc,
 				 ug_info->receiveFlowControl,
-				 1,
+				 ug_info->transmitFlowControl,
 				 ug_info->pausePeriod,
 				 ug_info->extensionField,
 				 &uf_regs->upsmr,
@@ -2527,8 +2555,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 					      ug_info->backToBackInterFrameGap,
 					      &ug_regs->ipgifg);
 	if (ret_val != 0) {
-		ugeth_err("%s: IPGIFG initialization parameter too large.",
-			  __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: IPGIFG initialization parameter too large.",
+				  __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return ret_val;
 	}
@@ -2544,7 +2573,8 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 					  ug_info->collisionWindow,
 					  &ug_regs->hafdup);
 	if (ret_val != 0) {
-		ugeth_err("%s: Half Duplex initialization parameter too large.",
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Half Duplex initialization parameter too large.",
 			  __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return ret_val;
@@ -2597,9 +2627,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 							 tx_bd_ring_offset[j]);
 		}
 		if (!ugeth->p_tx_bd_ring[j]) {
-			ugeth_err
-			    ("%s: Can not allocate memory for Tx bd rings.",
-			     __FUNCTION__);
+			if (netif_msg_ifup(ugeth))
+				ugeth_err
+				    ("%s: Can not allocate memory for Tx bd rings.",
+				     __FUNCTION__);
 			ucc_geth_memclean(ugeth);
 			return -ENOMEM;
 		}
@@ -2632,9 +2663,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 							 rx_bd_ring_offset[j]);
 		}
 		if (!ugeth->p_rx_bd_ring[j]) {
-			ugeth_err
-			    ("%s: Can not allocate memory for Rx bd rings.",
-			     __FUNCTION__);
+			if (netif_msg_ifup(ugeth))
+				ugeth_err
+				    ("%s: Can not allocate memory for Rx bd rings.",
+				     __FUNCTION__);
 			ucc_geth_memclean(ugeth);
 			return -ENOMEM;
 		}
@@ -2648,8 +2680,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 					      GFP_KERNEL);
 
 		if (ugeth->tx_skbuff[j] == NULL) {
-			ugeth_err("%s: Could not allocate tx_skbuff",
-				  __FUNCTION__);
+			if (netif_msg_ifup(ugeth))
+				ugeth_err("%s: Could not allocate tx_skbuff",
+					  __FUNCTION__);
 			ucc_geth_memclean(ugeth);
 			return -ENOMEM;
 		}
@@ -2679,8 +2712,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 					      GFP_KERNEL);
 
 		if (ugeth->rx_skbuff[j] == NULL) {
-			ugeth_err("%s: Could not allocate rx_skbuff",
-				  __FUNCTION__);
+			if (netif_msg_ifup(ugeth))
+				ugeth_err("%s: Could not allocate rx_skbuff",
+					  __FUNCTION__);
 			ucc_geth_memclean(ugeth);
 			return -ENOMEM;
 		}
@@ -2711,9 +2745,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	    qe_muram_alloc(sizeof(struct ucc_geth_tx_global_pram),
 			   UCC_GETH_TX_GLOBAL_PRAM_ALIGNMENT);
 	if (IS_ERR_VALUE(ugeth->tx_glbl_pram_offset)) {
-		ugeth_err
-		    ("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
-		     __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err
+			    ("%s: Can not allocate DPRAM memory for p_tx_glbl_pram.",
+			     __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -ENOMEM;
 	}
@@ -2733,9 +2768,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			   32 * (numThreadsTxNumerical == 1),
 			   UCC_GETH_THREAD_DATA_ALIGNMENT);
 	if (IS_ERR_VALUE(ugeth->thread_dat_tx_offset)) {
-		ugeth_err
-		    ("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
-		     __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err
+			    ("%s: Can not allocate DPRAM memory for p_thread_data_tx.",
+			     __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -ENOMEM;
 	}
@@ -2761,9 +2797,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			   sizeof(struct ucc_geth_send_queue_qd),
 			   UCC_GETH_SEND_QUEUE_QUEUE_DESCRIPTOR_ALIGNMENT);
 	if (IS_ERR_VALUE(ugeth->send_q_mem_reg_offset)) {
-		ugeth_err
-		    ("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
-		     __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err
+			    ("%s: Can not allocate DPRAM memory for p_send_q_mem_reg.",
+			     __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -ENOMEM;
 	}
@@ -2804,9 +2841,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		    qe_muram_alloc(sizeof(struct ucc_geth_scheduler),
 				   UCC_GETH_SCHEDULER_ALIGNMENT);
 		if (IS_ERR_VALUE(ugeth->scheduler_offset)) {
-			ugeth_err
-			 ("%s: Can not allocate DPRAM memory for p_scheduler.",
-			     __FUNCTION__);
+			if (netif_msg_ifup(ugeth))
+				ugeth_err
+				 ("%s: Can not allocate DPRAM memory for p_scheduler.",
+				     __FUNCTION__);
 			ucc_geth_memclean(ugeth);
 			return -ENOMEM;
 		}
@@ -2852,9 +2890,11 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 				   (struct ucc_geth_tx_firmware_statistics_pram),
 				   UCC_GETH_TX_STATISTICS_ALIGNMENT);
 		if (IS_ERR_VALUE(ugeth->tx_fw_statistics_pram_offset)) {
-			ugeth_err
-			    ("%s: Can not allocate DPRAM memory for"
-				" p_tx_fw_statistics_pram.", __FUNCTION__);
+			if (netif_msg_ifup(ugeth))
+				ugeth_err
+				    ("%s: Can not allocate DPRAM memory for"
+					" p_tx_fw_statistics_pram.",
+				       	__FUNCTION__);
 			ucc_geth_memclean(ugeth);
 			return -ENOMEM;
 		}
@@ -2891,9 +2931,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	    qe_muram_alloc(sizeof(struct ucc_geth_rx_global_pram),
 			   UCC_GETH_RX_GLOBAL_PRAM_ALIGNMENT);
 	if (IS_ERR_VALUE(ugeth->rx_glbl_pram_offset)) {
-		ugeth_err
-		    ("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
-		     __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err
+			    ("%s: Can not allocate DPRAM memory for p_rx_glbl_pram.",
+			     __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -ENOMEM;
 	}
@@ -2912,9 +2953,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			   sizeof(struct ucc_geth_thread_data_rx),
 			   UCC_GETH_THREAD_DATA_ALIGNMENT);
 	if (IS_ERR_VALUE(ugeth->thread_dat_rx_offset)) {
-		ugeth_err
-		    ("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
-		     __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err
+			    ("%s: Can not allocate DPRAM memory for p_thread_data_rx.",
+			     __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -ENOMEM;
 	}
@@ -2935,9 +2977,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 				   (struct ucc_geth_rx_firmware_statistics_pram),
 				   UCC_GETH_RX_STATISTICS_ALIGNMENT);
 		if (IS_ERR_VALUE(ugeth->rx_fw_statistics_pram_offset)) {
-			ugeth_err
-				("%s: Can not allocate DPRAM memory for"
-				" p_rx_fw_statistics_pram.", __FUNCTION__);
+			if (netif_msg_ifup(ugeth))
+				ugeth_err
+					("%s: Can not allocate DPRAM memory for"
+					" p_rx_fw_statistics_pram.", __FUNCTION__);
 			ucc_geth_memclean(ugeth);
 			return -ENOMEM;
 		}
@@ -2957,9 +3000,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			   sizeof(struct ucc_geth_rx_interrupt_coalescing_entry)
 			   + 4, UCC_GETH_RX_INTERRUPT_COALESCING_ALIGNMENT);
 	if (IS_ERR_VALUE(ugeth->rx_irq_coalescing_tbl_offset)) {
-		ugeth_err
-		    ("%s: Can not allocate DPRAM memory for"
-			" p_rx_irq_coalescing_tbl.", __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err
+			    ("%s: Can not allocate DPRAM memory for"
+				" p_rx_irq_coalescing_tbl.", __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -ENOMEM;
 	}
@@ -3025,9 +3069,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 			    sizeof(struct ucc_geth_rx_prefetched_bds)),
 			   UCC_GETH_RX_BD_QUEUES_ALIGNMENT);
 	if (IS_ERR_VALUE(ugeth->rx_bd_qs_tbl_offset)) {
-		ugeth_err
-		    ("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
-		     __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err
+			    ("%s: Can not allocate DPRAM memory for p_rx_bd_qs_tbl.",
+			     __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -ENOMEM;
 	}
@@ -3102,8 +3147,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	/* initialize extended filtering */
 	if (ug_info->rxExtendedFiltering) {
 		if (!ug_info->extendedFilteringChainPointer) {
-			ugeth_err("%s: Null Extended Filtering Chain Pointer.",
-				  __FUNCTION__);
+			if (netif_msg_ifup(ugeth))
+				ugeth_err("%s: Null Extended Filtering Chain Pointer.",
+					  __FUNCTION__);
 			ucc_geth_memclean(ugeth);
 			return -EINVAL;
 		}
@@ -3114,9 +3160,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		    qe_muram_alloc(sizeof(struct ucc_geth_exf_global_pram),
 		UCC_GETH_RX_EXTENDED_FILTERING_GLOBAL_PARAMETERS_ALIGNMENT);
 		if (IS_ERR_VALUE(ugeth->exf_glbl_param_offset)) {
-			ugeth_err
-				("%s: Can not allocate DPRAM memory for"
-				" p_exf_glbl_param.", __FUNCTION__);
+			if (netif_msg_ifup(ugeth))
+				ugeth_err
+					("%s: Can not allocate DPRAM memory for"
+					" p_exf_glbl_param.", __FUNCTION__);
 			ucc_geth_memclean(ugeth);
 			return -ENOMEM;
 		}
@@ -3161,9 +3208,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	 */
 	if (!(ugeth->p_init_enet_param_shadow =
 	      kmalloc(sizeof(struct ucc_geth_init_pram), GFP_KERNEL))) {
-		ugeth_err
-		    ("%s: Can not allocate memory for"
-			" p_UccInitEnetParamShadows.", __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err
+			    ("%s: Can not allocate memory for"
+				" p_UccInitEnetParamShadows.", __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -ENOMEM;
 	}
@@ -3196,8 +3244,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_8_BYTES)
 	    && (ug_info->largestexternallookupkeysize !=
 		QE_FLTR_LARGEST_EXTERNAL_TABLE_LOOKUP_KEY_SIZE_16_BYTES)) {
-		ugeth_err("%s: Invalid largest External Lookup Key Size.",
-			  __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Invalid largest External Lookup Key Size.",
+				  __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -EINVAL;
 	}
@@ -3222,8 +3271,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 		/* Rx needs one extra for terminator */
 		, size, UCC_GETH_THREAD_RX_PRAM_ALIGNMENT,
 		ug_info->riscRx, 1)) != 0) {
-			ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
-				__FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+				ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
+					__FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return ret_val;
 	}
@@ -3237,8 +3287,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 				    sizeof(struct ucc_geth_thread_tx_pram),
 				    UCC_GETH_THREAD_TX_PRAM_ALIGNMENT,
 				    ug_info->riscTx, 0)) != 0) {
-		ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
-			  __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Can not fill p_init_enet_param_shadow.",
+				  __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return ret_val;
 	}
@@ -3246,8 +3297,9 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	/* Load Rx bds with buffers */
 	for (i = 0; i < ug_info->numQueuesRx; i++) {
 		if ((ret_val = rx_bd_buffer_set(ugeth, (u8) i)) != 0) {
-			ugeth_err("%s: Can not fill Rx bds with buffers.",
-				  __FUNCTION__);
+			if (netif_msg_ifup(ugeth))
+				ugeth_err("%s: Can not fill Rx bds with buffers.",
+					  __FUNCTION__);
 			ucc_geth_memclean(ugeth);
 			return ret_val;
 		}
@@ -3256,9 +3308,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
 	/* Allocate InitEnet command parameter structure */
 	init_enet_pram_offset = qe_muram_alloc(sizeof(struct ucc_geth_init_pram), 4);
 	if (IS_ERR_VALUE(init_enet_pram_offset)) {
-		ugeth_err
-		    ("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
-		     __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err
+			    ("%s: Can not allocate DPRAM memory for p_init_enet_pram.",
+			     __FUNCTION__);
 		ucc_geth_memclean(ugeth);
 		return -ENOMEM;
 	}
@@ -3428,8 +3481,9 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
 		if (!skb ||
 		    (!(bd_status & (R_F | R_L))) ||
 		    (bd_status & R_ERRORS_FATAL)) {
-			ugeth_vdbg("%s, %d: ERROR!!! skb - 0x%08x",
-				   __FUNCTION__, __LINE__, (u32) skb);
+			if (netif_msg_rx_err(ugeth))
+				ugeth_err("%s, %d: ERROR!!! skb - 0x%08x",
+					   __FUNCTION__, __LINE__, (u32) skb);
 			if (skb)
 				dev_kfree_skb_any(skb);
 
@@ -3458,7 +3512,8 @@ static int ucc_geth_rx(struct ucc_geth_private *ugeth, u8 rxQ, int rx_work_limit
 
 		skb = get_new_skb(ugeth, bd);
 		if (!skb) {
-			ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
+			if (netif_msg_rx_err(ugeth))
+				ugeth_warn("%s: No Rx Data Buffer", __FUNCTION__);
 			ugeth->stats.rx_dropped++;
 			break;
 		}
@@ -3649,28 +3704,32 @@ static int ucc_geth_open(struct net_device *dev)
 
 	/* Test station address */
 	if (dev->dev_addr[0] & ENET_GROUP_ADDR) {
-		ugeth_err("%s: Multicast address used for station address"
-			  " - is this what you wanted?", __FUNCTION__);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Multicast address used for station address"
+				  " - is this what you wanted?", __FUNCTION__);
 		return -EINVAL;
 	}
 
 	err = ucc_struct_init(ugeth);
 	if (err) {
-		ugeth_err("%s: Cannot configure internal struct, aborting.", dev->name);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Cannot configure internal struct, aborting.", dev->name);
 		return err;
 	}
 
 	err = ucc_geth_startup(ugeth);
 	if (err) {
-		ugeth_err("%s: Cannot configure net device, aborting.",
-			  dev->name);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Cannot configure net device, aborting.",
+				  dev->name);
 		return err;
 	}
 
 	err = adjust_enet_interface(ugeth);
 	if (err) {
-		ugeth_err("%s: Cannot configure net device, aborting.",
-			  dev->name);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Cannot configure net device, aborting.",
+				  dev->name);
 		return err;
 	}
 
@@ -3687,7 +3746,8 @@ static int ucc_geth_open(struct net_device *dev)
 
 	err = init_phy(dev);
 	if (err) {
-		ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Cannot initialize PHY, aborting.", dev->name);
 		return err;
 	}
 
@@ -3697,15 +3757,17 @@ static int ucc_geth_open(struct net_device *dev)
 	    request_irq(ugeth->ug_info->uf_info.irq, ucc_geth_irq_handler, 0,
 			"UCC Geth", dev);
 	if (err) {
-		ugeth_err("%s: Cannot get IRQ for net device, aborting.",
-			  dev->name);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Cannot get IRQ for net device, aborting.",
+				  dev->name);
 		ucc_geth_stop(ugeth);
 		return err;
 	}
 
 	err = ugeth_enable(ugeth, COMM_DIR_RX_AND_TX);
 	if (err) {
-		ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
+		if (netif_msg_ifup(ugeth))
+			ugeth_err("%s: Cannot enable net device, aborting.", dev->name);
 		ucc_geth_stop(ugeth);
 		return err;
 	}
@@ -3732,8 +3794,6 @@ static int ucc_geth_close(struct net_device *dev)
 	return 0;
 }
 
-const struct ethtool_ops ucc_geth_ethtool_ops = { };
-
 static phy_interface_t to_phy_interface(const char *phy_connection_type)
 {
 	if (strcasecmp(phy_connection_type, "mii") == 0)
@@ -3790,6 +3850,13 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 		return -ENODEV;
 
 	ug_info = &ugeth_info[ucc_num];
+	if (ug_info == NULL) {
+		if (netif_msg_probe(&debug))
+			ugeth_err("%s: [%d] Missing additional data!",
+				       	__FUNCTION__, ucc_num);
+		return -ENODEV;
+	}
+
 	ug_info->uf_info.ucc_num = ucc_num;
 
 	prop = of_get_property(np, "rx-clock", NULL);
@@ -3868,15 +3935,10 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 
 	ug_info->mdio_bus = res.start;
 
-	printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
-		ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
-		ug_info->uf_info.irq);
-
-	if (ug_info == NULL) {
-		ugeth_err("%s: [%d] Missing additional data!", __FUNCTION__,
-			  ucc_num);
-		return -ENODEV;
-	}
+	if (netif_msg_probe(&debug))
+		printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
+			ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
+			ug_info->uf_info.irq);
 
 	/* Create an ethernet device instance */
 	dev = alloc_etherdev(sizeof(*ugeth));
@@ -3896,6 +3958,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 	SET_NETDEV_DEV(dev, device);
 
 	/* Fill in the dev structure */
+	uec_set_ethtool_ops(dev);
 	dev->open = ucc_geth_open;
 	dev->hard_start_xmit = ucc_geth_start_xmit;
 	dev->tx_timeout = ucc_geth_timeout;
@@ -3909,16 +3972,16 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 //    dev->change_mtu = ucc_geth_change_mtu;
 	dev->mtu = 1500;
 	dev->set_multicast_list = ucc_geth_set_multi;
-	dev->ethtool_ops = &ucc_geth_ethtool_ops;
 
-	ugeth->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
+	ugeth->msg_enable = netif_msg_init(debug.msg_enable, UGETH_MSG_DEFAULT);
 	ugeth->phy_interface = phy_interface;
 	ugeth->max_speed = max_speed;
 
 	err = register_netdev(dev);
 	if (err) {
-		ugeth_err("%s: Cannot register net device, aborting.",
-			  dev->name);
+		if (netif_msg_probe(ugeth))
+			ugeth_err("%s: Cannot register net device, aborting.",
+				  dev->name);
 		free_netdev(dev);
 		return err;
 	}
@@ -3972,7 +4035,8 @@ static int __init ucc_geth_init(void)
 	if (ret)
 		return ret;
 
-	printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
+	if (netif_msg_drv(&debug))
+		printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
 	for (i = 0; i < 8; i++)
 		memcpy(&(ugeth_info[i]), &ugeth_primary_info,
 		       sizeof(ugeth_primary_info));
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index a29e1c3..bb4dac8 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -30,6 +30,10 @@
 
 #include "ucc_geth_mii.h"
 
+#define DRV_DESC "QE UCC Gigabit Ethernet Controller"
+#define DRV_NAME "ucc_geth"
+#define DRV_VERSION "1.1"
+
 #define NUM_TX_QUEUES                   8
 #define NUM_RX_QUEUES                   8
 #define NUM_BDS_IN_PREFETCHED_BDS       4
@@ -896,6 +900,7 @@ struct ucc_geth_hardware_statistics {
 #define UCC_GETH_TX_VTAG_TABLE_ENTRY_MAX        8
 #define UCC_GETH_RX_BD_RING_SIZE_MIN            8
 #define UCC_GETH_TX_BD_RING_SIZE_MIN            2
+#define UCC_GETH_BD_RING_SIZE_MAX		0xffff
 
 #define UCC_GETH_SIZE_OF_BD                     QE_SIZEOF_BD
 
@@ -1135,6 +1140,7 @@ struct ucc_geth_info {
 	int bro;
 	int ecm;
 	int receiveFlowControl;
+	int transmitFlowControl;
 	u8 maxGroupAddrInHash;
 	u8 maxIndAddrInHash;
 	u8 prel;
diff --git a/drivers/net/ucc_geth_ethtool.c b/drivers/net/ucc_geth_ethtool.c
new file mode 100644
index 0000000..a8994c7
--- /dev/null
+++ b/drivers/net/ucc_geth_ethtool.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright (c) 2007 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * Description: QE UCC Gigabit Ethernet Ethtool API Set
+ *
+ * Author: Li Yang <leoli@freescale.com>
+ *
+ * Limitation: 
+ * Can only get/set setttings of the first queue.
+ * Need to re-open the interface manually after changing some paramters.
+ *
+ * This program is free software; you can redistribute  it and/or modify it
+ * under  the terms of  the GNU General  Public License as published by the
+ * Free Software Foundation;  either version 2 of the  License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/stddef.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/fsl_devices.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+#include <asm/types.h>
+#include <asm/uaccess.h>
+
+#include "ucc_geth.h"
+#include "ucc_geth_mii.h"
+
+static char hw_stat_gstrings[][ETH_GSTRING_LEN] = {
+	"tx-64-frames",
+	"tx-65-127-frames",
+	"tx-128-255-frames",
+	"rx-64-frames",
+	"rx-65-127-frames",
+	"rx-128-255-frames",
+	"tx-bytes-ok",
+	"tx-pause-frames",
+	"tx-multicast-frames",
+	"tx-broadcast-frames",
+	"rx-frames",
+	"rx-bytes-ok",
+	"rx-bytes-all",
+	"rx-multicast-frames",
+	"rx-broadcast-frames",
+	"stats-counter-carry",
+	"stats-counter-mask",
+	"rx-dropped-frames",
+};
+
+static char tx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
+	"tx-single-collision",
+	"tx-multiple-collision",
+	"tx-late-collsion",
+	"tx-aborted-frames",
+	"tx-lost-frames",
+	"tx-carrier-sense-errors",
+	"tx-frames-ok",
+	"tx-excessive-differ-frames",
+	"tx-256-511-frames",
+	"tx-1024-1518-frames",
+	"tx-jumbo-frames",
+};
+
+static char rx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
+	"rx-crc-errors",
+	"rx-alignment-errors",
+	"rx-in-range-length-errors",
+	"rx-out-of-range-length-errors",
+	"rx-too-long-frames",
+	"rx-runt",
+	"rx-very-long-event",
+	"rx-symbol-errors",
+	"rx-busy-drop-frames",
+	"reserved",
+	"reserved",
+	"rx-mismatch-drop-frames",
+	"rx-small-than-64",
+	"rx-256-511-frames",
+	"rx-512-1023-frames",
+	"rx-1024-1518-frames",
+	"rx-jumbo-frames",
+	"rx-mac-error-loss",
+	"rx-pause-frames",
+	"reserved",
+	"rx-vlan-removed",
+	"rx-vlan-replaced",
+	"rx-vlan-inserted",
+	"rx-ip-checksum-errors",
+};
+
+#define UEC_HW_STATS_LEN ARRAY_SIZE(hw_stat_gstrings)
+#define UEC_TX_FW_STATS_LEN ARRAY_SIZE(tx_fw_stat_gstrings)
+#define UEC_RX_FW_STATS_LEN ARRAY_SIZE(rx_fw_stat_gstrings)
+
+extern int init_flow_control_params(u32 automatic_flow_control_mode,
+		int rx_flow_control_enable,
+		int tx_flow_control_enable, u16 pause_period,
+		u16 extension_field, volatile u32 *upsmr_register,
+		volatile u32 *uempr_register, volatile u32 *maccfg1_register);
+
+static int
+uec_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	struct phy_device *phydev = ugeth->phydev;
+	struct ucc_geth_info *ug_info = ugeth->ug_info;
+
+	if (!phydev)
+		return -ENODEV;
+
+	ecmd->maxtxpkt = 1;
+	ecmd->maxrxpkt = ug_info->interruptcoalescingmaxvalue[0];
+
+	return phy_ethtool_gset(phydev, ecmd);
+}
+
+static int
+uec_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	struct phy_device *phydev = ugeth->phydev;
+
+	if (!phydev)
+		return -ENODEV;
+
+	return phy_ethtool_sset(phydev, ecmd);
+}
+
+static void
+uec_get_pauseparam(struct net_device *netdev,
+                     struct ethtool_pauseparam *pause)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+
+	pause->autoneg = ugeth->phydev->autoneg;
+
+	if (ugeth->ug_info->receiveFlowControl)
+		pause->rx_pause = 1;
+	if (ugeth->ug_info->transmitFlowControl)
+		pause->tx_pause = 1;
+}
+
+static int
+uec_set_pauseparam(struct net_device *netdev,
+                     struct ethtool_pauseparam *pause)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	int ret = 0;
+
+	ugeth->ug_info->receiveFlowControl = pause->rx_pause;
+	ugeth->ug_info->transmitFlowControl = pause->tx_pause;
+	
+	if (ugeth->phydev->autoneg) {
+		if (netif_running(netdev)) {
+			/* FIXME: automatically restart */
+			printk(KERN_INFO
+				"Please re-open the interface.\n");
+		}
+	} else {
+		struct ucc_geth_info *ug_info = ugeth->ug_info;
+
+		ret = init_flow_control_params(ug_info->aufc,
+					ug_info->receiveFlowControl,
+					ug_info->transmitFlowControl,
+					ug_info->pausePeriod,
+					ug_info->extensionField,
+					&ugeth->uccf->uf_regs->upsmr,
+					&ugeth->ug_regs->uempr,
+					&ugeth->ug_regs->maccfg1);
+	}
+
+	return ret;
+}
+
+static uint32_t
+uec_get_msglevel(struct net_device *netdev)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	return ugeth->msg_enable;
+}
+
+static void
+uec_set_msglevel(struct net_device *netdev, uint32_t data)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	ugeth->msg_enable = data;
+}
+
+static int
+uec_get_regs_len(struct net_device *netdev)
+{
+	return sizeof(struct ucc_geth);
+}
+
+static void
+uec_get_regs(struct net_device *netdev,
+               struct ethtool_regs *regs, void *p)
+{
+	int i;
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	u32 __iomem *ug_regs = (u32 __iomem *)ugeth->ug_regs;
+	u32 *buff = p;
+
+	for (i = 0; i < sizeof(struct ucc_geth) / sizeof(u32); i++)
+		buff[i] = in_be32(&ug_regs[i]);
+}
+
+static void
+uec_get_ringparam(struct net_device *netdev,
+                    struct ethtool_ringparam *ring)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	struct ucc_geth_info *ug_info = ugeth->ug_info;
+	int queue = 0;
+
+	ring->rx_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
+	ring->rx_mini_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
+	ring->rx_jumbo_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
+	ring->tx_max_pending = UCC_GETH_BD_RING_SIZE_MAX;
+
+	ring->rx_pending = ug_info->bdRingLenRx[queue];
+	ring->rx_mini_pending = ug_info->bdRingLenRx[queue];
+	ring->rx_jumbo_pending = ug_info->bdRingLenRx[queue];
+	ring->tx_pending = ug_info->bdRingLenTx[queue];
+}
+
+static int
+uec_set_ringparam(struct net_device *netdev,
+                    struct ethtool_ringparam *ring)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	struct ucc_geth_info *ug_info = ugeth->ug_info;
+	int queue = 0, ret = 0;
+
+	if (ring->rx_pending < UCC_GETH_RX_BD_RING_SIZE_MIN) {
+		printk("%s: RxBD ring size must be no smaller than %d.\n",
+			       	netdev->name, UCC_GETH_RX_BD_RING_SIZE_MIN);
+		return -EINVAL;
+	}
+	if (ring->rx_pending % UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT) {
+		printk("%s: RxBD ring size must be multiple of %d.\n",
+			netdev->name, UCC_GETH_RX_BD_RING_SIZE_ALIGNMENT);
+		return -EINVAL;
+	}
+	if (ring->tx_pending < UCC_GETH_TX_BD_RING_SIZE_MIN) {
+		printk("%s: TxBD ring size must be no smaller than %d.\n",
+				netdev->name, UCC_GETH_TX_BD_RING_SIZE_MIN);
+		return -EINVAL;
+	}
+
+	ug_info->bdRingLenRx[queue] = ring->rx_pending;
+	ug_info->bdRingLenTx[queue] = ring->tx_pending;
+
+	if (netif_running(netdev)) {
+		/* FIXME: restart automatically */
+		printk(KERN_INFO
+			"Please re-open the interface.\n");
+	}
+
+	return ret;
+}
+
+static int uec_get_stats_count(struct net_device *netdev)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	u32 stats_mode = ugeth->ug_info->statisticsMode;
+	int len = 0;
+
+	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE)
+		len += UEC_HW_STATS_LEN;
+	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX)
+		len += UEC_TX_FW_STATS_LEN;
+	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX)
+		len += UEC_RX_FW_STATS_LEN;
+
+	return len;
+}
+
+static void uec_get_strings(struct net_device *netdev, u32 stringset, u8 *buf)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	u32 stats_mode = ugeth->ug_info->statisticsMode;
+
+	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) {
+		memcpy(buf, hw_stat_gstrings, UEC_HW_STATS_LEN *
+			       	ETH_GSTRING_LEN);
+		buf += UEC_HW_STATS_LEN * ETH_GSTRING_LEN;
+	}
+	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
+		memcpy(buf, tx_fw_stat_gstrings, UEC_TX_FW_STATS_LEN *
+			       	ETH_GSTRING_LEN);
+		buf += UEC_TX_FW_STATS_LEN * ETH_GSTRING_LEN;
+	}
+	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX)
+		memcpy(buf, tx_fw_stat_gstrings, UEC_RX_FW_STATS_LEN *
+			       	ETH_GSTRING_LEN);
+}
+
+static void uec_get_ethtool_stats(struct net_device *netdev,
+		struct ethtool_stats *stats, uint64_t *data)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+	u32 stats_mode = ugeth->ug_info->statisticsMode;
+	u32 __iomem *base;
+	int i, j = 0;
+
+	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_HARDWARE) {
+		base = (u32 __iomem *)&ugeth->ug_regs->tx64;
+		for (i = 0; i < UEC_HW_STATS_LEN; i++)
+			data[j++] = (u64)in_be32(&base[i]);
+	}
+	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_TX) {
+		base = (u32 __iomem *)ugeth->p_tx_fw_statistics_pram;
+		for (i = 0; i < UEC_TX_FW_STATS_LEN; i++)
+			data[j++] = (u64)in_be32(&base[i]);
+	}
+	if (stats_mode & UCC_GETH_STATISTICS_GATHERING_MODE_FIRMWARE_RX) {
+		base = (u32 __iomem *)ugeth->p_rx_fw_statistics_pram;
+		for (i = 0; i < UEC_RX_FW_STATS_LEN; i++)
+			data[j++] = (u64)in_be32(&base[i]);
+	}
+}
+
+static int uec_nway_reset(struct net_device *netdev)
+{
+	struct ucc_geth_private *ugeth = netdev_priv(netdev);
+
+	return phy_start_aneg(ugeth->phydev);
+}
+
+/* Report driver information */
+static void
+uec_get_drvinfo(struct net_device *netdev,
+                       struct ethtool_drvinfo *drvinfo)
+{
+	strncpy(drvinfo->driver, DRV_NAME, 32);
+	strncpy(drvinfo->version, DRV_VERSION, 32);
+	strncpy(drvinfo->fw_version, "N/A", 32);
+	strncpy(drvinfo->bus_info, "QUICC ENGINE", 32);
+	drvinfo->n_stats = uec_get_stats_count(netdev);
+	drvinfo->testinfo_len = 0;
+	drvinfo->eedump_len = 0;
+	drvinfo->regdump_len = uec_get_regs_len(netdev);
+}
+
+static const struct ethtool_ops uec_ethtool_ops = {
+	.get_settings           = uec_get_settings,
+	.set_settings           = uec_set_settings,
+	.get_drvinfo            = uec_get_drvinfo,
+	.get_regs_len           = uec_get_regs_len,
+	.get_regs               = uec_get_regs,
+	.get_msglevel           = uec_get_msglevel,
+	.set_msglevel           = uec_set_msglevel,
+	.nway_reset             = uec_nway_reset,
+	.get_link               = ethtool_op_get_link,
+	.get_ringparam          = uec_get_ringparam,
+	.set_ringparam          = uec_set_ringparam,
+	.get_pauseparam         = uec_get_pauseparam,
+	.set_pauseparam         = uec_set_pauseparam,
+	.get_sg                 = ethtool_op_get_sg,
+	.set_sg                 = ethtool_op_set_sg,
+	.get_tso                = ethtool_op_get_tso,
+	.get_stats_count        = uec_get_stats_count,
+	.get_strings            = uec_get_strings,
+	.get_ethtool_stats      = uec_get_ethtool_stats,
+	.get_perm_addr          = ethtool_op_get_perm_addr,
+};
+
+void uec_set_ethtool_ops(struct net_device *netdev)
+{
+	SET_ETHTOOL_OPS(netdev, &uec_ethtool_ops);
+}
diff --git a/drivers/net/ucc_geth_mii.c b/drivers/net/ucc_geth_mii.c
index 7bcb82f..5f8c2d3 100644
--- a/drivers/net/ucc_geth_mii.c
+++ b/drivers/net/ucc_geth_mii.c
@@ -54,8 +54,8 @@
 #define vdbg(format, arg...) do {} while(0)
 #endif
 
-#define DRV_DESC "QE UCC Ethernet Controller MII Bus"
-#define DRV_NAME "fsl-uec_mdio"
+#define MII_DRV_DESC "QE UCC Ethernet Controller MII Bus"
+#define MII_DRV_NAME "fsl-uec_mdio"
 
 /* Write value to the PHY for this device to the register at regnum, */
 /* waiting until the write is done before it returns.  All PHY */
@@ -261,7 +261,7 @@ static struct of_device_id uec_mdio_match[] = {
 };
 
 static struct of_platform_driver uec_mdio_driver = {
-	.name	= DRV_NAME,
+	.name	= MII_DRV_NAME,
 	.probe	= uec_mdio_probe,
 	.remove	= uec_mdio_remove,
 	.match_table	= uec_mdio_match,
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index cbabb9c..42d3278 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1225,6 +1225,10 @@
 #define PCI_DEVICE_ID_NVIDIA_NVENET_25              0x054D
 #define PCI_DEVICE_ID_NVIDIA_NVENET_26              0x054E
 #define PCI_DEVICE_ID_NVIDIA_NVENET_27              0x054F
+#define PCI_DEVICE_ID_NVIDIA_NVENET_28              0x07DC
+#define PCI_DEVICE_ID_NVIDIA_NVENET_29              0x07DD
+#define PCI_DEVICE_ID_NVIDIA_NVENET_30              0x07DE
+#define PCI_DEVICE_ID_NVIDIA_NVENET_31              0x07DF
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE       0x0560
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE       0x056C
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE       0x0759

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-07-18 23:53 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2007-07-18 23:53 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML


Nothing highly notable.  Wireless pull, and new blackfin eth driver
(didn't get merged with rest of blackfin, since additional review was
requested).

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 Documentation/powerpc/booting-without-of.txt |    6 +
 MAINTAINERS                                  |    7 +
 arch/powerpc/boot/dts/mpc8641_hpcn.dts       |    4 +
 arch/powerpc/sysdev/fsl_soc.c                |    9 +
 drivers/net/Kconfig                          |   44 ++
 drivers/net/Makefile                         |    1 +
 drivers/net/arm/ether3.c                     |    2 +-
 drivers/net/bfin_mac.c                       | 1009 ++++++++++++++++++++++++++
 drivers/net/bfin_mac.h                       |  132 ++++
 drivers/net/ehea/ehea.h                      |    2 +-
 drivers/net/ehea/ehea_main.c                 |   37 +-
 drivers/net/gianfar.c                        |   12 +-
 drivers/net/ni5010.c                         |    6 +-
 drivers/net/ns83820.c                        |    2 +-
 drivers/net/phy/vitesse.c                    |   46 +-
 drivers/net/saa9730.c                        |    9 +-
 drivers/net/tc35815.c                        |    2 +-
 drivers/net/wireless/ipw2100.c               |    6 +-
 drivers/net/wireless/ipw2200.c               |   18 +-
 drivers/net/wireless/zd1211rw/zd_usb.c       |    2 +
 include/linux/fsl_devices.h                  |    1 +
 net/ieee80211/ieee80211_wx.c                 |    7 +-
 22 files changed, 1308 insertions(+), 56 deletions(-)
 create mode 100644 drivers/net/bfin_mac.c
 create mode 100644 drivers/net/bfin_mac.h

Andy Fleming (4):
      Fix Vitesse 824x PHY interrupt acking
      Add phy-connection-type to gianfar nodes
      Fix Vitesse RGMII-ID support
      Fix RGMII-ID handling in gianfar

Bryan Wu (1):
      Blackfin ethernet driver: on chip ethernet MAC controller driver

Daniel Drake (1):
      zd1211rw: Add ID for Siemens Gigaset USB Stick 54

Jean Tourrilhes (1):
      softmac: Channel is listed twice in scan output

Masakazu Mokuno (1):
      zd1211rw: Add ID for Planex GW-US54GXS

Thomas Klein (1):
      eHEA: Fix bonding support

YOSHIFUJI Hideaki / 吉藤英明 (4):
      NS83820: Handle multicast frames.
      NI5010: Handle multicast frames.
      SAA9730: Handle multicast frames.
      ARM/ETHER3: Handle multicast frames.

Yoichi Yuasa (1):
      fix wrong argument of tc35815_read_plat_dev_addr()

Zhu Yi (4):
      ipw2100: Fix `iwpriv set_power` error
      Fix ipw2200 set wrong power parameter causing firmware error
      ipw2200: Fix ipw_isr() comments error on shared IRQ
      Update version ipw2200 stamp to 1.2.2

diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 0c24348..76733a3 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -1250,6 +1250,12 @@ platforms are moved over to use the flattened-device-tree model.
       network device.  This is used by the bootwrapper to interpret
       MAC addresses passed by the firmware when no information other
       than indices is available to associate an address with a device.
+    - phy-connection-type : a string naming the controller/PHY interface type,
+      i.e., "mii" (default), "rmii", "gmii", "rgmii", "rgmii-id", "sgmii",
+      "tbi", or "rtbi".  This property is only really needed if the connection
+      is of type "rgmii-id", as all other connection types are detected by
+      hardware.
+
 
   Example:
 
diff --git a/MAINTAINERS b/MAINTAINERS
index e78f62f..f6b2665 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -732,6 +732,13 @@ L:	uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
 W:	http://blackfin.uclinux.org
 S:	Supported
 
+BLACKFIN EMAC DRIVER
+P:	Bryan Wu
+M:	bryan.wu@analog.com
+L:	uclinux-dist-devel@blackfin.uclinux.org (subscribers-only)
+W:	http://blackfin.uclinux.org
+S:	Supported
+
 BLACKFIN RTC DRIVER
 P:	Mike Frysinger
 M:	michael.frysinger@analog.com
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index db56a02..6a78a2b 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -131,6 +131,7 @@
 			interrupts = <1d 2 1e 2 22 2>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy0>;
+			phy-connection-type = "rgmii-id";
 		};
 
 		ethernet@25000 {
@@ -150,6 +151,7 @@
 			interrupts = <23 2 24 2 28 2>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy1>;
+			phy-connection-type = "rgmii-id";
 		};
 		
 		ethernet@26000 {
@@ -169,6 +171,7 @@
 			interrupts = <1F 2 20 2 21 2>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy2>;
+			phy-connection-type = "rgmii-id";
 		};
 
 		ethernet@27000 {
@@ -188,6 +191,7 @@
 			interrupts = <25 2 26 2 27 2>;
 			interrupt-parent = <&mpic>;
 			phy-handle = <&phy3>;
+			phy-connection-type = "rgmii-id";
 		};
 		serial@4500 {
 			device_type = "serial";
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index c0ddc80..3289fab 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -197,6 +197,7 @@ static int __init gfar_of_init(void)
 		struct gianfar_platform_data gfar_data;
 		const unsigned int *id;
 		const char *model;
+		const char *ctype;
 		const void *mac_addr;
 		const phandle *ph;
 		int n_res = 2;
@@ -254,6 +255,14 @@ static int __init gfar_of_init(void)
 			    FSL_GIANFAR_DEV_HAS_VLAN |
 			    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH;
 
+		ctype = of_get_property(np, "phy-connection-type", NULL);
+
+		/* We only care about rgmii-id.  The rest are autodetected */
+		if (ctype && !strcmp(ctype, "rgmii-id"))
+			gfar_data.interface = PHY_INTERFACE_MODE_RGMII_ID;
+		else
+			gfar_data.interface = PHY_INTERFACE_MODE_MII;
+
 		ph = of_get_property(np, "phy-handle", NULL);
 		phy = of_find_node_by_phandle(*ph);
 
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5fb659f..3073f67 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -838,6 +838,50 @@ config ULTRA32
 	  <file:Documentation/networking/net-modules.txt>. The module
 	  will be called smc-ultra32.
 
+config BFIN_MAC
+	tristate "Blackfin 536/537 on-chip mac support"
+	depends on NET_ETHERNET && (BF537 || BF536) && (!BF537_PORT_H)
+	select CRC32
+	select BFIN_MAC_USE_L1 if DMA_UNCACHED_NONE
+	help
+	  This is the driver for blackfin on-chip mac device. Say Y if you want it
+	  compiled into the kernel. This driver is also available as a module
+	  ( = code which can be inserted in and removed from the running kernel
+	  whenever you want). The module will be called bfin_mac.
+
+config BFIN_MAC_USE_L1
+	bool "Use L1 memory for rx/tx packets"
+	depends on BFIN_MAC && BF537
+	default y
+	help
+	  To get maximum network performace, you should use L1 memory as rx/tx buffers.
+	  Say N here if you want to reserve L1 memory for other uses.
+
+config BFIN_TX_DESC_NUM
+	int "Number of transmit buffer packets"
+	depends on BFIN_MAC
+	range 6 10 if BFIN_MAC_USE_L1
+	range 10 100
+	default "10"
+	help
+	  Set the number of buffer packets used in driver.
+
+config BFIN_RX_DESC_NUM
+	int "Number of receive buffer packets"
+	depends on BFIN_MAC
+	range 20 100 if BFIN_MAC_USE_L1
+	range 20 800
+	default "20"
+	help
+	  Set the number of buffer packets used in driver.
+
+config BFIN_MAC_RMII
+	bool "RMII PHY Interface (EXPERIMENTAL)"
+	depends on BFIN_MAC && EXPERIMENTAL
+	default n
+	help
+	  Use Reduced PHY MII Interface
+
 config SMC9194
 	tristate "SMC 9194 support"
 	depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 0e286ab..aaaa0a0 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -200,6 +200,7 @@ obj-$(CONFIG_S2IO) += s2io.o
 obj-$(CONFIG_MYRI10GE) += myri10ge/
 obj-$(CONFIG_SMC91X) += smc91x.o
 obj-$(CONFIG_SMC911X) += smc911x.o
+obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
 obj-$(CONFIG_DM9000) += dm9000.o
 obj-$(CONFIG_FEC_8XX) += fec_8xx/
 obj-$(CONFIG_PASEMI_MAC) += pasemi_mac.o
diff --git a/drivers/net/arm/ether3.c b/drivers/net/arm/ether3.c
index da71350..a7cac69 100644
--- a/drivers/net/arm/ether3.c
+++ b/drivers/net/arm/ether3.c
@@ -464,7 +464,7 @@ static void ether3_setmulticastlist(struct net_device *dev)
 	if (dev->flags & IFF_PROMISC) {
 		/* promiscuous mode */
 		priv(dev)->regs.config1 |= CFG1_RECVPROMISC;
-	} else if (dev->flags & IFF_ALLMULTI) {
+	} else if (dev->flags & IFF_ALLMULTI || dev->mc_count) {
 		priv(dev)->regs.config1 |= CFG1_RECVSPECBRMULTI;
 	} else
 		priv(dev)->regs.config1 |= CFG1_RECVSPECBROAD;
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
new file mode 100644
index 0000000..9a08d65
--- /dev/null
+++ b/drivers/net/bfin_mac.c
@@ -0,0 +1,1009 @@
+/*
+ * File:	drivers/net/bfin_mac.c
+ * Based on:
+ * Maintainer:
+ * 		Bryan Wu <bryan.wu@analog.com>
+ *
+ * Original author:
+ * 		Luke Yang <luke.yang@analog.com>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ *		Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:	Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software ;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation ;  either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that 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 ;  see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/crc32.h>
+#include <linux/device.h>
+#include <linux/spinlock.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <linux/platform_device.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/dma.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/blackfin.h>
+#include <asm/cacheflush.h>
+#include <asm/portmux.h>
+
+#include "bfin_mac.h"
+
+#define DRV_NAME	"bfin_mac"
+#define DRV_VERSION	"1.1"
+#define DRV_AUTHOR	"Bryan Wu, Luke Yang"
+#define DRV_DESC	"Blackfin BF53[67] on-chip Ethernet MAC driver"
+
+MODULE_AUTHOR(DRV_AUTHOR);
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION(DRV_DESC);
+
+#if defined(CONFIG_BFIN_MAC_USE_L1)
+# define bfin_mac_alloc(dma_handle, size)  l1_data_sram_zalloc(size)
+# define bfin_mac_free(dma_handle, ptr)    l1_data_sram_free(ptr)
+#else
+# define bfin_mac_alloc(dma_handle, size) \
+	dma_alloc_coherent(NULL, size, dma_handle, GFP_KERNEL)
+# define bfin_mac_free(dma_handle, ptr) \
+	dma_free_coherent(NULL, sizeof(*ptr), ptr, dma_handle)
+#endif
+
+#define PKT_BUF_SZ 1580
+
+#define MAX_TIMEOUT_CNT	500
+
+/* pointers to maintain transmit list */
+static struct net_dma_desc_tx *tx_list_head;
+static struct net_dma_desc_tx *tx_list_tail;
+static struct net_dma_desc_rx *rx_list_head;
+static struct net_dma_desc_rx *rx_list_tail;
+static struct net_dma_desc_rx *current_rx_ptr;
+static struct net_dma_desc_tx *current_tx_ptr;
+static struct net_dma_desc_tx *tx_desc;
+static struct net_dma_desc_rx *rx_desc;
+
+static void desc_list_free(void)
+{
+	struct net_dma_desc_rx *r;
+	struct net_dma_desc_tx *t;
+	int i;
+#if !defined(CONFIG_BFIN_MAC_USE_L1)
+	dma_addr_t dma_handle = 0;
+#endif
+
+	if (tx_desc) {
+		t = tx_list_head;
+		for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) {
+			if (t) {
+				if (t->skb) {
+					dev_kfree_skb(t->skb);
+					t->skb = NULL;
+				}
+				t = t->next;
+			}
+		}
+		bfin_mac_free(dma_handle, tx_desc);
+	}
+
+	if (rx_desc) {
+		r = rx_list_head;
+		for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) {
+			if (r) {
+				if (r->skb) {
+					dev_kfree_skb(r->skb);
+					r->skb = NULL;
+				}
+				r = r->next;
+			}
+		}
+		bfin_mac_free(dma_handle, rx_desc);
+	}
+}
+
+static int desc_list_init(void)
+{
+	int i;
+	struct sk_buff *new_skb;
+#if !defined(CONFIG_BFIN_MAC_USE_L1)
+	/*
+	 * This dma_handle is useless in Blackfin dma_alloc_coherent().
+	 * The real dma handler is the return value of dma_alloc_coherent().
+	 */
+	dma_addr_t dma_handle;
+#endif
+
+	tx_desc = bfin_mac_alloc(&dma_handle,
+				sizeof(struct net_dma_desc_tx) *
+				CONFIG_BFIN_TX_DESC_NUM);
+	if (tx_desc == NULL)
+		goto init_error;
+
+	rx_desc = bfin_mac_alloc(&dma_handle,
+				sizeof(struct net_dma_desc_rx) *
+				CONFIG_BFIN_RX_DESC_NUM);
+	if (rx_desc == NULL)
+		goto init_error;
+
+	/* init tx_list */
+	tx_list_head = tx_list_tail = tx_desc;
+
+	for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) {
+		struct net_dma_desc_tx *t = tx_desc + i;
+		struct dma_descriptor *a = &(t->desc_a);
+		struct dma_descriptor *b = &(t->desc_b);
+
+		/*
+		 * disable DMA
+		 * read from memory WNR = 0
+		 * wordsize is 32 bits
+		 * 6 half words is desc size
+		 * large desc flow
+		 */
+		a->config = WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
+		a->start_addr = (unsigned long)t->packet;
+		a->x_count = 0;
+		a->next_dma_desc = b;
+
+		/*
+		 * enabled DMA
+		 * write to memory WNR = 1
+		 * wordsize is 32 bits
+		 * disable interrupt
+		 * 6 half words is desc size
+		 * large desc flow
+		 */
+		b->config = DMAEN | WNR | WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
+		b->start_addr = (unsigned long)(&(t->status));
+		b->x_count = 0;
+
+		t->skb = NULL;
+		tx_list_tail->desc_b.next_dma_desc = a;
+		tx_list_tail->next = t;
+		tx_list_tail = t;
+	}
+	tx_list_tail->next = tx_list_head;	/* tx_list is a circle */
+	tx_list_tail->desc_b.next_dma_desc = &(tx_list_head->desc_a);
+	current_tx_ptr = tx_list_head;
+
+	/* init rx_list */
+	rx_list_head = rx_list_tail = rx_desc;
+
+	for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) {
+		struct net_dma_desc_rx *r = rx_desc + i;
+		struct dma_descriptor *a = &(r->desc_a);
+		struct dma_descriptor *b = &(r->desc_b);
+
+		/* allocate a new skb for next time receive */
+		new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
+		if (!new_skb) {
+			printk(KERN_NOTICE DRV_NAME
+			       ": init: low on mem - packet dropped\n");
+			goto init_error;
+		}
+		skb_reserve(new_skb, 2);
+		r->skb = new_skb;
+
+		/*
+		 * enabled DMA
+		 * write to memory WNR = 1
+		 * wordsize is 32 bits
+		 * disable interrupt
+		 * 6 half words is desc size
+		 * large desc flow
+		 */
+		a->config = DMAEN | WNR | WDSIZE_32 | NDSIZE_6 | DMAFLOW_LARGE;
+		/* since RXDWA is enabled */
+		a->start_addr = (unsigned long)new_skb->data - 2;
+		a->x_count = 0;
+		a->next_dma_desc = b;
+
+		/*
+		 * enabled DMA
+		 * write to memory WNR = 1
+		 * wordsize is 32 bits
+		 * enable interrupt
+		 * 6 half words is desc size
+		 * large desc flow
+		 */
+		b->config = DMAEN | WNR | WDSIZE_32 | DI_EN |
+				NDSIZE_6 | DMAFLOW_LARGE;
+		b->start_addr = (unsigned long)(&(r->status));
+		b->x_count = 0;
+
+		rx_list_tail->desc_b.next_dma_desc = a;
+		rx_list_tail->next = r;
+		rx_list_tail = r;
+	}
+	rx_list_tail->next = rx_list_head;	/* rx_list is a circle */
+	rx_list_tail->desc_b.next_dma_desc = &(rx_list_head->desc_a);
+	current_rx_ptr = rx_list_head;
+
+	return 0;
+
+init_error:
+	desc_list_free();
+	printk(KERN_ERR DRV_NAME ": kmalloc failed\n");
+	return -ENOMEM;
+}
+
+
+/*---PHY CONTROL AND CONFIGURATION-----------------------------------------*/
+
+/* Set FER regs to MUX in Ethernet pins */
+static int setup_pin_mux(int action)
+{
+#if defined(CONFIG_BFIN_MAC_RMII)
+	u16 pin_req[] = P_RMII0;
+#else
+	u16 pin_req[] = P_MII0;
+#endif
+
+	if (action) {
+		if (peripheral_request_list(pin_req, DRV_NAME)) {
+			printk(KERN_ERR DRV_NAME
+			": Requesting Peripherals failed\n");
+			return -EFAULT;
+		}
+	} else
+		peripheral_free_list(pin_req);
+
+	return 0;
+}
+
+/* Wait until the previous MDC/MDIO transaction has completed */
+static void poll_mdc_done(void)
+{
+	int timeout_cnt = MAX_TIMEOUT_CNT;
+
+	/* poll the STABUSY bit */
+	while ((bfin_read_EMAC_STAADD()) & STABUSY) {
+		mdelay(10);
+		if (timeout_cnt-- < 0) {
+			printk(KERN_ERR DRV_NAME
+			": wait MDC/MDIO transaction to complete timeout\n");
+			break;
+		}
+	}
+}
+
+/* Read an off-chip register in a PHY through the MDC/MDIO port */
+static u16 read_phy_reg(u16 PHYAddr, u16 RegAddr)
+{
+	poll_mdc_done();
+	/* read mode */
+	bfin_write_EMAC_STAADD(SET_PHYAD(PHYAddr) |
+				SET_REGAD(RegAddr) |
+				STABUSY);
+	poll_mdc_done();
+
+	return (u16) bfin_read_EMAC_STADAT();
+}
+
+/* Write an off-chip register in a PHY through the MDC/MDIO port */
+static void raw_write_phy_reg(u16 PHYAddr, u16 RegAddr, u32 Data)
+{
+	bfin_write_EMAC_STADAT(Data);
+
+	/* write mode */
+	bfin_write_EMAC_STAADD(SET_PHYAD(PHYAddr) |
+				SET_REGAD(RegAddr) |
+				STAOP |
+				STABUSY);
+
+	poll_mdc_done();
+}
+
+static void write_phy_reg(u16 PHYAddr, u16 RegAddr, u32 Data)
+{
+	poll_mdc_done();
+	raw_write_phy_reg(PHYAddr, RegAddr, Data);
+}
+
+/* set up the phy */
+static void bf537mac_setphy(struct net_device *dev)
+{
+	u16 phydat;
+	struct bf537mac_local *lp = netdev_priv(dev);
+
+	/* Program PHY registers */
+	pr_debug("start setting up phy\n");
+
+	/* issue a reset */
+	raw_write_phy_reg(lp->PhyAddr, PHYREG_MODECTL, 0x8000);
+
+	/* wait half a second */
+	msleep(500);
+
+	phydat = read_phy_reg(lp->PhyAddr, PHYREG_MODECTL);
+
+	/* advertise flow control supported */
+	phydat = read_phy_reg(lp->PhyAddr, PHYREG_ANAR);
+	phydat |= (1 << 10);
+	write_phy_reg(lp->PhyAddr, PHYREG_ANAR, phydat);
+
+	phydat = 0;
+	if (lp->Negotiate)
+		phydat |= 0x1000;	/* enable auto negotiation */
+	else {
+		if (lp->FullDuplex)
+			phydat |= (1 << 8);	/* full duplex */
+		else
+			phydat &= (~(1 << 8));	/* half duplex */
+
+		if (!lp->Port10)
+			phydat |= (1 << 13);	/* 100 Mbps */
+		else
+			phydat &= (~(1 << 13));	/* 10 Mbps */
+	}
+
+	if (lp->Loopback)
+		phydat |= (1 << 14);	/* enable TX->RX loopback */
+
+	write_phy_reg(lp->PhyAddr, PHYREG_MODECTL, phydat);
+	msleep(500);
+
+	phydat = read_phy_reg(lp->PhyAddr, PHYREG_MODECTL);
+	/* check for SMSC PHY */
+	if ((read_phy_reg(lp->PhyAddr, PHYREG_PHYID1) == 0x7) &&
+	((read_phy_reg(lp->PhyAddr, PHYREG_PHYID2) & 0xfff0) == 0xC0A0)) {
+		/*
+		 * we have SMSC PHY so reqest interrupt
+		 * on link down condition
+		 */
+
+		/* enable interrupts */
+		write_phy_reg(lp->PhyAddr, 30, 0x0ff);
+	}
+}
+
+/**************************************************************************/
+void setup_system_regs(struct net_device *dev)
+{
+	int phyaddr;
+	unsigned short sysctl, phydat;
+	u32 opmode;
+	struct bf537mac_local *lp = netdev_priv(dev);
+	int count = 0;
+
+	phyaddr = lp->PhyAddr;
+
+	/* Enable PHY output */
+	if (!(bfin_read_VR_CTL() & PHYCLKOE))
+		bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE);
+
+	/* MDC  = 2.5 MHz */
+	sysctl = SET_MDCDIV(24);
+	/* Odd word alignment for Receive Frame DMA word */
+	/* Configure checksum support and rcve frame word alignment */
+#if defined(BFIN_MAC_CSUM_OFFLOAD)
+	sysctl |= RXDWA | RXCKS;
+#else
+	sysctl |= RXDWA;
+#endif
+	bfin_write_EMAC_SYSCTL(sysctl);
+	/* auto negotiation on  */
+	/* full duplex          */
+	/* 100 Mbps             */
+	phydat = PHY_ANEG_EN | PHY_DUPLEX | PHY_SPD_SET;
+	write_phy_reg(phyaddr, PHYREG_MODECTL, phydat);
+
+	/* test if full duplex supported */
+	do {
+		msleep(100);
+		phydat = read_phy_reg(phyaddr, PHYREG_MODESTAT);
+		if (count > 30) {
+			printk(KERN_NOTICE DRV_NAME ": Link is down\n");
+			printk(KERN_NOTICE DRV_NAME
+				 "please check your network connection\n");
+			break;
+		}
+		count++;
+	} while (!(phydat & 0x0004));
+
+	phydat = read_phy_reg(phyaddr, PHYREG_ANLPAR);
+
+	if ((phydat & 0x0100) || (phydat & 0x0040)) {
+		opmode = FDMODE;
+	} else {
+		opmode = 0;
+		printk(KERN_INFO DRV_NAME
+			": Network is set to half duplex\n");
+	}
+
+#if defined(CONFIG_BFIN_MAC_RMII)
+	opmode |= RMII; /* For Now only 100MBit are supported */
+#endif
+
+	bfin_write_EMAC_OPMODE(opmode);
+
+	bfin_write_EMAC_MMC_CTL(RSTC | CROLL);
+
+	/* Initialize the TX DMA channel registers */
+	bfin_write_DMA2_X_COUNT(0);
+	bfin_write_DMA2_X_MODIFY(4);
+	bfin_write_DMA2_Y_COUNT(0);
+	bfin_write_DMA2_Y_MODIFY(0);
+
+	/* Initialize the RX DMA channel registers */
+	bfin_write_DMA1_X_COUNT(0);
+	bfin_write_DMA1_X_MODIFY(4);
+	bfin_write_DMA1_Y_COUNT(0);
+	bfin_write_DMA1_Y_MODIFY(0);
+}
+
+void setup_mac_addr(u8 * mac_addr)
+{
+	u32 addr_low = le32_to_cpu(*(__le32 *) & mac_addr[0]);
+	u16 addr_hi = le16_to_cpu(*(__le16 *) & mac_addr[4]);
+
+	/* this depends on a little-endian machine */
+	bfin_write_EMAC_ADDRLO(addr_low);
+	bfin_write_EMAC_ADDRHI(addr_hi);
+}
+
+static void adjust_tx_list(void)
+{
+	int timeout_cnt = MAX_TIMEOUT_CNT;
+
+	if (tx_list_head->status.status_word != 0
+	    && current_tx_ptr != tx_list_head) {
+		goto adjust_head;	/* released something, just return; */
+	}
+
+	/*
+	 * if nothing released, check wait condition
+	 * current's next can not be the head,
+	 * otherwise the dma will not stop as we want
+	 */
+	if (current_tx_ptr->next->next == tx_list_head) {
+		while (tx_list_head->status.status_word == 0) {
+			mdelay(10);
+			if (tx_list_head->status.status_word != 0
+			    || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) {
+				goto adjust_head;
+			}
+			if (timeout_cnt-- < 0) {
+				printk(KERN_ERR DRV_NAME
+				": wait for adjust tx list head timeout\n");
+				break;
+			}
+		}
+		if (tx_list_head->status.status_word != 0) {
+			goto adjust_head;
+		}
+	}
+
+	return;
+
+adjust_head:
+	do {
+		tx_list_head->desc_a.config &= ~DMAEN;
+		tx_list_head->status.status_word = 0;
+		if (tx_list_head->skb) {
+			dev_kfree_skb(tx_list_head->skb);
+			tx_list_head->skb = NULL;
+		} else {
+			printk(KERN_ERR DRV_NAME
+			       ": no sk_buff in a transmitted frame!\n");
+		}
+		tx_list_head = tx_list_head->next;
+	} while (tx_list_head->status.status_word != 0
+		 && current_tx_ptr != tx_list_head);
+	return;
+
+}
+
+static int bf537mac_hard_start_xmit(struct sk_buff *skb,
+				struct net_device *dev)
+{
+	struct bf537mac_local *lp = netdev_priv(dev);
+	unsigned int data;
+
+	current_tx_ptr->skb = skb;
+
+	/*
+	 * Is skb->data always 16-bit aligned?
+	 * Do we need to memcpy((char *)(tail->packet + 2), skb->data, len)?
+	 */
+	if ((((unsigned int)(skb->data)) & 0x02) == 2) {
+		/* move skb->data to current_tx_ptr payload */
+		data = (unsigned int)(skb->data) - 2;
+		*((unsigned short *)data) = (unsigned short)(skb->len);
+		current_tx_ptr->desc_a.start_addr = (unsigned long)data;
+		/* this is important! */
+		blackfin_dcache_flush_range(data, (data + (skb->len)) + 2);
+
+	} else {
+		*((unsigned short *)(current_tx_ptr->packet)) =
+		    (unsigned short)(skb->len);
+		memcpy((char *)(current_tx_ptr->packet + 2), skb->data,
+		       (skb->len));
+		current_tx_ptr->desc_a.start_addr =
+		    (unsigned long)current_tx_ptr->packet;
+		if (current_tx_ptr->status.status_word != 0)
+			current_tx_ptr->status.status_word = 0;
+		blackfin_dcache_flush_range((unsigned int)current_tx_ptr->
+					    packet,
+					    (unsigned int)(current_tx_ptr->
+							   packet + skb->len) +
+					    2);
+	}
+
+	/* enable this packet's dma */
+	current_tx_ptr->desc_a.config |= DMAEN;
+
+	/* tx dma is running, just return */
+	if (bfin_read_DMA2_IRQ_STATUS() & 0x08)
+		goto out;
+
+	/* tx dma is not running */
+	bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
+	/* dma enabled, read from memory, size is 6 */
+	bfin_write_DMA2_CONFIG(current_tx_ptr->desc_a.config);
+	/* Turn on the EMAC tx */
+	bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
+
+out:
+	adjust_tx_list();
+	current_tx_ptr = current_tx_ptr->next;
+	dev->trans_start = jiffies;
+	lp->stats.tx_packets++;
+	lp->stats.tx_bytes += (skb->len);
+	return 0;
+}
+
+static void bf537mac_rx(struct net_device *dev)
+{
+	struct sk_buff *skb, *new_skb;
+	struct bf537mac_local *lp = netdev_priv(dev);
+	unsigned short len;
+
+	/* allocate a new skb for next time receive */
+	skb = current_rx_ptr->skb;
+	new_skb = dev_alloc_skb(PKT_BUF_SZ + 2);
+	if (!new_skb) {
+		printk(KERN_NOTICE DRV_NAME
+		       ": rx: low on mem - packet dropped\n");
+		lp->stats.rx_dropped++;
+		goto out;
+	}
+	/* reserve 2 bytes for RXDWA padding */
+	skb_reserve(new_skb, 2);
+	current_rx_ptr->skb = new_skb;
+	current_rx_ptr->desc_a.start_addr = (unsigned long)new_skb->data - 2;
+
+	len = (unsigned short)((current_rx_ptr->status.status_word) & RX_FRLEN);
+	skb_put(skb, len);
+	blackfin_dcache_invalidate_range((unsigned long)skb->head,
+					 (unsigned long)skb->tail);
+
+	dev->last_rx = jiffies;
+	skb->dev = dev;
+	skb->protocol = eth_type_trans(skb, dev);
+#if defined(BFIN_MAC_CSUM_OFFLOAD)
+	skb->csum = current_rx_ptr->status.ip_payload_csum;
+	skb->ip_summed = CHECKSUM_PARTIAL;
+#endif
+
+	netif_rx(skb);
+	lp->stats.rx_packets++;
+	lp->stats.rx_bytes += len;
+	current_rx_ptr->status.status_word = 0x00000000;
+	current_rx_ptr = current_rx_ptr->next;
+
+out:
+	return;
+}
+
+/* interrupt routine to handle rx and error signal */
+static irqreturn_t bf537mac_interrupt(int irq, void *dev_id)
+{
+	struct net_device *dev = dev_id;
+	int number = 0;
+
+get_one_packet:
+	if (current_rx_ptr->status.status_word == 0) {
+		/* no more new packet received */
+		if (number == 0) {
+			if (current_rx_ptr->next->status.status_word != 0) {
+				current_rx_ptr = current_rx_ptr->next;
+				goto real_rx;
+			}
+		}
+		bfin_write_DMA1_IRQ_STATUS(bfin_read_DMA1_IRQ_STATUS() |
+					   DMA_DONE | DMA_ERR);
+		return IRQ_HANDLED;
+	}
+
+real_rx:
+	bf537mac_rx(dev);
+	number++;
+	goto get_one_packet;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void bf537mac_poll(struct net_device *dev)
+{
+	disable_irq(IRQ_MAC_RX);
+	bf537mac_interrupt(IRQ_MAC_RX, dev);
+	enable_irq(IRQ_MAC_RX);
+}
+#endif				/* CONFIG_NET_POLL_CONTROLLER */
+
+static void bf537mac_reset(void)
+{
+	unsigned int opmode;
+
+	opmode = bfin_read_EMAC_OPMODE();
+	opmode &= (~RE);
+	opmode &= (~TE);
+	/* Turn off the EMAC */
+	bfin_write_EMAC_OPMODE(opmode);
+}
+
+/*
+ * Enable Interrupts, Receive, and Transmit
+ */
+static int bf537mac_enable(struct net_device *dev)
+{
+	u32 opmode;
+
+	pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+
+	/* Set RX DMA */
+	bfin_write_DMA1_NEXT_DESC_PTR(&(rx_list_head->desc_a));
+	bfin_write_DMA1_CONFIG(rx_list_head->desc_a.config);
+
+	/* Wait MII done */
+	poll_mdc_done();
+
+	/* We enable only RX here */
+	/* ASTP   : Enable Automatic Pad Stripping
+	   PR     : Promiscuous Mode for test
+	   PSF    : Receive frames with total length less than 64 bytes.
+	   FDMODE : Full Duplex Mode
+	   LB     : Internal Loopback for test
+	   RE     : Receiver Enable */
+	opmode = bfin_read_EMAC_OPMODE();
+	if (opmode & FDMODE)
+		opmode |= PSF;
+	else
+		opmode |= DRO | DC | PSF;
+	opmode |= RE;
+
+#if defined(CONFIG_BFIN_MAC_RMII)
+	opmode |= RMII; /* For Now only 100MBit are supported */
+#ifdef CONFIG_BF_REV_0_2
+	opmode |= TE;
+#endif
+#endif
+	/* Turn on the EMAC rx */
+	bfin_write_EMAC_OPMODE(opmode);
+
+	return 0;
+}
+
+/* Our watchdog timed out. Called by the networking layer */
+static void bf537mac_timeout(struct net_device *dev)
+{
+	pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+
+	bf537mac_reset();
+
+	/* reset tx queue */
+	tx_list_tail = tx_list_head->next;
+
+	bf537mac_enable(dev);
+
+	/* We can accept TX packets again */
+	dev->trans_start = jiffies;
+	netif_wake_queue(dev);
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *bf537mac_query_statistics(struct net_device
+							  *dev)
+{
+	struct bf537mac_local *lp = netdev_priv(dev);
+
+	pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+
+	return &lp->stats;
+}
+
+/*
+ * This routine will, depending on the values passed to it,
+ * either make it accept multicast packets, go into
+ * promiscuous mode (for TCPDUMP and cousins) or accept
+ * a select set of multicast packets
+ */
+static void bf537mac_set_multicast_list(struct net_device *dev)
+{
+	u32 sysctl;
+
+	if (dev->flags & IFF_PROMISC) {
+		printk(KERN_INFO "%s: set to promisc mode\n", dev->name);
+		sysctl = bfin_read_EMAC_OPMODE();
+		sysctl |= RAF;
+		bfin_write_EMAC_OPMODE(sysctl);
+	} else if (dev->flags & IFF_ALLMULTI || dev->mc_count) {
+		/* accept all multicast */
+		sysctl = bfin_read_EMAC_OPMODE();
+		sysctl |= PAM;
+		bfin_write_EMAC_OPMODE(sysctl);
+	} else {
+		/* clear promisc or multicast mode */
+		sysctl = bfin_read_EMAC_OPMODE();
+		sysctl &= ~(RAF | PAM);
+		bfin_write_EMAC_OPMODE(sysctl);
+	}
+}
+
+/*
+ * this puts the device in an inactive state
+ */
+static void bf537mac_shutdown(struct net_device *dev)
+{
+	/* Turn off the EMAC */
+	bfin_write_EMAC_OPMODE(0x00000000);
+	/* Turn off the EMAC RX DMA */
+	bfin_write_DMA1_CONFIG(0x0000);
+	bfin_write_DMA2_CONFIG(0x0000);
+}
+
+/*
+ * Open and Initialize the interface
+ *
+ * Set up everything, reset the card, etc..
+ */
+static int bf537mac_open(struct net_device *dev)
+{
+	pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+
+	/*
+	 * Check that the address is valid.  If its not, refuse
+	 * to bring the device up.  The user must specify an
+	 * address using ifconfig eth0 hw ether xx:xx:xx:xx:xx:xx
+	 */
+	if (!is_valid_ether_addr(dev->dev_addr)) {
+		printk(KERN_WARNING DRV_NAME ": no valid ethernet hw addr\n");
+		return -EINVAL;
+	}
+
+	/* initial rx and tx list */
+	desc_list_init();
+
+	bf537mac_setphy(dev);
+	setup_system_regs(dev);
+	bf537mac_reset();
+	bf537mac_enable(dev);
+
+	pr_debug("hardware init finished\n");
+	netif_start_queue(dev);
+	netif_carrier_on(dev);
+
+	return 0;
+}
+
+/*
+ *
+ * this makes the board clean up everything that it can
+ * and not talk to the outside world.   Caused by
+ * an 'ifconfig ethX down'
+ */
+static int bf537mac_close(struct net_device *dev)
+{
+	pr_debug("%s: %s\n", dev->name, __FUNCTION__);
+
+	netif_stop_queue(dev);
+	netif_carrier_off(dev);
+
+	/* clear everything */
+	bf537mac_shutdown(dev);
+
+	/* free the rx/tx buffers */
+	desc_list_free();
+
+	return 0;
+}
+
+static int __init bf537mac_probe(struct net_device *dev)
+{
+	struct bf537mac_local *lp = netdev_priv(dev);
+	int retval;
+
+	/* Grab the MAC address in the MAC */
+	*(__le32 *) (&(dev->dev_addr[0])) = cpu_to_le32(bfin_read_EMAC_ADDRLO());
+	*(__le16 *) (&(dev->dev_addr[4])) = cpu_to_le16((u16) bfin_read_EMAC_ADDRHI());
+
+	/* probe mac */
+	/*todo: how to proble? which is revision_register */
+	bfin_write_EMAC_ADDRLO(0x12345678);
+	if (bfin_read_EMAC_ADDRLO() != 0x12345678) {
+		pr_debug("can't detect bf537 mac!\n");
+		retval = -ENODEV;
+		goto err_out;
+	}
+
+	/* set the GPIO pins to Ethernet mode */
+	retval = setup_pin_mux(1);
+
+	if (retval)
+		return retval;
+
+	/*Is it valid? (Did bootloader initialize it?) */
+	if (!is_valid_ether_addr(dev->dev_addr)) {
+		/* Grab the MAC from the board somehow - this is done in the
+		   arch/blackfin/mach-bf537/boards/eth_mac.c */
+		get_bf537_ether_addr(dev->dev_addr);
+	}
+
+	/* If still not valid, get a random one */
+	if (!is_valid_ether_addr(dev->dev_addr)) {
+		random_ether_addr(dev->dev_addr);
+	}
+
+	setup_mac_addr(dev->dev_addr);
+
+	/* Fill in the fields of the device structure with ethernet values. */
+	ether_setup(dev);
+
+	dev->open = bf537mac_open;
+	dev->stop = bf537mac_close;
+	dev->hard_start_xmit = bf537mac_hard_start_xmit;
+	dev->tx_timeout = bf537mac_timeout;
+	dev->get_stats = bf537mac_query_statistics;
+	dev->set_multicast_list = bf537mac_set_multicast_list;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = bf537mac_poll;
+#endif
+
+	/* fill in some of the fields */
+	lp->version = 1;
+	lp->PhyAddr = 0x01;
+	lp->CLKIN = 25;
+	lp->FullDuplex = 0;
+	lp->Negotiate = 1;
+	lp->FlowControl = 0;
+	spin_lock_init(&lp->lock);
+
+	/* now, enable interrupts */
+	/* register irq handler */
+	if (request_irq
+	    (IRQ_MAC_RX, bf537mac_interrupt, IRQF_DISABLED | IRQF_SHARED,
+	     "BFIN537_MAC_RX", dev)) {
+		printk(KERN_WARNING DRV_NAME
+		       ": Unable to attach BlackFin MAC RX interrupt\n");
+		return -EBUSY;
+	}
+
+	/* Enable PHY output early */
+	if (!(bfin_read_VR_CTL() & PHYCLKOE))
+		bfin_write_VR_CTL(bfin_read_VR_CTL() | PHYCLKOE);
+
+	retval = register_netdev(dev);
+	if (retval == 0) {
+		/* now, print out the card info, in a short format.. */
+		printk(KERN_INFO "%s: Version %s, %s\n",
+			 DRV_NAME, DRV_VERSION, DRV_DESC);
+	}
+
+err_out:
+	return retval;
+}
+
+static int bfin_mac_probe(struct platform_device *pdev)
+{
+	struct net_device *ndev;
+
+	ndev = alloc_etherdev(sizeof(struct bf537mac_local));
+	if (!ndev) {
+		printk(KERN_WARNING DRV_NAME ": could not allocate device\n");
+		return -ENOMEM;
+	}
+
+	SET_MODULE_OWNER(ndev);
+	SET_NETDEV_DEV(ndev, &pdev->dev);
+
+	platform_set_drvdata(pdev, ndev);
+
+	if (bf537mac_probe(ndev) != 0) {
+		platform_set_drvdata(pdev, NULL);
+		free_netdev(ndev);
+		printk(KERN_WARNING DRV_NAME ": not found\n");
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+static int bfin_mac_remove(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+
+	platform_set_drvdata(pdev, NULL);
+
+	unregister_netdev(ndev);
+
+	free_irq(IRQ_MAC_RX, ndev);
+
+	free_netdev(ndev);
+
+	setup_pin_mux(0);
+
+	return 0;
+}
+
+static int bfin_mac_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	return 0;
+}
+
+static int bfin_mac_resume(struct platform_device *pdev)
+{
+	return 0;
+}
+
+static struct platform_driver bfin_mac_driver = {
+	.probe = bfin_mac_probe,
+	.remove = bfin_mac_remove,
+	.resume = bfin_mac_resume,
+	.suspend = bfin_mac_suspend,
+	.driver = {
+		   .name = DRV_NAME,
+		   },
+};
+
+static int __init bfin_mac_init(void)
+{
+	return platform_driver_register(&bfin_mac_driver);
+}
+
+module_init(bfin_mac_init);
+
+static void __exit bfin_mac_cleanup(void)
+{
+	platform_driver_unregister(&bfin_mac_driver);
+}
+
+module_exit(bfin_mac_cleanup);
diff --git a/drivers/net/bfin_mac.h b/drivers/net/bfin_mac.h
new file mode 100644
index 0000000..af87189
--- /dev/null
+++ b/drivers/net/bfin_mac.h
@@ -0,0 +1,132 @@
+/*
+ * File:	drivers/net/bfin_mac.c
+ * Based on:
+ * Maintainer:
+ * 		Bryan Wu <bryan.wu@analog.com>
+ *
+ * Original author:
+ * 		Luke Yang <luke.yang@analog.com>
+ *
+ * Created:
+ * Description:
+ *
+ * Modified:
+ *		Copyright 2004-2006 Analog Devices Inc.
+ *
+ * Bugs:	Enter bugs at http://blackfin.uclinux.org/
+ *
+ * This program is free software ;  you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation ;  either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that 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 ;  see the file COPYING.
+ * If not, write to the Free Software Foundation,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * PHY REGISTER NAMES
+ */
+#define PHYREG_MODECTL		0x0000
+#define PHYREG_MODESTAT		0x0001
+#define PHYREG_PHYID1		0x0002
+#define PHYREG_PHYID2		0x0003
+#define PHYREG_ANAR		0x0004
+#define PHYREG_ANLPAR		0x0005
+#define PHYREG_ANER		0x0006
+#define PHYREG_NSR		0x0010
+#define PHYREG_LBREMR		0x0011
+#define PHYREG_REC		0x0012
+#define PHYREG_10CFG		0x0013
+#define PHYREG_PHY1_1		0x0014
+#define PHYREG_PHY1_2		0x0015
+#define PHYREG_PHY2		0x0016
+#define PHYREG_TW_1		0x0017
+#define PHYREG_TW_2		0x0018
+#define PHYREG_TEST		0x0019
+
+#define PHY_RESET		0x8000
+#define PHY_ANEG_EN		0x1000
+#define PHY_DUPLEX		0x0100
+#define PHY_SPD_SET		0x2000
+
+#define BFIN_MAC_CSUM_OFFLOAD
+
+struct dma_descriptor {
+	struct dma_descriptor *next_dma_desc;
+	unsigned long start_addr;
+	unsigned short config;
+	unsigned short x_count;
+};
+
+struct status_area_rx {
+#if defined(BFIN_MAC_CSUM_OFFLOAD)
+	unsigned short ip_hdr_csum;	/* ip header checksum */
+	/* ip payload(udp or tcp or others) checksum */
+	unsigned short ip_payload_csum;
+#endif
+	unsigned long status_word;	/* the frame status word */
+};
+
+struct status_area_tx {
+	unsigned long status_word;	/* the frame status word */
+};
+
+/* use two descriptors for a packet */
+struct net_dma_desc_rx {
+	struct net_dma_desc_rx *next;
+	struct sk_buff *skb;
+	struct dma_descriptor desc_a;
+	struct dma_descriptor desc_b;
+	struct status_area_rx status;
+};
+
+/* use two descriptors for a packet */
+struct net_dma_desc_tx {
+	struct net_dma_desc_tx *next;
+	struct sk_buff *skb;
+	struct dma_descriptor desc_a;
+	struct dma_descriptor desc_b;
+	unsigned char packet[1560];
+	struct status_area_tx status;
+};
+
+struct bf537mac_local {
+	/*
+	 * these are things that the kernel wants me to keep, so users
+	 * can find out semi-useless statistics of how well the card is
+	 * performing
+	 */
+	struct net_device_stats stats;
+
+	int version;
+
+	int FlowEnabled;	/* record if data flow is active */
+	int EtherIntIVG;	/* IVG for the ethernet interrupt */
+	int RXIVG;		/* IVG for the RX completion */
+	int TXIVG;		/* IVG for the TX completion */
+	int PhyAddr;		/* PHY address */
+	int OpMode;		/* set these bits n the OPMODE regs */
+	int Port10;		/* set port speed to 10 Mbit/s */
+	int GenChksums;		/* IP checksums to be calculated */
+	int NoRcveLnth;		/* dont insert recv length at start of buffer */
+	int StripPads;		/* remove trailing pad bytes */
+	int FullDuplex;		/* set full duplex mode */
+	int Negotiate;		/* enable auto negotiation */
+	int Loopback;		/* loopback at the PHY */
+	int Cache;		/* Buffers may be cached */
+	int FlowControl;	/* flow control active */
+	int CLKIN;		/* clock in value in MHZ */
+	unsigned short IntMask;	/* interrupt mask */
+	unsigned char Mac[6];	/* MAC address of the board */
+	spinlock_t lock;
+};
+
+extern void get_bf537_ether_addr(char *addr);
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 6628fa6..489c8b2 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0070"
+#define DRV_VERSION	"EHEA_0071"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 1d1571c..4c70a93 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -466,6 +466,8 @@ static struct ehea_cqe *ehea_proc_rwqes(struct net_device *dev,
 							 cqe->vlan_tag);
 			else
 				netif_receive_skb(skb);
+
+			dev->last_rx = jiffies;
 		} else {
 			pr->p_stats.poll_receive_errors++;
 			port_reset = ehea_treat_poll_error(pr, rq, cqe,
@@ -1433,7 +1435,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid)
 				     port->logical_port_id,
 				     reg_type, port->mac_addr, 0, hcallid);
 	if (hret != H_SUCCESS) {
-		ehea_error("reg_dereg_bcmc failed (tagged)");
+		ehea_error("%sregistering bc address failed (tagged)",
+                           hcallid == H_REG_BCMC ? "" : "de");
 		ret = -EIO;
 		goto out_herr;
 	}
@@ -1444,7 +1447,8 @@ static int ehea_broadcast_reg_helper(struct ehea_port *port, u32 hcallid)
 				     port->logical_port_id,
 				     reg_type, port->mac_addr, 0, hcallid);
 	if (hret != H_SUCCESS) {
-		ehea_error("reg_dereg_bcmc failed (vlan)");
+		ehea_error("%sregistering bc address failed (vlan)",
+			   hcallid == H_REG_BCMC ? "" : "de");
 		ret = -EIO;
 	}
 out_herr:
@@ -2170,7 +2174,6 @@ static int ehea_up(struct net_device *dev)
 {
 	int ret, i;
 	struct ehea_port *port = netdev_priv(dev);
-	u64 mac_addr = 0;
 
 	if (port->state == EHEA_PORT_UP)
 		return 0;
@@ -2189,18 +2192,10 @@ static int ehea_up(struct net_device *dev)
 		goto out_clean_pr;
 	}
 
-	ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
-	if (ret) {
-		ret = -EIO;
-		ehea_error("out_clean_pr");
-		goto out_clean_pr;
-	}
-	mac_addr = (*(u64*)dev->dev_addr) >> 16;
-
 	ret = ehea_reg_interrupts(dev);
 	if (ret) {
-		ehea_error("out_dereg_bc");
-		goto out_dereg_bc;
+		ehea_error("reg_interrupts failed. ret:%d", ret);
+		goto out_clean_pr;
 	}
 
 	for(i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
@@ -2226,9 +2221,6 @@ static int ehea_up(struct net_device *dev)
 out_free_irqs:
 	ehea_free_interrupts(dev);
 
-out_dereg_bc:
-	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
-
 out_clean_pr:
 	ehea_clean_all_portres(port);
 out:
@@ -2273,7 +2265,6 @@ static int ehea_down(struct net_device *dev)
 				&port->port_res[i].d_netdev->state))
 			msleep(1);
 
-	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
 	port->state = EHEA_PORT_DOWN;
 
 	ret = ehea_clean_all_portres(port);
@@ -2655,12 +2646,18 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 
 	INIT_WORK(&port->reset_task, ehea_reset_port);
 
+	ret = ehea_broadcast_reg_helper(port, H_REG_BCMC);
+	if (ret) {
+		ret = -EIO;
+		goto out_unreg_port;
+	}
+
 	ehea_set_ethtool_ops(dev);
 
 	ret = register_netdev(dev);
 	if (ret) {
 		ehea_error("register_netdev failed. ret=%d", ret);
-		goto out_unreg_port;
+		goto out_dereg_bc;
 	}
 
 	ret = ehea_get_jumboframe_status(port, &jumbo);
@@ -2675,6 +2672,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 
 	return port;
 
+out_dereg_bc:
+	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
+
 out_unreg_port:
 	ehea_unregister_port(port);
 
@@ -2694,6 +2694,7 @@ static void ehea_shutdown_single_port(struct ehea_port *port)
 {
 	unregister_netdev(port->netdev);
 	ehea_unregister_port(port);
+	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
 	kfree(port->mc_list);
 	free_netdev(port->netdev);
 	port->adapter->active_ports--;
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index d7a1a58..f926905 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -420,8 +420,18 @@ static phy_interface_t gfar_get_interface(struct net_device *dev)
 	if (ecntrl & ECNTRL_REDUCED_MODE) {
 		if (ecntrl & ECNTRL_REDUCED_MII_MODE)
 			return PHY_INTERFACE_MODE_RMII;
-		else
+		else {
+			phy_interface_t interface = priv->einfo->interface;
+
+			/*
+			 * This isn't autodetected right now, so it must
+			 * be set by the device tree or platform code.
+			 */
+			if (interface == PHY_INTERFACE_MODE_RGMII_ID)
+				return PHY_INTERFACE_MODE_RGMII_ID;
+
 			return PHY_INTERFACE_MODE_RGMII;
+		}
 	}
 
 	if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT)
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c
index 3d5b423..22a3b3d 100644
--- a/drivers/net/ni5010.c
+++ b/drivers/net/ni5010.c
@@ -670,14 +670,10 @@ static void ni5010_set_multicast_list(struct net_device *dev)
 
 	PRINTK2((KERN_DEBUG "%s: entering set_multicast_list\n", dev->name));
 
-	if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI) {
+	if (dev->flags&IFF_PROMISC || dev->flags&IFF_ALLMULTI || dev->mc_list) {
 		dev->flags |= IFF_PROMISC;
 		outb(RMD_PROMISC, EDLC_RMODE); /* Enable promiscuous mode */
 		PRINTK((KERN_DEBUG "%s: Entering promiscuous mode\n", dev->name));
-	} else if (dev->mc_list) {
-		/* Sorry, multicast not supported */
-		PRINTK((KERN_DEBUG "%s: No multicast, entering broadcast mode\n", dev->name));
-		outb(RMD_BROADCAST, EDLC_RMODE);
 	} else {
 		PRINTK((KERN_DEBUG "%s: Entering broadcast mode\n", dev->name));
 		outb(RMD_BROADCAST, EDLC_RMODE);  /* Disable promiscuous mode, use normal mode */
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 104aab3..ea80e6c 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1582,7 +1582,7 @@ static void ns83820_set_multicast(struct net_device *ndev)
 	else
 		and_mask &= ~(RFCR_AAU | RFCR_AAM);
 
-	if (ndev->flags & IFF_ALLMULTI)
+	if (ndev->flags & IFF_ALLMULTI || ndev->mc_count)
 		or_mask |= RFCR_AAM;
 	else
 		and_mask &= ~RFCR_AAM;
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 596222b..6a53856 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -21,6 +21,10 @@
 /* Vitesse Extended Control Register 1 */
 #define MII_VSC8244_EXT_CON1           0x17
 #define MII_VSC8244_EXTCON1_INIT       0x0000
+#define MII_VSC8244_EXTCON1_TX_SKEW_MASK	0x0c00
+#define MII_VSC8244_EXTCON1_RX_SKEW_MASK	0x0300
+#define MII_VSC8244_EXTCON1_TX_SKEW	0x0800
+#define MII_VSC8244_EXTCON1_RX_SKEW	0x0200
 
 /* Vitesse Interrupt Mask Register */
 #define MII_VSC8244_IMASK		0x19
@@ -39,7 +43,7 @@
 
 /* Vitesse Auxiliary Control/Status Register */
 #define MII_VSC8244_AUX_CONSTAT        	0x1c
-#define MII_VSC8244_AUXCONSTAT_INIT    	0x0004
+#define MII_VSC8244_AUXCONSTAT_INIT    	0x0000
 #define MII_VSC8244_AUXCONSTAT_DUPLEX  	0x0020
 #define MII_VSC8244_AUXCONSTAT_SPEED   	0x0018
 #define MII_VSC8244_AUXCONSTAT_GBIT    	0x0010
@@ -51,6 +55,7 @@ MODULE_LICENSE("GPL");
 
 static int vsc824x_config_init(struct phy_device *phydev)
 {
+	int extcon;
 	int err;
 
 	err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT,
@@ -58,14 +63,34 @@ static int vsc824x_config_init(struct phy_device *phydev)
 	if (err < 0)
 		return err;
 
-	err = phy_write(phydev, MII_VSC8244_EXT_CON1,
-			MII_VSC8244_EXTCON1_INIT);
+	extcon = phy_read(phydev, MII_VSC8244_EXT_CON1);
+
+	if (extcon < 0)
+		return err;
+
+	extcon &= ~(MII_VSC8244_EXTCON1_TX_SKEW_MASK |
+			MII_VSC8244_EXTCON1_RX_SKEW_MASK);
+
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
+		extcon |= (MII_VSC8244_EXTCON1_TX_SKEW |
+				MII_VSC8244_EXTCON1_RX_SKEW);
+
+	err = phy_write(phydev, MII_VSC8244_EXT_CON1, extcon);
+
 	return err;
 }
 
 static int vsc824x_ack_interrupt(struct phy_device *phydev)
 {
-	int err = phy_read(phydev, MII_VSC8244_ISTAT);
+	int err = 0;
+	
+	/*
+	 * Don't bother to ACK the interrupts if interrupts
+	 * are disabled.  The 824x cannot clear the interrupts
+	 * if they are disabled.
+	 */
+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
+		err = phy_read(phydev, MII_VSC8244_ISTAT);
 
 	return (err < 0) ? err : 0;
 }
@@ -77,8 +102,19 @@ static int vsc824x_config_intr(struct phy_device *phydev)
 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 		err = phy_write(phydev, MII_VSC8244_IMASK,
 				MII_VSC8244_IMASK_MASK);
-	else
+	else {
+		/*
+		 * The Vitesse PHY cannot clear the interrupt
+		 * once it has disabled them, so we clear them first
+		 */
+		err = phy_read(phydev, MII_VSC8244_ISTAT);
+
+		if (err)
+			return err;
+
 		err = phy_write(phydev, MII_VSC8244_IMASK, 0);
+	}
+
 	return err;
 }
 
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index 451486b..7dae4d4 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -940,15 +940,14 @@ static void lan_saa9730_set_multicast(struct net_device *dev)
 		       CAM_CONTROL_GROUP_ACC | CAM_CONTROL_BROAD_ACC,
 		       &lp->lan_saa9730_regs->CamCtl);
 	} else {
-		if (dev->flags & IFF_ALLMULTI) {
+		if (dev->flags & IFF_ALLMULTI || dev->mc_count) {
 			/* accept all multicast packets */
-			writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
-			       CAM_CONTROL_BROAD_ACC,
-			       &lp->lan_saa9730_regs->CamCtl);
-		} else {
 			/*
 			 * Will handle the multicast stuff later. -carstenl
 			 */
+			writel(CAM_CONTROL_COMP_EN | CAM_CONTROL_GROUP_ACC |
+			       CAM_CONTROL_BROAD_ACC,
+			       &lp->lan_saa9730_regs->CamCtl);
 		}
 	}
 
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index 75655ad..7f94ca9 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -626,7 +626,7 @@ static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev)
 	return -ENODEV;
 }
 #else
-static int __devinit tc35815_read_plat_dev_addr(struct device *dev)
+static int __devinit tc35815_read_plat_dev_addr(struct net_device *dev)
 {
 	return -ENODEV;
 }
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 072ede7..8990585 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -7868,10 +7868,10 @@ static int ipw2100_wx_set_powermode(struct net_device *dev,
 		goto done;
 	}
 
-	if ((mode < 1) || (mode > POWER_MODES))
+	if ((mode < 0) || (mode > POWER_MODES))
 		mode = IPW_POWER_AUTO;
 
-	if (priv->power_mode != mode)
+	if (IPW_POWER_LEVEL(priv->power_mode) != mode)
 		err = ipw2100_set_power_mode(priv, mode);
       done:
 	mutex_unlock(&priv->action_mutex);
@@ -7902,7 +7902,7 @@ static int ipw2100_wx_get_powermode(struct net_device *dev,
 			break;
 		case IPW_POWER_AUTO:
 			snprintf(extra, MAX_POWER_STRING,
-				 "Power save level: %d (Auto)", 0);
+				 "Power save level: %d (Auto)", level);
 			break;
 		default:
 			timeout = timeout_duration[level - 1] / 1000;
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index aa32a97..61497c4 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -70,7 +70,7 @@
 #define VQ
 #endif
 
-#define IPW2200_VERSION "1.2.0" VK VD VM VP VR VQ
+#define IPW2200_VERSION "1.2.2" VK VD VM VP VR VQ
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2006 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
@@ -2506,7 +2506,7 @@ static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
 		break;
 	}
 
-	param = cpu_to_le32(mode);
+	param = cpu_to_le32(param);
 	return ipw_send_cmd_pdu(priv, IPW_CMD_POWER_MODE, sizeof(param),
 				&param);
 }
@@ -9568,6 +9568,7 @@ static int ipw_wx_set_power(struct net_device *dev,
 		priv->power_mode = IPW_POWER_ENABLED | IPW_POWER_BATTERY;
 	else
 		priv->power_mode = IPW_POWER_ENABLED | priv->power_mode;
+
 	err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
 	if (err) {
 		IPW_DEBUG_WX("failed setting power mode.\n");
@@ -9604,22 +9605,19 @@ static int ipw_wx_set_powermode(struct net_device *dev,
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int mode = *(int *)extra;
 	int err;
+
 	mutex_lock(&priv->mutex);
-	if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
+	if ((mode < 1) || (mode > IPW_POWER_LIMIT))
 		mode = IPW_POWER_AC;
-		priv->power_mode = mode;
-	} else {
-		priv->power_mode = IPW_POWER_ENABLED | mode;
-	}
 
-	if (priv->power_mode != mode) {
+	if (IPW_POWER_LEVEL(priv->power_mode) != mode) {
 		err = ipw_send_power_mode(priv, mode);
-
 		if (err) {
 			IPW_DEBUG_WX("failed setting power mode.\n");
 			mutex_unlock(&priv->mutex);
 			return err;
 		}
+		priv->power_mode = IPW_POWER_ENABLED | mode;
 	}
 	mutex_unlock(&priv->mutex);
 	return 0;
@@ -10555,7 +10553,7 @@ static irqreturn_t ipw_isr(int irq, void *data)
 	spin_lock(&priv->irq_lock);
 
 	if (!(priv->status & STATUS_INT_ENABLED)) {
-		/* Shared IRQ */
+		/* IRQ is disabled */
 		goto none;
 	}
 
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 28d41a2..a9c339e 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -72,6 +72,8 @@ static struct usb_device_id usb_ids[] = {
 	{ USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x2019, 0x5303), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x129b, 0x1667), .driver_info = DEVICE_ZD1211B },
 	/* "Driverless" devices that need ejecting */
 	{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
 	{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 695741b..1831b19 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -53,6 +53,7 @@ struct gianfar_platform_data {
 	u32	bus_id;
 	u32	phy_id;
 	u8	mac_addr[6];
+	phy_interface_t interface;
 };
 
 struct gianfar_mdio_data {
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 523a137..465b73d 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -90,14 +90,11 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
 	}
 
 	/* Add channel and frequency */
+	/* Note : userspace automatically computes channel using iwrange */
 	iwe.cmd = SIOCGIWFREQ;
-	iwe.u.freq.m = network->channel;
-	iwe.u.freq.e = 0;
-	iwe.u.freq.i = 0;
-	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
-
 	iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
 	iwe.u.freq.e = 6;
+	iwe.u.freq.i = 0;
 	start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
 
 	/* Add encryption capability */

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-07-16 22:57 Jeff Garzik
@ 2007-07-17  8:02 ` maximilian attems
  0 siblings, 0 replies; 101+ messages in thread
From: maximilian attems @ 2007-07-17  8:02 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

On Mon, Jul 16, 2007 at 06:57:21PM -0400, Jeff Garzik wrote:
> Minor fixes and cleanups, and a wireless pull from Linville.
> 
> Please pull from 'upstream-linus' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus
> 

did you get the dgrs removal patch?
mail didn't hit netdev due to beeing too large,
but you were on cc.

shall i rebase?

--
maks

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-07-16 22:57 Jeff Garzik
  2007-07-17  8:02 ` maximilian attems
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2007-07-16 22:57 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML

Minor fixes and cleanups, and a wireless pull from Linville.

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 drivers/net/8139cp.c                           |   27 +-
 drivers/net/Kconfig                            |    2 +-
 drivers/net/arm/Kconfig                        |    1 +
 drivers/net/atl1/atl1.h                        |  156 +-
 drivers/net/atl1/atl1_main.c                   | 2176 ++++++++++++------------
 drivers/net/ehea/ehea.h                        |   23 +-
 drivers/net/ehea/ehea_main.c                   |  144 ++-
 drivers/net/ehea/ehea_phyp.h                   |    3 +
 drivers/net/ehea/ehea_qmr.c                    |  156 ++-
 drivers/net/ehea/ehea_qmr.h                    |   14 +-
 drivers/net/forcedeth.c                        |  162 ++-
 drivers/net/gianfar_mii.c                      |    1 -
 drivers/net/macb.c                             |  563 ++++---
 drivers/net/macb.h                             |   10 +-
 drivers/net/myri10ge/myri10ge.c                |    6 -
 drivers/net/s2io.c                             |    4 +-
 drivers/net/usb/cdc_subset.c                   |    3 +
 drivers/net/wireless/airo.c                    |  208 ++--
 drivers/net/wireless/ipw2100.c                 |   11 +-
 drivers/net/wireless/ipw2200.c                 |    5 +-
 drivers/net/wireless/libertas/cmd.c            |    2 +-
 drivers/net/wireless/libertas/rx.c             |    1 -
 drivers/net/wireless/libertas/version.h        |    1 -
 drivers/net/wireless/libertas/wext.c           |    3 -
 drivers/net/wireless/prism54/isl_ioctl.c       |   22 +-
 drivers/net/wireless/rtl8187_rtl8225.c         |    4 +-
 drivers/net/wireless/zd1211rw/zd_chip.c        |   88 +-
 drivers/net/wireless/zd1211rw/zd_chip.h        |   13 +-
 drivers/net/wireless/zd1211rw/zd_mac.c         |   59 +-
 drivers/net/wireless/zd1211rw/zd_mac.h         |    3 +-
 drivers/net/wireless/zd1211rw/zd_rf.c          |    3 +-
 drivers/net/wireless/zd1211rw/zd_rf.h          |    2 +-
 drivers/net/wireless/zd1211rw/zd_rf_al2230.c   |   12 +-
 drivers/net/wireless/zd1211rw/zd_rf_al7230b.c  |    2 +-
 drivers/net/wireless/zd1211rw/zd_rf_rf2959.c   |    2 +-
 drivers/net/wireless/zd1211rw/zd_rf_uw2453.c   |    2 +-
 drivers/net/wireless/zd1211rw/zd_usb.c         |   98 +-
 drivers/net/wireless/zd1211rw/zd_usb.h         |    3 +
 drivers/s390/net/qeth.h                        |    9 +
 drivers/s390/net/qeth_main.c                   |  183 ++-
 drivers/s390/net/qeth_proc.c                   |    6 +
 include/asm-arm/arch-at91/board.h              |    1 +
 include/asm-avr32/arch-at32ap/board.h          |    1 +
 net/ieee80211/softmac/ieee80211softmac_assoc.c |    5 +-
 44 files changed, 2400 insertions(+), 1800 deletions(-)
 delete mode 100644 drivers/net/wireless/libertas/version.h

Adrian Bunk (1):
      drivers/net/wireless/libertas/wext.c: remove dead code

Ayaz Abdulla (3):
      forcedeth bug fix: cicada phy
      forcedeth bug fix: vitesse phy
      forcedeth bug fix: realtek phy

Brice Goglin (1):
      myri10ge: Remove nonsensical limit in the tx done routine

Dan Williams (1):
      libertas: fix disabling WPA

Daniel Drake (4):
      zd1211rw: Allow channels 1-11 for unrecognised regulatory domains
      zd1211rw: Detect more AL2230S radios
      zd1211rw: Add ID for Buffalo WLI-U2-KG54L
      zd1211rw: Defer firmware load until first ifup

Francois Romieu (1):
      8139cp: implement the missing dev->tx_timeout

Frank Blaschka (2):
      s390: scatter-gather for inbound traffic in qeth driver
      s390: add barriers to qeth driver

Holger Schurig (1):
      libertas: fix use-after-free in rx path

Jay Cliburn (5):
      atl1: remove irq_sem
      atl1: header file cleanup
      atl1: cleanup atl1_main
      atl1: fix excessively indented code
      atl1: reorder atl1_main functions

Jean Tourrilhes (1):
      softmac: Fix ESSID problem

John Donoghue (1):
      EP93XX_ETH must select MII

Kumar Gala (1):
      gianfar: kill unused header

Matthias Kaehlcke (1):
      use list_for_each_entry() for iteration in Prism 54 driver

Micah Gruber (1):
      Fix a potential NULL pointer dereference in free_shared_mem() in drivers/net/s2io.c

Michael Wu (1):
      rtl8187: fix endianness issue in rtl8225 register writing

Michal Schmidt (5):
      airo: disable the PCI device when unloading module
      airo: delay some initialization until the netdev is up
      airo: fix a race causing initialization failures
      airo: simpler calling convention for enable_MAC()
      airo: start with radio off

Patrice Vilchez (1):
      macb: Add multicast capability

Robert P. J. Day (1):
      WIRELESS: Remove clearly obsolete libertas/version.h file.

Stephen Hemminger (2):
      ipw2200: rf kill switch polling power saving
      ipw2100: RF kill switch timer power save

Thomas Klein (1):
      eHEA: Introducing support vor DLPAR memory add

frederic RODO (1):
      macb: Use generic PHY layer

jing xiang (1):
      cdc-subset to support new vendor/product ID

diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 58bbc3e..f5223ec 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -26,7 +26,6 @@
 
 	TODO:
 	* Test Tx checksumming thoroughly
-	* Implement dev->tx_timeout
 
 	Low priority TODO:
 	* Complete reset on PciErr
@@ -1218,6 +1217,30 @@ static int cp_close (struct net_device *dev)
 	return 0;
 }
 
+static void cp_tx_timeout(struct net_device *dev)
+{
+	struct cp_private *cp = netdev_priv(dev);
+	unsigned long flags;
+	int rc;
+
+	printk(KERN_WARNING "%s: Transmit timeout, status %2x %4x %4x %4x\n",
+	       dev->name, cpr8(Cmd), cpr16(CpCmd),
+	       cpr16(IntrStatus), cpr16(IntrMask));
+
+	spin_lock_irqsave(&cp->lock, flags);
+
+	cp_stop_hw(cp);
+	cp_clean_rings(cp);
+	rc = cp_init_rings(cp);
+	cp_start_hw(cp);
+
+	netif_wake_queue(dev);
+
+	spin_unlock_irqrestore(&cp->lock, flags);
+
+	return;
+}
+
 #ifdef BROKEN
 static int cp_change_mtu(struct net_device *dev, int new_mtu)
 {
@@ -1923,10 +1946,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 	dev->change_mtu = cp_change_mtu;
 #endif
 	dev->ethtool_ops = &cp_ethtool_ops;
-#if 0
 	dev->tx_timeout = cp_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
-#endif
 
 #if CP_VLAN_TAG_USED
 	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index b941c74..4b9b7fe 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -187,7 +187,7 @@ config MII
 config MACB
 	tristate "Atmel MACB support"
 	depends on AVR32 || ARCH_AT91SAM9260 || ARCH_AT91SAM9263
-	select MII
+	select PHYLIB
 	help
 	  The Atmel MACB ethernet interface is found on many AT32 and AT91
 	  parts. Say Y to include support for the MACB chip.
diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig
index 5bf2d33..f9cc2b6 100644
--- a/drivers/net/arm/Kconfig
+++ b/drivers/net/arm/Kconfig
@@ -43,6 +43,7 @@ config ARM_AT91_ETHER
 config EP93XX_ETH
 	tristate "EP93xx Ethernet support"
 	depends on ARM && ARCH_EP93XX
+	select MII
 	help
 	  This is a driver for the ethernet hardware included in EP93xx CPUs.
 	  Say Y if you are building a kernel for EP93xx based devices.
diff --git a/drivers/net/atl1/atl1.h b/drivers/net/atl1/atl1.h
index b1c6034..991c8b9 100644
--- a/drivers/net/atl1/atl1.h
+++ b/drivers/net/atl1/atl1.h
@@ -43,6 +43,7 @@ extern const struct ethtool_ops atl1_ethtool_ops;
 struct atl1_adapter;
 
 #define ATL1_MAX_INTR		3
+#define ATL1_MAX_TX_BUF_LEN	0x3000	/* 12288 bytes */
 
 #define ATL1_DEFAULT_TPD	256
 #define ATL1_MAX_TPD		1024
@@ -57,29 +58,45 @@ struct atl1_adapter;
 #define ATL1_RRD_DESC(R, i)	ATL1_GET_DESC(R, i, struct rx_return_desc)
 
 /*
+ * This detached comment is preserved for documentation purposes only.
+ * It was originally attached to some code that got deleted, but seems
+ * important enough to keep around...
+ *
+ * <begin detached comment>
  * Some workarounds require millisecond delays and are run during interrupt
  * context.  Most notably, when establishing link, the phy may need tweaking
  * but cannot process phy register reads/writes faster than millisecond
  * intervals...and we establish link due to a "link status change" interrupt.
+ * <end detached comment>
+ */
+
+/*
+ * atl1_ring_header represents a single, contiguous block of DMA space
+ * mapped for the three descriptor rings (tpd, rfd, rrd) and the two
+ * message blocks (cmb, smb) described below
  */
+struct atl1_ring_header {
+	void *desc;		/* virtual address */
+	dma_addr_t dma;		/* physical address*/
+	unsigned int size;	/* length in bytes */
+};
 
 /*
- * wrapper around a pointer to a socket buffer,
- * so a DMA handle can be stored along with the buffer
+ * atl1_buffer is wrapper around a pointer to a socket buffer
+ * so a DMA handle can be stored along with the skb
  */
 struct atl1_buffer {
-	struct sk_buff *skb;
-	u16 length;
-	u16 alloced;
+	struct sk_buff *skb;	/* socket buffer */
+	u16 length;		/* rx buffer length */
+	u16 alloced;		/* 1 if skb allocated */
 	dma_addr_t dma;
 };
 
-#define MAX_TX_BUF_LEN		0x3000	/* 12KB */
-
+/* transmit packet descriptor (tpd) ring */
 struct atl1_tpd_ring {
-	void *desc;		/* pointer to the descriptor ring memory */
-	dma_addr_t dma;		/* physical adress of the descriptor ring */
-	u16 size;		/* length of descriptor ring in bytes */
+	void *desc;		/* descriptor ring virtual address */
+	dma_addr_t dma;		/* descriptor ring physical address */
+	u16 size;		/* descriptor ring length in bytes */
 	u16 count;		/* number of descriptors in the ring */
 	u16 hw_idx;		/* hardware index */
 	atomic_t next_to_clean;
@@ -87,36 +104,34 @@ struct atl1_tpd_ring {
 	struct atl1_buffer *buffer_info;
 };
 
+/* receive free descriptor (rfd) ring */
 struct atl1_rfd_ring {
-	void *desc;
-	dma_addr_t dma;
-	u16 size;
-	u16 count;
+	void *desc;		/* descriptor ring virtual address */
+	dma_addr_t dma;		/* descriptor ring physical address */
+	u16 size;		/* descriptor ring length in bytes */
+	u16 count;		/* number of descriptors in the ring */
 	atomic_t next_to_use;
 	u16 next_to_clean;
 	struct atl1_buffer *buffer_info;
 };
 
+/* receive return descriptor (rrd) ring */
 struct atl1_rrd_ring {
-	void *desc;
-	dma_addr_t dma;
-	unsigned int size;
-	u16 count;
+	void *desc;		/* descriptor ring virtual address */
+	dma_addr_t dma;		/* descriptor ring physical address */
+	unsigned int size;	/* descriptor ring length in bytes */
+	u16 count;		/* number of descriptors in the ring */
 	u16 next_to_use;
 	atomic_t next_to_clean;
 };
 
-struct atl1_ring_header {
-	void *desc;		/* pointer to the descriptor ring memory */
-	dma_addr_t dma;		/* physical adress of the descriptor ring */
-	unsigned int size;	/* length of descriptor ring in bytes */
-};
-
+/* coalescing message block (cmb) */
 struct atl1_cmb {
 	struct coals_msg_block *cmb;
 	dma_addr_t dma;
 };
 
+/* statistics message block (smb) */
 struct atl1_smb {
 	struct stats_msg_block *smb;
 	dma_addr_t dma;
@@ -141,24 +156,26 @@ struct atl1_sft_stats {
 	u64 tx_aborted_errors;
 	u64 tx_window_errors;
 	u64 tx_carrier_errors;
-
-	u64 tx_pause;		/* num Pause packet transmitted. */
-	u64 excecol;		/* num tx packets aborted due to excessive collisions. */
-	u64 deffer;		/* num deferred tx packets */
-	u64 scc;		/* num packets subsequently transmitted successfully w/ single prior collision. */
-	u64 mcc;		/* num packets subsequently transmitted successfully w/ multiple prior collisions. */
+	u64 tx_pause;		/* num pause packets transmitted. */
+	u64 excecol;		/* num tx packets w/ excessive collisions. */
+	u64 deffer;		/* num tx packets deferred */
+	u64 scc;		/* num packets subsequently transmitted
+				 * successfully w/ single prior collision. */
+	u64 mcc;		/* num packets subsequently transmitted
+				 * successfully w/ multiple prior collisions. */
 	u64 latecol;		/* num tx packets  w/ late collisions. */
-	u64 tx_underun;		/* num tx packets aborted due to transmit FIFO underrun, or TRD FIFO underrun */
-	u64 tx_trunc;		/* num tx packets truncated due to size exceeding MTU, regardless whether truncated by Selene or not. (The name doesn't really reflect the meaning in this case.) */
+	u64 tx_underun;		/* num tx packets aborted due to transmit
+				 * FIFO underrun, or TRD FIFO underrun */
+	u64 tx_trunc;		/* num tx packets truncated due to size
+				 * exceeding MTU, regardless whether truncated
+				 * by the chip or not. (The name doesn't really
+				 * reflect the meaning in this case.) */
 	u64 rx_pause;		/* num Pause packets received. */
 	u64 rx_rrd_ov;
 	u64 rx_trunc;
 };
 
-/* board specific private data structure */
-#define ATL1_REGS_LEN	8
-
-/* Structure containing variables used by the shared code */
+/* hardware structure */
 struct atl1_hw {
 	u8 __iomem *hw_addr;
 	struct atl1_adapter *back;
@@ -167,24 +184,35 @@ struct atl1_hw {
 	enum atl1_dma_req_block dmar_block;
 	enum atl1_dma_req_block dmaw_block;
 	u8 preamble_len;
-	u8 max_retry;		/* Retransmission maximum, after which the packet will be discarded */
-	u8 jam_ipg;		/* IPG to start JAM for collision based flow control in half-duplex mode. In units of 8-bit time */
-	u8 ipgt;		/* Desired back to back inter-packet gap. The default is 96-bit time */
-	u8 min_ifg;		/* Minimum number of IFG to enforce in between RX frames. Frame gap below such IFP is dropped */
+	u8 max_retry;		/* Retransmission maximum, after which the
+				 * packet will be discarded */
+	u8 jam_ipg;		/* IPG to start JAM for collision based flow
+				 * control in half-duplex mode. In units of
+				 * 8-bit time */
+	u8 ipgt;		/* Desired back to back inter-packet gap.
+				 * The default is 96-bit time */
+	u8 min_ifg;		/* Minimum number of IFG to enforce in between
+				 * receive frames. Frame gap below such IFP
+				 * is dropped */
 	u8 ipgr1;		/* 64bit Carrier-Sense window */
 	u8 ipgr2;		/* 96-bit IPG window */
-	u8 tpd_burst;		/* Number of TPD to prefetch in cache-aligned burst. Each TPD is 16 bytes long */
-	u8 rfd_burst;		/* Number of RFD to prefetch in cache-aligned burst. Each RFD is 12 bytes long */
+	u8 tpd_burst;		/* Number of TPD to prefetch in cache-aligned
+				 * burst. Each TPD is 16 bytes long */
+	u8 rfd_burst;		/* Number of RFD to prefetch in cache-aligned
+				 * burst. Each RFD is 12 bytes long */
 	u8 rfd_fetch_gap;
-	u8 rrd_burst;		/* Threshold number of RRDs that can be retired in a burst. Each RRD is 16 bytes long */
+	u8 rrd_burst;		/* Threshold number of RRDs that can be retired
+				 * in a burst. Each RRD is 16 bytes long */
 	u8 tpd_fetch_th;
 	u8 tpd_fetch_gap;
 	u16 tx_jumbo_task_th;
-	u16 txf_burst;		/* Number of data bytes to read in a cache-aligned burst. Each SRAM entry is
-				   8 bytes long */
-	u16 rx_jumbo_th;	/* Jumbo packet size for non-VLAN packet. VLAN packets should add 4 bytes */
+	u16 txf_burst;		/* Number of data bytes to read in a cache-
+				 * aligned burst. Each SRAM entry is 8 bytes */
+	u16 rx_jumbo_th;	/* Jumbo packet size for non-VLAN packet. VLAN
+				 * packets should add 4 bytes */
 	u16 rx_jumbo_lkah;
-	u16 rrd_ret_timer;	/* RRD retirement timer. Decrement by 1 after every 512ns passes. */
+	u16 rrd_ret_timer;	/* RRD retirement timer. Decrement by 1 after
+				 * every 512ns passes. */
 	u16 lcol;		/* Collision Window */
 
 	u16 cmb_tpd;
@@ -194,20 +222,12 @@ struct atl1_hw {
 	u32 smb_timer;
 	u16 media_type;
 	u16 autoneg_advertised;
-	u16 pci_cmd_word;
 
 	u16 mii_autoneg_adv_reg;
 	u16 mii_1000t_ctrl_reg;
 
-	u32 mem_rang;
-	u32 txcw;
 	u32 max_frame_size;
 	u32 min_frame_size;
-	u32 mc_filter_type;
-	u32 num_mc_addrs;
-	u32 collision_delta;
-	u32 tx_packet_delta;
-	u16 phy_spd_default;
 
 	u16 dev_rev;
 	u8 revision_id;
@@ -215,28 +235,23 @@ struct atl1_hw {
 	/* spi flash */
 	u8 flash_vendor;
 
-	u8 dma_fairness;
 	u8 mac_addr[ETH_ALEN];
 	u8 perm_mac_addr[ETH_ALEN];
 
-	/* bool phy_preamble_sup; */
 	bool phy_configured;
 };
 
 struct atl1_adapter {
-	/* OS defined structs */
 	struct net_device *netdev;
 	struct pci_dev *pdev;
 	struct net_device_stats net_stats;
 	struct atl1_sft_stats soft_stats;
-
 	struct vlan_group *vlgrp;
 	u32 rx_buffer_len;
 	u32 wol;
 	u16 link_speed;
 	u16 link_duplex;
 	spinlock_t lock;
-	atomic_t irq_sem;
 	struct work_struct tx_timeout_task;
 	struct work_struct link_chg_task;
 	struct work_struct pcie_dma_to_rst_task;
@@ -244,9 +259,7 @@ struct atl1_adapter {
 	struct timer_list phy_config_timer;
 	bool phy_timer_pending;
 
-	bool mac_disabled;
-
-	/* All descriptor rings' memory */
+	/* all descriptor rings' memory */
 	struct atl1_ring_header ring_header;
 
 	/* TX */
@@ -259,25 +272,16 @@ struct atl1_adapter {
 	u64 hw_csum_err;
 	u64 hw_csum_good;
 
-	u32 gorcl;
-	u64 gorcl_old;
-
-	/* Interrupt Moderator timer ( 2us resolution) */
-	u16 imt;
-	/* Interrupt Clear timer (2us resolution) */
-	u16 ict;
-
-	/* MII interface info */
-	struct mii_if_info mii;
+	u16 imt;	/* interrupt moderator timer (2us resolution */
+	u16 ict;	/* interrupt clear timer (2us resolution */
+	struct mii_if_info mii;		/* MII interface info */
 
 	/* structs defined in atl1_hw.h */
-	u32 bd_number;		/* board number */
+	u32 bd_number;			/* board number */
 	bool pci_using_64;
 	struct atl1_hw hw;
 	struct atl1_smb smb;
 	struct atl1_cmb cmb;
-
-	u32 pci_state[16];
 };
 
 #endif	/* _ATL1_H_ */
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 3bb40dd..f7ac475 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -38,7 +38,7 @@
  * TODO:
  * Fix TSO; tx performance is horrible with TSO enabled.
  * Wake on LAN.
- * Add more ethtool functions, including set ring parameters.
+ * Add more ethtool functions.
  * Fix abstruse irq enable/disable condition described here:
  *	http://marc.theaimsgroup.com/?l=linux-netdev&m=116398508500553&w=2
  *
@@ -162,13 +162,70 @@ static int __devinit atl1_sw_init(struct atl1_adapter *adapter)
 	hw->cmb_tx_timer = 1;	/* about 2us */
 	hw->smb_timer = 100000;	/* about 200ms */
 
-	atomic_set(&adapter->irq_sem, 0);
 	spin_lock_init(&adapter->lock);
 	spin_lock_init(&adapter->mb_lock);
 
 	return 0;
 }
 
+static int mdio_read(struct net_device *netdev, int phy_id, int reg_num)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	u16 result;
+
+	atl1_read_phy_reg(&adapter->hw, reg_num & 0x1f, &result);
+
+	return result;
+}
+
+static void mdio_write(struct net_device *netdev, int phy_id, int reg_num,
+	int val)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+
+	atl1_write_phy_reg(&adapter->hw, reg_num, val);
+}
+
+/*
+ * atl1_mii_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	unsigned long flags;
+	int retval;
+
+	if (!netif_running(netdev))
+		return -EINVAL;
+
+	spin_lock_irqsave(&adapter->lock, flags);
+	retval = generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL);
+	spin_unlock_irqrestore(&adapter->lock, flags);
+
+	return retval;
+}
+
+/*
+ * atl1_ioctl -
+ * @netdev:
+ * @ifreq:
+ * @cmd:
+ */
+static int atl1_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
+{
+	switch (cmd) {
+	case SIOCGMIIPHY:
+	case SIOCGMIIREG:
+	case SIOCSMIIREG:
+		return atl1_mii_ioctl(netdev, ifr, cmd);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
 /*
  * atl1_setup_mem_resources - allocate Tx / RX descriptor resources
  * @adapter: board private structure
@@ -192,19 +249,22 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
 		goto err_nomem;
 	}
 	rfd_ring->buffer_info =
-	    (struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count);
+		(struct atl1_buffer *)(tpd_ring->buffer_info + tpd_ring->count);
 
-	/* real ring DMA buffer */
-	ring_header->size = size = sizeof(struct tx_packet_desc) *
-					tpd_ring->count
-	    + sizeof(struct rx_free_desc) * rfd_ring->count
-	    + sizeof(struct rx_return_desc) * rrd_ring->count
-	    + sizeof(struct coals_msg_block)
-	    + sizeof(struct stats_msg_block)
-	    + 40;		/* "40: for 8 bytes align" huh? -- CHS */
+	/* real ring DMA buffer
+	 * each ring/block may need up to 8 bytes for alignment, hence the
+	 * additional 40 bytes tacked onto the end.
+	 */
+	ring_header->size = size =
+		sizeof(struct tx_packet_desc) * tpd_ring->count
+		+ sizeof(struct rx_free_desc) * rfd_ring->count
+		+ sizeof(struct rx_return_desc) * rrd_ring->count
+		+ sizeof(struct coals_msg_block)
+		+ sizeof(struct stats_msg_block)
+		+ 40;
 
 	ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
-						&ring_header->dma);
+		&ring_header->dma);
 	if (unlikely(!ring_header->desc)) {
 		dev_err(&pdev->dev, "pci_alloc_consistent failed\n");
 		goto err_nomem;
@@ -218,8 +278,6 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
 	tpd_ring->dma += offset;
 	tpd_ring->desc = (u8 *) ring_header->desc + offset;
 	tpd_ring->size = sizeof(struct tx_packet_desc) * tpd_ring->count;
-	atomic_set(&tpd_ring->next_to_use, 0);
-	atomic_set(&tpd_ring->next_to_clean, 0);
 
 	/* init RFD ring */
 	rfd_ring->dma = tpd_ring->dma + tpd_ring->size;
@@ -227,9 +285,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
 	rfd_ring->dma += offset;
 	rfd_ring->desc = (u8 *) tpd_ring->desc + (tpd_ring->size + offset);
 	rfd_ring->size = sizeof(struct rx_free_desc) * rfd_ring->count;
-	rfd_ring->next_to_clean = 0;
-	/* rfd_ring->next_to_use = rfd_ring->count - 1; */
-	atomic_set(&rfd_ring->next_to_use, 0);
+
 
 	/* init RRD ring */
 	rrd_ring->dma = rfd_ring->dma + rfd_ring->size;
@@ -237,23 +293,22 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
 	rrd_ring->dma += offset;
 	rrd_ring->desc = (u8 *) rfd_ring->desc + (rfd_ring->size + offset);
 	rrd_ring->size = sizeof(struct rx_return_desc) * rrd_ring->count;
-	rrd_ring->next_to_use = 0;
-	atomic_set(&rrd_ring->next_to_clean, 0);
+
 
 	/* init CMB */
 	adapter->cmb.dma = rrd_ring->dma + rrd_ring->size;
 	offset = (adapter->cmb.dma & 0x7) ? (8 - (adapter->cmb.dma & 0x7)) : 0;
 	adapter->cmb.dma += offset;
-	adapter->cmb.cmb =
-	    (struct coals_msg_block *) ((u8 *) rrd_ring->desc +
-				   (rrd_ring->size + offset));
+	adapter->cmb.cmb = (struct coals_msg_block *)
+		((u8 *) rrd_ring->desc + (rrd_ring->size + offset));
 
 	/* init SMB */
 	adapter->smb.dma = adapter->cmb.dma + sizeof(struct coals_msg_block);
 	offset = (adapter->smb.dma & 0x7) ? (8 - (adapter->smb.dma & 0x7)) : 0;
 	adapter->smb.dma += offset;
 	adapter->smb.smb = (struct stats_msg_block *)
-	    ((u8 *) adapter->cmb.cmb + (sizeof(struct coals_msg_block) + offset));
+		((u8 *) adapter->cmb.cmb +
+		(sizeof(struct coals_msg_block) + offset));
 
 	return ATL1_SUCCESS;
 
@@ -262,559 +317,133 @@ err_nomem:
 	return -ENOMEM;
 }
 
-/*
- * atl1_irq_enable - Enable default interrupt generation settings
- * @adapter: board private structure
- */
-static void atl1_irq_enable(struct atl1_adapter *adapter)
-{
-	if (likely(!atomic_dec_and_test(&adapter->irq_sem)))
-		iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR);
-}
-
-static void atl1_clear_phy_int(struct atl1_adapter *adapter)
-{
-	u16 phy_data;
-	unsigned long flags;
-
-	spin_lock_irqsave(&adapter->lock, flags);
-	atl1_read_phy_reg(&adapter->hw, 19, &phy_data);
-	spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-static void atl1_inc_smb(struct atl1_adapter *adapter)
-{
-	struct stats_msg_block *smb = adapter->smb.smb;
-
-	/* Fill out the OS statistics structure */
-	adapter->soft_stats.rx_packets += smb->rx_ok;
-	adapter->soft_stats.tx_packets += smb->tx_ok;
-	adapter->soft_stats.rx_bytes += smb->rx_byte_cnt;
-	adapter->soft_stats.tx_bytes += smb->tx_byte_cnt;
-	adapter->soft_stats.multicast += smb->rx_mcast;
-	adapter->soft_stats.collisions += (smb->tx_1_col +
-					   smb->tx_2_col * 2 +
-					   smb->tx_late_col +
-					   smb->tx_abort_col *
-					   adapter->hw.max_retry);
-
-	/* Rx Errors */
-	adapter->soft_stats.rx_errors += (smb->rx_frag +
-					  smb->rx_fcs_err +
-					  smb->rx_len_err +
-					  smb->rx_sz_ov +
-					  smb->rx_rxf_ov +
-					  smb->rx_rrd_ov + smb->rx_align_err);
-	adapter->soft_stats.rx_fifo_errors += smb->rx_rxf_ov;
-	adapter->soft_stats.rx_length_errors += smb->rx_len_err;
-	adapter->soft_stats.rx_crc_errors += smb->rx_fcs_err;
-	adapter->soft_stats.rx_frame_errors += smb->rx_align_err;
-	adapter->soft_stats.rx_missed_errors += (smb->rx_rrd_ov +
-						 smb->rx_rxf_ov);
-
-	adapter->soft_stats.rx_pause += smb->rx_pause;
-	adapter->soft_stats.rx_rrd_ov += smb->rx_rrd_ov;
-	adapter->soft_stats.rx_trunc += smb->rx_sz_ov;
-
-	/* Tx Errors */
-	adapter->soft_stats.tx_errors += (smb->tx_late_col +
-					  smb->tx_abort_col +
-					  smb->tx_underrun + smb->tx_trunc);
-	adapter->soft_stats.tx_fifo_errors += smb->tx_underrun;
-	adapter->soft_stats.tx_aborted_errors += smb->tx_abort_col;
-	adapter->soft_stats.tx_window_errors += smb->tx_late_col;
-
-	adapter->soft_stats.excecol += smb->tx_abort_col;
-	adapter->soft_stats.deffer += smb->tx_defer;
-	adapter->soft_stats.scc += smb->tx_1_col;
-	adapter->soft_stats.mcc += smb->tx_2_col;
-	adapter->soft_stats.latecol += smb->tx_late_col;
-	adapter->soft_stats.tx_underun += smb->tx_underrun;
-	adapter->soft_stats.tx_trunc += smb->tx_trunc;
-	adapter->soft_stats.tx_pause += smb->tx_pause;
-
-	adapter->net_stats.rx_packets = adapter->soft_stats.rx_packets;
-	adapter->net_stats.tx_packets = adapter->soft_stats.tx_packets;
-	adapter->net_stats.rx_bytes = adapter->soft_stats.rx_bytes;
-	adapter->net_stats.tx_bytes = adapter->soft_stats.tx_bytes;
-	adapter->net_stats.multicast = adapter->soft_stats.multicast;
-	adapter->net_stats.collisions = adapter->soft_stats.collisions;
-	adapter->net_stats.rx_errors = adapter->soft_stats.rx_errors;
-	adapter->net_stats.rx_over_errors =
-	    adapter->soft_stats.rx_missed_errors;
-	adapter->net_stats.rx_length_errors =
-	    adapter->soft_stats.rx_length_errors;
-	adapter->net_stats.rx_crc_errors = adapter->soft_stats.rx_crc_errors;
-	adapter->net_stats.rx_frame_errors =
-	    adapter->soft_stats.rx_frame_errors;
-	adapter->net_stats.rx_fifo_errors = adapter->soft_stats.rx_fifo_errors;
-	adapter->net_stats.rx_missed_errors =
-	    adapter->soft_stats.rx_missed_errors;
-	adapter->net_stats.tx_errors = adapter->soft_stats.tx_errors;
-	adapter->net_stats.tx_fifo_errors = adapter->soft_stats.tx_fifo_errors;
-	adapter->net_stats.tx_aborted_errors =
-	    adapter->soft_stats.tx_aborted_errors;
-	adapter->net_stats.tx_window_errors =
-	    adapter->soft_stats.tx_window_errors;
-	adapter->net_stats.tx_carrier_errors =
-	    adapter->soft_stats.tx_carrier_errors;
-}
-
-static void atl1_rx_checksum(struct atl1_adapter *adapter,
-					struct rx_return_desc *rrd,
-					struct sk_buff *skb)
+void atl1_init_ring_ptrs(struct atl1_adapter *adapter)
 {
-	skb->ip_summed = CHECKSUM_NONE;
-
-	if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
-		if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
-					ERR_FLAG_CODE | ERR_FLAG_OV)) {
-			adapter->hw_csum_err++;
-			dev_dbg(&adapter->pdev->dev, "rx checksum error\n");
-			return;
-		}
-	}
+	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+	struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+	struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
 
-	/* not IPv4 */
-	if (!(rrd->pkt_flg & PACKET_FLAG_IPV4))
-		/* checksum is invalid, but it's not an IPv4 pkt, so ok */
-		return;
+	atomic_set(&tpd_ring->next_to_use, 0);
+	atomic_set(&tpd_ring->next_to_clean, 0);
 
-	/* IPv4 packet */
-	if (likely(!(rrd->err_flg &
-		(ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM)))) {
-		skb->ip_summed = CHECKSUM_UNNECESSARY;
-		adapter->hw_csum_good++;
-		return;
-	}
+	rfd_ring->next_to_clean = 0;
+	atomic_set(&rfd_ring->next_to_use, 0);
 
-	/* IPv4, but hardware thinks its checksum is wrong */
-	dev_dbg(&adapter->pdev->dev,
-		"hw csum wrong, pkt_flag:%x, err_flag:%x\n",
-		rrd->pkt_flg, rrd->err_flg);
-	skb->ip_summed = CHECKSUM_COMPLETE;
-	skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum);
-	adapter->hw_csum_err++;
-	return;
+	rrd_ring->next_to_use = 0;
+	atomic_set(&rrd_ring->next_to_clean, 0);
 }
 
 /*
- * atl1_alloc_rx_buffers - Replace used receive buffers
- * @adapter: address of board private structure
+ * atl1_clean_rx_ring - Free RFD Buffers
+ * @adapter: board private structure
  */
-static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
-{
-	struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-	struct pci_dev *pdev = adapter->pdev;
-	struct page *page;
-	unsigned long offset;
-	struct atl1_buffer *buffer_info, *next_info;
-	struct sk_buff *skb;
-	u16 num_alloc = 0;
-	u16 rfd_next_to_use, next_next;
-	struct rx_free_desc *rfd_desc;
-
-	next_next = rfd_next_to_use = atomic_read(&rfd_ring->next_to_use);
-	if (++next_next == rfd_ring->count)
-		next_next = 0;
-	buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
-	next_info = &rfd_ring->buffer_info[next_next];
-
-	while (!buffer_info->alloced && !next_info->alloced) {
-		if (buffer_info->skb) {
-			buffer_info->alloced = 1;
-			goto next;
-		}
-
-		rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use);
-
-		skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
-		if (unlikely(!skb)) {	/* Better luck next round */
-			adapter->net_stats.rx_dropped++;
-			break;
-		}
-
-		/*
-		 * Make buffer alignment 2 beyond a 16 byte boundary
-		 * this will result in a 16 byte aligned IP header after
-		 * the 14 byte MAC header is removed
-		 */
-		skb_reserve(skb, NET_IP_ALIGN);
-
-		buffer_info->alloced = 1;
-		buffer_info->skb = skb;
-		buffer_info->length = (u16) adapter->rx_buffer_len;
-		page = virt_to_page(skb->data);
-		offset = (unsigned long)skb->data & ~PAGE_MASK;
-		buffer_info->dma = pci_map_page(pdev, page, offset,
-						adapter->rx_buffer_len,
-						PCI_DMA_FROMDEVICE);
-		rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
-		rfd_desc->buf_len = cpu_to_le16(adapter->rx_buffer_len);
-		rfd_desc->coalese = 0;
-
-next:
-		rfd_next_to_use = next_next;
-		if (unlikely(++next_next == rfd_ring->count))
-			next_next = 0;
-
-		buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
-		next_info = &rfd_ring->buffer_info[next_next];
-		num_alloc++;
-	}
-
-	if (num_alloc) {
-		/*
-		 * Force memory writes to complete before letting h/w
-		 * know there are new descriptors to fetch.  (Only
-		 * applicable for weak-ordered memory model archs,
-		 * such as IA-64).
-		 */
-		wmb();
-		atomic_set(&rfd_ring->next_to_use, (int)rfd_next_to_use);
-	}
-	return num_alloc;
-}
-
-static void atl1_intr_rx(struct atl1_adapter *adapter)
+static void atl1_clean_rx_ring(struct atl1_adapter *adapter)
 {
-	int i, count;
-	u16 length;
-	u16 rrd_next_to_clean;
-	u32 value;
 	struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
 	struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
 	struct atl1_buffer *buffer_info;
-	struct rx_return_desc *rrd;
-	struct sk_buff *skb;
-
-	count = 0;
-
-	rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean);
-
-	while (1) {
-		rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean);
-		i = 1;
-		if (likely(rrd->xsz.valid)) {	/* packet valid */
-chk_rrd:
-			/* check rrd status */
-			if (likely(rrd->num_buf == 1))
-				goto rrd_ok;
-
-			/* rrd seems to be bad */
-			if (unlikely(i-- > 0)) {
-				/* rrd may not be DMAed completely */
-				dev_dbg(&adapter->pdev->dev,
-					"incomplete RRD DMA transfer\n");
-				udelay(1);
-				goto chk_rrd;
-			}
-			/* bad rrd */
-			dev_dbg(&adapter->pdev->dev, "bad RRD\n");
-			/* see if update RFD index */
-			if (rrd->num_buf > 1) {
-				u16 num_buf;
-				num_buf =
-				    (rrd->xsz.xsum_sz.pkt_size +
-				     adapter->rx_buffer_len -
-				     1) / adapter->rx_buffer_len;
-				if (rrd->num_buf == num_buf) {
-					/* clean alloc flag for bad rrd */
-					while (rfd_ring->next_to_clean !=
-					       (rrd->buf_indx + num_buf)) {
-						rfd_ring->buffer_info[rfd_ring->
-								      next_to_clean].alloced = 0;
-						if (++rfd_ring->next_to_clean ==
-						    rfd_ring->count) {
-							rfd_ring->
-							    next_to_clean = 0;
-						}
-					}
-				}
-			}
-
-			/* update rrd */
-			rrd->xsz.valid = 0;
-			if (++rrd_next_to_clean == rrd_ring->count)
-				rrd_next_to_clean = 0;
-			count++;
-			continue;
-		} else {	/* current rrd still not be updated */
+	struct pci_dev *pdev = adapter->pdev;
+	unsigned long size;
+	unsigned int i;
 
-			break;
-		}
-rrd_ok:
-		/* clean alloc flag for bad rrd */
-		while (rfd_ring->next_to_clean != rrd->buf_indx) {
-			rfd_ring->buffer_info[rfd_ring->next_to_clean].alloced =
-			    0;
-			if (++rfd_ring->next_to_clean == rfd_ring->count)
-				rfd_ring->next_to_clean = 0;
+	/* Free all the Rx ring sk_buffs */
+	for (i = 0; i < rfd_ring->count; i++) {
+		buffer_info = &rfd_ring->buffer_info[i];
+		if (buffer_info->dma) {
+			pci_unmap_page(pdev, buffer_info->dma,
+				buffer_info->length, PCI_DMA_FROMDEVICE);
+			buffer_info->dma = 0;
 		}
-
-		buffer_info = &rfd_ring->buffer_info[rrd->buf_indx];
-		if (++rfd_ring->next_to_clean == rfd_ring->count)
-			rfd_ring->next_to_clean = 0;
-
-		/* update rrd next to clean */
-		if (++rrd_next_to_clean == rrd_ring->count)
-			rrd_next_to_clean = 0;
-		count++;
-
-		if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
-			if (!(rrd->err_flg &
-				(ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM
-				| ERR_FLAG_LEN))) {
-				/* packet error, don't need upstream */
-				buffer_info->alloced = 0;
-				rrd->xsz.valid = 0;
-				continue;
-			}
+		if (buffer_info->skb) {
+			dev_kfree_skb(buffer_info->skb);
+			buffer_info->skb = NULL;
 		}
-
-		/* Good Receive */
-		pci_unmap_page(adapter->pdev, buffer_info->dma,
-			       buffer_info->length, PCI_DMA_FROMDEVICE);
-		skb = buffer_info->skb;
-		length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size);
-
-		skb_put(skb, length - ETHERNET_FCS_SIZE);
-
-		/* Receive Checksum Offload */
-		atl1_rx_checksum(adapter, rrd, skb);
-		skb->protocol = eth_type_trans(skb, adapter->netdev);
-
-		if (adapter->vlgrp && (rrd->pkt_flg & PACKET_FLAG_VLAN_INS)) {
-			u16 vlan_tag = (rrd->vlan_tag >> 4) |
-					((rrd->vlan_tag & 7) << 13) |
-					((rrd->vlan_tag & 8) << 9);
-			vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag);
-		} else
-			netif_rx(skb);
-
-		/* let protocol layer free skb */
-		buffer_info->skb = NULL;
-		buffer_info->alloced = 0;
-		rrd->xsz.valid = 0;
-
-		adapter->netdev->last_rx = jiffies;
 	}
 
-	atomic_set(&rrd_ring->next_to_clean, rrd_next_to_clean);
-
-	atl1_alloc_rx_buffers(adapter);
+	size = sizeof(struct atl1_buffer) * rfd_ring->count;
+	memset(rfd_ring->buffer_info, 0, size);
 
-	/* update mailbox ? */
-	if (count) {
-		u32 tpd_next_to_use;
-		u32 rfd_next_to_use;
-		u32 rrd_next_to_clean;
+	/* Zero out the descriptor ring */
+	memset(rfd_ring->desc, 0, rfd_ring->size);
 
-		spin_lock(&adapter->mb_lock);
+	rfd_ring->next_to_clean = 0;
+	atomic_set(&rfd_ring->next_to_use, 0);
 
-		tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use);
-		rfd_next_to_use =
-		    atomic_read(&adapter->rfd_ring.next_to_use);
-		rrd_next_to_clean =
-		    atomic_read(&adapter->rrd_ring.next_to_clean);
-		value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) <<
-			MB_RFD_PROD_INDX_SHIFT) |
-                        ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) <<
-			MB_RRD_CONS_INDX_SHIFT) |
-                        ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) <<
-			MB_TPD_PROD_INDX_SHIFT);
-		iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
-		spin_unlock(&adapter->mb_lock);
-	}
+	rrd_ring->next_to_use = 0;
+	atomic_set(&rrd_ring->next_to_clean, 0);
 }
 
-static void atl1_intr_tx(struct atl1_adapter *adapter)
+/*
+ * atl1_clean_tx_ring - Free Tx Buffers
+ * @adapter: board private structure
+ */
+static void atl1_clean_tx_ring(struct atl1_adapter *adapter)
 {
 	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
 	struct atl1_buffer *buffer_info;
-	u16 sw_tpd_next_to_clean;
-	u16 cmb_tpd_next_to_clean;
-
-	sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
-	cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
-
-	while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
-		struct tx_packet_desc *tpd;
+	struct pci_dev *pdev = adapter->pdev;
+	unsigned long size;
+	unsigned int i;
 
-		tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean);
-		buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
+	/* Free all the Tx ring sk_buffs */
+	for (i = 0; i < tpd_ring->count; i++) {
+		buffer_info = &tpd_ring->buffer_info[i];
 		if (buffer_info->dma) {
-			pci_unmap_page(adapter->pdev, buffer_info->dma,
-				       buffer_info->length, PCI_DMA_TODEVICE);
+			pci_unmap_page(pdev, buffer_info->dma,
+				buffer_info->length, PCI_DMA_TODEVICE);
 			buffer_info->dma = 0;
 		}
+	}
 
+	for (i = 0; i < tpd_ring->count; i++) {
+		buffer_info = &tpd_ring->buffer_info[i];
 		if (buffer_info->skb) {
-			dev_kfree_skb_irq(buffer_info->skb);
+			dev_kfree_skb_any(buffer_info->skb);
 			buffer_info->skb = NULL;
 		}
-		tpd->buffer_addr = 0;
-		tpd->desc.data = 0;
-
-		if (++sw_tpd_next_to_clean == tpd_ring->count)
-			sw_tpd_next_to_clean = 0;
 	}
-	atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean);
-
-	if (netif_queue_stopped(adapter->netdev)
-	    && netif_carrier_ok(adapter->netdev))
-		netif_wake_queue(adapter->netdev);
-}
 
-static void atl1_check_for_link(struct atl1_adapter *adapter)
-{
-	struct net_device *netdev = adapter->netdev;
-	u16 phy_data = 0;
-
-	spin_lock(&adapter->lock);
-	adapter->phy_timer_pending = false;
-	atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-	atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
-	spin_unlock(&adapter->lock);
-
-	/* notify upper layer link down ASAP */
-	if (!(phy_data & BMSR_LSTATUS)) {	/* Link Down */
-		if (netif_carrier_ok(netdev)) {	/* old link state: Up */
-			dev_info(&adapter->pdev->dev, "%s link is down\n",
-				netdev->name);
-			adapter->link_speed = SPEED_0;
-			netif_carrier_off(netdev);
-			netif_stop_queue(netdev);
-		}
-	}
-	schedule_work(&adapter->link_chg_task);
-}
-
-/*
- * atl1_intr - Interrupt Handler
- * @irq: interrupt number
- * @data: pointer to a network interface device structure
- * @pt_regs: CPU registers structure
- */
-static irqreturn_t atl1_intr(int irq, void *data)
-{
-	/*struct atl1_adapter *adapter = ((struct net_device *)data)->priv;*/
-	struct atl1_adapter *adapter = netdev_priv(data);
-	u32 status;
-	u8 update_rx;
-	int max_ints = 10;
-
-	status = adapter->cmb.cmb->int_stats;
-	if (!status)
-		return IRQ_NONE;
-
-	update_rx = 0;
-
-	do {
-		/* clear CMB interrupt status at once */
-		adapter->cmb.cmb->int_stats = 0;
-
-		if (status & ISR_GPHY)	/* clear phy status */
-			atl1_clear_phy_int(adapter);
-
-		/* clear ISR status, and Enable CMB DMA/Disable Interrupt */
-		iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR);
-
-		/* check if SMB intr */
-		if (status & ISR_SMB)
-			atl1_inc_smb(adapter);
-
-		/* check if PCIE PHY Link down */
-		if (status & ISR_PHY_LINKDOWN) {
-			dev_dbg(&adapter->pdev->dev, "pcie phy link down %x\n",
-				status);
-			if (netif_running(adapter->netdev)) {	/* reset MAC */
-				iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-				schedule_work(&adapter->pcie_dma_to_rst_task);
-				return IRQ_HANDLED;
-			}
-		}
-
-		/* check if DMA read/write error ? */
-		if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
-			dev_dbg(&adapter->pdev->dev,
-				"pcie DMA r/w error (status = 0x%x)\n",
-				status);
-			iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-			schedule_work(&adapter->pcie_dma_to_rst_task);
-			return IRQ_HANDLED;
-		}
-
-		/* link event */
-		if (status & ISR_GPHY) {
-			adapter->soft_stats.tx_carrier_errors++;
-			atl1_check_for_link(adapter);
-		}
-
-		/* transmit event */
-		if (status & ISR_CMB_TX)
-			atl1_intr_tx(adapter);
-
-		/* rx exception */
-		if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
-			ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
-			ISR_HOST_RRD_OV | ISR_CMB_RX))) {
-			if (status & (ISR_RXF_OV | ISR_RFD_UNRUN |
-				ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
-				ISR_HOST_RRD_OV))
-				dev_dbg(&adapter->pdev->dev,
-					"rx exception, ISR = 0x%x\n", status);
-			atl1_intr_rx(adapter);
-		}
-
-		if (--max_ints < 0)
-			break;
+	size = sizeof(struct atl1_buffer) * tpd_ring->count;
+	memset(tpd_ring->buffer_info, 0, size);
 
-	} while ((status = adapter->cmb.cmb->int_stats));
+	/* Zero out the descriptor ring */
+	memset(tpd_ring->desc, 0, tpd_ring->size);
 
-	/* re-enable Interrupt */
-	iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR);
-	return IRQ_HANDLED;
+	atomic_set(&tpd_ring->next_to_use, 0);
+	atomic_set(&tpd_ring->next_to_clean, 0);
 }
 
 /*
- * atl1_set_multi - Multicast and Promiscuous mode set
- * @netdev: network interface device structure
+ * atl1_free_ring_resources - Free Tx / RX descriptor Resources
+ * @adapter: board private structure
  *
- * The set_multi entry point is called whenever the multicast address
- * list or the network interface flags are updated.  This routine is
- * responsible for configuring the hardware for proper multicast,
- * promiscuous mode, and all-multi behavior.
+ * Free all transmit software resources
  */
-static void atl1_set_multi(struct net_device *netdev)
+void atl1_free_ring_resources(struct atl1_adapter *adapter)
 {
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	struct atl1_hw *hw = &adapter->hw;
-	struct dev_mc_list *mc_ptr;
-	u32 rctl;
-	u32 hash_value;
+	struct pci_dev *pdev = adapter->pdev;
+	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+	struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+	struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
+	struct atl1_ring_header *ring_header = &adapter->ring_header;
 
-	/* Check for Promiscuous and All Multicast modes */
-	rctl = ioread32(hw->hw_addr + REG_MAC_CTRL);
-	if (netdev->flags & IFF_PROMISC)
-		rctl |= MAC_CTRL_PROMIS_EN;
-	else if (netdev->flags & IFF_ALLMULTI) {
-		rctl |= MAC_CTRL_MC_ALL_EN;
-		rctl &= ~MAC_CTRL_PROMIS_EN;
-	} else
-		rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
+	atl1_clean_tx_ring(adapter);
+	atl1_clean_rx_ring(adapter);
 
-	iowrite32(rctl, hw->hw_addr + REG_MAC_CTRL);
+	kfree(tpd_ring->buffer_info);
+	pci_free_consistent(pdev, ring_header->size, ring_header->desc,
+		ring_header->dma);
 
-	/* clear the old settings from the multicast hash table */
-	iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
-	iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
+	tpd_ring->buffer_info = NULL;
+	tpd_ring->desc = NULL;
+	tpd_ring->dma = 0;
 
-	/* compute mc addresses' hash value ,and put it into hash table */
-	for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
-		hash_value = atl1_hash_mc_addr(hw, mc_ptr->dmi_addr);
-		atl1_hash_set(hw, hash_value);
-	}
+	rfd_ring->buffer_info = NULL;
+	rfd_ring->desc = NULL;
+	rfd_ring->dma = 0;
+
+	rrd_ring->desc = NULL;
+	rrd_ring->dma = 0;
 }
 
 static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
@@ -855,6 +484,31 @@ static void atl1_setup_mac_ctrl(struct atl1_adapter *adapter)
 	iowrite32(value, hw->hw_addr + REG_MAC_CTRL);
 }
 
+/*
+ * atl1_set_mac - Change the Ethernet Address of the NIC
+ * @netdev: network interface device structure
+ * @p: pointer to an address structure
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1_set_mac(struct net_device *netdev, void *p)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct sockaddr *addr = p;
+
+	if (netif_running(netdev))
+		return -EBUSY;
+
+	if (!is_valid_ether_addr(addr->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
+	memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
+
+	atl1_set_mac_addr(&adapter->hw);
+	return 0;
+}
+
 static u32 atl1_check_link(struct atl1_adapter *adapter)
 {
 	struct atl1_hw *hw = &adapter->hw;
@@ -962,6 +616,103 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
 	return ATL1_SUCCESS;
 }
 
+static void atl1_check_for_link(struct atl1_adapter *adapter)
+{
+	struct net_device *netdev = adapter->netdev;
+	u16 phy_data = 0;
+
+	spin_lock(&adapter->lock);
+	adapter->phy_timer_pending = false;
+	atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+	atl1_read_phy_reg(&adapter->hw, MII_BMSR, &phy_data);
+	spin_unlock(&adapter->lock);
+
+	/* notify upper layer link down ASAP */
+	if (!(phy_data & BMSR_LSTATUS)) {	/* Link Down */
+		if (netif_carrier_ok(netdev)) {	/* old link state: Up */
+			dev_info(&adapter->pdev->dev, "%s link is down\n",
+				netdev->name);
+			adapter->link_speed = SPEED_0;
+			netif_carrier_off(netdev);
+			netif_stop_queue(netdev);
+		}
+	}
+	schedule_work(&adapter->link_chg_task);
+}
+
+/*
+ * atl1_set_multi - Multicast and Promiscuous mode set
+ * @netdev: network interface device structure
+ *
+ * The set_multi entry point is called whenever the multicast address
+ * list or the network interface flags are updated.  This routine is
+ * responsible for configuring the hardware for proper multicast,
+ * promiscuous mode, and all-multi behavior.
+ */
+static void atl1_set_multi(struct net_device *netdev)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_hw *hw = &adapter->hw;
+	struct dev_mc_list *mc_ptr;
+	u32 rctl;
+	u32 hash_value;
+
+	/* Check for Promiscuous and All Multicast modes */
+	rctl = ioread32(hw->hw_addr + REG_MAC_CTRL);
+	if (netdev->flags & IFF_PROMISC)
+		rctl |= MAC_CTRL_PROMIS_EN;
+	else if (netdev->flags & IFF_ALLMULTI) {
+		rctl |= MAC_CTRL_MC_ALL_EN;
+		rctl &= ~MAC_CTRL_PROMIS_EN;
+	} else
+		rctl &= ~(MAC_CTRL_PROMIS_EN | MAC_CTRL_MC_ALL_EN);
+
+	iowrite32(rctl, hw->hw_addr + REG_MAC_CTRL);
+
+	/* clear the old settings from the multicast hash table */
+	iowrite32(0, hw->hw_addr + REG_RX_HASH_TABLE);
+	iowrite32(0, (hw->hw_addr + REG_RX_HASH_TABLE) + (1 << 2));
+
+	/* compute mc addresses' hash value ,and put it into hash table */
+	for (mc_ptr = netdev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) {
+		hash_value = atl1_hash_mc_addr(hw, mc_ptr->dmi_addr);
+		atl1_hash_set(hw, hash_value);
+	}
+}
+
+/*
+ * atl1_change_mtu - Change the Maximum Transfer Unit
+ * @netdev: network interface device structure
+ * @new_mtu: new value for maximum frame size
+ *
+ * Returns 0 on success, negative on failure
+ */
+static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	int old_mtu = netdev->mtu;
+	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
+
+	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
+	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
+		dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
+		return -EINVAL;
+	}
+
+	adapter->hw.max_frame_size = max_frame;
+	adapter->hw.tx_jumbo_task_th = (max_frame + 7) >> 3;
+	adapter->rx_buffer_len = (max_frame + 7) & ~7;
+	adapter->hw.rx_jumbo_th = adapter->rx_buffer_len / 8;
+
+	netdev->mtu = new_mtu;
+	if ((old_mtu != new_mtu) && netif_running(netdev)) {
+		atl1_down(adapter);
+		atl1_up(adapter);
+	}
+
+	return 0;
+}
+
 static void set_flow_ctrl_old(struct atl1_adapter *adapter)
 {
 	u32 hi, lo, value;
@@ -974,7 +725,7 @@ static void set_flow_ctrl_old(struct atl1_adapter *adapter)
 	lo = value * 7 / 8;
 
 	value = ((hi & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) |
-	    ((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT);
+		((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT);
 	iowrite32(value, adapter->hw.hw_addr + REG_RXQ_RXF_PAUSE_THRESH);
 
 	/* RRD Flow Control */
@@ -984,7 +735,7 @@ static void set_flow_ctrl_old(struct atl1_adapter *adapter)
 	if (lo < 2)
 		lo = 2;
 	value = ((hi & RXQ_RRD_PAUSE_TH_HI_MASK) << RXQ_RRD_PAUSE_TH_HI_SHIFT) |
-	    ((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT);
+		((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT);
 	iowrite32(value, adapter->hw.hw_addr + REG_RXQ_RRD_PAUSE_THRESH);
 }
 
@@ -1001,7 +752,7 @@ static void set_flow_ctrl_new(struct atl1_hw *hw)
 	if (hi < lo)
 		hi = lo + 16;
 	value = ((hi & RXQ_RXF_PAUSE_TH_HI_MASK) << RXQ_RXF_PAUSE_TH_HI_SHIFT) |
-	    ((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT);
+		((lo & RXQ_RXF_PAUSE_TH_LO_MASK) << RXQ_RXF_PAUSE_TH_LO_SHIFT);
 	iowrite32(value, hw->hw_addr + REG_RXQ_RXF_PAUSE_THRESH);
 
 	/* RRD Flow Control */
@@ -1013,7 +764,7 @@ static void set_flow_ctrl_new(struct atl1_hw *hw)
 	if (hi < lo)
 		hi = lo + 3;
 	value = ((hi & RXQ_RRD_PAUSE_TH_HI_MASK) << RXQ_RRD_PAUSE_TH_HI_SHIFT) |
-	    ((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT);
+		((lo & RXQ_RRD_PAUSE_TH_LO_MASK) << RXQ_RRD_PAUSE_TH_LO_SHIFT);
 	iowrite32(value, hw->hw_addr + REG_RXQ_RRD_PAUSE_THRESH);
 }
 
@@ -1062,7 +813,8 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
 	value <<= 16;
 	value += adapter->rfd_ring.count;
 	iowrite32(value, hw->hw_addr + REG_DESC_RFD_RRD_RING_SIZE);
-	iowrite32(adapter->tpd_ring.count, hw->hw_addr + REG_DESC_TPD_RING_SIZE);
+	iowrite32(adapter->tpd_ring.count, hw->hw_addr +
+		REG_DESC_TPD_RING_SIZE);
 
 	/* Load Ptr */
 	iowrite32(1, hw->hw_addr + REG_LOAD_PTR);
@@ -1070,31 +822,31 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
 	/* config Mailbox */
 	value = ((atomic_read(&adapter->tpd_ring.next_to_use)
 		  & MB_TPD_PROD_INDX_MASK) << MB_TPD_PROD_INDX_SHIFT) |
-	    ((atomic_read(&adapter->rrd_ring.next_to_clean)
-	      & MB_RRD_CONS_INDX_MASK) << MB_RRD_CONS_INDX_SHIFT) |
-	    ((atomic_read(&adapter->rfd_ring.next_to_use)
-	      & MB_RFD_PROD_INDX_MASK) << MB_RFD_PROD_INDX_SHIFT);
+		((atomic_read(&adapter->rrd_ring.next_to_clean)
+		& MB_RRD_CONS_INDX_MASK) << MB_RRD_CONS_INDX_SHIFT) |
+		((atomic_read(&adapter->rfd_ring.next_to_use)
+		& MB_RFD_PROD_INDX_MASK) << MB_RFD_PROD_INDX_SHIFT);
 	iowrite32(value, hw->hw_addr + REG_MAILBOX);
 
 	/* config IPG/IFG */
 	value = (((u32) hw->ipgt & MAC_IPG_IFG_IPGT_MASK)
 		 << MAC_IPG_IFG_IPGT_SHIFT) |
-	    (((u32) hw->min_ifg & MAC_IPG_IFG_MIFG_MASK)
-	     << MAC_IPG_IFG_MIFG_SHIFT) |
-	    (((u32) hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK)
-	     << MAC_IPG_IFG_IPGR1_SHIFT) |
-	    (((u32) hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK)
-	     << MAC_IPG_IFG_IPGR2_SHIFT);
+		(((u32) hw->min_ifg & MAC_IPG_IFG_MIFG_MASK)
+		<< MAC_IPG_IFG_MIFG_SHIFT) |
+		(((u32) hw->ipgr1 & MAC_IPG_IFG_IPGR1_MASK)
+		<< MAC_IPG_IFG_IPGR1_SHIFT) |
+		(((u32) hw->ipgr2 & MAC_IPG_IFG_IPGR2_MASK)
+		<< MAC_IPG_IFG_IPGR2_SHIFT);
 	iowrite32(value, hw->hw_addr + REG_MAC_IPG_IFG);
 
 	/* config  Half-Duplex Control */
 	value = ((u32) hw->lcol & MAC_HALF_DUPLX_CTRL_LCOL_MASK) |
-	    (((u32) hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK)
-	     << MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) |
-	    MAC_HALF_DUPLX_CTRL_EXC_DEF_EN |
-	    (0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) |
-	    (((u32) hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK)
-	     << MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT);
+		(((u32) hw->max_retry & MAC_HALF_DUPLX_CTRL_RETRY_MASK)
+		<< MAC_HALF_DUPLX_CTRL_RETRY_SHIFT) |
+		MAC_HALF_DUPLX_CTRL_EXC_DEF_EN |
+		(0xa << MAC_HALF_DUPLX_CTRL_ABEBT_SHIFT) |
+		(((u32) hw->jam_ipg & MAC_HALF_DUPLX_CTRL_JAMIPG_MASK)
+		<< MAC_HALF_DUPLX_CTRL_JAMIPG_SHIFT);
 	iowrite32(value, hw->hw_addr + REG_MAC_HALF_DUPLX_CTRL);
 
 	/* set Interrupt Moderator Timer */
@@ -1110,10 +862,10 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
 	/* jumbo size & rrd retirement timer */
 	value = (((u32) hw->rx_jumbo_th & RXQ_JMBOSZ_TH_MASK)
 		 << RXQ_JMBOSZ_TH_SHIFT) |
-	    (((u32) hw->rx_jumbo_lkah & RXQ_JMBO_LKAH_MASK)
-	     << RXQ_JMBO_LKAH_SHIFT) |
-	    (((u32) hw->rrd_ret_timer & RXQ_RRD_TIMER_MASK)
-	     << RXQ_RRD_TIMER_SHIFT);
+		(((u32) hw->rx_jumbo_lkah & RXQ_JMBO_LKAH_MASK)
+		<< RXQ_JMBO_LKAH_SHIFT) |
+		(((u32) hw->rrd_ret_timer & RXQ_RRD_TIMER_MASK)
+		<< RXQ_RRD_TIMER_SHIFT);
 	iowrite32(value, hw->hw_addr + REG_RXQ_JMBOSZ_RRDTIM);
 
 	/* Flow Control */
@@ -1132,35 +884,36 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
 	/* config TXQ */
 	value = (((u32) hw->tpd_burst & TXQ_CTRL_TPD_BURST_NUM_MASK)
 		 << TXQ_CTRL_TPD_BURST_NUM_SHIFT) |
-	    (((u32) hw->txf_burst & TXQ_CTRL_TXF_BURST_NUM_MASK)
-	     << TXQ_CTRL_TXF_BURST_NUM_SHIFT) |
-	    (((u32) hw->tpd_fetch_th & TXQ_CTRL_TPD_FETCH_TH_MASK)
-	     << TXQ_CTRL_TPD_FETCH_TH_SHIFT) | TXQ_CTRL_ENH_MODE | TXQ_CTRL_EN;
+		(((u32) hw->txf_burst & TXQ_CTRL_TXF_BURST_NUM_MASK)
+		<< TXQ_CTRL_TXF_BURST_NUM_SHIFT) |
+		(((u32) hw->tpd_fetch_th & TXQ_CTRL_TPD_FETCH_TH_MASK)
+		<< TXQ_CTRL_TPD_FETCH_TH_SHIFT) | TXQ_CTRL_ENH_MODE |
+		TXQ_CTRL_EN;
 	iowrite32(value, hw->hw_addr + REG_TXQ_CTRL);
 
 	/* min tpd fetch gap & tx jumbo packet size threshold for taskoffload */
 	value = (((u32) hw->tx_jumbo_task_th & TX_JUMBO_TASK_TH_MASK)
-		 << TX_JUMBO_TASK_TH_SHIFT) |
-	    (((u32) hw->tpd_fetch_gap & TX_TPD_MIN_IPG_MASK)
-	     << TX_TPD_MIN_IPG_SHIFT);
+		<< TX_JUMBO_TASK_TH_SHIFT) |
+		(((u32) hw->tpd_fetch_gap & TX_TPD_MIN_IPG_MASK)
+		<< TX_TPD_MIN_IPG_SHIFT);
 	iowrite32(value, hw->hw_addr + REG_TX_JUMBO_TASK_TH_TPD_IPG);
 
 	/* config RXQ */
 	value = (((u32) hw->rfd_burst & RXQ_CTRL_RFD_BURST_NUM_MASK)
-		 << RXQ_CTRL_RFD_BURST_NUM_SHIFT) |
-	    (((u32) hw->rrd_burst & RXQ_CTRL_RRD_BURST_THRESH_MASK)
-	     << RXQ_CTRL_RRD_BURST_THRESH_SHIFT) |
-	    (((u32) hw->rfd_fetch_gap & RXQ_CTRL_RFD_PREF_MIN_IPG_MASK)
-	     << RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT) |
-	    RXQ_CTRL_CUT_THRU_EN | RXQ_CTRL_EN;
+		<< RXQ_CTRL_RFD_BURST_NUM_SHIFT) |
+		(((u32) hw->rrd_burst & RXQ_CTRL_RRD_BURST_THRESH_MASK)
+		<< RXQ_CTRL_RRD_BURST_THRESH_SHIFT) |
+		(((u32) hw->rfd_fetch_gap & RXQ_CTRL_RFD_PREF_MIN_IPG_MASK)
+		<< RXQ_CTRL_RFD_PREF_MIN_IPG_SHIFT) | RXQ_CTRL_CUT_THRU_EN |
+		RXQ_CTRL_EN;
 	iowrite32(value, hw->hw_addr + REG_RXQ_CTRL);
 
 	/* config DMA Engine */
 	value = ((((u32) hw->dmar_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
-		 << DMA_CTRL_DMAR_BURST_LEN_SHIFT) |
-	    ((((u32) hw->dmaw_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
-	     << DMA_CTRL_DMAR_BURST_LEN_SHIFT) |
-	    DMA_CTRL_DMAR_EN | DMA_CTRL_DMAW_EN;
+		<< DMA_CTRL_DMAR_BURST_LEN_SHIFT) |
+		((((u32) hw->dmaw_block) & DMA_CTRL_DMAR_BURST_LEN_MASK)
+		<< DMA_CTRL_DMAR_BURST_LEN_SHIFT) | DMA_CTRL_DMAR_EN |
+		DMA_CTRL_DMAW_EN;
 	value |= (u32) hw->dma_ord;
 	if (atl1_rcb_128 == hw->rcb_value)
 		value |= DMA_CTRL_RCB_VALUE;
@@ -1190,56 +943,495 @@ static u32 atl1_configure(struct atl1_adapter *adapter)
 }
 
 /*
+ * atl1_pcie_patch - Patch for PCIE module
+ */
+static void atl1_pcie_patch(struct atl1_adapter *adapter)
+{
+	u32 value;
+
+	/* much vendor magic here */
+	value = 0x6500;
+	iowrite32(value, adapter->hw.hw_addr + 0x12FC);
+	/* pcie flow control mode change */
+	value = ioread32(adapter->hw.hw_addr + 0x1008);
+	value |= 0x8000;
+	iowrite32(value, adapter->hw.hw_addr + 0x1008);
+}
+
+/*
+ * When ACPI resume on some VIA MotherBoard, the Interrupt Disable bit/0x400
+ * on PCI Command register is disable.
+ * The function enable this bit.
+ * Brackett, 2006/03/15
+ */
+static void atl1_via_workaround(struct atl1_adapter *adapter)
+{
+	unsigned long value;
+
+	value = ioread16(adapter->hw.hw_addr + PCI_COMMAND);
+	if (value & PCI_COMMAND_INTX_DISABLE)
+		value &= ~PCI_COMMAND_INTX_DISABLE;
+	iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND);
+}
+
+/*
+ * atl1_irq_enable - Enable default interrupt generation settings
+ * @adapter: board private structure
+ */
+static void atl1_irq_enable(struct atl1_adapter *adapter)
+{
+	iowrite32(IMR_NORMAL_MASK, adapter->hw.hw_addr + REG_IMR);
+	ioread32(adapter->hw.hw_addr + REG_IMR);
+}
+
+/*
  * atl1_irq_disable - Mask off interrupt generation on the NIC
  * @adapter: board private structure
  */
 static void atl1_irq_disable(struct atl1_adapter *adapter)
 {
-	atomic_inc(&adapter->irq_sem);
 	iowrite32(0, adapter->hw.hw_addr + REG_IMR);
 	ioread32(adapter->hw.hw_addr + REG_IMR);
 	synchronize_irq(adapter->pdev->irq);
 }
 
-static void atl1_vlan_rx_register(struct net_device *netdev,
-				struct vlan_group *grp)
+static void atl1_clear_phy_int(struct atl1_adapter *adapter)
 {
-	struct atl1_adapter *adapter = netdev_priv(netdev);
+	u16 phy_data;
 	unsigned long flags;
-	u32 ctrl;
 
 	spin_lock_irqsave(&adapter->lock, flags);
-	/* atl1_irq_disable(adapter); */
-	adapter->vlgrp = grp;
+	atl1_read_phy_reg(&adapter->hw, 19, &phy_data);
+	spin_unlock_irqrestore(&adapter->lock, flags);
+}
 
-	if (grp) {
-		/* enable VLAN tag insert/strip */
-		ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
-		ctrl |= MAC_CTRL_RMV_VLAN;
-		iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
-	} else {
-		/* disable VLAN tag insert/strip */
-		ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
-		ctrl &= ~MAC_CTRL_RMV_VLAN;
-		iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
+static void atl1_inc_smb(struct atl1_adapter *adapter)
+{
+	struct stats_msg_block *smb = adapter->smb.smb;
+
+	/* Fill out the OS statistics structure */
+	adapter->soft_stats.rx_packets += smb->rx_ok;
+	adapter->soft_stats.tx_packets += smb->tx_ok;
+	adapter->soft_stats.rx_bytes += smb->rx_byte_cnt;
+	adapter->soft_stats.tx_bytes += smb->tx_byte_cnt;
+	adapter->soft_stats.multicast += smb->rx_mcast;
+	adapter->soft_stats.collisions += (smb->tx_1_col + smb->tx_2_col * 2 +
+		smb->tx_late_col + smb->tx_abort_col * adapter->hw.max_retry);
+
+	/* Rx Errors */
+	adapter->soft_stats.rx_errors += (smb->rx_frag + smb->rx_fcs_err +
+		smb->rx_len_err + smb->rx_sz_ov + smb->rx_rxf_ov +
+		smb->rx_rrd_ov + smb->rx_align_err);
+	adapter->soft_stats.rx_fifo_errors += smb->rx_rxf_ov;
+	adapter->soft_stats.rx_length_errors += smb->rx_len_err;
+	adapter->soft_stats.rx_crc_errors += smb->rx_fcs_err;
+	adapter->soft_stats.rx_frame_errors += smb->rx_align_err;
+	adapter->soft_stats.rx_missed_errors += (smb->rx_rrd_ov +
+		smb->rx_rxf_ov);
+
+	adapter->soft_stats.rx_pause += smb->rx_pause;
+	adapter->soft_stats.rx_rrd_ov += smb->rx_rrd_ov;
+	adapter->soft_stats.rx_trunc += smb->rx_sz_ov;
+
+	/* Tx Errors */
+	adapter->soft_stats.tx_errors += (smb->tx_late_col +
+		smb->tx_abort_col + smb->tx_underrun + smb->tx_trunc);
+	adapter->soft_stats.tx_fifo_errors += smb->tx_underrun;
+	adapter->soft_stats.tx_aborted_errors += smb->tx_abort_col;
+	adapter->soft_stats.tx_window_errors += smb->tx_late_col;
+
+	adapter->soft_stats.excecol += smb->tx_abort_col;
+	adapter->soft_stats.deffer += smb->tx_defer;
+	adapter->soft_stats.scc += smb->tx_1_col;
+	adapter->soft_stats.mcc += smb->tx_2_col;
+	adapter->soft_stats.latecol += smb->tx_late_col;
+	adapter->soft_stats.tx_underun += smb->tx_underrun;
+	adapter->soft_stats.tx_trunc += smb->tx_trunc;
+	adapter->soft_stats.tx_pause += smb->tx_pause;
+
+	adapter->net_stats.rx_packets = adapter->soft_stats.rx_packets;
+	adapter->net_stats.tx_packets = adapter->soft_stats.tx_packets;
+	adapter->net_stats.rx_bytes = adapter->soft_stats.rx_bytes;
+	adapter->net_stats.tx_bytes = adapter->soft_stats.tx_bytes;
+	adapter->net_stats.multicast = adapter->soft_stats.multicast;
+	adapter->net_stats.collisions = adapter->soft_stats.collisions;
+	adapter->net_stats.rx_errors = adapter->soft_stats.rx_errors;
+	adapter->net_stats.rx_over_errors =
+		adapter->soft_stats.rx_missed_errors;
+	adapter->net_stats.rx_length_errors =
+		adapter->soft_stats.rx_length_errors;
+	adapter->net_stats.rx_crc_errors = adapter->soft_stats.rx_crc_errors;
+	adapter->net_stats.rx_frame_errors =
+		adapter->soft_stats.rx_frame_errors;
+	adapter->net_stats.rx_fifo_errors = adapter->soft_stats.rx_fifo_errors;
+	adapter->net_stats.rx_missed_errors =
+		adapter->soft_stats.rx_missed_errors;
+	adapter->net_stats.tx_errors = adapter->soft_stats.tx_errors;
+	adapter->net_stats.tx_fifo_errors = adapter->soft_stats.tx_fifo_errors;
+	adapter->net_stats.tx_aborted_errors =
+		adapter->soft_stats.tx_aborted_errors;
+	adapter->net_stats.tx_window_errors =
+		adapter->soft_stats.tx_window_errors;
+	adapter->net_stats.tx_carrier_errors =
+		adapter->soft_stats.tx_carrier_errors;
+}
+
+/*
+ * atl1_get_stats - Get System Network Statistics
+ * @netdev: network interface device structure
+ *
+ * Returns the address of the device statistics structure.
+ * The statistics are actually updated from the timer callback.
+ */
+static struct net_device_stats *atl1_get_stats(struct net_device *netdev)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	return &adapter->net_stats;
+}
+
+static void atl1_update_mailbox(struct atl1_adapter *adapter)
+{
+	unsigned long flags;
+	u32 tpd_next_to_use;
+	u32 rfd_next_to_use;
+	u32 rrd_next_to_clean;
+	u32 value;
+
+	spin_lock_irqsave(&adapter->mb_lock, flags);
+
+	tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use);
+	rfd_next_to_use = atomic_read(&adapter->rfd_ring.next_to_use);
+	rrd_next_to_clean = atomic_read(&adapter->rrd_ring.next_to_clean);
+
+	value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) <<
+		MB_RFD_PROD_INDX_SHIFT) |
+		((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) <<
+		MB_RRD_CONS_INDX_SHIFT) |
+		((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) <<
+		MB_TPD_PROD_INDX_SHIFT);
+	iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
+
+	spin_unlock_irqrestore(&adapter->mb_lock, flags);
+}
+
+static void atl1_clean_alloc_flag(struct atl1_adapter *adapter,
+	struct rx_return_desc *rrd, u16 offset)
+{
+	struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+
+	while (rfd_ring->next_to_clean != (rrd->buf_indx + offset)) {
+		rfd_ring->buffer_info[rfd_ring->next_to_clean].alloced = 0;
+		if (++rfd_ring->next_to_clean == rfd_ring->count) {
+			rfd_ring->next_to_clean = 0;
+		}
 	}
+}
 
-	/* atl1_irq_enable(adapter); */
-	spin_unlock_irqrestore(&adapter->lock, flags);
+static void atl1_update_rfd_index(struct atl1_adapter *adapter,
+	struct rx_return_desc *rrd)
+{
+	u16 num_buf;
+
+	num_buf = (rrd->xsz.xsum_sz.pkt_size + adapter->rx_buffer_len - 1) /
+		adapter->rx_buffer_len;
+	if (rrd->num_buf == num_buf)
+		/* clean alloc flag for bad rrd */
+		atl1_clean_alloc_flag(adapter, rrd, num_buf);
 }
 
-static void atl1_restore_vlan(struct atl1_adapter *adapter)
+static void atl1_rx_checksum(struct atl1_adapter *adapter,
+	struct rx_return_desc *rrd, struct sk_buff *skb)
 {
-	atl1_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+	struct pci_dev *pdev = adapter->pdev;
+
+	skb->ip_summed = CHECKSUM_NONE;
+
+	if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
+		if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
+					ERR_FLAG_CODE | ERR_FLAG_OV)) {
+			adapter->hw_csum_err++;
+			dev_printk(KERN_DEBUG, &pdev->dev,
+				"rx checksum error\n");
+			return;
+		}
+	}
+
+	/* not IPv4 */
+	if (!(rrd->pkt_flg & PACKET_FLAG_IPV4))
+		/* checksum is invalid, but it's not an IPv4 pkt, so ok */
+		return;
+
+	/* IPv4 packet */
+	if (likely(!(rrd->err_flg &
+		(ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM)))) {
+		skb->ip_summed = CHECKSUM_UNNECESSARY;
+		adapter->hw_csum_good++;
+		return;
+	}
+
+	/* IPv4, but hardware thinks its checksum is wrong */
+	dev_printk(KERN_DEBUG, &pdev->dev,
+		"hw csum wrong, pkt_flag:%x, err_flag:%x\n",
+		rrd->pkt_flg, rrd->err_flg);
+	skb->ip_summed = CHECKSUM_COMPLETE;
+	skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum);
+	adapter->hw_csum_err++;
+	return;
+}
+
+/*
+ * atl1_alloc_rx_buffers - Replace used receive buffers
+ * @adapter: address of board private structure
+ */
+static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
+{
+	struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+	struct pci_dev *pdev = adapter->pdev;
+	struct page *page;
+	unsigned long offset;
+	struct atl1_buffer *buffer_info, *next_info;
+	struct sk_buff *skb;
+	u16 num_alloc = 0;
+	u16 rfd_next_to_use, next_next;
+	struct rx_free_desc *rfd_desc;
+
+	next_next = rfd_next_to_use = atomic_read(&rfd_ring->next_to_use);
+	if (++next_next == rfd_ring->count)
+		next_next = 0;
+	buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+	next_info = &rfd_ring->buffer_info[next_next];
+
+	while (!buffer_info->alloced && !next_info->alloced) {
+		if (buffer_info->skb) {
+			buffer_info->alloced = 1;
+			goto next;
+		}
+
+		rfd_desc = ATL1_RFD_DESC(rfd_ring, rfd_next_to_use);
+
+		skb = dev_alloc_skb(adapter->rx_buffer_len + NET_IP_ALIGN);
+		if (unlikely(!skb)) {	/* Better luck next round */
+			adapter->net_stats.rx_dropped++;
+			break;
+		}
+
+		/*
+		 * Make buffer alignment 2 beyond a 16 byte boundary
+		 * this will result in a 16 byte aligned IP header after
+		 * the 14 byte MAC header is removed
+		 */
+		skb_reserve(skb, NET_IP_ALIGN);
+
+		buffer_info->alloced = 1;
+		buffer_info->skb = skb;
+		buffer_info->length = (u16) adapter->rx_buffer_len;
+		page = virt_to_page(skb->data);
+		offset = (unsigned long)skb->data & ~PAGE_MASK;
+		buffer_info->dma = pci_map_page(pdev, page, offset,
+						adapter->rx_buffer_len,
+						PCI_DMA_FROMDEVICE);
+		rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
+		rfd_desc->buf_len = cpu_to_le16(adapter->rx_buffer_len);
+		rfd_desc->coalese = 0;
+
+next:
+		rfd_next_to_use = next_next;
+		if (unlikely(++next_next == rfd_ring->count))
+			next_next = 0;
+
+		buffer_info = &rfd_ring->buffer_info[rfd_next_to_use];
+		next_info = &rfd_ring->buffer_info[next_next];
+		num_alloc++;
+	}
+
+	if (num_alloc) {
+		/*
+		 * Force memory writes to complete before letting h/w
+		 * know there are new descriptors to fetch.  (Only
+		 * applicable for weak-ordered memory model archs,
+		 * such as IA-64).
+		 */
+		wmb();
+		atomic_set(&rfd_ring->next_to_use, (int)rfd_next_to_use);
+	}
+	return num_alloc;
+}
+
+static void atl1_intr_rx(struct atl1_adapter *adapter)
+{
+	int i, count;
+	u16 length;
+	u16 rrd_next_to_clean;
+	u32 value;
+	struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
+	struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
+	struct atl1_buffer *buffer_info;
+	struct rx_return_desc *rrd;
+	struct sk_buff *skb;
+
+	count = 0;
+
+	rrd_next_to_clean = atomic_read(&rrd_ring->next_to_clean);
+
+	while (1) {
+		rrd = ATL1_RRD_DESC(rrd_ring, rrd_next_to_clean);
+		i = 1;
+		if (likely(rrd->xsz.valid)) {	/* packet valid */
+chk_rrd:
+			/* check rrd status */
+			if (likely(rrd->num_buf == 1))
+				goto rrd_ok;
+
+			/* rrd seems to be bad */
+			if (unlikely(i-- > 0)) {
+				/* rrd may not be DMAed completely */
+				dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+					"incomplete RRD DMA transfer\n");
+				udelay(1);
+				goto chk_rrd;
+			}
+			/* bad rrd */
+			dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+				"bad RRD\n");
+			/* see if update RFD index */
+			if (rrd->num_buf > 1)
+				atl1_update_rfd_index(adapter, rrd);
+
+			/* update rrd */
+			rrd->xsz.valid = 0;
+			if (++rrd_next_to_clean == rrd_ring->count)
+				rrd_next_to_clean = 0;
+			count++;
+			continue;
+		} else {	/* current rrd still not be updated */
+
+			break;
+		}
+rrd_ok:
+		/* clean alloc flag for bad rrd */
+		atl1_clean_alloc_flag(adapter, rrd, 0);
+
+		buffer_info = &rfd_ring->buffer_info[rrd->buf_indx];
+		if (++rfd_ring->next_to_clean == rfd_ring->count)
+			rfd_ring->next_to_clean = 0;
+
+		/* update rrd next to clean */
+		if (++rrd_next_to_clean == rrd_ring->count)
+			rrd_next_to_clean = 0;
+		count++;
+
+		if (unlikely(rrd->pkt_flg & PACKET_FLAG_ERR)) {
+			if (!(rrd->err_flg &
+				(ERR_FLAG_IP_CHKSUM | ERR_FLAG_L4_CHKSUM
+				| ERR_FLAG_LEN))) {
+				/* packet error, don't need upstream */
+				buffer_info->alloced = 0;
+				rrd->xsz.valid = 0;
+				continue;
+			}
+		}
+
+		/* Good Receive */
+		pci_unmap_page(adapter->pdev, buffer_info->dma,
+			       buffer_info->length, PCI_DMA_FROMDEVICE);
+		skb = buffer_info->skb;
+		length = le16_to_cpu(rrd->xsz.xsum_sz.pkt_size);
+
+		skb_put(skb, length - ETHERNET_FCS_SIZE);
+
+		/* Receive Checksum Offload */
+		atl1_rx_checksum(adapter, rrd, skb);
+		skb->protocol = eth_type_trans(skb, adapter->netdev);
+
+		if (adapter->vlgrp && (rrd->pkt_flg & PACKET_FLAG_VLAN_INS)) {
+			u16 vlan_tag = (rrd->vlan_tag >> 4) |
+					((rrd->vlan_tag & 7) << 13) |
+					((rrd->vlan_tag & 8) << 9);
+			vlan_hwaccel_rx(skb, adapter->vlgrp, vlan_tag);
+		} else
+			netif_rx(skb);
+
+		/* let protocol layer free skb */
+		buffer_info->skb = NULL;
+		buffer_info->alloced = 0;
+		rrd->xsz.valid = 0;
+
+		adapter->netdev->last_rx = jiffies;
+	}
+
+	atomic_set(&rrd_ring->next_to_clean, rrd_next_to_clean);
+
+	atl1_alloc_rx_buffers(adapter);
+
+	/* update mailbox ? */
+	if (count) {
+		u32 tpd_next_to_use;
+		u32 rfd_next_to_use;
+		u32 rrd_next_to_clean;
+
+		spin_lock(&adapter->mb_lock);
+
+		tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use);
+		rfd_next_to_use =
+		    atomic_read(&adapter->rfd_ring.next_to_use);
+		rrd_next_to_clean =
+		    atomic_read(&adapter->rrd_ring.next_to_clean);
+		value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) <<
+			MB_RFD_PROD_INDX_SHIFT) |
+                        ((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) <<
+			MB_RRD_CONS_INDX_SHIFT) |
+                        ((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) <<
+			MB_TPD_PROD_INDX_SHIFT);
+		iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
+		spin_unlock(&adapter->mb_lock);
+	}
+}
+
+static void atl1_intr_tx(struct atl1_adapter *adapter)
+{
+	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
+	struct atl1_buffer *buffer_info;
+	u16 sw_tpd_next_to_clean;
+	u16 cmb_tpd_next_to_clean;
+
+	sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
+	cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
+
+	while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
+		struct tx_packet_desc *tpd;
+
+		tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean);
+		buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
+		if (buffer_info->dma) {
+			pci_unmap_page(adapter->pdev, buffer_info->dma,
+				       buffer_info->length, PCI_DMA_TODEVICE);
+			buffer_info->dma = 0;
+		}
+
+		if (buffer_info->skb) {
+			dev_kfree_skb_irq(buffer_info->skb);
+			buffer_info->skb = NULL;
+		}
+		tpd->buffer_addr = 0;
+		tpd->desc.data = 0;
+
+		if (++sw_tpd_next_to_clean == tpd_ring->count)
+			sw_tpd_next_to_clean = 0;
+	}
+	atomic_set(&tpd_ring->next_to_clean, sw_tpd_next_to_clean);
+
+	if (netif_queue_stopped(adapter->netdev)
+	    && netif_carrier_ok(adapter->netdev))
+		netif_wake_queue(adapter->netdev);
 }
 
 static u16 tpd_avail(struct atl1_tpd_ring *tpd_ring)
 {
 	u16 next_to_clean = atomic_read(&tpd_ring->next_to_clean);
 	u16 next_to_use = atomic_read(&tpd_ring->next_to_use);
-	return ((next_to_clean >
-		 next_to_use) ? next_to_clean - next_to_use -
-		1 : tpd_ring->count + next_to_clean - next_to_use - 1);
+	return ((next_to_clean > next_to_use) ?
+		next_to_clean - next_to_use - 1 :
+		tpd_ring->count + next_to_clean - next_to_use - 1);
 }
 
 static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
@@ -1262,9 +1454,7 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
 			iph->tot_len = 0;
 			iph->check = 0;
 			tcp_hdr(skb)->check = ~csum_tcpudp_magic(iph->saddr,
-								 iph->daddr, 0,
-								 IPPROTO_TCP,
-								 0);
+				iph->daddr, 0, IPPROTO_TCP, 0);
 			ipofst = skb_network_offset(skb);
 			if (ipofst != ENET_HEADER_SIZE) /* 802.3 frame */
 				tso->tsopl |= 1 << TSO_PARAM_ETHTYPE_SHIFT;
@@ -1272,7 +1462,8 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
 			tso->tsopl |= (iph->ihl &
 				CSUM_PARAM_IPHL_MASK) << CSUM_PARAM_IPHL_SHIFT;
 			tso->tsopl |= (tcp_hdrlen(skb) &
-				TSO_PARAM_TCPHDRLEN_MASK) << TSO_PARAM_TCPHDRLEN_SHIFT;
+				TSO_PARAM_TCPHDRLEN_MASK) <<
+				TSO_PARAM_TCPHDRLEN_SHIFT;
 			tso->tsopl |= (skb_shinfo(skb)->gso_size &
 				TSO_PARAM_MSS_MASK) << TSO_PARAM_MSS_SHIFT;
 			tso->tsopl |= 1 << TSO_PARAM_IPCKSUM_SHIFT;
@@ -1285,7 +1476,7 @@ static int atl1_tso(struct atl1_adapter *adapter, struct sk_buff *skb,
 }
 
 static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
-			struct csum_param *csum)
+	struct csum_param *csum)
 {
 	u8 css, cso;
 
@@ -1293,7 +1484,7 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
 		cso = skb_transport_offset(skb);
 		css = cso + skb->csum_offset;
 		if (unlikely(cso & 0x1)) {
-			dev_dbg(&adapter->pdev->dev,
+			dev_printk(KERN_DEBUG, &adapter->pdev->dev,
 				"payload offset not an even number\n");
 			return -1;
 		}
@@ -1308,8 +1499,8 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
 	return true;
 }
 
-static void atl1_tx_map(struct atl1_adapter *adapter,
-				struct sk_buff *skb, bool tcp_seg)
+static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
+	bool tcp_seg)
 {
 	/* We enter this function holding a spinlock. */
 	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
@@ -1346,26 +1537,25 @@ static void atl1_tx_map(struct atl1_adapter *adapter,
 
 		if (first_buf_len > proto_hdr_len) {
 			len12 = first_buf_len - proto_hdr_len;
-			m = (len12 + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN;
+			m = (len12 + ATL1_MAX_TX_BUF_LEN - 1) /
+				ATL1_MAX_TX_BUF_LEN;
 			for (i = 0; i < m; i++) {
 				buffer_info =
 				    &tpd_ring->buffer_info[tpd_next_to_use];
 				buffer_info->skb = NULL;
 				buffer_info->length =
-				    (MAX_TX_BUF_LEN >=
-				     len12) ? MAX_TX_BUF_LEN : len12;
+				    (ATL1_MAX_TX_BUF_LEN >=
+				     len12) ? ATL1_MAX_TX_BUF_LEN : len12;
 				len12 -= buffer_info->length;
 				page = virt_to_page(skb->data +
-						 (proto_hdr_len +
-						  i * MAX_TX_BUF_LEN));
+					(proto_hdr_len +
+					i * ATL1_MAX_TX_BUF_LEN));
 				offset = (unsigned long)(skb->data +
-							(proto_hdr_len +
-							i * MAX_TX_BUF_LEN)) &
-							~PAGE_MASK;
-				buffer_info->dma =
-				    pci_map_page(adapter->pdev, page, offset,
-						 buffer_info->length,
-						 PCI_DMA_TODEVICE);
+					(proto_hdr_len +
+					i * ATL1_MAX_TX_BUF_LEN)) & ~PAGE_MASK;
+				buffer_info->dma = pci_map_page(adapter->pdev,
+					page, offset, buffer_info->length,
+					PCI_DMA_TODEVICE);
 				if (++tpd_next_to_use == tpd_ring->count)
 					tpd_next_to_use = 0;
 			}
@@ -1376,8 +1566,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter,
 		page = virt_to_page(skb->data);
 		offset = (unsigned long)skb->data & ~PAGE_MASK;
 		buffer_info->dma = pci_map_page(adapter->pdev, page,
-						offset, first_buf_len,
-						PCI_DMA_TODEVICE);
+			offset, first_buf_len, PCI_DMA_TODEVICE);
 		if (++tpd_next_to_use == tpd_ring->count)
 			tpd_next_to_use = 0;
 	}
@@ -1389,19 +1578,19 @@ static void atl1_tx_map(struct atl1_adapter *adapter,
 		frag = &skb_shinfo(skb)->frags[f];
 		lenf = frag->size;
 
-		m = (lenf + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN;
+		m = (lenf + ATL1_MAX_TX_BUF_LEN - 1) / ATL1_MAX_TX_BUF_LEN;
 		for (i = 0; i < m; i++) {
 			buffer_info = &tpd_ring->buffer_info[tpd_next_to_use];
 			if (unlikely(buffer_info->skb))
 				BUG();
 			buffer_info->skb = NULL;
-			buffer_info->length =
-			    (lenf > MAX_TX_BUF_LEN) ? MAX_TX_BUF_LEN : lenf;
+			buffer_info->length = (lenf > ATL1_MAX_TX_BUF_LEN) ?
+				ATL1_MAX_TX_BUF_LEN : lenf;
 			lenf -= buffer_info->length;
-			buffer_info->dma =
-			    pci_map_page(adapter->pdev, frag->page,
-					 frag->page_offset + i * MAX_TX_BUF_LEN,
-					 buffer_info->length, PCI_DMA_TODEVICE);
+			buffer_info->dma = pci_map_page(adapter->pdev,
+				frag->page,
+				frag->page_offset + (i * ATL1_MAX_TX_BUF_LEN),
+				buffer_info->length, PCI_DMA_TODEVICE);
 
 			if (++tpd_next_to_use == tpd_ring->count)
 				tpd_next_to_use = 0;
@@ -1413,7 +1602,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter,
 }
 
 static void atl1_tx_queue(struct atl1_adapter *adapter, int count,
-			       union tpd_descr *descr)
+       union tpd_descr *descr)
 {
 	/* We enter this function holding a spinlock. */
 	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
@@ -1457,31 +1646,6 @@ static void atl1_tx_queue(struct atl1_adapter *adapter, int count,
 	atomic_set(&tpd_ring->next_to_use, (int)tpd_next_to_use);
 }
 
-static void atl1_update_mailbox(struct atl1_adapter *adapter)
-{
-	unsigned long flags;
-	u32 tpd_next_to_use;
-	u32 rfd_next_to_use;
-	u32 rrd_next_to_clean;
-	u32 value;
-
-	spin_lock_irqsave(&adapter->mb_lock, flags);
-
-	tpd_next_to_use = atomic_read(&adapter->tpd_ring.next_to_use);
-	rfd_next_to_use = atomic_read(&adapter->rfd_ring.next_to_use);
-	rrd_next_to_clean = atomic_read(&adapter->rrd_ring.next_to_clean);
-
-	value = ((rfd_next_to_use & MB_RFD_PROD_INDX_MASK) <<
-		MB_RFD_PROD_INDX_SHIFT) |
-		((rrd_next_to_clean & MB_RRD_CONS_INDX_MASK) <<
-		MB_RRD_CONS_INDX_SHIFT) |
-		((tpd_next_to_use & MB_TPD_PROD_INDX_MASK) <<
-		MB_TPD_PROD_INDX_SHIFT);
-	iowrite32(value, adapter->hw.hw_addr + REG_MAILBOX);
-
-	spin_unlock_irqrestore(&adapter->mb_lock, flags);
-}
-
 static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct atl1_adapter *adapter = netdev_priv(netdev);
@@ -1517,8 +1681,8 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	for (f = 0; f < nr_frags; f++) {
 		frag_size = skb_shinfo(skb)->frags[f].size;
 		if (frag_size)
-			count +=
-			    (frag_size + MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN;
+			count += (frag_size + ATL1_MAX_TX_BUF_LEN - 1) /
+				ATL1_MAX_TX_BUF_LEN;
 	}
 
 	/* mss will be nonzero if we're doing segment offload (TSO/GSO) */
@@ -1534,7 +1698,8 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 			/* need additional TPD ? */
 			if (proto_hdr_len != len)
 				count += (len - proto_hdr_len +
-					MAX_TX_BUF_LEN - 1) / MAX_TX_BUF_LEN;
+					ATL1_MAX_TX_BUF_LEN - 1) /
+					ATL1_MAX_TX_BUF_LEN;
 		}
 	}
 
@@ -1542,7 +1707,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	if (!spin_trylock(&adapter->lock)) {
 		/* Can't get lock - tell upper layer to requeue */
 		local_irq_restore(flags);
-		dev_dbg(&adapter->pdev->dev, "tx locked\n");
+		dev_printk(KERN_DEBUG, &adapter->pdev->dev, "tx locked\n");
 		return NETDEV_TX_LOCKED;
 	}
 
@@ -1550,7 +1715,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		/* not enough descriptors */
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&adapter->lock, flags);
-		dev_dbg(&adapter->pdev->dev, "tx busy\n");
+		dev_printk(KERN_DEBUG, &adapter->pdev->dev, "tx busy\n");
 		return NETDEV_TX_BUSY;
 	}
 
@@ -1592,131 +1757,208 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 }
 
 /*
- * atl1_get_stats - Get System Network Statistics
- * @netdev: network interface device structure
- *
- * Returns the address of the device statistics structure.
- * The statistics are actually updated from the timer callback.
+ * atl1_intr - Interrupt Handler
+ * @irq: interrupt number
+ * @data: pointer to a network interface device structure
+ * @pt_regs: CPU registers structure
  */
-static struct net_device_stats *atl1_get_stats(struct net_device *netdev)
+static irqreturn_t atl1_intr(int irq, void *data)
 {
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	return &adapter->net_stats;
-}
+	struct atl1_adapter *adapter = netdev_priv(data);
+	u32 status;
+	u8 update_rx;
+	int max_ints = 10;
 
-/*
- * atl1_clean_rx_ring - Free RFD Buffers
- * @adapter: board private structure
- */
-static void atl1_clean_rx_ring(struct atl1_adapter *adapter)
-{
-	struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-	struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
-	struct atl1_buffer *buffer_info;
-	struct pci_dev *pdev = adapter->pdev;
-	unsigned long size;
-	unsigned int i;
+	status = adapter->cmb.cmb->int_stats;
+	if (!status)
+		return IRQ_NONE;
 
-	/* Free all the Rx ring sk_buffs */
-	for (i = 0; i < rfd_ring->count; i++) {
-		buffer_info = &rfd_ring->buffer_info[i];
-		if (buffer_info->dma) {
-			pci_unmap_page(pdev,
-					buffer_info->dma,
-					buffer_info->length,
-					PCI_DMA_FROMDEVICE);
-			buffer_info->dma = 0;
+	update_rx = 0;
+
+	do {
+		/* clear CMB interrupt status at once */
+		adapter->cmb.cmb->int_stats = 0;
+
+		if (status & ISR_GPHY)	/* clear phy status */
+			atl1_clear_phy_int(adapter);
+
+		/* clear ISR status, and Enable CMB DMA/Disable Interrupt */
+		iowrite32(status | ISR_DIS_INT, adapter->hw.hw_addr + REG_ISR);
+
+		/* check if SMB intr */
+		if (status & ISR_SMB)
+			atl1_inc_smb(adapter);
+
+		/* check if PCIE PHY Link down */
+		if (status & ISR_PHY_LINKDOWN) {
+			dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+				"pcie phy link down %x\n", status);
+			if (netif_running(adapter->netdev)) {	/* reset MAC */
+				iowrite32(0, adapter->hw.hw_addr + REG_IMR);
+				schedule_work(&adapter->pcie_dma_to_rst_task);
+				return IRQ_HANDLED;
+			}
 		}
-		if (buffer_info->skb) {
-			dev_kfree_skb(buffer_info->skb);
-			buffer_info->skb = NULL;
+
+		/* check if DMA read/write error ? */
+		if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
+			dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+				"pcie DMA r/w error (status = 0x%x)\n",
+				status);
+			iowrite32(0, adapter->hw.hw_addr + REG_IMR);
+			schedule_work(&adapter->pcie_dma_to_rst_task);
+			return IRQ_HANDLED;
 		}
-	}
 
-	size = sizeof(struct atl1_buffer) * rfd_ring->count;
-	memset(rfd_ring->buffer_info, 0, size);
+		/* link event */
+		if (status & ISR_GPHY) {
+			adapter->soft_stats.tx_carrier_errors++;
+			atl1_check_for_link(adapter);
+		}
 
-	/* Zero out the descriptor ring */
-	memset(rfd_ring->desc, 0, rfd_ring->size);
+		/* transmit event */
+		if (status & ISR_CMB_TX)
+			atl1_intr_tx(adapter);
 
-	rfd_ring->next_to_clean = 0;
-	atomic_set(&rfd_ring->next_to_use, 0);
+		/* rx exception */
+		if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
+			ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
+			ISR_HOST_RRD_OV | ISR_CMB_RX))) {
+			if (status & (ISR_RXF_OV | ISR_RFD_UNRUN |
+				ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
+				ISR_HOST_RRD_OV))
+				dev_printk(KERN_DEBUG, &adapter->pdev->dev,
+					"rx exception, ISR = 0x%x\n", status);
+			atl1_intr_rx(adapter);
+		}
 
-	rrd_ring->next_to_use = 0;
-	atomic_set(&rrd_ring->next_to_clean, 0);
+		if (--max_ints < 0)
+			break;
+
+	} while ((status = adapter->cmb.cmb->int_stats));
+
+	/* re-enable Interrupt */
+	iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR);
+	return IRQ_HANDLED;
 }
 
 /*
- * atl1_clean_tx_ring - Free Tx Buffers
- * @adapter: board private structure
+ * atl1_watchdog - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
  */
-static void atl1_clean_tx_ring(struct atl1_adapter *adapter)
+static void atl1_watchdog(unsigned long data)
 {
-	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-	struct atl1_buffer *buffer_info;
-	struct pci_dev *pdev = adapter->pdev;
-	unsigned long size;
-	unsigned int i;
+	struct atl1_adapter *adapter = (struct atl1_adapter *)data;
 
-	/* Free all the Tx ring sk_buffs */
-	for (i = 0; i < tpd_ring->count; i++) {
-		buffer_info = &tpd_ring->buffer_info[i];
-		if (buffer_info->dma) {
-			pci_unmap_page(pdev, buffer_info->dma,
-				       buffer_info->length, PCI_DMA_TODEVICE);
-			buffer_info->dma = 0;
-		}
-	}
+	/* Reset the timer */
+	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
+}
 
-	for (i = 0; i < tpd_ring->count; i++) {
-		buffer_info = &tpd_ring->buffer_info[i];
-		if (buffer_info->skb) {
-			dev_kfree_skb_any(buffer_info->skb);
-			buffer_info->skb = NULL;
-		}
-	}
+/*
+ * atl1_phy_config - Timer Call-back
+ * @data: pointer to netdev cast into an unsigned long
+ */
+static void atl1_phy_config(unsigned long data)
+{
+	struct atl1_adapter *adapter = (struct atl1_adapter *)data;
+	struct atl1_hw *hw = &adapter->hw;
+	unsigned long flags;
 
-	size = sizeof(struct atl1_buffer) * tpd_ring->count;
-	memset(tpd_ring->buffer_info, 0, size);
+	spin_lock_irqsave(&adapter->lock, flags);
+	adapter->phy_timer_pending = false;
+	atl1_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
+	atl1_write_phy_reg(hw, MII_AT001_CR, hw->mii_1000t_ctrl_reg);
+	atl1_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN);
+	spin_unlock_irqrestore(&adapter->lock, flags);
+}
 
-	/* Zero out the descriptor ring */
-	memset(tpd_ring->desc, 0, tpd_ring->size);
+/*
+ * atl1_tx_timeout - Respond to a Tx Hang
+ * @netdev: network interface device structure
+ */
+static void atl1_tx_timeout(struct net_device *netdev)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	/* Do the reset outside of interrupt context */
+	schedule_work(&adapter->tx_timeout_task);
+}
 
-	atomic_set(&tpd_ring->next_to_use, 0);
-	atomic_set(&tpd_ring->next_to_clean, 0);
+/*
+ * Orphaned vendor comment left intact here:
+ * <vendor comment>
+ * If TPD Buffer size equal to 0, PCIE DMAR_TO_INT
+ * will assert. We do soft reset <0x1400=1> according
+ * with the SPEC. BUT, it seemes that PCIE or DMA
+ * state-machine will not be reset. DMAR_TO_INT will
+ * assert again and again.
+ * </vendor comment>
+ */
+static void atl1_tx_timeout_task(struct work_struct *work)
+{
+	struct atl1_adapter *adapter =
+		container_of(work, struct atl1_adapter, tx_timeout_task);
+	struct net_device *netdev = adapter->netdev;
+
+	netif_device_detach(netdev);
+	atl1_down(adapter);
+	atl1_up(adapter);
+	netif_device_attach(netdev);
 }
 
 /*
- * atl1_free_ring_resources - Free Tx / RX descriptor Resources
- * @adapter: board private structure
- *
- * Free all transmit software resources
+ * atl1_link_chg_task - deal with link change event Out of interrupt context
  */
-void atl1_free_ring_resources(struct atl1_adapter *adapter)
+static void atl1_link_chg_task(struct work_struct *work)
 {
-	struct pci_dev *pdev = adapter->pdev;
-	struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
-	struct atl1_rfd_ring *rfd_ring = &adapter->rfd_ring;
-	struct atl1_rrd_ring *rrd_ring = &adapter->rrd_ring;
-	struct atl1_ring_header *ring_header = &adapter->ring_header;
+	struct atl1_adapter *adapter =
+               container_of(work, struct atl1_adapter, link_chg_task);
+	unsigned long flags;
 
-	atl1_clean_tx_ring(adapter);
-	atl1_clean_rx_ring(adapter);
+	spin_lock_irqsave(&adapter->lock, flags);
+	atl1_check_link(adapter);
+	spin_unlock_irqrestore(&adapter->lock, flags);
+}
 
-	kfree(tpd_ring->buffer_info);
-	pci_free_consistent(pdev, ring_header->size, ring_header->desc,
-			    ring_header->dma);
+static void atl1_vlan_rx_register(struct net_device *netdev,
+	struct vlan_group *grp)
+{
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	unsigned long flags;
+	u32 ctrl;
 
-	tpd_ring->buffer_info = NULL;
-	tpd_ring->desc = NULL;
-	tpd_ring->dma = 0;
+	spin_lock_irqsave(&adapter->lock, flags);
+	/* atl1_irq_disable(adapter); */
+	adapter->vlgrp = grp;
 
-	rfd_ring->buffer_info = NULL;
-	rfd_ring->desc = NULL;
-	rfd_ring->dma = 0;
+	if (grp) {
+		/* enable VLAN tag insert/strip */
+		ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
+		ctrl |= MAC_CTRL_RMV_VLAN;
+		iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
+	} else {
+		/* disable VLAN tag insert/strip */
+		ctrl = ioread32(adapter->hw.hw_addr + REG_MAC_CTRL);
+		ctrl &= ~MAC_CTRL_RMV_VLAN;
+		iowrite32(ctrl, adapter->hw.hw_addr + REG_MAC_CTRL);
+	}
 
-	rrd_ring->desc = NULL;
-	rrd_ring->dma = 0;
+	/* atl1_irq_enable(adapter); */
+	spin_unlock_irqrestore(&adapter->lock, flags);
+}
+
+static void atl1_restore_vlan(struct atl1_adapter *adapter)
+{
+	atl1_vlan_rx_register(adapter->netdev, adapter->vlgrp);
+}
+
+int atl1_reset(struct atl1_adapter *adapter)
+{
+	int ret;
+
+	ret = atl1_reset_hw(&adapter->hw);
+	if (ret != ATL1_SUCCESS)
+		return ret;
+	return atl1_init_hw(&adapter->hw);
 }
 
 s32 atl1_up(struct atl1_adapter *adapter)
@@ -1727,6 +1969,7 @@ s32 atl1_up(struct atl1_adapter *adapter)
 
 	/* hardware has been reset, we need to reload some things */
 	atl1_set_multi(netdev);
+	atl1_init_ring_ptrs(adapter);
 	atl1_restore_vlan(adapter);
 	err = atl1_alloc_rx_buffers(adapter);
 	if (unlikely(!err))		/* no RX BUFFER allocated */
@@ -1754,11 +1997,6 @@ s32 atl1_up(struct atl1_adapter *adapter)
 	atl1_check_link(adapter);
 	return 0;
 
-	/* FIXME: unreachable code! -- CHS */
-	/* free irq disable any interrupt */
-	iowrite32(0, adapter->hw.hw_addr + REG_IMR);
-	free_irq(adapter->pdev->irq, netdev);
-
 err_up:
 	pci_disable_msi(adapter->pdev);
 	/* free rx_buffers */
@@ -1790,172 +2028,6 @@ void atl1_down(struct atl1_adapter *adapter)
 }
 
 /*
- * atl1_change_mtu - Change the Maximum Transfer Unit
- * @netdev: network interface device structure
- * @new_mtu: new value for maximum frame size
- *
- * Returns 0 on success, negative on failure
- */
-static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	int old_mtu = netdev->mtu;
-	int max_frame = new_mtu + ENET_HEADER_SIZE + ETHERNET_FCS_SIZE;
-
-	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
-	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-		dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
-		return -EINVAL;
-	}
-
-	adapter->hw.max_frame_size = max_frame;
-	adapter->hw.tx_jumbo_task_th = (max_frame + 7) >> 3;
-	adapter->rx_buffer_len = (max_frame + 7) & ~7;
-	adapter->hw.rx_jumbo_th = adapter->rx_buffer_len / 8;
-
-	netdev->mtu = new_mtu;
-	if ((old_mtu != new_mtu) && netif_running(netdev)) {
-		atl1_down(adapter);
-		atl1_up(adapter);
-	}
-
-	return 0;
-}
-
-/*
- * atl1_set_mac - Change the Ethernet Address of the NIC
- * @netdev: network interface device structure
- * @p: pointer to an address structure
- *
- * Returns 0 on success, negative on failure
- */
-static int atl1_set_mac(struct net_device *netdev, void *p)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	struct sockaddr *addr = p;
-
-	if (netif_running(netdev))
-		return -EBUSY;
-
-	if (!is_valid_ether_addr(addr->sa_data))
-		return -EADDRNOTAVAIL;
-
-	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
-	memcpy(adapter->hw.mac_addr, addr->sa_data, netdev->addr_len);
-
-	atl1_set_mac_addr(&adapter->hw);
-	return 0;
-}
-
-/*
- * atl1_watchdog - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
- */
-static void atl1_watchdog(unsigned long data)
-{
-	struct atl1_adapter *adapter = (struct atl1_adapter *)data;
-
-	/* Reset the timer */
-	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
-}
-
-static int mdio_read(struct net_device *netdev, int phy_id, int reg_num)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	u16 result;
-
-	atl1_read_phy_reg(&adapter->hw, reg_num & 0x1f, &result);
-
-	return result;
-}
-
-static void mdio_write(struct net_device *netdev, int phy_id, int reg_num, int val)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-
-	atl1_write_phy_reg(&adapter->hw, reg_num, val);
-}
-
-/*
- * atl1_mii_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl1_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	unsigned long flags;
-	int retval;
-
-	if (!netif_running(netdev))
-		return -EINVAL;
-
-	spin_lock_irqsave(&adapter->lock, flags);
-	retval = generic_mii_ioctl(&adapter->mii, if_mii(ifr), cmd, NULL);
-	spin_unlock_irqrestore(&adapter->lock, flags);
-
-	return retval;
-}
-
-/*
- * atl1_ioctl -
- * @netdev:
- * @ifreq:
- * @cmd:
- */
-static int atl1_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
-{
-	switch (cmd) {
-	case SIOCGMIIPHY:
-	case SIOCGMIIREG:
-	case SIOCSMIIREG:
-		return atl1_mii_ioctl(netdev, ifr, cmd);
-	default:
-		return -EOPNOTSUPP;
-	}
-}
-
-/*
- * atl1_tx_timeout - Respond to a Tx Hang
- * @netdev: network interface device structure
- */
-static void atl1_tx_timeout(struct net_device *netdev)
-{
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	/* Do the reset outside of interrupt context */
-	schedule_work(&adapter->tx_timeout_task);
-}
-
-/*
- * atl1_phy_config - Timer Call-back
- * @data: pointer to netdev cast into an unsigned long
- */
-static void atl1_phy_config(unsigned long data)
-{
-	struct atl1_adapter *adapter = (struct atl1_adapter *)data;
-	struct atl1_hw *hw = &adapter->hw;
-	unsigned long flags;
-
-	spin_lock_irqsave(&adapter->lock, flags);
-	adapter->phy_timer_pending = false;
-	atl1_write_phy_reg(hw, MII_ADVERTISE, hw->mii_autoneg_adv_reg);
-	atl1_write_phy_reg(hw, MII_AT001_CR, hw->mii_1000t_ctrl_reg);
-	atl1_write_phy_reg(hw, MII_BMCR, MII_CR_RESET | MII_CR_AUTO_NEG_EN);
-	spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-int atl1_reset(struct atl1_adapter *adapter)
-{
-	int ret;
-
-	ret = atl1_reset_hw(&adapter->hw);
-	if (ret != ATL1_SUCCESS)
-		return ret;
-	return atl1_init_hw(&adapter->hw);
-}
-
-/*
  * atl1_open - Called when a network interface is made active
  * @netdev: network interface device structure
  *
@@ -2007,77 +2079,113 @@ static int atl1_close(struct net_device *netdev)
 	return 0;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void atl1_poll_controller(struct net_device *netdev)
-{
-	disable_irq(netdev->irq);
-	atl1_intr(netdev->irq, netdev);
-	enable_irq(netdev->irq);
-}
-#endif
-
-/*
- * If TPD Buffer size equal to 0, PCIE DMAR_TO_INT
- * will assert. We do soft reset <0x1400=1> according
- * with the SPEC. BUT, it seemes that PCIE or DMA
- * state-machine will not be reset. DMAR_TO_INT will
- * assert again and again.
- */
-static void atl1_tx_timeout_task(struct work_struct *work)
+#ifdef CONFIG_PM
+static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
 {
-	struct atl1_adapter *adapter =
-		container_of(work, struct atl1_adapter, tx_timeout_task);
-	struct net_device *netdev = adapter->netdev;
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	struct atl1_hw *hw = &adapter->hw;
+	u32 ctrl = 0;
+	u32 wufc = adapter->wol;
 
 	netif_device_detach(netdev);
-	atl1_down(adapter);
-	atl1_up(adapter);
-	netif_device_attach(netdev);
-}
+	if (netif_running(netdev))
+		atl1_down(adapter);
 
-/*
- * atl1_link_chg_task - deal with link change event Out of interrupt context
- */
-static void atl1_link_chg_task(struct work_struct *work)
-{
-	struct atl1_adapter *adapter =
-               container_of(work, struct atl1_adapter, link_chg_task);
-	unsigned long flags;
+	atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
+	atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
+	if (ctrl & BMSR_LSTATUS)
+		wufc &= ~ATL1_WUFC_LNKC;
 
-	spin_lock_irqsave(&adapter->lock, flags);
-	atl1_check_link(adapter);
-	spin_unlock_irqrestore(&adapter->lock, flags);
+	/* reduce speed to 10/100M */
+	if (wufc) {
+		atl1_phy_enter_power_saving(hw);
+		/* if resume, let driver to re- setup link */
+		hw->phy_configured = false;
+		atl1_set_mac_addr(hw);
+		atl1_set_multi(netdev);
+
+		ctrl = 0;
+		/* turn on magic packet wol */
+		if (wufc & ATL1_WUFC_MAG)
+			ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
+
+		/* turn on Link change WOL */
+		if (wufc & ATL1_WUFC_LNKC)
+			ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
+		iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
+
+		/* turn on all-multi mode if wake on multicast is enabled */
+		ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL);
+		ctrl &= ~MAC_CTRL_DBG;
+		ctrl &= ~MAC_CTRL_PROMIS_EN;
+		if (wufc & ATL1_WUFC_MC)
+			ctrl |= MAC_CTRL_MC_ALL_EN;
+		else
+			ctrl &= ~MAC_CTRL_MC_ALL_EN;
+
+		/* turn on broadcast mode if wake on-BC is enabled */
+		if (wufc & ATL1_WUFC_BC)
+			ctrl |= MAC_CTRL_BC_EN;
+		else
+			ctrl &= ~MAC_CTRL_BC_EN;
+
+		/* enable RX */
+		ctrl |= MAC_CTRL_RX_EN;
+		iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL);
+		pci_enable_wake(pdev, PCI_D3hot, 1);
+		pci_enable_wake(pdev, PCI_D3cold, 1);
+	} else {
+		iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
+		pci_enable_wake(pdev, PCI_D3hot, 0);
+		pci_enable_wake(pdev, PCI_D3cold, 0);
+	}
+
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+
+	pci_set_power_state(pdev, PCI_D3hot);
+
+	return 0;
 }
 
-/*
- * atl1_pcie_patch - Patch for PCIE module
- */
-static void atl1_pcie_patch(struct atl1_adapter *adapter)
+static int atl1_resume(struct pci_dev *pdev)
 {
-	u32 value;
-	value = 0x6500;
-	iowrite32(value, adapter->hw.hw_addr + 0x12FC);
-	/* pcie flow control mode change */
-	value = ioread32(adapter->hw.hw_addr + 0x1008);
-	value |= 0x8000;
-	iowrite32(value, adapter->hw.hw_addr + 0x1008);
+	struct net_device *netdev = pci_get_drvdata(pdev);
+	struct atl1_adapter *adapter = netdev_priv(netdev);
+	u32 ret_val;
+
+	pci_set_power_state(pdev, 0);
+	pci_restore_state(pdev);
+
+	ret_val = pci_enable_device(pdev);
+	pci_enable_wake(pdev, PCI_D3hot, 0);
+	pci_enable_wake(pdev, PCI_D3cold, 0);
+
+	iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
+	atl1_reset(adapter);
+
+	if (netif_running(netdev))
+		atl1_up(adapter);
+	netif_device_attach(netdev);
+
+	atl1_via_workaround(adapter);
+
+	return 0;
 }
+#else
+#define atl1_suspend NULL
+#define atl1_resume NULL
+#endif
 
-/*
- * When ACPI resume on some VIA MotherBoard, the Interrupt Disable bit/0x400
- * on PCI Command register is disable.
- * The function enable this bit.
- * Brackett, 2006/03/15
- */
-static void atl1_via_workaround(struct atl1_adapter *adapter)
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void atl1_poll_controller(struct net_device *netdev)
 {
-	unsigned long value;
-
-	value = ioread16(adapter->hw.hw_addr + PCI_COMMAND);
-	if (value & PCI_COMMAND_INTX_DISABLE)
-		value &= ~PCI_COMMAND_INTX_DISABLE;
-	iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND);
+	disable_irq(netdev->irq);
+	atl1_intr(netdev->irq, netdev);
+	enable_irq(netdev->irq);
 }
+#endif
 
 /*
  * atl1_probe - Device Initialization Routine
@@ -2091,7 +2199,7 @@ static void atl1_via_workaround(struct atl1_adapter *adapter)
  * and a hardware reset occur.
  */
 static int __devinit atl1_probe(struct pci_dev *pdev,
-			      const struct pci_device_id *ent)
+	const struct pci_device_id *ent)
 {
 	struct net_device *netdev;
 	struct atl1_adapter *adapter;
@@ -2145,7 +2253,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 	}
 	/* get device revision number */
 	adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr +
-					(REG_MASTER_CTRL + 2));
+		(REG_MASTER_CTRL + 2));
 	dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
 
 	/* set default ring resource counts */
@@ -2298,7 +2406,8 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
 	 * address, we need to save the permanent one.
 	 */
 	if (memcmp(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN)) {
-		memcpy(adapter->hw.mac_addr, adapter->hw.perm_mac_addr, ETH_ALEN);
+		memcpy(adapter->hw.mac_addr, adapter->hw.perm_mac_addr,
+			ETH_ALEN);
 		atl1_set_mac_addr(&adapter->hw);
 	}
 
@@ -2310,112 +2419,11 @@ static void __devexit atl1_remove(struct pci_dev *pdev)
 	pci_disable_device(pdev);
 }
 
-#ifdef CONFIG_PM
-static int atl1_suspend(struct pci_dev *pdev, pm_message_t state)
-{
-	struct net_device *netdev = pci_get_drvdata(pdev);
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	struct atl1_hw *hw = &adapter->hw;
-	u32 ctrl = 0;
-	u32 wufc = adapter->wol;
-
-	netif_device_detach(netdev);
-	if (netif_running(netdev))
-		atl1_down(adapter);
-
-	atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
-	atl1_read_phy_reg(hw, MII_BMSR, (u16 *) & ctrl);
-	if (ctrl & BMSR_LSTATUS)
-		wufc &= ~ATL1_WUFC_LNKC;
-
-	/* reduce speed to 10/100M */
-	if (wufc) {
-		atl1_phy_enter_power_saving(hw);
-		/* if resume, let driver to re- setup link */
-		hw->phy_configured = false;
-		atl1_set_mac_addr(hw);
-		atl1_set_multi(netdev);
-
-		ctrl = 0;
-		/* turn on magic packet wol */
-		if (wufc & ATL1_WUFC_MAG)
-			ctrl = WOL_MAGIC_EN | WOL_MAGIC_PME_EN;
-
-		/* turn on Link change WOL */
-		if (wufc & ATL1_WUFC_LNKC)
-			ctrl |= (WOL_LINK_CHG_EN | WOL_LINK_CHG_PME_EN);
-		iowrite32(ctrl, hw->hw_addr + REG_WOL_CTRL);
-
-		/* turn on all-multi mode if wake on multicast is enabled */
-		ctrl = ioread32(hw->hw_addr + REG_MAC_CTRL);
-		ctrl &= ~MAC_CTRL_DBG;
-		ctrl &= ~MAC_CTRL_PROMIS_EN;
-		if (wufc & ATL1_WUFC_MC)
-			ctrl |= MAC_CTRL_MC_ALL_EN;
-		else
-			ctrl &= ~MAC_CTRL_MC_ALL_EN;
-
-		/* turn on broadcast mode if wake on-BC is enabled */
-		if (wufc & ATL1_WUFC_BC)
-			ctrl |= MAC_CTRL_BC_EN;
-		else
-			ctrl &= ~MAC_CTRL_BC_EN;
-
-		/* enable RX */
-		ctrl |= MAC_CTRL_RX_EN;
-		iowrite32(ctrl, hw->hw_addr + REG_MAC_CTRL);
-		pci_enable_wake(pdev, PCI_D3hot, 1);
-		pci_enable_wake(pdev, PCI_D3cold, 1);	/* 4 == D3 cold */
-	} else {
-		iowrite32(0, hw->hw_addr + REG_WOL_CTRL);
-		pci_enable_wake(pdev, PCI_D3hot, 0);
-		pci_enable_wake(pdev, PCI_D3cold, 0);	/* 4 == D3 cold */
-	}
-
-	pci_save_state(pdev);
-	pci_disable_device(pdev);
-
-	pci_set_power_state(pdev, PCI_D3hot);
-
-	return 0;
-}
-
-static int atl1_resume(struct pci_dev *pdev)
-{
-	struct net_device *netdev = pci_get_drvdata(pdev);
-	struct atl1_adapter *adapter = netdev_priv(netdev);
-	u32 ret_val;
-
-	pci_set_power_state(pdev, 0);
-	pci_restore_state(pdev);
-
-	ret_val = pci_enable_device(pdev);
-	pci_enable_wake(pdev, PCI_D3hot, 0);
-	pci_enable_wake(pdev, PCI_D3cold, 0);
-
-	iowrite32(0, adapter->hw.hw_addr + REG_WOL_CTRL);
-	atl1_reset(adapter);
-
-	if (netif_running(netdev))
-		atl1_up(adapter);
-	netif_device_attach(netdev);
-
-	atl1_via_workaround(adapter);
-
-	return 0;
-}
-#else
-#define atl1_suspend NULL
-#define atl1_resume NULL
-#endif
-
 static struct pci_driver atl1_driver = {
 	.name = atl1_driver_name,
 	.id_table = atl1_pci_tbl,
 	.probe = atl1_probe,
 	.remove = __devexit_p(atl1_remove),
-	/* Power Managment Hooks */
-	/* probably broken right now -- CHS */
 	.suspend = atl1_suspend,
 	.resume = atl1_resume
 };
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index f03f070..6628fa6 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,13 +39,13 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0067"
+#define DRV_VERSION	"EHEA_0070"
 
-/* EHEA capability flags */
+/* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
-#define DLPAR_MEM_ADD 2
-#define DLPAR_MEM_REM 4
-#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM)
+#define DLPAR_MEM_ADD      2
+#define DLPAR_MEM_REM      4
+#define EHEA_CAPABILITIES  (DLPAR_PORT_ADD_REM)
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
 	| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
@@ -113,6 +113,8 @@
 /* Memory Regions */
 #define EHEA_MR_ACC_CTRL       0x00800000
 
+#define EHEA_BUSMAP_START      0x8000000000000000ULL
+
 #define EHEA_WATCH_DOG_TIMEOUT 10*HZ
 
 /* utility functions */
@@ -186,6 +188,12 @@ struct h_epas {
 				   set to 0 if unused */
 };
 
+struct ehea_busmap {
+	unsigned int entries;		/* total number of entries */
+	unsigned int valid_sections;	/* number of valid sections */
+	u64 *vaddr;
+};
+
 struct ehea_qp;
 struct ehea_cq;
 struct ehea_eq;
@@ -382,6 +390,8 @@ struct ehea_adapter {
 	struct ehea_mr mr;
 	u32 pd;                    /* protection domain */
 	u64 max_mc_mac;            /* max number of multicast mac addresses */
+	int active_ports;
+	struct list_head list;
 };
 
 
@@ -431,6 +441,9 @@ struct port_res_cfg {
 	int max_entries_rq3;
 };
 
+enum ehea_flag_bits {
+	__EHEA_STOP_XFER
+};
 
 void ehea_set_ethtool_ops(struct net_device *netdev);
 int ehea_sense_port_attr(struct ehea_port *port);
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 383144d..1d1571c 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -79,6 +79,11 @@ MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue  "
 MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 ");
 
 static int port_name_cnt = 0;
+static LIST_HEAD(adapter_list);
+u64 ehea_driver_flags = 0;
+struct workqueue_struct *ehea_driver_wq;
+struct work_struct ehea_rereg_mr_task;
+
 
 static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
 					const struct of_device_id *id);
@@ -238,13 +243,17 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
 		rwqe->wr_id = EHEA_BMASK_SET(EHEA_WR_ID_TYPE, wqe_type)
 			    | EHEA_BMASK_SET(EHEA_WR_ID_INDEX, index);
 		rwqe->sg_list[0].l_key = pr->recv_mr.lkey;
-		rwqe->sg_list[0].vaddr = (u64)skb->data;
+		rwqe->sg_list[0].vaddr = ehea_map_vaddr(skb->data);
 		rwqe->sg_list[0].len = packet_size;
 		rwqe->data_segments = 1;
 
 		index++;
 		index &= max_index_mask;
+
+		if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)))
+			goto out;
 	}
+
 	q_skba->index = index;
 
 	/* Ring doorbell */
@@ -253,7 +262,7 @@ static int ehea_refill_rq_def(struct ehea_port_res *pr,
 		ehea_update_rq2a(pr->qp, i);
 	else
 		ehea_update_rq3a(pr->qp, i);
-
+out:
 	return ret;
 }
 
@@ -1321,7 +1330,7 @@ static void write_swqe2_TSO(struct sk_buff *skb,
 			sg1entry->len = skb_data_size - headersize;
 
 			tmp_addr = (u64)(skb->data + headersize);
-			sg1entry->vaddr = tmp_addr;
+			sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
 			swqe->descriptors++;
 		}
 	} else
@@ -1352,7 +1361,7 @@ static void write_swqe2_nonTSO(struct sk_buff *skb,
 			sg1entry->l_key = lkey;
 			sg1entry->len = skb_data_size - SWQE2_MAX_IMM;
 			tmp_addr = (u64)(skb->data + SWQE2_MAX_IMM);
-			sg1entry->vaddr = tmp_addr;
+			sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
 			swqe->descriptors++;
 		}
 	} else {
@@ -1391,7 +1400,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
 			sg1entry->len = frag->size;
 			tmp_addr =  (u64)(page_address(frag->page)
 					  + frag->page_offset);
-			sg1entry->vaddr = tmp_addr;
+			sg1entry->vaddr = ehea_map_vaddr(tmp_addr);
 			swqe->descriptors++;
 			sg1entry_contains_frag_data = 1;
 		}
@@ -1406,7 +1415,7 @@ static inline void write_swqe2_data(struct sk_buff *skb, struct net_device *dev,
 
 			tmp_addr = (u64)(page_address(frag->page)
 					 + frag->page_offset);
-			sgentry->vaddr = tmp_addr;
+			sgentry->vaddr = ehea_map_vaddr(tmp_addr);
 			swqe->descriptors++;
 		}
 	}
@@ -1878,6 +1887,9 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		ehea_dump(swqe, 512, "swqe");
 	}
 
+	if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags)))
+		goto out;
+
 	ehea_post_swqe(pr->qp, swqe);
 	pr->tx_packets++;
 
@@ -1892,7 +1904,7 @@ static int ehea_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 	dev->trans_start = jiffies;
 	spin_unlock(&pr->xmit_lock);
-
+out:
 	return NETDEV_TX_OK;
 }
 
@@ -2220,6 +2232,9 @@ out_dereg_bc:
 out_clean_pr:
 	ehea_clean_all_portres(port);
 out:
+	if (ret)
+		ehea_info("Failed starting %s. ret=%i", dev->name, ret);
+
 	return ret;
 }
 
@@ -2259,8 +2274,13 @@ static int ehea_down(struct net_device *dev)
 			msleep(1);
 
 	ehea_broadcast_reg_helper(port, H_DEREG_BCMC);
-	ret = ehea_clean_all_portres(port);
 	port->state = EHEA_PORT_DOWN;
+
+	ret = ehea_clean_all_portres(port);
+	if (ret)
+		ehea_info("Failed freeing resources for %s. ret=%i",
+			  dev->name, ret);
+
 	return ret;
 }
 
@@ -2292,15 +2312,11 @@ static void ehea_reset_port(struct work_struct *work)
 	netif_stop_queue(dev);
 	netif_poll_disable(dev);
 
-	ret = ehea_down(dev);
-	if (ret)
-		ehea_error("ehea_down failed. not all resources are freed");
+	ehea_down(dev);
 
 	ret = ehea_up(dev);
-	if (ret) {
-		ehea_error("Reset device %s failed: ret=%d", dev->name, ret);
+	if (ret)
 		goto out;
-	}
 
 	if (netif_msg_timer(port))
 		ehea_info("Device %s resetted successfully", dev->name);
@@ -2312,6 +2328,88 @@ out:
 	return;
 }
 
+static void ehea_rereg_mrs(struct work_struct *work)
+{
+	int ret, i;
+	struct ehea_adapter *adapter;
+
+	ehea_info("LPAR memory enlarged - re-initializing driver");
+
+	list_for_each_entry(adapter, &adapter_list, list)
+		if (adapter->active_ports) {
+			/* Shutdown all ports */
+			for (i = 0; i < EHEA_MAX_PORTS; i++) {
+				struct ehea_port *port = adapter->port[i];
+
+				if (port) {
+					struct net_device *dev = port->netdev;
+
+					if (dev->flags & IFF_UP) {
+						ehea_info("stopping %s",
+							  dev->name);
+						down(&port->port_lock);
+						netif_stop_queue(dev);
+						netif_poll_disable(dev);
+						ehea_down(dev);
+						up(&port->port_lock);
+					}
+				}
+			}
+
+			/* Unregister old memory region */
+			ret = ehea_rem_mr(&adapter->mr);
+			if (ret) {
+				ehea_error("unregister MR failed - driver"
+					   " inoperable!");
+				goto out;
+			}
+		}
+
+	ehea_destroy_busmap();
+
+	ret = ehea_create_busmap();
+	if (ret)
+		goto out;
+
+	clear_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
+
+	list_for_each_entry(adapter, &adapter_list, list)
+		if (adapter->active_ports) {
+			/* Register new memory region */
+			ret = ehea_reg_kernel_mr(adapter, &adapter->mr);
+			if (ret) {
+				ehea_error("register MR failed - driver"
+					   " inoperable!");
+				goto out;
+			}
+
+			/* Restart all ports */
+			for (i = 0; i < EHEA_MAX_PORTS; i++) {
+				struct ehea_port *port = adapter->port[i];
+
+				if (port) {
+					struct net_device *dev = port->netdev;
+
+					if (dev->flags & IFF_UP) {
+						ehea_info("restarting %s",
+							  dev->name);
+						down(&port->port_lock);
+
+						ret = ehea_up(dev);
+						if (!ret) {
+							netif_poll_enable(dev);
+							netif_wake_queue(dev);
+						}
+
+						up(&port->port_lock);
+					}
+				}
+			}
+		}
+out:
+	return;
+}
+
 static void ehea_tx_watchdog(struct net_device *dev)
 {
 	struct ehea_port *port = netdev_priv(dev);
@@ -2573,6 +2671,8 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
 	ehea_info("%s: Jumbo frames are %sabled", dev->name,
 		  jumbo == 1 ? "en" : "dis");
 
+	adapter->active_ports++;
+
 	return port;
 
 out_unreg_port:
@@ -2596,6 +2696,7 @@ static void ehea_shutdown_single_port(struct ehea_port *port)
 	ehea_unregister_port(port);
 	kfree(port->mc_list);
 	free_netdev(port->netdev);
+	port->adapter->active_ports--;
 }
 
 static int ehea_setup_ports(struct ehea_adapter *adapter)
@@ -2788,6 +2889,8 @@ static int __devinit ehea_probe_adapter(struct ibmebus_dev *dev,
 		goto out;
 	}
 
+	list_add(&adapter->list, &adapter_list);
+
 	adapter->ebus_dev = dev;
 
 	adapter_handle = of_get_property(dev->ofdev.node, "ibm,hea-handle",
@@ -2891,7 +2994,10 @@ static int __devexit ehea_remove(struct ibmebus_dev *dev)
 
 	ehea_destroy_eq(adapter->neq);
 	ehea_remove_adapter_mr(adapter);
+	list_del(&adapter->list);
+
 	kfree(adapter);
+
 	return 0;
 }
 
@@ -2939,9 +3045,18 @@ int __init ehea_module_init(void)
 	printk(KERN_INFO "IBM eHEA ethernet device driver (Release %s)\n",
 	       DRV_VERSION);
 
+	ehea_driver_wq = create_workqueue("ehea_driver_wq");
+
+	INIT_WORK(&ehea_rereg_mr_task, ehea_rereg_mrs);
+
 	ret = check_module_parm();
 	if (ret)
 		goto out;
+
+	ret = ehea_create_busmap();
+	if (ret)
+		goto out;
+
 	ret = ibmebus_register_driver(&ehea_driver);
 	if (ret) {
 		ehea_error("failed registering eHEA device driver on ebus");
@@ -2965,6 +3080,7 @@ static void __exit ehea_module_exit(void)
 {
 	driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
 	ibmebus_unregister_driver(&ehea_driver);
+	ehea_destroy_busmap();
 }
 
 module_init(ehea_module_init);
diff --git a/drivers/net/ehea/ehea_phyp.h b/drivers/net/ehea/ehea_phyp.h
index d17a45a..89b6353 100644
--- a/drivers/net/ehea/ehea_phyp.h
+++ b/drivers/net/ehea/ehea_phyp.h
@@ -60,6 +60,9 @@ static inline u32 get_longbusy_msecs(int long_busy_ret_code)
 	}
 }
 
+/* Number of pages which can be registered at once by H_REGISTER_HEA_RPAGES */
+#define EHEA_MAX_RPAGE 512
+
 /* Notification Event Queue (NEQ) Entry bit masks */
 #define NEQE_EVENT_CODE		EHEA_BMASK_IBM(2, 7)
 #define NEQE_PORTNUM  		EHEA_BMASK_IBM(32, 47)
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 29eaa46..a36fa6c 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -31,6 +31,13 @@
 #include "ehea_phyp.h"
 #include "ehea_qmr.h"
 
+
+struct ehea_busmap ehea_bmap = { 0, 0, NULL };
+extern u64 ehea_driver_flags;
+extern struct workqueue_struct *ehea_driver_wq;
+extern struct work_struct ehea_rereg_mr_task;
+
+
 static void *hw_qpageit_get_inc(struct hw_queue *queue)
 {
 	void *retvalue = hw_qeit_get(queue);
@@ -547,18 +554,84 @@ int ehea_destroy_qp(struct ehea_qp *qp)
 	return 0;
 }
 
+int ehea_create_busmap( void )
+{
+	u64 vaddr = EHEA_BUSMAP_START;
+	unsigned long abs_max_pfn = 0;
+	unsigned long sec_max_pfn;
+	int i;
+
+	/*
+	 * Sections are not in ascending order -> Loop over all sections and
+	 * find the highest PFN to compute the required map size.
+	*/
+	ehea_bmap.valid_sections = 0;
+
+	for (i = 0; i < NR_MEM_SECTIONS; i++)
+		if (valid_section_nr(i)) {
+			sec_max_pfn = section_nr_to_pfn(i);
+			if (sec_max_pfn > abs_max_pfn)
+				abs_max_pfn = sec_max_pfn;
+			ehea_bmap.valid_sections++;
+		}
+
+	ehea_bmap.entries = abs_max_pfn / EHEA_PAGES_PER_SECTION + 1;
+	ehea_bmap.vaddr = vmalloc(ehea_bmap.entries * sizeof(*ehea_bmap.vaddr));
+
+	if (!ehea_bmap.vaddr)
+		return -ENOMEM;
+
+	for (i = 0 ; i < ehea_bmap.entries; i++) {
+		unsigned long pfn = section_nr_to_pfn(i);
+
+		if (pfn_valid(pfn)) {
+			ehea_bmap.vaddr[i] = vaddr;
+			vaddr += EHEA_SECTSIZE;
+		} else
+			ehea_bmap.vaddr[i] = 0;
+	}
+
+	return 0;
+}
+
+void ehea_destroy_busmap( void )
+{
+	vfree(ehea_bmap.vaddr);
+}
+
+u64 ehea_map_vaddr(void *caddr)
+{
+	u64 mapped_addr;
+	unsigned long index = __pa(caddr) >> SECTION_SIZE_BITS;
+
+	if (likely(index < ehea_bmap.entries)) {
+		mapped_addr = ehea_bmap.vaddr[index];
+		if (likely(mapped_addr))
+			mapped_addr |= (((unsigned long)caddr)
+					& (EHEA_SECTSIZE - 1));
+		else
+			mapped_addr = -1;
+	} else
+		mapped_addr = -1;
+
+	if (unlikely(mapped_addr == -1))
+		if (!test_and_set_bit(__EHEA_STOP_XFER, &ehea_driver_flags))
+			queue_work(ehea_driver_wq, &ehea_rereg_mr_task);
+
+	return mapped_addr;
+}
+
 int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
 {
-	int i, k, ret;
-	u64 hret, pt_abs, start, end, nr_pages;
-	u32 acc_ctrl = EHEA_MR_ACC_CTRL;
+	int ret;
 	u64 *pt;
+	void *pg;
+	u64 hret, pt_abs, i, j, m, mr_len;
+	u32 acc_ctrl = EHEA_MR_ACC_CTRL;
 
-	start = KERNELBASE;
-	end = (u64)high_memory;
-	nr_pages = (end - start) / EHEA_PAGESIZE;
+	mr_len = ehea_bmap.valid_sections * EHEA_SECTSIZE;
 
-	pt =  kzalloc(PAGE_SIZE, GFP_KERNEL);
+	pt =  kzalloc(EHEA_MAX_RPAGE * sizeof(u64), GFP_KERNEL);
 	if (!pt) {
 		ehea_error("no mem");
 		ret = -ENOMEM;
@@ -566,7 +639,8 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
 	}
 	pt_abs = virt_to_abs(pt);
 
-	hret = ehea_h_alloc_resource_mr(adapter->handle, start, end - start,
+	hret = ehea_h_alloc_resource_mr(adapter->handle,
+					EHEA_BUSMAP_START, mr_len,
 					acc_ctrl, adapter->pd,
 					&mr->handle, &mr->lkey);
 	if (hret != H_SUCCESS) {
@@ -575,49 +649,43 @@ int ehea_reg_kernel_mr(struct ehea_adapter *adapter, struct ehea_mr *mr)
 		goto out;
 	}
 
-	mr->vaddr = KERNELBASE;
-	k = 0;
-
-	while (nr_pages > 0) {
-		if (nr_pages > 1) {
-			u64 num_pages = min(nr_pages, (u64)512);
-			for (i = 0; i < num_pages; i++)
-				pt[i] = virt_to_abs((void*)(((u64)start) +
-							    ((k++) *
-							     EHEA_PAGESIZE)));
-
-			hret = ehea_h_register_rpage_mr(adapter->handle,
-							mr->handle, 0,
-							0, (u64)pt_abs,
-							num_pages);
-			nr_pages -= num_pages;
-		} else {
-			u64 abs_adr = virt_to_abs((void*)(((u64)start) +
-							  (k * EHEA_PAGESIZE)));
-
-			hret = ehea_h_register_rpage_mr(adapter->handle,
-							mr->handle, 0,
-							0, abs_adr,1);
-			nr_pages--;
-		}
-
-		if ((hret != H_SUCCESS) && (hret != H_PAGE_REGISTERED)) {
-			ehea_h_free_resource(adapter->handle,
-					     mr->handle, FORCE_FREE);
-			ehea_error("register_rpage_mr failed");
-			ret = -EIO;
-			goto out;
+	for (i = 0 ; i < ehea_bmap.entries; i++)
+		if (ehea_bmap.vaddr[i]) {
+			void *sectbase = __va(i << SECTION_SIZE_BITS);
+			unsigned long k = 0;
+
+			for (j = 0; j < (PAGES_PER_SECTION / EHEA_MAX_RPAGE);
+			      j++) {
+
+				for (m = 0; m < EHEA_MAX_RPAGE; m++) {
+					pg = sectbase + ((k++) * EHEA_PAGESIZE);
+					pt[m] = virt_to_abs(pg);
+				}
+
+				hret = ehea_h_register_rpage_mr(adapter->handle,
+								mr->handle,
+								0, 0, pt_abs,
+								EHEA_MAX_RPAGE);
+				if ((hret != H_SUCCESS)
+				    && (hret != H_PAGE_REGISTERED)) {
+					ehea_h_free_resource(adapter->handle,
+							     mr->handle,
+							     FORCE_FREE);
+					ehea_error("register_rpage_mr failed");
+					ret = -EIO;
+					goto out;
+				}
+			}
 		}
-	}
 
 	if (hret != H_SUCCESS) {
-		ehea_h_free_resource(adapter->handle, mr->handle,
-				     FORCE_FREE);
-		ehea_error("register_rpage failed for last page");
+		ehea_h_free_resource(adapter->handle, mr->handle, FORCE_FREE);
+		ehea_error("registering mr failed");
 		ret = -EIO;
 		goto out;
 	}
 
+	mr->vaddr = EHEA_BUSMAP_START;
 	mr->adapter = adapter;
 	ret = 0;
 out:
diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h
index c0eb3e0..b71f845 100644
--- a/drivers/net/ehea/ehea_qmr.h
+++ b/drivers/net/ehea/ehea_qmr.h
@@ -36,8 +36,14 @@
  * page size of ehea hardware queues
  */
 
-#define EHEA_PAGESHIFT  12
-#define EHEA_PAGESIZE   4096UL
+#define EHEA_PAGESHIFT         12
+#define EHEA_PAGESIZE          (1UL << EHEA_PAGESHIFT)
+#define EHEA_SECTSIZE          (1UL << 24)
+#define EHEA_PAGES_PER_SECTION (EHEA_SECTSIZE >> PAGE_SHIFT)
+
+#if (1UL << SECTION_SIZE_BITS) < EHEA_SECTSIZE
+#error eHEA module can't work if kernel sectionsize < ehea sectionsize
+#endif
 
 /* Some abbreviations used here:
  *
@@ -372,4 +378,8 @@ int ehea_rem_mr(struct ehea_mr *mr);
 
 void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle);
 
+int ehea_create_busmap( void );
+void ehea_destroy_busmap( void );
+u64 ehea_map_vaddr(void *caddr);
+
 #endif	/* __EHEA_QMR_H__ */
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 42ba1c0..a361dba 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -550,6 +550,8 @@ union ring_type {
 /* PHY defines */
 #define PHY_OUI_MARVELL	0x5043
 #define PHY_OUI_CICADA	0x03f1
+#define PHY_OUI_VITESSE	0x01c1
+#define PHY_OUI_REALTEK	0x01c1
 #define PHYID1_OUI_MASK	0x03ff
 #define PHYID1_OUI_SHFT	6
 #define PHYID2_OUI_MASK	0xfc00
@@ -557,12 +559,36 @@ union ring_type {
 #define PHYID2_MODEL_MASK		0x03f0
 #define PHY_MODEL_MARVELL_E3016		0x220
 #define PHY_MARVELL_E3016_INITMASK	0x0300
-#define PHY_INIT1	0x0f000
-#define PHY_INIT2	0x0e00
-#define PHY_INIT3	0x01000
-#define PHY_INIT4	0x0200
-#define PHY_INIT5	0x0004
-#define PHY_INIT6	0x02000
+#define PHY_CICADA_INIT1	0x0f000
+#define PHY_CICADA_INIT2	0x0e00
+#define PHY_CICADA_INIT3	0x01000
+#define PHY_CICADA_INIT4	0x0200
+#define PHY_CICADA_INIT5	0x0004
+#define PHY_CICADA_INIT6	0x02000
+#define PHY_VITESSE_INIT_REG1	0x1f
+#define PHY_VITESSE_INIT_REG2	0x10
+#define PHY_VITESSE_INIT_REG3	0x11
+#define PHY_VITESSE_INIT_REG4	0x12
+#define PHY_VITESSE_INIT_MSK1	0xc
+#define PHY_VITESSE_INIT_MSK2	0x0180
+#define PHY_VITESSE_INIT1	0x52b5
+#define PHY_VITESSE_INIT2	0xaf8a
+#define PHY_VITESSE_INIT3	0x8
+#define PHY_VITESSE_INIT4	0x8f8a
+#define PHY_VITESSE_INIT5	0xaf86
+#define PHY_VITESSE_INIT6	0x8f86
+#define PHY_VITESSE_INIT7	0xaf82
+#define PHY_VITESSE_INIT8	0x0100
+#define PHY_VITESSE_INIT9	0x8f82
+#define PHY_VITESSE_INIT10	0x0
+#define PHY_REALTEK_INIT_REG1	0x1f
+#define PHY_REALTEK_INIT_REG2	0x19
+#define PHY_REALTEK_INIT_REG3	0x13
+#define PHY_REALTEK_INIT1	0x0000
+#define PHY_REALTEK_INIT2	0x8e00
+#define PHY_REALTEK_INIT3	0x0001
+#define PHY_REALTEK_INIT4	0xad17
+
 #define PHY_GIGABIT	0x0100
 
 #define PHY_TIMEOUT	0x1
@@ -1096,6 +1122,28 @@ static int phy_init(struct net_device *dev)
 			return PHY_ERROR;
 		}
 	}
+	if (np->phy_oui == PHY_OUI_REALTEK) {
+		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+	}
 
 	/* set advertise register */
 	reg = mii_rw(dev, np->phyaddr, MII_ADVERTISE, MII_READ);
@@ -1141,14 +1189,14 @@ static int phy_init(struct net_device *dev)
 	/* phy vendor specific configuration */
 	if ((np->phy_oui == PHY_OUI_CICADA) && (phyinterface & PHY_RGMII) ) {
 		phy_reserved = mii_rw(dev, np->phyaddr, MII_RESV1, MII_READ);
-		phy_reserved &= ~(PHY_INIT1 | PHY_INIT2);
-		phy_reserved |= (PHY_INIT3 | PHY_INIT4);
+		phy_reserved &= ~(PHY_CICADA_INIT1 | PHY_CICADA_INIT2);
+		phy_reserved |= (PHY_CICADA_INIT3 | PHY_CICADA_INIT4);
 		if (mii_rw(dev, np->phyaddr, MII_RESV1, phy_reserved)) {
 			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
 			return PHY_ERROR;
 		}
 		phy_reserved = mii_rw(dev, np->phyaddr, MII_NCONFIG, MII_READ);
-		phy_reserved |= PHY_INIT5;
+		phy_reserved |= PHY_CICADA_INIT5;
 		if (mii_rw(dev, np->phyaddr, MII_NCONFIG, phy_reserved)) {
 			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
 			return PHY_ERROR;
@@ -1156,12 +1204,106 @@ static int phy_init(struct net_device *dev)
 	}
 	if (np->phy_oui == PHY_OUI_CICADA) {
 		phy_reserved = mii_rw(dev, np->phyaddr, MII_SREVISION, MII_READ);
-		phy_reserved |= PHY_INIT6;
+		phy_reserved |= PHY_CICADA_INIT6;
 		if (mii_rw(dev, np->phyaddr, MII_SREVISION, phy_reserved)) {
 			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
 			return PHY_ERROR;
 		}
 	}
+	if (np->phy_oui == PHY_OUI_VITESSE) {
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT1)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT2)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
+		phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
+		phy_reserved |= PHY_VITESSE_INIT3;
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT4)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT5)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
+		phy_reserved &= ~PHY_VITESSE_INIT_MSK1;
+		phy_reserved |= PHY_VITESSE_INIT3;
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT6)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT7)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, MII_READ);
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG4, phy_reserved)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		phy_reserved = mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, MII_READ);
+		phy_reserved &= ~PHY_VITESSE_INIT_MSK2;
+		phy_reserved |= PHY_VITESSE_INIT8;
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG3, phy_reserved)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG2, PHY_VITESSE_INIT9)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_VITESSE_INIT_REG1, PHY_VITESSE_INIT10)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+	}
+	if (np->phy_oui == PHY_OUI_REALTEK) {
+		/* reset could have cleared these out, set them back */
+		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG2, PHY_REALTEK_INIT2)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT3)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG3, PHY_REALTEK_INIT4)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+		if (mii_rw(dev, np->phyaddr, PHY_REALTEK_INIT_REG1, PHY_REALTEK_INIT1)) {
+			printk(KERN_INFO "%s: phy init failed.\n", pci_name(np->pci_dev));
+			return PHY_ERROR;
+		}
+	}
+
 	/* some phys clear out pause advertisment on reset, set it back */
 	mii_rw(dev, np->phyaddr, MII_ADVERTISE, reg);
 
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index 5dd34a1..ac3596f 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -31,7 +31,6 @@
 #include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
-#include <asm/ocp.h>
 #include <linux/crc32.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 0e04f7a..a4bb026 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -17,13 +17,12 @@
 #include <linux/init.h>
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
-#include <linux/mii.h>
-#include <linux/mutex.h>
 #include <linux/dma-mapping.h>
-#include <linux/ethtool.h>
 #include <linux/platform_device.h>
+#include <linux/phy.h>
 
 #include <asm/arch/board.h>
+#include <asm/arch/cpu.h>
 
 #include "macb.h"
 
@@ -85,172 +84,202 @@ static void __init macb_get_hwaddr(struct macb *bp)
 		memcpy(bp->dev->dev_addr, addr, sizeof(addr));
 }
 
-static void macb_enable_mdio(struct macb *bp)
+static int macb_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 {
-	unsigned long flags;
-	u32 reg;
-
-	spin_lock_irqsave(&bp->lock, flags);
-	reg = macb_readl(bp, NCR);
-	reg |= MACB_BIT(MPE);
-	macb_writel(bp, NCR, reg);
-	macb_writel(bp, IER, MACB_BIT(MFD));
-	spin_unlock_irqrestore(&bp->lock, flags);
-}
-
-static void macb_disable_mdio(struct macb *bp)
-{
-	unsigned long flags;
-	u32 reg;
-
-	spin_lock_irqsave(&bp->lock, flags);
-	reg = macb_readl(bp, NCR);
-	reg &= ~MACB_BIT(MPE);
-	macb_writel(bp, NCR, reg);
-	macb_writel(bp, IDR, MACB_BIT(MFD));
-	spin_unlock_irqrestore(&bp->lock, flags);
-}
-
-static int macb_mdio_read(struct net_device *dev, int phy_id, int location)
-{
-	struct macb *bp = netdev_priv(dev);
+	struct macb *bp = bus->priv;
 	int value;
 
-	mutex_lock(&bp->mdio_mutex);
-
-	macb_enable_mdio(bp);
 	macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
 			      | MACB_BF(RW, MACB_MAN_READ)
-			      | MACB_BF(PHYA, phy_id)
-			      | MACB_BF(REGA, location)
+			      | MACB_BF(PHYA, mii_id)
+			      | MACB_BF(REGA, regnum)
 			      | MACB_BF(CODE, MACB_MAN_CODE)));
 
-	wait_for_completion(&bp->mdio_complete);
+	/* wait for end of transfer */
+	while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
+		cpu_relax();
 
 	value = MACB_BFEXT(DATA, macb_readl(bp, MAN));
-	macb_disable_mdio(bp);
-	mutex_unlock(&bp->mdio_mutex);
 
 	return value;
 }
 
-static void macb_mdio_write(struct net_device *dev, int phy_id,
-			    int location, int val)
+static int macb_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+			   u16 value)
 {
-	struct macb *bp = netdev_priv(dev);
-
-	dev_dbg(&bp->pdev->dev, "mdio_write %02x:%02x <- %04x\n",
-		phy_id, location, val);
-
-	mutex_lock(&bp->mdio_mutex);
-	macb_enable_mdio(bp);
+	struct macb *bp = bus->priv;
 
 	macb_writel(bp, MAN, (MACB_BF(SOF, MACB_MAN_SOF)
 			      | MACB_BF(RW, MACB_MAN_WRITE)
-			      | MACB_BF(PHYA, phy_id)
-			      | MACB_BF(REGA, location)
+			      | MACB_BF(PHYA, mii_id)
+			      | MACB_BF(REGA, regnum)
 			      | MACB_BF(CODE, MACB_MAN_CODE)
-			      | MACB_BF(DATA, val)));
+			      | MACB_BF(DATA, value)));
 
-	wait_for_completion(&bp->mdio_complete);
+	/* wait for end of transfer */
+	while (!MACB_BFEXT(IDLE, macb_readl(bp, NSR)))
+		cpu_relax();
 
-	macb_disable_mdio(bp);
-	mutex_unlock(&bp->mdio_mutex);
+	return 0;
 }
 
-static int macb_phy_probe(struct macb *bp)
+static int macb_mdio_reset(struct mii_bus *bus)
 {
-	int phy_address;
-	u16 phyid1, phyid2;
+	return 0;
+}
 
-	for (phy_address = 0; phy_address < 32; phy_address++) {
-		phyid1 = macb_mdio_read(bp->dev, phy_address, MII_PHYSID1);
-		phyid2 = macb_mdio_read(bp->dev, phy_address, MII_PHYSID2);
+static void macb_handle_link_change(struct net_device *dev)
+{
+	struct macb *bp = netdev_priv(dev);
+	struct phy_device *phydev = bp->phy_dev;
+	unsigned long flags;
 
-		if (phyid1 != 0xffff && phyid1 != 0x0000
-		    && phyid2 != 0xffff && phyid2 != 0x0000)
-			break;
+	int status_change = 0;
+
+	spin_lock_irqsave(&bp->lock, flags);
+
+	if (phydev->link) {
+		if ((bp->speed != phydev->speed) ||
+		    (bp->duplex != phydev->duplex)) {
+			u32 reg;
+
+			reg = macb_readl(bp, NCFGR);
+			reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
+
+			if (phydev->duplex)
+				reg |= MACB_BIT(FD);
+			if (phydev->speed)
+				reg |= MACB_BIT(SPD);
+
+			macb_writel(bp, NCFGR, reg);
+
+			bp->speed = phydev->speed;
+			bp->duplex = phydev->duplex;
+			status_change = 1;
+		}
 	}
 
-	if (phy_address == 32)
-		return -ENODEV;
+	if (phydev->link != bp->link) {
+		if (phydev->link)
+			netif_schedule(dev);
+		else {
+			bp->speed = 0;
+			bp->duplex = -1;
+		}
+		bp->link = phydev->link;
 
-	dev_info(&bp->pdev->dev,
-		 "detected PHY at address %d (ID %04x:%04x)\n",
-		 phy_address, phyid1, phyid2);
+		status_change = 1;
+	}
 
-	bp->mii.phy_id = phy_address;
-	return 0;
+	spin_unlock_irqrestore(&bp->lock, flags);
+
+	if (status_change) {
+		if (phydev->link)
+			printk(KERN_INFO "%s: link up (%d/%s)\n",
+			       dev->name, phydev->speed,
+			       DUPLEX_FULL == phydev->duplex ? "Full":"Half");
+		else
+			printk(KERN_INFO "%s: link down\n", dev->name);
+	}
 }
 
-static void macb_set_media(struct macb *bp, int media)
+/* based on au1000_eth. c*/
+static int macb_mii_probe(struct net_device *dev)
 {
-	u32 reg;
+	struct macb *bp = netdev_priv(dev);
+	struct phy_device *phydev = NULL;
+	struct eth_platform_data *pdata;
+	int phy_addr;
 
-	spin_lock_irq(&bp->lock);
-	reg = macb_readl(bp, NCFGR);
-	reg &= ~(MACB_BIT(SPD) | MACB_BIT(FD));
-	if (media & (ADVERTISE_100HALF | ADVERTISE_100FULL))
-		reg |= MACB_BIT(SPD);
-	if (media & ADVERTISE_FULL)
-		reg |= MACB_BIT(FD);
-	macb_writel(bp, NCFGR, reg);
-	spin_unlock_irq(&bp->lock);
+	/* find the first phy */
+	for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
+		if (bp->mii_bus.phy_map[phy_addr]) {
+			phydev = bp->mii_bus.phy_map[phy_addr];
+			break;
+		}
+	}
+
+	if (!phydev) {
+		printk (KERN_ERR "%s: no PHY found\n", dev->name);
+		return -1;
+	}
+
+	pdata = bp->pdev->dev.platform_data;
+	/* TODO : add pin_irq */
+
+	/* attach the mac to the phy */
+	if (pdata && pdata->is_rmii) {
+		phydev = phy_connect(dev, phydev->dev.bus_id,
+			&macb_handle_link_change, 0, PHY_INTERFACE_MODE_RMII);
+	} else {
+		phydev = phy_connect(dev, phydev->dev.bus_id,
+			&macb_handle_link_change, 0, PHY_INTERFACE_MODE_MII);
+	}
+
+	if (IS_ERR(phydev)) {
+		printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
+		return PTR_ERR(phydev);
+	}
+
+	/* mask with MAC supported features */
+	phydev->supported &= PHY_BASIC_FEATURES;
+
+	phydev->advertising = phydev->supported;
+
+	bp->link = 0;
+	bp->speed = 0;
+	bp->duplex = -1;
+	bp->phy_dev = phydev;
+
+	return 0;
 }
 
-static void macb_check_media(struct macb *bp, int ok_to_print, int init_media)
+static int macb_mii_init(struct macb *bp)
 {
-	struct mii_if_info *mii = &bp->mii;
-	unsigned int old_carrier, new_carrier;
-	int advertise, lpa, media, duplex;
+	struct eth_platform_data *pdata;
+	int err = -ENXIO, i;
 
-	/* if forced media, go no further */
-	if (mii->force_media)
-		return;
+	/* Enable managment port */
+	macb_writel(bp, NCR, MACB_BIT(MPE));
 
-	/* check current and old link status */
-	old_carrier = netif_carrier_ok(mii->dev) ? 1 : 0;
-	new_carrier = (unsigned int) mii_link_ok(mii);
+	bp->mii_bus.name = "MACB_mii_bus",
+	bp->mii_bus.read = &macb_mdio_read,
+	bp->mii_bus.write = &macb_mdio_write,
+	bp->mii_bus.reset = &macb_mdio_reset,
+	bp->mii_bus.id = bp->pdev->id,
+	bp->mii_bus.priv = bp,
+	bp->mii_bus.dev = &bp->dev->dev;
+	pdata = bp->pdev->dev.platform_data;
 
-	/* if carrier state did not change, assume nothing else did */
-	if (!init_media && old_carrier == new_carrier)
-		return;
+	if (pdata)
+		bp->mii_bus.phy_mask = pdata->phy_mask;
 
-	/* no carrier, nothing much to do */
-	if (!new_carrier) {
-		netif_carrier_off(mii->dev);
-		printk(KERN_INFO "%s: link down\n", mii->dev->name);
-		return;
+	bp->mii_bus.irq = kmalloc(sizeof(int)*PHY_MAX_ADDR, GFP_KERNEL);
+	if (!bp->mii_bus.irq) {
+		err = -ENOMEM;
+		goto err_out;
 	}
 
-	/*
-	 * we have carrier, see who's on the other end
-	 */
-	netif_carrier_on(mii->dev);
+	for (i = 0; i < PHY_MAX_ADDR; i++)
+		bp->mii_bus.irq[i] = PHY_POLL;
 
-	/* get MII advertise and LPA values */
-	if (!init_media && mii->advertising) {
-		advertise = mii->advertising;
-	} else {
-		advertise = mii->mdio_read(mii->dev, mii->phy_id, MII_ADVERTISE);
-		mii->advertising = advertise;
-	}
-	lpa = mii->mdio_read(mii->dev, mii->phy_id, MII_LPA);
+	platform_set_drvdata(bp->dev, &bp->mii_bus);
 
-	/* figure out media and duplex from advertise and LPA values */
-	media = mii_nway_result(lpa & advertise);
-	duplex = (media & ADVERTISE_FULL) ? 1 : 0;
+	if (mdiobus_register(&bp->mii_bus))
+		goto err_out_free_mdio_irq;
 
-	if (ok_to_print)
-		printk(KERN_INFO "%s: link up, %sMbps, %s-duplex, lpa 0x%04X\n",
-		       mii->dev->name,
-		       media & (ADVERTISE_100FULL | ADVERTISE_100HALF) ? "100" : "10",
-		       duplex ? "full" : "half", lpa);
+	if (macb_mii_probe(bp->dev) != 0) {
+		goto err_out_unregister_bus;
+	}
 
-	mii->full_duplex = duplex;
+	return 0;
 
-	/* Let the MAC know about the new link state */
-	macb_set_media(bp, media);
+err_out_unregister_bus:
+	mdiobus_unregister(&bp->mii_bus);
+err_out_free_mdio_irq:
+	kfree(bp->mii_bus.irq);
+err_out:
+	return err;
 }
 
 static void macb_update_stats(struct macb *bp)
@@ -265,16 +294,6 @@ static void macb_update_stats(struct macb *bp)
 		*p += __raw_readl(reg);
 }
 
-static void macb_periodic_task(struct work_struct *work)
-{
-	struct macb *bp = container_of(work, struct macb, periodic_task.work);
-
-	macb_update_stats(bp);
-	macb_check_media(bp, 1, 0);
-
-	schedule_delayed_work(&bp->periodic_task, HZ);
-}
-
 static void macb_tx(struct macb *bp)
 {
 	unsigned int tail;
@@ -519,9 +538,6 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
 	spin_lock(&bp->lock);
 
 	while (status) {
-		if (status & MACB_BIT(MFD))
-			complete(&bp->mdio_complete);
-
 		/* close possible race with dev_close */
 		if (unlikely(!netif_running(dev))) {
 			macb_writel(bp, IDR, ~0UL);
@@ -535,7 +551,8 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
 				 * until we have processed the buffers
 				 */
 				macb_writel(bp, IDR, MACB_RX_INT_FLAGS);
-				dev_dbg(&bp->pdev->dev, "scheduling RX softirq\n");
+				dev_dbg(&bp->pdev->dev,
+					"scheduling RX softirq\n");
 				__netif_rx_schedule(dev);
 			}
 		}
@@ -765,7 +782,7 @@ static void macb_init_hw(struct macb *bp)
 	macb_writel(bp, TBQP, bp->tx_ring_dma);
 
 	/* Enable TX and RX */
-	macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE));
+	macb_writel(bp, NCR, MACB_BIT(RE) | MACB_BIT(TE) | MACB_BIT(MPE));
 
 	/* Enable interrupts */
 	macb_writel(bp, IER, (MACB_BIT(RCOMP)
@@ -776,18 +793,126 @@ static void macb_init_hw(struct macb *bp)
 			      | MACB_BIT(TCOMP)
 			      | MACB_BIT(ISR_ROVR)
 			      | MACB_BIT(HRESP)));
+
 }
 
-static void macb_init_phy(struct net_device *dev)
+/*
+ * The hash address register is 64 bits long and takes up two
+ * locations in the memory map.  The least significant bits are stored
+ * in EMAC_HSL and the most significant bits in EMAC_HSH.
+ *
+ * The unicast hash enable and the multicast hash enable bits in the
+ * network configuration register enable the reception of hash matched
+ * frames. The destination address is reduced to a 6 bit index into
+ * the 64 bit hash register using the following hash function.  The
+ * hash function is an exclusive or of every sixth bit of the
+ * destination address.
+ *
+ * hi[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47]
+ * hi[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46]
+ * hi[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45]
+ * hi[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44]
+ * hi[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43]
+ * hi[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42]
+ *
+ * da[0] represents the least significant bit of the first byte
+ * received, that is, the multicast/unicast indicator, and da[47]
+ * represents the most significant bit of the last byte received.  If
+ * the hash index, hi[n], points to a bit that is set in the hash
+ * register then the frame will be matched according to whether the
+ * frame is multicast or unicast.  A multicast match will be signalled
+ * if the multicast hash enable bit is set, da[0] is 1 and the hash
+ * index points to a bit set in the hash register.  A unicast match
+ * will be signalled if the unicast hash enable bit is set, da[0] is 0
+ * and the hash index points to a bit set in the hash register.  To
+ * receive all multicast frames, the hash register should be set with
+ * all ones and the multicast hash enable bit should be set in the
+ * network configuration register.
+ */
+
+static inline int hash_bit_value(int bitnr, __u8 *addr)
 {
+	if (addr[bitnr / 8] & (1 << (bitnr % 8)))
+		return 1;
+	return 0;
+}
+
+/*
+ * Return the hash index value for the specified address.
+ */
+static int hash_get_index(__u8 *addr)
+{
+	int i, j, bitval;
+	int hash_index = 0;
+
+	for (j = 0; j < 6; j++) {
+		for (i = 0, bitval = 0; i < 8; i++)
+			bitval ^= hash_bit_value(i*6 + j, addr);
+
+		hash_index |= (bitval << j);
+	}
+
+	return hash_index;
+}
+
+/*
+ * Add multicast addresses to the internal multicast-hash table.
+ */
+static void macb_sethashtable(struct net_device *dev)
+{
+	struct dev_mc_list *curr;
+	unsigned long mc_filter[2];
+	unsigned int i, bitnr;
+	struct macb *bp = netdev_priv(dev);
+
+	mc_filter[0] = mc_filter[1] = 0;
+
+	curr = dev->mc_list;
+	for (i = 0; i < dev->mc_count; i++, curr = curr->next) {
+		if (!curr) break;	/* unexpected end of list */
+
+		bitnr = hash_get_index(curr->dmi_addr);
+		mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
+	}
+
+	macb_writel(bp, HRB, mc_filter[0]);
+	macb_writel(bp, HRT, mc_filter[1]);
+}
+
+/*
+ * Enable/Disable promiscuous and multicast modes.
+ */
+static void macb_set_rx_mode(struct net_device *dev)
+{
+	unsigned long cfg;
 	struct macb *bp = netdev_priv(dev);
 
-	/* Set some reasonable default settings */
-	macb_mdio_write(dev, bp->mii.phy_id, MII_ADVERTISE,
-			ADVERTISE_CSMA | ADVERTISE_ALL);
-	macb_mdio_write(dev, bp->mii.phy_id, MII_BMCR,
-			(BMCR_SPEED100 | BMCR_ANENABLE
-			 | BMCR_ANRESTART | BMCR_FULLDPLX));
+	cfg = macb_readl(bp, NCFGR);
+
+	if (dev->flags & IFF_PROMISC)
+		/* Enable promiscuous mode */
+		cfg |= MACB_BIT(CAF);
+	else if (dev->flags & (~IFF_PROMISC))
+		 /* Disable promiscuous mode */
+		cfg &= ~MACB_BIT(CAF);
+
+	if (dev->flags & IFF_ALLMULTI) {
+		/* Enable all multicast mode */
+		macb_writel(bp, HRB, -1);
+		macb_writel(bp, HRT, -1);
+		cfg |= MACB_BIT(NCFGR_MTI);
+	} else if (dev->mc_count > 0) {
+		/* Enable specific multicasts */
+		macb_sethashtable(dev);
+		cfg |= MACB_BIT(NCFGR_MTI);
+	} else if (dev->flags & (~IFF_ALLMULTI)) {
+		/* Disable all multicast mode */
+		macb_writel(bp, HRB, 0);
+		macb_writel(bp, HRT, 0);
+		cfg &= ~MACB_BIT(NCFGR_MTI);
+	}
+
+	macb_writel(bp, NCFGR, cfg);
 }
 
 static int macb_open(struct net_device *dev)
@@ -797,6 +922,10 @@ static int macb_open(struct net_device *dev)
 
 	dev_dbg(&bp->pdev->dev, "open\n");
 
+	/* if the phy is not yet register, retry later*/
+	if (!bp->phy_dev)
+		return -EAGAIN;
+
 	if (!is_valid_ether_addr(dev->dev_addr))
 		return -EADDRNOTAVAIL;
 
@@ -810,12 +939,11 @@ static int macb_open(struct net_device *dev)
 
 	macb_init_rings(bp);
 	macb_init_hw(bp);
-	macb_init_phy(dev);
 
-	macb_check_media(bp, 1, 1);
-	netif_start_queue(dev);
+	/* schedule a link state check */
+	phy_start(bp->phy_dev);
 
-	schedule_delayed_work(&bp->periodic_task, HZ);
+	netif_start_queue(dev);
 
 	return 0;
 }
@@ -825,10 +953,11 @@ static int macb_close(struct net_device *dev)
 	struct macb *bp = netdev_priv(dev);
 	unsigned long flags;
 
-	cancel_rearming_delayed_work(&bp->periodic_task);
-
 	netif_stop_queue(dev);
 
+	if (bp->phy_dev)
+		phy_stop(bp->phy_dev);
+
 	spin_lock_irqsave(&bp->lock, flags);
 	macb_reset_hw(bp);
 	netif_carrier_off(dev);
@@ -845,6 +974,9 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev)
 	struct net_device_stats *nstat = &bp->stats;
 	struct macb_stats *hwstat = &bp->hw_stats;
 
+	/* read stats from hardware */
+	macb_update_stats(bp);
+
 	/* Convert HW stats into netdevice stats */
 	nstat->rx_errors = (hwstat->rx_fcs_errors +
 			    hwstat->rx_align_errors +
@@ -882,18 +1014,27 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev)
 static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct macb *bp = netdev_priv(dev);
+	struct phy_device *phydev = bp->phy_dev;
 
-	return mii_ethtool_gset(&bp->mii, cmd);
+	if (!phydev)
+		return -ENODEV;
+
+	return phy_ethtool_gset(phydev, cmd);
 }
 
 static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct macb *bp = netdev_priv(dev);
+	struct phy_device *phydev = bp->phy_dev;
+
+	if (!phydev)
+		return -ENODEV;
 
-	return mii_ethtool_sset(&bp->mii, cmd);
+	return phy_ethtool_sset(phydev, cmd);
 }
 
-static void macb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+static void macb_get_drvinfo(struct net_device *dev,
+			     struct ethtool_drvinfo *info)
 {
 	struct macb *bp = netdev_priv(dev);
 
@@ -902,104 +1043,34 @@ static void macb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *inf
 	strcpy(info->bus_info, bp->pdev->dev.bus_id);
 }
 
-static int macb_nway_reset(struct net_device *dev)
-{
-	struct macb *bp = netdev_priv(dev);
-	return mii_nway_restart(&bp->mii);
-}
-
 static struct ethtool_ops macb_ethtool_ops = {
 	.get_settings		= macb_get_settings,
 	.set_settings		= macb_set_settings,
 	.get_drvinfo		= macb_get_drvinfo,
-	.nway_reset		= macb_nway_reset,
 	.get_link		= ethtool_op_get_link,
 };
 
 static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct macb *bp = netdev_priv(dev);
+	struct phy_device *phydev = bp->phy_dev;
 
 	if (!netif_running(dev))
 		return -EINVAL;
 
-	return generic_mii_ioctl(&bp->mii, if_mii(rq), cmd, NULL);
-}
-
-static ssize_t macb_mii_show(const struct device *_dev, char *buf,
-			unsigned long addr)
-{
-	struct net_device *dev = to_net_dev(_dev);
-	struct macb *bp = netdev_priv(dev);
-	ssize_t ret = -EINVAL;
-
-	if (netif_running(dev)) {
-		int value;
-		value = macb_mdio_read(dev, bp->mii.phy_id, addr);
-		ret = sprintf(buf, "0x%04x\n", (uint16_t)value);
-	}
-
-	return ret;
-}
-
-#define MII_ENTRY(name, addr)					\
-static ssize_t show_##name(struct device *_dev,			\
-			   struct device_attribute *attr,	\
-			   char *buf)				\
-{								\
-	return macb_mii_show(_dev, buf, addr);			\
-}								\
-static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL)
-
-MII_ENTRY(bmcr, MII_BMCR);
-MII_ENTRY(bmsr, MII_BMSR);
-MII_ENTRY(physid1, MII_PHYSID1);
-MII_ENTRY(physid2, MII_PHYSID2);
-MII_ENTRY(advertise, MII_ADVERTISE);
-MII_ENTRY(lpa, MII_LPA);
-MII_ENTRY(expansion, MII_EXPANSION);
-
-static struct attribute *macb_mii_attrs[] = {
-	&dev_attr_bmcr.attr,
-	&dev_attr_bmsr.attr,
-	&dev_attr_physid1.attr,
-	&dev_attr_physid2.attr,
-	&dev_attr_advertise.attr,
-	&dev_attr_lpa.attr,
-	&dev_attr_expansion.attr,
-	NULL,
-};
-
-static struct attribute_group macb_mii_group = {
-	.name	= "mii",
-	.attrs	= macb_mii_attrs,
-};
-
-static void macb_unregister_sysfs(struct net_device *net)
-{
-	struct device *_dev = &net->dev;
+	if (!phydev)
+		return -ENODEV;
 
-	sysfs_remove_group(&_dev->kobj, &macb_mii_group);
+	return phy_mii_ioctl(phydev, if_mii(rq), cmd);
 }
 
-static int macb_register_sysfs(struct net_device *net)
-{
-	struct device *_dev = &net->dev;
-	int ret;
-
-	ret = sysfs_create_group(&_dev->kobj, &macb_mii_group);
-	if (ret)
-		printk(KERN_WARNING
-		       "%s: sysfs mii attribute registration failed: %d\n",
-		       net->name, ret);
-	return ret;
-}
 static int __devinit macb_probe(struct platform_device *pdev)
 {
 	struct eth_platform_data *pdata;
 	struct resource *regs;
 	struct net_device *dev;
 	struct macb *bp;
+	struct phy_device *phydev;
 	unsigned long pclk_hz;
 	u32 config;
 	int err = -ENXIO;
@@ -1073,6 +1144,7 @@ static int __devinit macb_probe(struct platform_device *pdev)
 	dev->stop = macb_close;
 	dev->hard_start_xmit = macb_start_xmit;
 	dev->get_stats = macb_get_stats;
+	dev->set_multicast_list = macb_set_rx_mode;
 	dev->do_ioctl = macb_ioctl;
 	dev->poll = macb_poll;
 	dev->weight = 64;
@@ -1080,10 +1152,6 @@ static int __devinit macb_probe(struct platform_device *pdev)
 
 	dev->base_addr = regs->start;
 
-	INIT_DELAYED_WORK(&bp->periodic_task, macb_periodic_task);
-	mutex_init(&bp->mdio_mutex);
-	init_completion(&bp->mdio_complete);
-
 	/* Set MII management clock divider */
 	pclk_hz = clk_get_rate(bp->pclk);
 	if (pclk_hz <= 20000000)
@@ -1096,20 +1164,9 @@ static int __devinit macb_probe(struct platform_device *pdev)
 		config = MACB_BF(CLK, MACB_CLK_DIV64);
 	macb_writel(bp, NCFGR, config);
 
-	bp->mii.dev = dev;
-	bp->mii.mdio_read = macb_mdio_read;
-	bp->mii.mdio_write = macb_mdio_write;
-	bp->mii.phy_id_mask = 0x1f;
-	bp->mii.reg_num_mask = 0x1f;
-
 	macb_get_hwaddr(bp);
-	err = macb_phy_probe(bp);
-	if (err) {
-		dev_err(&pdev->dev, "Failed to detect PHY, aborting.\n");
-		goto err_out_free_irq;
-	}
-
 	pdata = pdev->dev.platform_data;
+
 	if (pdata && pdata->is_rmii)
 #if defined(CONFIG_ARCH_AT91)
 		macb_writel(bp, USRIO, (MACB_BIT(RMII) | MACB_BIT(CLKEN)) );
@@ -1131,9 +1188,11 @@ static int __devinit macb_probe(struct platform_device *pdev)
 		goto err_out_free_irq;
 	}
 
-	platform_set_drvdata(pdev, dev);
+	if (macb_mii_init(bp) != 0) {
+		goto err_out_unregister_netdev;
+	}
 
-	macb_register_sysfs(dev);
+	platform_set_drvdata(pdev, dev);
 
 	printk(KERN_INFO "%s: Atmel MACB at 0x%08lx irq %d "
 	       "(%02x:%02x:%02x:%02x:%02x:%02x)\n",
@@ -1141,8 +1200,15 @@ static int __devinit macb_probe(struct platform_device *pdev)
 	       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
 	       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
 
+	phydev = bp->phy_dev;
+	printk(KERN_INFO "%s: attached PHY driver [%s] "
+		"(mii_bus:phy_addr=%s, irq=%d)\n",
+		dev->name, phydev->drv->name, phydev->dev.bus_id, phydev->irq);
+
 	return 0;
 
+err_out_unregister_netdev:
+	unregister_netdev(dev);
 err_out_free_irq:
 	free_irq(dev->irq, dev);
 err_out_iounmap:
@@ -1153,7 +1219,9 @@ err_out_disable_clocks:
 	clk_put(bp->hclk);
 #endif
 	clk_disable(bp->pclk);
+#ifndef CONFIG_ARCH_AT91
 err_out_put_pclk:
+#endif
 	clk_put(bp->pclk);
 err_out_free_dev:
 	free_netdev(dev);
@@ -1171,7 +1239,8 @@ static int __devexit macb_remove(struct platform_device *pdev)
 
 	if (dev) {
 		bp = netdev_priv(dev);
-		macb_unregister_sysfs(dev);
+		mdiobus_unregister(&bp->mii_bus);
+		kfree(bp->mii_bus.irq);
 		unregister_netdev(dev);
 		free_irq(dev->irq, dev);
 		iounmap(bp->regs);
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
index b3bb218..4e3283e 100644
--- a/drivers/net/macb.h
+++ b/drivers/net/macb.h
@@ -383,11 +383,11 @@ struct macb {
 
 	unsigned int		rx_pending, tx_pending;
 
-	struct delayed_work	periodic_task;
-
-	struct mutex		mdio_mutex;
-	struct completion	mdio_complete;
-	struct mii_if_info	mii;
+	struct mii_bus		mii_bus;
+	struct phy_device	*phy_dev;
+	unsigned int 		link;
+	unsigned int 		speed;
+	unsigned int 		duplex;
 };
 
 #endif /* _MACB_H */
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index e1732c1..deca653 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -1060,7 +1060,6 @@ static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index)
 	struct myri10ge_tx_buf *tx = &mgp->tx;
 	struct sk_buff *skb;
 	int idx, len;
-	int limit = 0;
 
 	while (tx->pkt_done != mcp_index) {
 		idx = tx->done & tx->mask;
@@ -1091,11 +1090,6 @@ static inline void myri10ge_tx_done(struct myri10ge_priv *mgp, int mcp_index)
 							      bus), len,
 					       PCI_DMA_TODEVICE);
 		}
-
-		/* limit potential for livelock by only handling
-		 * 2 full tx rings per call */
-		if (unlikely(++limit > 2 * tx->mask))
-			break;
 	}
 	/* start the queue if we've stopped it */
 	if (netif_queue_stopped(mgp->dev)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index fa29a40..7d54935 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -796,12 +796,14 @@ static void free_shared_mem(struct s2io_nic *nic)
 	struct mac_info *mac_control;
 	struct config_param *config;
 	int lst_size, lst_per_page;
-	struct net_device *dev = nic->dev;
+	struct net_device *dev;
 	int page_num = 0;
 
 	if (!nic)
 		return;
 
+	dev = nic->dev;
+
 	mac_control = &nic->mac_control;
 	config = &nic->config;
 
diff --git a/drivers/net/usb/cdc_subset.c b/drivers/net/usb/cdc_subset.c
index bc62b01..943988e 100644
--- a/drivers/net/usb/cdc_subset.c
+++ b/drivers/net/usb/cdc_subset.c
@@ -305,6 +305,9 @@ static const struct usb_device_id	products [] = {
 	USB_DEVICE (0x8086, 0x07d3),	// "blob" bootloader
 	.driver_info =	(unsigned long) &blob_info,
 }, {
+	USB_DEVICE (0x1286, 0x8001),    // "blob" bootloader
+	.driver_info =  (unsigned long) &blob_info,
+}, {
 	// Linux Ethernet/RNDIS gadget on pxa210/25x/26x, second config
 	// e.g. Gumstix, current OpenZaurus, ...
 	USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203),
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 2d3a180..1c54908 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -52,6 +52,8 @@
 
 #include "airo.h"
 
+#define DRV_NAME "airo"
+
 #ifdef CONFIG_PCI
 static struct pci_device_id card_ids[] = {
 	{ 0x14b9, 1, PCI_ANY_ID, PCI_ANY_ID, },
@@ -71,7 +73,7 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state);
 static int airo_pci_resume(struct pci_dev *pdev);
 
 static struct pci_driver airo_driver = {
-	.name     = "airo",
+	.name     = DRV_NAME,
 	.id_table = card_ids,
 	.probe    = airo_pci_probe,
 	.remove   = __devexit_p(airo_pci_remove),
@@ -1092,7 +1094,7 @@ static int get_dec_u16( char *buffer, int *start, int limit );
 static void OUT4500( struct airo_info *, u16 register, u16 value );
 static unsigned short IN4500( struct airo_info *, u16 register );
 static u16 setup_card(struct airo_info*, u8 *mac, int lock);
-static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock );
+static int enable_MAC(struct airo_info *ai, int lock);
 static void disable_MAC(struct airo_info *ai, int lock);
 static void enable_interrupts(struct airo_info*);
 static void disable_interrupts(struct airo_info*);
@@ -1250,7 +1252,7 @@ static int flashputbuf(struct airo_info *ai);
 static int flashrestart(struct airo_info *ai,struct net_device *dev);
 
 #define airo_print(type, name, fmt, args...) \
-	{ printk(type "airo(%s): " fmt "\n", name, ##args); }
+	printk(type DRV_NAME "(%s): " fmt "\n", name, ##args)
 
 #define airo_print_info(name, fmt, args...) \
 	airo_print(KERN_INFO, name, fmt, ##args)
@@ -1926,28 +1928,54 @@ static int readStatsRid(struct airo_info*ai, StatsRid *sr, int rid, int lock) {
 	return rc;
 }
 
+static void try_auto_wep(struct airo_info *ai)
+{
+	if (auto_wep && !(ai->flags & FLAG_RADIO_DOWN)) {
+		ai->expires = RUN_AT(3*HZ);
+		wake_up_interruptible(&ai->thr_wait);
+	}
+}
+
 static int airo_open(struct net_device *dev) {
-	struct airo_info *info = dev->priv;
-	Resp rsp;
+	struct airo_info *ai = dev->priv;
+	int rc = 0;
 
-	if (test_bit(FLAG_FLASHING, &info->flags))
+	if (test_bit(FLAG_FLASHING, &ai->flags))
 		return -EIO;
 
 	/* Make sure the card is configured.
 	 * Wireless Extensions may postpone config changes until the card
 	 * is open (to pipeline changes and speed-up card setup). If
 	 * those changes are not yet commited, do it now - Jean II */
-	if (test_bit (FLAG_COMMIT, &info->flags)) {
-		disable_MAC(info, 1);
-		writeConfigRid(info, 1);
+	if (test_bit(FLAG_COMMIT, &ai->flags)) {
+		disable_MAC(ai, 1);
+		writeConfigRid(ai, 1);
 	}
 
-	if (info->wifidev != dev) {
+	if (ai->wifidev != dev) {
+		clear_bit(JOB_DIE, &ai->jobs);
+		ai->airo_thread_task = kthread_run(airo_thread, dev, dev->name);
+		if (IS_ERR(ai->airo_thread_task))
+			return (int)PTR_ERR(ai->airo_thread_task);
+
+		rc = request_irq(dev->irq, airo_interrupt, IRQF_SHARED,
+			dev->name, dev);
+		if (rc) {
+			airo_print_err(dev->name,
+				"register interrupt %d failed, rc %d",
+				dev->irq, rc);
+			set_bit(JOB_DIE, &ai->jobs);
+			kthread_stop(ai->airo_thread_task);
+			return rc;
+		}
+
 		/* Power on the MAC controller (which may have been disabled) */
-		clear_bit(FLAG_RADIO_DOWN, &info->flags);
-		enable_interrupts(info);
+		clear_bit(FLAG_RADIO_DOWN, &ai->flags);
+		enable_interrupts(ai);
+
+		try_auto_wep(ai);
 	}
-	enable_MAC(info, &rsp, 1);
+	enable_MAC(ai, 1);
 
 	netif_start_queue(dev);
 	return 0;
@@ -2338,14 +2366,13 @@ static int airo_set_mac_address(struct net_device *dev, void *p)
 {
 	struct airo_info *ai = dev->priv;
 	struct sockaddr *addr = p;
-	Resp rsp;
 
 	readConfigRid(ai, 1);
 	memcpy (ai->config.macAddr, addr->sa_data, dev->addr_len);
 	set_bit (FLAG_COMMIT, &ai->flags);
 	disable_MAC(ai, 1);
 	writeConfigRid (ai, 1);
-	enable_MAC(ai, &rsp, 1);
+	enable_MAC(ai, 1);
 	memcpy (ai->dev->dev_addr, addr->sa_data, dev->addr_len);
 	if (ai->wifidev)
 		memcpy (ai->wifidev->dev_addr, addr->sa_data, dev->addr_len);
@@ -2392,6 +2419,11 @@ static int airo_close(struct net_device *dev) {
 		disable_MAC(ai, 1);
 #endif
 		disable_interrupts( ai );
+
+		free_irq(dev->irq, dev);
+
+		set_bit(JOB_DIE, &ai->jobs);
+		kthread_stop(ai->airo_thread_task);
 	}
 	return 0;
 }
@@ -2403,7 +2435,6 @@ void stop_airo_card( struct net_device *dev, int freeres )
 	set_bit(FLAG_RADIO_DOWN, &ai->flags);
 	disable_MAC(ai, 1);
 	disable_interrupts(ai);
-	free_irq( dev->irq, dev );
 	takedown_proc_entry( dev, ai );
 	if (test_bit(FLAG_REGISTERED, &ai->flags)) {
 		unregister_netdev( dev );
@@ -2414,9 +2445,6 @@ void stop_airo_card( struct net_device *dev, int freeres )
 		}
 		clear_bit(FLAG_REGISTERED, &ai->flags);
 	}
-	set_bit(JOB_DIE, &ai->jobs);
-	kthread_stop(ai->airo_thread_task);
-
 	/*
 	 * Clean out tx queue
 	 */
@@ -2554,8 +2582,7 @@ static int mpi_init_descriptors (struct airo_info *ai)
  * 2) Map PCI memory for issueing commands.
  * 3) Allocate memory (shared) to send and receive ethernet frames.
  */
-static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
-		    const char *name)
+static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci)
 {
 	unsigned long mem_start, mem_len, aux_start, aux_len;
 	int rc = -1;
@@ -2569,35 +2596,35 @@ static int mpi_map_card(struct airo_info *ai, struct pci_dev *pci,
 	aux_start = pci_resource_start(pci, 2);
 	aux_len = AUXMEMSIZE;
 
-	if (!request_mem_region(mem_start, mem_len, name)) {
-		airo_print_err(ai->dev->name, "Couldn't get region %x[%x] for %s",
-		       (int)mem_start, (int)mem_len, name);
+	if (!request_mem_region(mem_start, mem_len, DRV_NAME)) {
+		airo_print_err("", "Couldn't get region %x[%x]",
+			(int)mem_start, (int)mem_len);
 		goto out;
 	}
-	if (!request_mem_region(aux_start, aux_len, name)) {
-		airo_print_err(ai->dev->name, "Couldn't get region %x[%x] for %s",
-		       (int)aux_start, (int)aux_len, name);
+	if (!request_mem_region(aux_start, aux_len, DRV_NAME)) {
+		airo_print_err("", "Couldn't get region %x[%x]",
+			(int)aux_start, (int)aux_len);
 		goto free_region1;
 	}
 
 	ai->pcimem = ioremap(mem_start, mem_len);
 	if (!ai->pcimem) {
-		airo_print_err(ai->dev->name, "Couldn't map region %x[%x] for %s",
-		       (int)mem_start, (int)mem_len, name);
+		airo_print_err("", "Couldn't map region %x[%x]",
+			(int)mem_start, (int)mem_len);
 		goto free_region2;
 	}
 	ai->pciaux = ioremap(aux_start, aux_len);
 	if (!ai->pciaux) {
-		airo_print_err(ai->dev->name, "Couldn't map region %x[%x] for %s",
-		       (int)aux_start, (int)aux_len, name);
+		airo_print_err("", "Couldn't map region %x[%x]",
+			(int)aux_start, (int)aux_len);
 		goto free_memmap;
 	}
 
 	/* Reserve PKTSIZE for each fid and 2K for the Rids */
 	ai->shared = pci_alloc_consistent(pci, PCI_SHARED_LEN, &ai->shared_dma);
 	if (!ai->shared) {
-		airo_print_err(ai->dev->name, "Couldn't alloc_consistent %d",
-		       PCI_SHARED_LEN);
+		airo_print_err("", "Couldn't alloc_consistent %d",
+			PCI_SHARED_LEN);
 		goto free_auxmap;
 	}
 
@@ -2742,7 +2769,7 @@ static int airo_networks_allocate(struct airo_info *ai)
 	    kzalloc(AIRO_MAX_NETWORK_COUNT * sizeof(BSSListElement),
 		    GFP_KERNEL);
 	if (!ai->networks) {
-		airo_print_warn(ai->dev->name, "Out of memory allocating beacons");
+		airo_print_warn("", "Out of memory allocating beacons");
 		return -ENOMEM;
 	}
 
@@ -2770,7 +2797,6 @@ static int airo_test_wpa_capable(struct airo_info *ai)
 {
 	int status;
 	CapabilityRid cap_rid;
-	const char *name = ai->dev->name;
 
 	status = readCapabilityRid(ai, &cap_rid, 1);
 	if (status != SUCCESS) return 0;
@@ -2778,12 +2804,12 @@ static int airo_test_wpa_capable(struct airo_info *ai)
 	/* Only firmware versions 5.30.17 or better can do WPA */
 	if ((cap_rid.softVer > 0x530)
 	  || ((cap_rid.softVer == 0x530) && (cap_rid.softSubVer >= 17))) {
-		airo_print_info(name, "WPA is supported.");
+		airo_print_info("", "WPA is supported.");
 		return 1;
 	}
 
 	/* No WPA support */
-	airo_print_info(name, "WPA unsupported (only firmware versions 5.30.17"
+	airo_print_info("", "WPA unsupported (only firmware versions 5.30.17"
 		" and greater support WPA.  Detected %s)", cap_rid.prodVer);
 	return 0;
 }
@@ -2797,23 +2823,19 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
 	int i, rc;
 
 	/* Create the network device object. */
-        dev = alloc_etherdev(sizeof(*ai));
-        if (!dev) {
+	dev = alloc_netdev(sizeof(*ai), "", ether_setup);
+	if (!dev) {
 		airo_print_err("", "Couldn't alloc_etherdev");
 		return NULL;
-        }
-	if (dev_alloc_name(dev, dev->name) < 0) {
-		airo_print_err("", "Couldn't get name!");
-		goto err_out_free;
 	}
 
 	ai = dev->priv;
 	ai->wifidev = NULL;
-	ai->flags = 0;
+	ai->flags = 1 << FLAG_RADIO_DOWN;
 	ai->jobs = 0;
 	ai->dev = dev;
 	if (pci && (pci->device == 0x5000 || pci->device == 0xa504)) {
-		airo_print_dbg(dev->name, "Found an MPI350 card");
+		airo_print_dbg("", "Found an MPI350 card");
 		set_bit(FLAG_MPI, &ai->flags);
 	}
 	spin_lock_init(&ai->aux_lock);
@@ -2821,14 +2843,11 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
 	ai->config.len = 0;
 	ai->pci = pci;
 	init_waitqueue_head (&ai->thr_wait);
-	ai->airo_thread_task = kthread_run(airo_thread, dev, dev->name);
-	if (IS_ERR(ai->airo_thread_task))
-		goto err_out_free;
 	ai->tfm = NULL;
 	add_airo_dev(ai);
 
 	if (airo_networks_allocate (ai))
-		goto err_out_thr;
+		goto err_out_free;
 	airo_networks_initialize (ai);
 
 	/* The Airo-specific entries in the device structure. */
@@ -2851,27 +2870,22 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
 	dev->base_addr = port;
 
 	SET_NETDEV_DEV(dev, dmdev);
+	SET_MODULE_OWNER(dev);
 
 	reset_card (dev, 1);
 	msleep(400);
 
-	rc = request_irq( dev->irq, airo_interrupt, IRQF_SHARED, dev->name, dev );
-	if (rc) {
-		airo_print_err(dev->name, "register interrupt %d failed, rc %d",
-				irq, rc);
-		goto err_out_nets;
-	}
 	if (!is_pcmcia) {
-		if (!request_region( dev->base_addr, 64, dev->name )) {
+		if (!request_region(dev->base_addr, 64, DRV_NAME)) {
 			rc = -EBUSY;
 			airo_print_err(dev->name, "Couldn't request region");
-			goto err_out_irq;
+			goto err_out_nets;
 		}
 	}
 
 	if (test_bit(FLAG_MPI,&ai->flags)) {
-		if (mpi_map_card(ai, pci, dev->name)) {
-			airo_print_err(dev->name, "Could not map memory");
+		if (mpi_map_card(ai, pci)) {
+			airo_print_err("", "Could not map memory");
 			goto err_out_res;
 		}
 	}
@@ -2899,6 +2913,7 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
 		ai->bssListRidLen = sizeof(BSSListRid) - sizeof(BSSListRidExtra);
 	}
 
+	strcpy(dev->name, "eth%d");
 	rc = register_netdev(dev);
 	if (rc) {
 		airo_print_err(dev->name, "Couldn't register_netdev");
@@ -2921,8 +2936,6 @@ static struct net_device *_init_airo_card( unsigned short irq, int port,
 	if (setup_proc_entry(dev, dev->priv) < 0)
 		goto err_out_wifi;
 
-	netif_start_queue(dev);
-	SET_MODULE_OWNER(dev);
 	return dev;
 
 err_out_wifi:
@@ -2940,14 +2953,9 @@ err_out_map:
 err_out_res:
 	if (!is_pcmcia)
 	        release_region( dev->base_addr, 64 );
-err_out_irq:
-	free_irq(dev->irq, dev);
 err_out_nets:
 	airo_networks_free(ai);
-err_out_thr:
 	del_airo_dev(ai);
-	set_bit(JOB_DIE, &ai->jobs);
-	kthread_stop(ai->airo_thread_task);
 err_out_free:
 	free_netdev(dev);
 	return NULL;
@@ -3529,9 +3537,11 @@ static u16 IN4500( struct airo_info *ai, u16 reg ) {
 	return rc;
 }
 
-static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) {
+static int enable_MAC(struct airo_info *ai, int lock)
+{
 	int rc;
-        Cmd cmd;
+	Cmd cmd;
+	Resp rsp;
 
 	/* FLAG_RADIO_OFF : Radio disabled via /proc or Wireless Extensions
 	 * FLAG_RADIO_DOWN : Radio disabled via "ifconfig ethX down"
@@ -3547,7 +3557,7 @@ static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) {
 	if (!test_bit(FLAG_ENABLED, &ai->flags)) {
 		memset(&cmd, 0, sizeof(cmd));
 		cmd.cmd = MAC_ENABLE;
-		rc = issuecommand(ai, &cmd, rsp);
+		rc = issuecommand(ai, &cmd, &rsp);
 		if (rc == SUCCESS)
 			set_bit(FLAG_ENABLED, &ai->flags);
 	} else
@@ -3557,8 +3567,12 @@ static int enable_MAC( struct airo_info *ai, Resp *rsp, int lock ) {
 	    up(&ai->sem);
 
 	if (rc)
-		airo_print_err(ai->dev->name, "%s: Cannot enable MAC, err=%d",
-			__FUNCTION__, rc);
+		airo_print_err(ai->dev->name, "Cannot enable MAC");
+	else if ((rsp.status & 0xFF00) != 0) {
+		airo_print_err(ai->dev->name, "Bad MAC enable reason=%x, "
+			"rid=%x, offset=%d", rsp.rsp0, rsp.rsp1, rsp.rsp2);
+		rc = ERROR;
+	}
 	return rc;
 }
 
@@ -3902,12 +3916,9 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
 		if ( status != SUCCESS ) return ERROR;
 	}
 
-	status = enable_MAC(ai, &rsp, lock);
-	if ( status != SUCCESS || (rsp.status & 0xFF00) != 0) {
-		airo_print_err(ai->dev->name, "Bad MAC enable reason = %x, rid = %x,"
-			" offset = %d", rsp.rsp0, rsp.rsp1, rsp.rsp2 );
+	status = enable_MAC(ai, lock);
+	if (status != SUCCESS)
 		return ERROR;
-	}
 
 	/* Grab the initial wep key, we gotta save it for auto_wep */
 	rc = readWepKeyRid(ai, &wkr, 1, lock);
@@ -3919,10 +3930,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac, int lock)
 		rc = readWepKeyRid(ai, &wkr, 0, lock);
 	} while(lastindex != wkr.kindex);
 
-	if (auto_wep) {
-		ai->expires = RUN_AT(3*HZ);
-		wake_up_interruptible(&ai->thr_wait);
-	}
+	try_auto_wep(ai);
 
 	return SUCCESS;
 }
@@ -4004,7 +4012,7 @@ static int bap_setup(struct airo_info *ai, u16 rid, u16 offset, int whichbap )
 		}
 		if ( !(max_tries--) ) {
 			airo_print_err(ai->dev->name,
-				"airo: BAP setup error too many retries\n");
+				"BAP setup error too many retries\n");
 			return ERROR;
 		}
 		// -- PC4500 missed it, try again
@@ -5152,7 +5160,6 @@ static void proc_SSID_on_close( struct inode *inode, struct file *file ) {
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = dev->priv;
 	SsidRid SSID_rid;
-	Resp rsp;
 	int i;
 	int offset = 0;
 
@@ -5177,7 +5184,7 @@ static void proc_SSID_on_close( struct inode *inode, struct file *file ) {
 		SSID_rid.len = sizeof(SSID_rid);
 	disable_MAC(ai, 1);
 	writeSsidRid(ai, &SSID_rid, 1);
-	enable_MAC(ai, &rsp, 1);
+	enable_MAC(ai, 1);
 }
 
 static inline u8 hexVal(char c) {
@@ -5193,7 +5200,6 @@ static void proc_APList_on_close( struct inode *inode, struct file *file ) {
 	struct net_device *dev = dp->data;
 	struct airo_info *ai = dev->priv;
 	APListRid APList_rid;
-	Resp rsp;
 	int i;
 
 	if ( !data->writelen ) return;
@@ -5218,18 +5224,17 @@ static void proc_APList_on_close( struct inode *inode, struct file *file ) {
 	}
 	disable_MAC(ai, 1);
 	writeAPListRid(ai, &APList_rid, 1);
-	enable_MAC(ai, &rsp, 1);
+	enable_MAC(ai, 1);
 }
 
 /* This function wraps PC4500_writerid with a MAC disable */
 static int do_writerid( struct airo_info *ai, u16 rid, const void *rid_data,
 			int len, int dummy ) {
 	int rc;
-	Resp rsp;
 
 	disable_MAC(ai, 1);
 	rc = PC4500_writerid(ai, rid, rid_data, len, 1);
-	enable_MAC(ai, &rsp, 1);
+	enable_MAC(ai, 1);
 	return rc;
 }
 
@@ -5260,7 +5265,6 @@ static int set_wep_key(struct airo_info *ai, u16 index,
 		       const char *key, u16 keylen, int perm, int lock ) {
 	static const unsigned char macaddr[ETH_ALEN] = { 0x01, 0, 0, 0, 0, 0 };
 	WepKeyRid wkr;
-	Resp rsp;
 
 	memset(&wkr, 0, sizeof(wkr));
 	if (keylen == 0) {
@@ -5280,7 +5284,7 @@ static int set_wep_key(struct airo_info *ai, u16 index,
 
 	if (perm) disable_MAC(ai, lock);
 	writeWepKeyRid(ai, &wkr, perm, lock);
-	if (perm) enable_MAC(ai, &rsp, lock);
+	if (perm) enable_MAC(ai, lock);
 	return 0;
 }
 
@@ -5548,7 +5552,6 @@ static int proc_close( struct inode *inode, struct file *file )
    changed. */
 static void timer_func( struct net_device *dev ) {
 	struct airo_info *apriv = dev->priv;
-	Resp rsp;
 
 /* We don't have a link so try changing the authtype */
 	readConfigRid(apriv, 0);
@@ -5575,7 +5578,7 @@ static void timer_func( struct net_device *dev ) {
 	}
 	set_bit (FLAG_COMMIT, &apriv->flags);
 	writeConfigRid(apriv, 0);
-	enable_MAC(apriv, &rsp, 0);
+	enable_MAC(apriv, 0);
 	up(&apriv->sem);
 
 /* Schedule check to see if the change worked */
@@ -5597,8 +5600,10 @@ static int __devinit airo_pci_probe(struct pci_dev *pdev,
 			dev = _init_airo_card(pdev->irq, pdev->resource[0].start, 0, pdev, &pdev->dev);
 	else
 			dev = _init_airo_card(pdev->irq, pdev->resource[2].start, 0, pdev, &pdev->dev);
-	if (!dev)
+	if (!dev) {
+		pci_disable_device(pdev);
 		return -ENODEV;
+	}
 
 	pci_set_drvdata(pdev, dev);
 	return 0;
@@ -5610,6 +5615,8 @@ static void __devexit airo_pci_remove(struct pci_dev *pdev)
 
 	airo_print_info(dev->name, "Unregistering...");
 	stop_airo_card(dev, 1);
+	pci_disable_device(pdev);
+	pci_set_drvdata(pdev, NULL);
 }
 
 static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state)
@@ -5646,7 +5653,6 @@ static int airo_pci_resume(struct pci_dev *pdev)
 {
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct airo_info *ai = dev->priv;
-	Resp rsp;
 	pci_power_t prev_state = pdev->current_state;
 
 	pci_set_power_state(pdev, PCI_D0);
@@ -5679,7 +5685,7 @@ static int airo_pci_resume(struct pci_dev *pdev)
 		ai->APList = NULL;
 	}
 	writeConfigRid(ai, 0);
-	enable_MAC(ai, &rsp, 0);
+	enable_MAC(ai, 0);
 	ai->power = PMSG_ON;
 	netif_device_attach(dev);
 	netif_wake_queue(dev);
@@ -5903,7 +5909,6 @@ static int airo_set_essid(struct net_device *dev,
 			  char *extra)
 {
 	struct airo_info *local = dev->priv;
-	Resp rsp;
 	SsidRid SSID_rid;		/* SSIDs */
 
 	/* Reload the list of current SSID */
@@ -5935,7 +5940,7 @@ static int airo_set_essid(struct net_device *dev,
 	/* Write it to the card */
 	disable_MAC(local, 1);
 	writeSsidRid(local, &SSID_rid, 1);
-	enable_MAC(local, &rsp, 1);
+	enable_MAC(local, 1);
 
 	return 0;
 }
@@ -6000,7 +6005,7 @@ static int airo_set_wap(struct net_device *dev,
 		memcpy(APList_rid.ap[0], awrq->sa_data, ETH_ALEN);
 		disable_MAC(local, 1);
 		writeAPListRid(local, &APList_rid, 1);
-		enable_MAC(local, &rsp, 1);
+		enable_MAC(local, 1);
 	}
 	return 0;
 }
@@ -7454,7 +7459,6 @@ static int airo_config_commit(struct net_device *dev,
 			      char *extra)			/* NULL */
 {
 	struct airo_info *local = dev->priv;
-	Resp rsp;
 
 	if (!test_bit (FLAG_COMMIT, &local->flags))
 		return 0;
@@ -7479,7 +7483,7 @@ static int airo_config_commit(struct net_device *dev,
 	if (down_interruptible(&local->sem))
 		return -ERESTARTSYS;
 	writeConfigRid(local, 0);
-	enable_MAC(local, &rsp, 0);
+	enable_MAC(local, 0);
 	if (test_bit (FLAG_RESET, &local->flags))
 		airo_set_promisc(local);
 	else
@@ -7746,7 +7750,6 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
 	unsigned char *iobuf;
 	int len;
 	struct airo_info *ai = dev->priv;
-	Resp rsp;
 
 	if (test_bit(FLAG_FLASHING, &ai->flags))
 		return -EIO;
@@ -7758,7 +7761,7 @@ static int readrids(struct net_device *dev, aironet_ioctl *comp) {
 		if (test_bit(FLAG_COMMIT, &ai->flags)) {
 			disable_MAC (ai, 1);
 			writeConfigRid (ai, 1);
-			enable_MAC (ai, &rsp, 1);
+			enable_MAC(ai, 1);
 		}
 		break;
 	case AIROGSLIST:    ridcode = RID_SSID;         break;
@@ -7815,7 +7818,6 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) {
 	struct airo_info *ai = dev->priv;
 	int  ridcode;
         int  enabled;
-	Resp      rsp;
 	static int (* writer)(struct airo_info *, u16 rid, const void *, int, int);
 	unsigned char *iobuf;
 
@@ -7849,7 +7851,7 @@ static int writerids(struct net_device *dev, aironet_ioctl *comp) {
 		 * same with MAC off
 		 */
 	case AIROPMACON:
-		if (enable_MAC(ai, &rsp, 1) != 0)
+		if (enable_MAC(ai, 1) != 0)
 			return -EIO;
 		return 0;
 
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index d51daf8..072ede7 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -1768,7 +1768,8 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
 
 		if (priv->stop_rf_kill) {
 			priv->stop_rf_kill = 0;
-			queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
+			queue_delayed_work(priv->workqueue, &priv->rf_kill,
+					   round_jiffies(HZ));
 		}
 
 		deferred = 1;
@@ -2098,7 +2099,7 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
 	/* Make sure the RF Kill check timer is running */
 	priv->stop_rf_kill = 0;
 	cancel_delayed_work(&priv->rf_kill);
-	queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
+	queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
 }
 
 static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
@@ -4233,7 +4234,8 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
 			/* Make sure the RF_KILL check timer is running */
 			priv->stop_rf_kill = 0;
 			cancel_delayed_work(&priv->rf_kill);
-			queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
+			queue_delayed_work(priv->workqueue, &priv->rf_kill,
+					   round_jiffies(HZ));
 		} else
 			schedule_reset(priv);
 	}
@@ -5969,7 +5971,8 @@ static void ipw2100_rf_kill(struct work_struct *work)
 	if (rf_kill_active(priv)) {
 		IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
 		if (!priv->stop_rf_kill)
-			queue_delayed_work(priv->workqueue, &priv->rf_kill, HZ);
+			queue_delayed_work(priv->workqueue, &priv->rf_kill,
+					   round_jiffies(HZ));
 		goto exit_unlock;
 	}
 
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 7cb2052..aa32a97 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1751,7 +1751,7 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
 			/* Make sure the RF_KILL check timer is running */
 			cancel_delayed_work(&priv->rf_kill);
 			queue_delayed_work(priv->workqueue, &priv->rf_kill,
-					   2 * HZ);
+					   round_jiffies(2 * HZ));
 		} else
 			queue_work(priv->workqueue, &priv->up);
 	}
@@ -4690,7 +4690,8 @@ static void ipw_rx_notification(struct ipw_priv *priv,
 			else if (priv->config & CFG_BACKGROUND_SCAN
 				 && priv->status & STATUS_ASSOCIATED)
 				queue_delayed_work(priv->workqueue,
-						   &priv->request_scan, HZ);
+						   &priv->request_scan,
+						   round_jiffies(HZ));
 
 			/* Send an empty event to user space.
 			 * We don't send the received data on the event because
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index 13f6528..4a8f5dc 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -240,7 +240,7 @@ static int wlan_cmd_802_11_enable_rsn(wlan_private * priv,
 		if (*enable)
 			penableRSN->enable = cpu_to_le16(cmd_enable_rsn);
 		else
-			penableRSN->enable = cpu_to_le16(cmd_enable_rsn);
+			penableRSN->enable = cpu_to_le16(cmd_disable_rsn);
 	}
 
 	lbs_deb_leave(LBS_DEB_CMD);
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 88d9d2d..769c86f 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -439,7 +439,6 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
 	ret = 0;
 
 done:
-	skb->protocol = __constant_htons(0x0019);	/* ETH_P_80211_RAW */
 	lbs_deb_leave_args(LBS_DEB_RX, "ret %d", ret);
 	return ret;
 }
diff --git a/drivers/net/wireless/libertas/version.h b/drivers/net/wireless/libertas/version.h
deleted file mode 100644
index 8b13789..0000000
--- a/drivers/net/wireless/libertas/version.h
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index f42b796..2fcc3bf 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -1719,9 +1719,6 @@ static int wlan_set_encodeext(struct net_device *dev,
 			pkey->type = KEY_TYPE_ID_TKIP;
 		} else if (alg == IW_ENCODE_ALG_CCMP) {
 			pkey->type = KEY_TYPE_ID_AES;
-		} else {
-			ret = -EINVAL;
-			goto out;
 		}
 
 		/* If WPA isn't enabled yet, do that now */
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 283be4a..585f599 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -1853,7 +1853,6 @@ prism54_del_mac(struct net_device *ndev, struct iw_request_info *info,
 	islpci_private *priv = netdev_priv(ndev);
 	struct islpci_acl *acl = &priv->acl;
 	struct mac_entry *entry;
-	struct list_head *ptr;
 	struct sockaddr *addr = (struct sockaddr *) extra;
 
 	if (addr->sa_family != ARPHRD_ETHER)
@@ -1861,11 +1860,9 @@ prism54_del_mac(struct net_device *ndev, struct iw_request_info *info,
 
 	if (down_interruptible(&acl->sem))
 		return -ERESTARTSYS;
-	for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
-		entry = list_entry(ptr, struct mac_entry, _list);
-
+	list_for_each_entry(entry, &acl->mac_list, _list) {
 		if (memcmp(entry->addr, addr->sa_data, ETH_ALEN) == 0) {
-			list_del(ptr);
+			list_del(&entry->_list);
 			acl->size--;
 			kfree(entry);
 			up(&acl->sem);
@@ -1883,7 +1880,6 @@ prism54_get_mac(struct net_device *ndev, struct iw_request_info *info,
 	islpci_private *priv = netdev_priv(ndev);
 	struct islpci_acl *acl = &priv->acl;
 	struct mac_entry *entry;
-	struct list_head *ptr;
 	struct sockaddr *dst = (struct sockaddr *) extra;
 
 	dwrq->length = 0;
@@ -1891,9 +1887,7 @@ prism54_get_mac(struct net_device *ndev, struct iw_request_info *info,
 	if (down_interruptible(&acl->sem))
 		return -ERESTARTSYS;
 
-	for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
-		entry = list_entry(ptr, struct mac_entry, _list);
-
+	list_for_each_entry(entry, &acl->mac_list, _list) {
 		memcpy(dst->sa_data, entry->addr, ETH_ALEN);
 		dst->sa_family = ARPHRD_ETHER;
 		dwrq->length++;
@@ -1960,7 +1954,6 @@ prism54_get_policy(struct net_device *ndev, struct iw_request_info *info,
 static int
 prism54_mac_accept(struct islpci_acl *acl, char *mac)
 {
-	struct list_head *ptr;
 	struct mac_entry *entry;
 	int res = 0;
 
@@ -1972,8 +1965,7 @@ prism54_mac_accept(struct islpci_acl *acl, char *mac)
 		return 1;
 	}
 
-	for (ptr = acl->mac_list.next; ptr != &acl->mac_list; ptr = ptr->next) {
-		entry = list_entry(ptr, struct mac_entry, _list);
+	list_for_each_entry(entry, &acl->mac_list, _list) {
 		if (memcmp(entry->addr, mac, ETH_ALEN) == 0) {
 			res = 1;
 			break;
@@ -2216,11 +2208,9 @@ prism54_wpa_bss_ie_init(islpci_private *priv)
 void
 prism54_wpa_bss_ie_clean(islpci_private *priv)
 {
-	struct list_head *ptr, *n;
+	struct islpci_bss_wpa_ie *bss, *n;
 
-	list_for_each_safe(ptr, n, &priv->bss_wpa_list) {
-		struct islpci_bss_wpa_ie *bss;
-		bss = list_entry(ptr, struct islpci_bss_wpa_ie, list);
+	list_for_each_entry_safe(bss, n, &priv->bss_wpa_list, list) {
 		kfree(bss);
 	}
 }
diff --git a/drivers/net/wireless/rtl8187_rtl8225.c b/drivers/net/wireless/rtl8187_rtl8225.c
index e25a09f..efc4120 100644
--- a/drivers/net/wireless/rtl8187_rtl8225.c
+++ b/drivers/net/wireless/rtl8187_rtl8225.c
@@ -67,7 +67,7 @@ static void rtl8225_write_bitbang(struct ieee80211_hw *dev, u8 addr, u16 data)
 	msleep(2);
 }
 
-static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, u16 data)
+static void rtl8225_write_8051(struct ieee80211_hw *dev, u8 addr, __le16 data)
 {
 	struct rtl8187_priv *priv = dev->priv;
 	u16 reg80, reg82, reg84;
@@ -106,7 +106,7 @@ void rtl8225_write(struct ieee80211_hw *dev, u8 addr, u16 data)
 	struct rtl8187_priv *priv = dev->priv;
 
 	if (priv->asic_rev)
-		rtl8225_write_8051(dev, addr, data);
+		rtl8225_write_8051(dev, addr, cpu_to_le16(data));
 	else
 		rtl8225_write_bitbang(dev, addr, data);
 }
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 5b624bf..c39f198 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -49,8 +49,9 @@ void zd_chip_clear(struct zd_chip *chip)
 	ZD_MEMCLEAR(chip, sizeof(*chip));
 }
 
-static int scnprint_mac_oui(const u8 *addr, char *buffer, size_t size)
+static int scnprint_mac_oui(struct zd_chip *chip, char *buffer, size_t size)
 {
+	u8 *addr = zd_usb_to_netdev(&chip->usb)->dev_addr;
 	return scnprintf(buffer, size, "%02x-%02x-%02x",
 		         addr[0], addr[1], addr[2]);
 }
@@ -61,10 +62,10 @@ static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
 	int i = 0;
 
 	i = scnprintf(buffer, size, "zd1211%s chip ",
-		      chip->is_zd1211b ? "b" : "");
+		      zd_chip_is_zd1211b(chip) ? "b" : "");
 	i += zd_usb_scnprint_id(&chip->usb, buffer+i, size-i);
 	i += scnprintf(buffer+i, size-i, " ");
-	i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i);
+	i += scnprint_mac_oui(chip, buffer+i, size-i);
 	i += scnprintf(buffer+i, size-i, " ");
 	i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
 	i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c%c", chip->pa_type,
@@ -366,64 +367,9 @@ error:
 	return r;
 }
 
-static int _read_mac_addr(struct zd_chip *chip, u8 *mac_addr,
-	                  const zd_addr_t *addr)
-{
-	int r;
-	u32 parts[2];
-
-	r = zd_ioread32v_locked(chip, parts, (const zd_addr_t *)addr, 2);
-	if (r) {
-		dev_dbg_f(zd_chip_dev(chip),
-			"error: couldn't read e2p macs. Error number %d\n", r);
-		return r;
-	}
-
-	mac_addr[0] = parts[0];
-	mac_addr[1] = parts[0] >>  8;
-	mac_addr[2] = parts[0] >> 16;
-	mac_addr[3] = parts[0] >> 24;
-	mac_addr[4] = parts[1];
-	mac_addr[5] = parts[1] >>  8;
-
-	return 0;
-}
-
-static int read_e2p_mac_addr(struct zd_chip *chip)
-{
-	static const zd_addr_t addr[2] = { E2P_MAC_ADDR_P1, E2P_MAC_ADDR_P2 };
-
-	ZD_ASSERT(mutex_is_locked(&chip->mutex));
-	return _read_mac_addr(chip, chip->e2p_mac, (const zd_addr_t *)addr);
-}
-
 /* MAC address: if custom mac addresses are to to be used CR_MAC_ADDR_P1 and
  *              CR_MAC_ADDR_P2 must be overwritten
  */
-void zd_get_e2p_mac_addr(struct zd_chip *chip, u8 *mac_addr)
-{
-	mutex_lock(&chip->mutex);
-	memcpy(mac_addr, chip->e2p_mac, ETH_ALEN);
-	mutex_unlock(&chip->mutex);
-}
-
-static int read_mac_addr(struct zd_chip *chip, u8 *mac_addr)
-{
-	static const zd_addr_t addr[2] = { CR_MAC_ADDR_P1, CR_MAC_ADDR_P2 };
-	return _read_mac_addr(chip, mac_addr, (const zd_addr_t *)addr);
-}
-
-int zd_read_mac_addr(struct zd_chip *chip, u8 *mac_addr)
-{
-	int r;
-
-	dev_dbg_f(zd_chip_dev(chip), "\n");
-	mutex_lock(&chip->mutex);
-	r = read_mac_addr(chip, mac_addr);
-	mutex_unlock(&chip->mutex);
-	return r;
-}
-
 int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
 {
 	int r;
@@ -444,12 +390,6 @@ int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr)
 
 	mutex_lock(&chip->mutex);
 	r = zd_iowrite32a_locked(chip, reqs, ARRAY_SIZE(reqs));
-#ifdef DEBUG
-	{
-		u8 tmp[ETH_ALEN];
-		read_mac_addr(chip, tmp);
-	}
-#endif /* DEBUG */
 	mutex_unlock(&chip->mutex);
 	return r;
 }
@@ -809,7 +749,7 @@ out:
 
 static int hw_reset_phy(struct zd_chip *chip)
 {
-	return chip->is_zd1211b ? zd1211b_hw_reset_phy(chip) :
+	return zd_chip_is_zd1211b(chip) ? zd1211b_hw_reset_phy(chip) :
 		                  zd1211_hw_reset_phy(chip);
 }
 
@@ -874,7 +814,7 @@ static int hw_init_hmac(struct zd_chip *chip)
 	if (r)
 		return r;
 
-	return chip->is_zd1211b ?
+	return zd_chip_is_zd1211b(chip) ?
 		zd1211b_hw_init_hmac(chip) : zd1211_hw_init_hmac(chip);
 }
 
@@ -1136,8 +1076,15 @@ static int read_fw_regs_offset(struct zd_chip *chip)
 	return 0;
 }
 
+/* Read mac address using pre-firmware interface */
+int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr)
+{
+	dev_dbg_f(zd_chip_dev(chip), "\n");
+	return zd_usb_read_fw(&chip->usb, E2P_MAC_ADDR_P1, addr,
+		ETH_ALEN);
+}
 
-int zd_chip_init_hw(struct zd_chip *chip, u8 device_type)
+int zd_chip_init_hw(struct zd_chip *chip)
 {
 	int r;
 	u8 rf_type;
@@ -1145,7 +1092,6 @@ int zd_chip_init_hw(struct zd_chip *chip, u8 device_type)
 	dev_dbg_f(zd_chip_dev(chip), "\n");
 
 	mutex_lock(&chip->mutex);
-	chip->is_zd1211b = (device_type == DEVICE_ZD1211B) != 0;
 
 #ifdef DEBUG
 	r = test_init(chip);
@@ -1201,10 +1147,6 @@ int zd_chip_init_hw(struct zd_chip *chip, u8 device_type)
 		goto out;
 #endif /* DEBUG */
 
-	r = read_e2p_mac_addr(chip);
-	if (r)
-		goto out;
-
 	r = read_cal_int_tables(chip);
 	if (r)
 		goto out;
@@ -1259,7 +1201,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip,
 	r = update_pwr_int(chip, channel);
 	if (r)
 		return r;
-	if (chip->is_zd1211b) {
+	if (zd_chip_is_zd1211b(chip)) {
 		static const struct zd_ioreq16 ioreqs[] = {
 			{ CR69, 0x28 },
 			{},
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.h b/drivers/net/wireless/zd1211rw/zd_chip.h
index 79d0288..f469857 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.h
+++ b/drivers/net/wireless/zd1211rw/zd_chip.h
@@ -704,7 +704,6 @@ struct zd_chip {
 	struct mutex mutex;
 	/* Base address of FW_REG_ registers */
 	zd_addr_t fw_regs_base;
-	u8 e2p_mac[ETH_ALEN];
 	/* EepSetPoint in the vendor driver */
 	u8 pwr_cal_values[E2P_CHANNEL_COUNT];
 	/* integration values in the vendor driver */
@@ -715,7 +714,7 @@ struct zd_chip {
 	unsigned int pa_type:4,
 		patch_cck_gain:1, patch_cr157:1, patch_6m_band_edge:1,
 		new_phy_layout:1, al2230s_bit:1,
-		is_zd1211b:1, supports_tx_led:1;
+		supports_tx_led:1;
 };
 
 static inline struct zd_chip *zd_usb_to_chip(struct zd_usb *usb)
@@ -734,9 +733,15 @@ void zd_chip_init(struct zd_chip *chip,
 	         struct net_device *netdev,
 	         struct usb_interface *intf);
 void zd_chip_clear(struct zd_chip *chip);
-int zd_chip_init_hw(struct zd_chip *chip, u8 device_type);
+int zd_chip_read_mac_addr_fw(struct zd_chip *chip, u8 *addr);
+int zd_chip_init_hw(struct zd_chip *chip);
 int zd_chip_reset(struct zd_chip *chip);
 
+static inline int zd_chip_is_zd1211b(struct zd_chip *chip)
+{
+	return chip->usb.is_zd1211b;
+}
+
 static inline int zd_ioread16v_locked(struct zd_chip *chip, u16 *values,
 	                              const zd_addr_t *addresses,
 				      unsigned int count)
@@ -825,8 +830,6 @@ static inline u8 _zd_chip_get_channel(struct zd_chip *chip)
 }
 u8  zd_chip_get_channel(struct zd_chip *chip);
 int zd_read_regdomain(struct zd_chip *chip, u8 *regdomain);
-void zd_get_e2p_mac_addr(struct zd_chip *chip, u8 *mac_addr);
-int zd_read_mac_addr(struct zd_chip *chip, u8 *mac_addr);
 int zd_write_mac_addr(struct zd_chip *chip, const u8 *mac_addr);
 int zd_chip_switch_radio_on(struct zd_chip *chip);
 int zd_chip_switch_radio_off(struct zd_chip *chip);
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 6753d24..f6c487a 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -86,38 +86,46 @@ out:
 	return r;
 }
 
-int zd_mac_init_hw(struct zd_mac *mac, u8 device_type)
+int zd_mac_preinit_hw(struct zd_mac *mac)
 {
 	int r;
-	struct zd_chip *chip = &mac->chip;
 	u8 addr[ETH_ALEN];
+
+	r = zd_chip_read_mac_addr_fw(&mac->chip, addr);
+	if (r)
+		return r;
+
+	memcpy(mac->netdev->dev_addr, addr, ETH_ALEN);
+	return 0;
+}
+
+int zd_mac_init_hw(struct zd_mac *mac)
+{
+	int r;
+	struct zd_chip *chip = &mac->chip;
 	u8 default_regdomain;
 
 	r = zd_chip_enable_int(chip);
 	if (r)
 		goto out;
-	r = zd_chip_init_hw(chip, device_type);
+	r = zd_chip_init_hw(chip);
 	if (r)
 		goto disable_int;
 
-	zd_get_e2p_mac_addr(chip, addr);
-	r = zd_write_mac_addr(chip, addr);
-	if (r)
-		goto disable_int;
 	ZD_ASSERT(!irqs_disabled());
-	spin_lock_irq(&mac->lock);
-	memcpy(mac->netdev->dev_addr, addr, ETH_ALEN);
-	spin_unlock_irq(&mac->lock);
 
 	r = zd_read_regdomain(chip, &default_regdomain);
 	if (r)
 		goto disable_int;
 	if (!zd_regdomain_supported(default_regdomain)) {
-		dev_dbg_f(zd_mac_dev(mac),
-			  "Regulatory Domain %#04x is not supported.\n",
-		          default_regdomain);
-		r = -EINVAL;
-		goto disable_int;
+		/* The vendor driver overrides the regulatory domain and
+		 * allowed channel registers and unconditionally restricts
+		 * available channels to 1-11 everywhere. Match their
+		 * questionable behaviour only for regdomains which we don't
+		 * recognise. */
+		dev_warn(zd_mac_dev(mac),  "Unrecognised regulatory domain: "
+			"%#04x. Defaulting to FCC.\n", default_regdomain);
+		default_regdomain = ZD_REGDOMAIN_FCC;
 	}
 	spin_lock_irq(&mac->lock);
 	mac->regdomain = mac->default_regdomain = default_regdomain;
@@ -164,14 +172,25 @@ int zd_mac_open(struct net_device *netdev)
 {
 	struct zd_mac *mac = zd_netdev_mac(netdev);
 	struct zd_chip *chip = &mac->chip;
+	struct zd_usb *usb = &chip->usb;
 	int r;
 
+	if (!usb->initialized) {
+		r = zd_usb_init_hw(usb);
+		if (r)
+			goto out;
+	}
+
 	tasklet_enable(&mac->rx_tasklet);
 
 	r = zd_chip_enable_int(chip);
 	if (r < 0)
 		goto out;
 
+	r = zd_write_mac_addr(chip, netdev->dev_addr);
+	if (r)
+		goto disable_int;
+
 	r = zd_chip_set_basic_rates(chip, CR_RATES_80211B | CR_RATES_80211G);
 	if (r < 0)
 		goto disable_int;
@@ -251,9 +270,11 @@ int zd_mac_set_mac_address(struct net_device *netdev, void *p)
 	dev_dbg_f(zd_mac_dev(mac),
 		  "Setting MAC to " MAC_FMT "\n", MAC_ARG(addr->sa_data));
 
-	r = zd_write_mac_addr(chip, addr->sa_data);
-	if (r)
-		return r;
+	if (netdev->flags & IFF_UP) {
+		r = zd_write_mac_addr(chip, addr->sa_data);
+		if (r)
+			return r;
+	}
 
 	spin_lock_irqsave(&mac->lock, flags);
 	memcpy(netdev->dev_addr, addr->sa_data, ETH_ALEN);
@@ -855,7 +876,7 @@ static int fill_ctrlset(struct zd_mac *mac,
 	/* ZD1211B: Computing the length difference this way, gives us
 	 * flexibility to compute the packet length.
 	 */
-	cs->packet_length = cpu_to_le16(mac->chip.is_zd1211b ?
+	cs->packet_length = cpu_to_le16(zd_chip_is_zd1211b(&mac->chip) ?
 			packet_length - frag_len : packet_length);
 
 	/*
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.h b/drivers/net/wireless/zd1211rw/zd_mac.h
index faf4c78..9f9344e 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.h
+++ b/drivers/net/wireless/zd1211rw/zd_mac.h
@@ -189,7 +189,8 @@ int zd_mac_init(struct zd_mac *mac,
 		struct usb_interface *intf);
 void zd_mac_clear(struct zd_mac *mac);
 
-int zd_mac_init_hw(struct zd_mac *mac, u8 device_type);
+int zd_mac_preinit_hw(struct zd_mac *mac);
+int zd_mac_init_hw(struct zd_mac *mac);
 
 int zd_mac_open(struct net_device *netdev);
 int zd_mac_stop(struct net_device *netdev);
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.c b/drivers/net/wireless/zd1211rw/zd_rf.c
index 7407409..abe5d38 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf.c
@@ -34,7 +34,7 @@ static const char * const rfs[] = {
 	[AL2210_RF]	= "AL2210_RF",
 	[MAXIM_NEW_RF]	= "MAXIM_NEW_RF",
 	[UW2453_RF]	= "UW2453_RF",
-	[UNKNOWN_A_RF]	= "UNKNOWN_A_RF",
+	[AL2230S_RF]	= "AL2230S_RF",
 	[RALINK_RF]	= "RALINK_RF",
 	[INTERSIL_RF]	= "INTERSIL_RF",
 	[RF2959_RF]	= "RF2959_RF",
@@ -77,6 +77,7 @@ int zd_rf_init_hw(struct zd_rf *rf, u8 type)
 		r = zd_rf_init_rf2959(rf);
 		break;
 	case AL2230_RF:
+	case AL2230S_RF:
 		r = zd_rf_init_al2230(rf);
 		break;
 	case AL7230B_RF:
diff --git a/drivers/net/wireless/zd1211rw/zd_rf.h b/drivers/net/wireless/zd1211rw/zd_rf.h
index c6dfd82..30502f2 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf.h
+++ b/drivers/net/wireless/zd1211rw/zd_rf.h
@@ -26,7 +26,7 @@
 #define AL2210_RF			0x7
 #define MAXIM_NEW_RF			0x8
 #define UW2453_RF			0x9
-#define UNKNOWN_A_RF			0xa
+#define AL2230S_RF			0xa
 #define RALINK_RF			0xb
 #define INTERSIL_RF			0xc
 #define RF2959_RF			0xd
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
index e7a4ecf..006774d 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al2230.c
@@ -21,6 +21,8 @@
 #include "zd_usb.h"
 #include "zd_chip.h"
 
+#define IS_AL2230S(chip) ((chip)->al2230s_bit || (chip)->rf.type == AL2230S_RF)
+
 static const u32 zd1211_al2230_table[][3] = {
 	RF_CHANNEL( 1) = { 0x03f790, 0x033331, 0x00000d, },
 	RF_CHANNEL( 2) = { 0x03f790, 0x0b3331, 0x00000d, },
@@ -176,7 +178,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
 	if (r)
 		return r;
 
-	if (chip->al2230s_bit) {
+	if (IS_AL2230S(chip)) {
 		r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
 			ARRAY_SIZE(ioreqs_init_al2230s));
 		if (r)
@@ -188,7 +190,7 @@ static int zd1211_al2230_init_hw(struct zd_rf *rf)
 		return r;
 
 	/* improve band edge for AL2230S */
-	if (chip->al2230s_bit)
+	if (IS_AL2230S(chip))
 		r = zd_rfwrite_locked(chip, 0x000824, RF_RV_BITS);
 	else
 		r = zd_rfwrite_locked(chip, 0x0005a4, RF_RV_BITS);
@@ -314,7 +316,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
 	if (r)
 		return r;
 
-	if (chip->al2230s_bit) {
+	if (IS_AL2230S(chip)) {
 		r = zd_iowrite16a_locked(chip, ioreqs_init_al2230s,
 			ARRAY_SIZE(ioreqs_init_al2230s));
 		if (r)
@@ -328,7 +330,7 @@ static int zd1211b_al2230_init_hw(struct zd_rf *rf)
 	if (r)
 		return r;
 
-	if (chip->al2230s_bit)
+	if (IS_AL2230S(chip))
 		r = zd_rfwrite_locked(chip, 0x241000, RF_RV_BITS);
 	else
 		r = zd_rfwrite_locked(chip, 0x25a000, RF_RV_BITS);
@@ -422,7 +424,7 @@ int zd_rf_init_al2230(struct zd_rf *rf)
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
 	rf->switch_radio_off = al2230_switch_radio_off;
-	if (chip->is_zd1211b) {
+	if (zd_chip_is_zd1211b(chip)) {
 		rf->init_hw = zd1211b_al2230_init_hw;
 		rf->set_channel = zd1211b_al2230_set_channel;
 		rf->switch_radio_on = zd1211b_al2230_switch_radio_on;
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
index f4e8b6a..73d0bb2 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_al7230b.c
@@ -473,7 +473,7 @@ int zd_rf_init_al7230b(struct zd_rf *rf)
 {
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
-	if (chip->is_zd1211b) {
+	if (zd_chip_is_zd1211b(chip)) {
 		rf->init_hw = zd1211b_al7230b_init_hw;
 		rf->switch_radio_on = zd1211b_al7230b_switch_radio_on;
 		rf->set_channel = zd1211b_al7230b_set_channel;
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
index 2d736bd..cc70d40 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_rf2959.c
@@ -265,7 +265,7 @@ int zd_rf_init_rf2959(struct zd_rf *rf)
 {
 	struct zd_chip *chip = zd_rf_to_chip(rf);
 
-	if (chip->is_zd1211b) {
+	if (zd_chip_is_zd1211b(chip)) {
 		dev_err(zd_chip_dev(chip),
 		       "RF2959 is currently not supported for ZD1211B"
 		       " devices\n");
diff --git a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
index 414e40d..857dcf3 100644
--- a/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
+++ b/drivers/net/wireless/zd1211rw/zd_rf_uw2453.c
@@ -486,7 +486,7 @@ static int uw2453_switch_radio_on(struct zd_rf *rf)
 	if (r)
 		return r;
 
-	if (chip->is_zd1211b)
+	if (zd_chip_is_zd1211b(chip))
 		ioreqs[1].value = 0x7f;
 
 	return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 740a219..a1a5474 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -71,6 +71,7 @@ static struct usb_device_id usb_ids[] = {
 	{ USB_DEVICE(0x0586, 0x3412), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0586, 0x3413), .driver_info = DEVICE_ZD1211B },
 	{ USB_DEVICE(0x0053, 0x5301), .driver_info = DEVICE_ZD1211B },
+	{ USB_DEVICE(0x0411, 0x00da), .driver_info = DEVICE_ZD1211B },
 	/* "Driverless" devices that need ejecting */
 	{ USB_DEVICE(0x0ace, 0x2011), .driver_info = DEVICE_INSTALLER },
 	{ USB_DEVICE(0x0ace, 0x20ff), .driver_info = DEVICE_INSTALLER },
@@ -195,26 +196,27 @@ static u16 get_word(const void *data, u16 offset)
 	return le16_to_cpu(p[offset]);
 }
 
-static char *get_fw_name(char *buffer, size_t size, u8 device_type,
+static char *get_fw_name(struct zd_usb *usb, char *buffer, size_t size,
 	               const char* postfix)
 {
 	scnprintf(buffer, size, "%s%s",
-		device_type == DEVICE_ZD1211B ?
+		usb->is_zd1211b ?
 			FW_ZD1211B_PREFIX : FW_ZD1211_PREFIX,
 		postfix);
 	return buffer;
 }
 
-static int handle_version_mismatch(struct usb_device *udev, u8 device_type,
+static int handle_version_mismatch(struct zd_usb *usb,
 	const struct firmware *ub_fw)
 {
+	struct usb_device *udev = zd_usb_to_usbdev(usb);
 	const struct firmware *ur_fw = NULL;
 	int offset;
 	int r = 0;
 	char fw_name[128];
 
 	r = request_fw_file(&ur_fw,
-		get_fw_name(fw_name, sizeof(fw_name), device_type, "ur"),
+		get_fw_name(usb, fw_name, sizeof(fw_name), "ur"),
 		&udev->dev);
 	if (r)
 		goto error;
@@ -237,11 +239,12 @@ error:
 	return r;
 }
 
-static int upload_firmware(struct usb_device *udev, u8 device_type)
+static int upload_firmware(struct zd_usb *usb)
 {
 	int r;
 	u16 fw_bcdDevice;
 	u16 bcdDevice;
+	struct usb_device *udev = zd_usb_to_usbdev(usb);
 	const struct firmware *ub_fw = NULL;
 	const struct firmware *uph_fw = NULL;
 	char fw_name[128];
@@ -249,7 +252,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
 	bcdDevice = get_bcdDevice(udev);
 
 	r = request_fw_file(&ub_fw,
-		get_fw_name(fw_name, sizeof(fw_name), device_type,  "ub"),
+		get_fw_name(usb, fw_name, sizeof(fw_name), "ub"),
 		&udev->dev);
 	if (r)
 		goto error;
@@ -264,7 +267,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
 			dev_warn(&udev->dev, "device has old bootcode, please "
 				"report success or failure\n");
 
-		r = handle_version_mismatch(udev, device_type, ub_fw);
+		r = handle_version_mismatch(usb, ub_fw);
 		if (r)
 			goto error;
 	} else {
@@ -275,7 +278,7 @@ static int upload_firmware(struct usb_device *udev, u8 device_type)
 
 
 	r = request_fw_file(&uph_fw,
-		get_fw_name(fw_name, sizeof(fw_name), device_type, "uphr"),
+		get_fw_name(usb, fw_name, sizeof(fw_name), "uphr"),
 		&udev->dev);
 	if (r)
 		goto error;
@@ -294,6 +297,30 @@ error:
 	return r;
 }
 
+/* Read data from device address space using "firmware interface" which does
+ * not require firmware to be loaded. */
+int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len)
+{
+	int r;
+	struct usb_device *udev = zd_usb_to_usbdev(usb);
+
+	r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+		USB_REQ_FIRMWARE_READ_DATA, USB_DIR_IN | 0x40, addr, 0,
+		data, len, 5000);
+	if (r < 0) {
+		dev_err(&udev->dev,
+			"read over firmware interface failed: %d\n", r);
+		return r;
+	} else if (r != len) {
+		dev_err(&udev->dev,
+			"incomplete read over firmware interface: %d/%d\n",
+			r, len);
+		return -EIO;
+	}
+
+	return 0;
+}
+
 #define urb_dev(urb) (&(urb)->dev->dev)
 
 static inline void handle_regs_int(struct urb *urb)
@@ -920,9 +947,42 @@ static int eject_installer(struct usb_interface *intf)
 	return 0;
 }
 
+int zd_usb_init_hw(struct zd_usb *usb)
+{
+	int r;
+	struct zd_mac *mac = zd_usb_to_mac(usb);
+
+	dev_dbg_f(zd_usb_dev(usb), "\n");
+
+	r = upload_firmware(usb);
+	if (r) {
+		dev_err(zd_usb_dev(usb),
+		       "couldn't load firmware. Error number %d\n", r);
+		return r;
+	}
+
+	r = usb_reset_configuration(zd_usb_to_usbdev(usb));
+	if (r) {
+		dev_dbg_f(zd_usb_dev(usb),
+			"couldn't reset configuration. Error number %d\n", r);
+		return r;
+	}
+
+	r = zd_mac_init_hw(mac);
+	if (r) {
+		dev_dbg_f(zd_usb_dev(usb),
+		         "couldn't initialize mac. Error number %d\n", r);
+		return r;
+	}
+
+	usb->initialized = 1;
+	return 0;
+}
+
 static int probe(struct usb_interface *intf, const struct usb_device_id *id)
 {
 	int r;
+	struct zd_usb *usb;
 	struct usb_device *udev = interface_to_usbdev(intf);
 	struct net_device *netdev = NULL;
 
@@ -950,26 +1010,10 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id)
 		goto error;
 	}
 
-	r = upload_firmware(udev, id->driver_info);
-	if (r) {
-		dev_err(&intf->dev,
-		       "couldn't load firmware. Error number %d\n", r);
-		goto error;
-	}
+	usb = &zd_netdev_mac(netdev)->chip.usb;
+	usb->is_zd1211b = (id->driver_info == DEVICE_ZD1211B) != 0;
 
-	r = usb_reset_configuration(udev);
-	if (r) {
-		dev_dbg_f(&intf->dev,
-			"couldn't reset configuration. Error number %d\n", r);
-		goto error;
-	}
-
-	/* At this point the interrupt endpoint is not generally enabled. We
-	 * save the USB bandwidth until the network device is opened. But
-	 * notify that the initialization of the MAC will require the
-	 * interrupts to be temporary enabled.
-	 */
-	r = zd_mac_init_hw(zd_netdev_mac(netdev), id->driver_info);
+	r = zd_mac_preinit_hw(zd_netdev_mac(netdev));
 	if (r) {
 		dev_dbg_f(&intf->dev,
 		         "couldn't initialize mac. Error number %d\n", r);
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.h b/drivers/net/wireless/zd1211rw/zd_usb.h
index 506ea6a..961a7a1 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.h
+++ b/drivers/net/wireless/zd1211rw/zd_usb.h
@@ -188,6 +188,7 @@ struct zd_usb {
 	struct zd_usb_rx rx;
 	struct zd_usb_tx tx;
 	struct usb_interface *intf;
+	u8 is_zd1211b:1, initialized:1;
 };
 
 #define zd_usb_dev(usb) (&usb->intf->dev)
@@ -236,6 +237,8 @@ int zd_usb_iowrite16v(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
 
 int zd_usb_rfwrite(struct zd_usb *usb, u32 value, u8 bits);
 
+int zd_usb_read_fw(struct zd_usb *usb, zd_addr_t addr, u8 *data, u16 len);
+
 extern struct workqueue_struct *zd_workqueue;
 
 #endif /* _ZD_USB_H */
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index b34eb82..ec18bae 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -211,6 +211,10 @@ struct qeth_perf_stats {
 	/* initial values when measuring starts */
 	unsigned long initial_rx_packets;
 	unsigned long initial_tx_packets;
+	/* inbound scatter gather data */
+	unsigned int sg_skbs_rx;
+	unsigned int sg_frags_rx;
+	unsigned int sg_alloc_page_rx;
 };
 
 /* Routing stuff */
@@ -341,6 +345,9 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
 
 #define QETH_IP_HEADER_SIZE 40
 
+/* large receive scatter gather copy break */
+#define QETH_RX_SG_CB (PAGE_SIZE >> 1)
+
 struct qeth_hdr_layer3 {
 	__u8  id;
 	__u8  flags;
@@ -771,6 +778,7 @@ struct qeth_card_options {
 	int layer2;
 	enum qeth_large_send_types large_send;
 	int performance_stats;
+	int rx_sg_cb;
 };
 
 /*
@@ -828,6 +836,7 @@ struct qeth_card {
 	int (*orig_hard_header)(struct sk_buff *,struct net_device *,
 				unsigned short,void *,void *,unsigned);
 	struct qeth_osn_info osn_info;
+	atomic_t force_alloc_skb;
 };
 
 struct qeth_card_list_struct {
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 86b0c44..57f6943 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1054,6 +1054,7 @@ qeth_set_intial_options(struct qeth_card *card)
 	else
 		card->options.layer2 = 0;
 	card->options.performance_stats = 0;
+	card->options.rx_sg_cb = QETH_RX_SG_CB;
 }
 
 /**
@@ -1934,6 +1935,7 @@ qeth_send_control_data(struct qeth_card *card, int len,
 			atomic_inc(&reply->received);
 			wake_up(&reply->wait_q);
 		}
+		cpu_relax();
 	};
 	rc = reply->rc;
 	qeth_put_reply(reply);
@@ -2258,6 +2260,89 @@ qeth_get_skb(unsigned int length, struct qeth_hdr *hdr)
 	return skb;
 }
 
+static inline int
+qeth_create_skb_frag(struct qdio_buffer_element *element,
+		     struct sk_buff **pskb,
+		     int offset, int *pfrag, int data_len)
+{
+	struct page *page = virt_to_page(element->addr);
+	if (*pfrag == 0) {
+		/* the upper protocol layers assume that there is data in the
+		 * skb itself. Copy a small amount (64 bytes) to make them
+		 * happy. */
+		*pskb = dev_alloc_skb(64 + QETH_FAKE_LL_LEN_ETH);
+		if (!(*pskb))
+			return -ENOMEM;
+		skb_reserve(*pskb, QETH_FAKE_LL_LEN_ETH);
+		if (data_len <= 64) {
+			memcpy(skb_put(*pskb, data_len), element->addr + offset,
+				data_len);
+		} else {
+			get_page(page);
+			memcpy(skb_put(*pskb, 64), element->addr + offset, 64);
+			skb_fill_page_desc(*pskb, *pfrag, page, offset + 64,
+				data_len - 64);
+			(*pskb)->data_len += data_len - 64;
+			(*pskb)->len	  += data_len - 64;
+			(*pskb)->truesize += data_len - 64;
+		}
+	} else {
+		get_page(page);
+		skb_fill_page_desc(*pskb, *pfrag, page, offset, data_len);
+		(*pskb)->data_len += data_len;
+		(*pskb)->len	  += data_len;
+		(*pskb)->truesize += data_len;
+	}
+	(*pfrag)++;
+	return 0;
+}
+
+static inline struct qeth_buffer_pool_entry *
+qeth_find_free_buffer_pool_entry(struct qeth_card *card)
+{
+	struct list_head *plh;
+	struct qeth_buffer_pool_entry *entry;
+	int i, free;
+	struct page *page;
+
+	if (list_empty(&card->qdio.in_buf_pool.entry_list))
+		return NULL;
+
+	list_for_each(plh, &card->qdio.in_buf_pool.entry_list) {
+		entry = list_entry(plh, struct qeth_buffer_pool_entry, list);
+		free = 1;
+		for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
+			if (page_count(virt_to_page(entry->elements[i])) > 1) {
+				free = 0;
+				break;
+			}
+		}
+		if (free) {
+			list_del_init(&entry->list);
+			return entry;
+		}
+	}
+
+	/* no free buffer in pool so take first one and swap pages */
+	entry = list_entry(card->qdio.in_buf_pool.entry_list.next,
+			struct qeth_buffer_pool_entry, list);
+	for (i = 0; i < QETH_MAX_BUFFER_ELEMENTS(card); ++i) {
+		if (page_count(virt_to_page(entry->elements[i])) > 1) {
+			page = alloc_page(GFP_ATOMIC|GFP_DMA);
+			if (!page) {
+				return NULL;
+			} else {
+				free_page((unsigned long)entry->elements[i]);
+				entry->elements[i] = page_address(page);
+				if (card->options.performance_stats)
+					card->perf_stats.sg_alloc_page_rx++;
+			}
+		}
+	}
+	list_del_init(&entry->list);
+	return entry;
+}
+
 static struct sk_buff *
 qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
 		  struct qdio_buffer_element **__element, int *__offset,
@@ -2269,6 +2354,8 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
 	int skb_len;
 	void *data_ptr;
 	int data_len;
+	int use_rx_sg = 0;
+	int frag = 0;
 
 	QETH_DBF_TEXT(trace,6,"nextskb");
 	/* qeth_hdr must not cross element boundaries */
@@ -2293,23 +2380,43 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
 
 	if (!skb_len)
 		return NULL;
-	if (card->options.fake_ll){
-		if(card->dev->type == ARPHRD_IEEE802_TR){
-			if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_TR, *hdr)))
-				goto no_mem;
-			skb_reserve(skb,QETH_FAKE_LL_LEN_TR);
+	if ((skb_len >= card->options.rx_sg_cb) &&
+	    (!(card->info.type == QETH_CARD_TYPE_OSN)) &&
+	    (!atomic_read(&card->force_alloc_skb))) {
+		use_rx_sg = 1;
+	} else {
+		if (card->options.fake_ll) {
+			if (card->dev->type == ARPHRD_IEEE802_TR) {
+				if (!(skb = qeth_get_skb(skb_len +
+						QETH_FAKE_LL_LEN_TR, *hdr)))
+					goto no_mem;
+				skb_reserve(skb, QETH_FAKE_LL_LEN_TR);
+			} else {
+				if (!(skb = qeth_get_skb(skb_len +
+						QETH_FAKE_LL_LEN_ETH, *hdr)))
+					goto no_mem;
+				skb_reserve(skb, QETH_FAKE_LL_LEN_ETH);
+			}
 		} else {
-			if (!(skb = qeth_get_skb(skb_len+QETH_FAKE_LL_LEN_ETH, *hdr)))
+			skb = qeth_get_skb(skb_len, *hdr);
+			if (!skb)
 				goto no_mem;
-			skb_reserve(skb,QETH_FAKE_LL_LEN_ETH);
 		}
-	} else if (!(skb = qeth_get_skb(skb_len, *hdr)))
-		goto no_mem;
+	}
+
 	data_ptr = element->addr + offset;
 	while (skb_len) {
 		data_len = min(skb_len, (int)(element->length - offset));
-		if (data_len)
-			memcpy(skb_put(skb, data_len), data_ptr, data_len);
+		if (data_len) {
+			if (use_rx_sg) {
+				if (qeth_create_skb_frag(element, &skb, offset,
+				    &frag, data_len))
+					goto no_mem;
+			} else {
+				memcpy(skb_put(skb, data_len), data_ptr,
+					data_len);
+			}
+		}
 		skb_len -= data_len;
 		if (skb_len){
 			if (qeth_is_last_sbale(element)){
@@ -2331,6 +2438,10 @@ qeth_get_next_skb(struct qeth_card *card, struct qdio_buffer *buffer,
 	}
 	*__element = element;
 	*__offset = offset;
+	if (use_rx_sg && card->options.performance_stats) {
+		card->perf_stats.sg_skbs_rx++;
+		card->perf_stats.sg_frags_rx += skb_shinfo(skb)->nr_frags;
+	}
 	return skb;
 no_mem:
 	if (net_ratelimit()){
@@ -2608,28 +2719,15 @@ qeth_process_inbound_buffer(struct qeth_card *card,
 	}
 }
 
-static struct qeth_buffer_pool_entry *
-qeth_get_buffer_pool_entry(struct qeth_card *card)
-{
-	struct qeth_buffer_pool_entry *entry;
-
-	QETH_DBF_TEXT(trace, 6, "gtbfplen");
-	if (!list_empty(&card->qdio.in_buf_pool.entry_list)) {
-		entry = list_entry(card->qdio.in_buf_pool.entry_list.next,
-				struct qeth_buffer_pool_entry, list);
-		list_del_init(&entry->list);
-		return entry;
-	}
-	return NULL;
-}
-
-static void
+static int
 qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
 {
 	struct qeth_buffer_pool_entry *pool_entry;
 	int i;
- 
-	pool_entry = qeth_get_buffer_pool_entry(card);
+
+	pool_entry = qeth_find_free_buffer_pool_entry(card);
+	if (!pool_entry)
+		return 1;
 	/*
 	 * since the buffer is accessed only from the input_tasklet
 	 * there shouldn't be a need to synchronize; also, since we use
@@ -2648,6 +2746,7 @@ qeth_init_input_buffer(struct qeth_card *card, struct qeth_qdio_buffer *buf)
 			buf->buffer->element[i].flags = 0;
 	}
 	buf->state = QETH_QDIO_BUF_EMPTY;
+	return 0;
 }
 
 static void
@@ -2682,6 +2781,7 @@ qeth_queue_input_buffer(struct qeth_card *card, int index)
 	int count;
 	int i;
 	int rc;
+	int newcount = 0;
 
 	QETH_DBF_TEXT(trace,6,"queinbuf");
 	count = (index < queue->next_buf_to_init)?
@@ -2692,9 +2792,27 @@ qeth_queue_input_buffer(struct qeth_card *card, int index)
 	/* only requeue at a certain threshold to avoid SIGAs */
 	if (count >= QETH_IN_BUF_REQUEUE_THRESHOLD(card)){
 		for (i = queue->next_buf_to_init;
-		     i < queue->next_buf_to_init + count; ++i)
-			qeth_init_input_buffer(card,
-				&queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q]);
+		     i < queue->next_buf_to_init + count; ++i) {
+			if (qeth_init_input_buffer(card,
+				&queue->bufs[i % QDIO_MAX_BUFFERS_PER_Q])) {
+				break;
+			} else {
+				newcount++;
+			}
+		}
+
+		if (newcount < count) {
+			/* we are in memory shortage so we switch back to
+			   traditional skb allocation and drop packages */
+			if (atomic_cmpxchg(&card->force_alloc_skb, 0, 1))
+				printk(KERN_WARNING
+					"qeth: switch to alloc skb\n");
+			count = newcount;
+		} else {
+			if (atomic_cmpxchg(&card->force_alloc_skb, 1, 0))
+				printk(KERN_WARNING "qeth: switch to sg\n");
+		}
+
 		/*
 		 * according to old code it should be avoided to requeue all
 		 * 128 buffers in order to benefit from PCI avoidance.
@@ -6494,6 +6612,7 @@ qeth_hardsetup_card(struct qeth_card *card)
 
 	QETH_DBF_TEXT(setup, 2, "hrdsetup");
 
+	atomic_set(&card->force_alloc_skb, 0);
 retry:
 	if (retries < 3){
 		PRINT_WARN("Retrying to do IDX activates.\n");
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index 89d56c8..f1ff165 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -212,6 +212,12 @@ qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
 		      "  Skb fragments sent in SG mode          : %u\n\n",
 		      card->perf_stats.sg_skbs_sent,
 		      card->perf_stats.sg_frags_sent);
+	seq_printf(s, "  Skbs received in SG mode               : %u\n"
+		      "  Skb fragments received in SG mode      : %u\n"
+		      "  Page allocations for rx SG mode        : %u\n\n",
+		      card->perf_stats.sg_skbs_rx,
+		      card->perf_stats.sg_frags_rx,
+		      card->perf_stats.sg_alloc_page_rx);
 	seq_printf(s, "  large_send tx (in Kbytes)              : %u\n"
 		      "  large_send count                       : %u\n\n",
 		      card->perf_stats.large_send_bytes >> 10,
diff --git a/include/asm-arm/arch-at91/board.h b/include/asm-arm/arch-at91/board.h
index 0ce6ee9..d96b10f 100644
--- a/include/asm-arm/arch-at91/board.h
+++ b/include/asm-arm/arch-at91/board.h
@@ -64,6 +64,7 @@ extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
 
  /* Ethernet (EMAC & MACB) */
 struct at91_eth_data {
+	u32		phy_mask;
 	u8		phy_irq_pin;	/* PHY IRQ */
 	u8		is_rmii;	/* using RMII interface? */
 };
diff --git a/include/asm-avr32/arch-at32ap/board.h b/include/asm-avr32/arch-at32ap/board.h
index 9fd2e32..9744804 100644
--- a/include/asm-avr32/arch-at32ap/board.h
+++ b/include/asm-avr32/arch-at32ap/board.h
@@ -21,6 +21,7 @@ void at32_map_usart(unsigned int hw_id, unsigned int line);
 struct platform_device *at32_add_device_usart(unsigned int id);
 
 struct eth_platform_data {
+	u32	phy_mask;
 	u8	is_rmii;
 };
 struct platform_device *
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index cc8110b..afb6c66 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -271,8 +271,11 @@ ieee80211softmac_assoc_work(struct work_struct *work)
 			 */
 			dprintk(KERN_INFO PFX "Associate: Scanning for networks first.\n");
 			ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL);
-			if (ieee80211softmac_start_scan(mac))
+			if (ieee80211softmac_start_scan(mac)) {
 				dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n");
+				mac->associnfo.associating = 0;
+				mac->associnfo.associated = 0;
+			}
 			goto out;
 		} else {
 			mac->associnfo.associating = 0;

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-07-11  9:34 ` Jiri Kosina
@ 2007-07-11 16:28   ` Chris Stromsoe
  0 siblings, 0 replies; 101+ messages in thread
From: Chris Stromsoe @ 2007-07-11 16:28 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Jeff Garzik, Andrew Morton, Linus Torvalds, netdev, LKML,
	Stephen Hemminger

On Wed, 11 Jul 2007, Jiri Kosina wrote:
> On Tue, 10 Jul 2007, Jeff Garzik wrote:
>
>> Various minor updates.  The only thing of note is sk98lin driver 
>> removal. Please pull from 'upstream-linus' branch of 
>> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git 
>> upstream-linus
>
> This is probably going to cause a new entry in regressions list, as at 
> least Chris Stromsoe has reported bonding-related problems with skge 
> that don't happen with sklin - 
> http://www.uwsg.indiana.edu/hypermail/linux/kernel/0707.1/1158.html

It's worse than just bonding related.  This also causes a reliable hard 
lockup with skge:

fresno:~# modprobe skge
fresno:~# ip li set eth2 up
fresno:~# ip li set eth2 down
fresno:~# ip li set eth3 up

The server locks up there.  Nothing is printed to console and it takes a 
power cycle to fix the problem.

eth2 and eth3 are both ports on an SK-9844 dual-port card.  The test above 
is with 2.6.22.  I've also had it fail with .21.*, .20.*, and several 
other kernels.

fresno:~# uname -a
Linux fresno 2.6.22 #4 SMP Tue Jul 10 11:38:19 PDT 2007 i686 GNU/Linux

fresno:~# dmesg | grep skge
skge 1.11 addr 0xfebfc000 irq 22 chip Genesis rev 0
skge eth2: addr 00:00:5a:98:ac:8c
skge eth3: addr 00:00:5a:98:ac:8d

fresno:~# lspci -v -s 02:01
02:01.0 Ethernet controller: SysKonnect SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link) (rev 11)
         Subsystem: SysKonnect SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
         Flags: bus master, 66MHz, medium devsel, latency 64, IRQ 22
         Memory at febfc000 (32-bit, non-prefetchable) [size=16K]
         I/O ports at e800 [size=256]
         Expansion ROM at febc0000 [disabled] [size=128K]
         Capabilities: [48] Power Management version 1
         Capabilities: [50] Vital Product Data


-Chris


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-07-10 18:39 Jeff Garzik
@ 2007-07-11  9:34 ` Jiri Kosina
  2007-07-11 16:28   ` Chris Stromsoe
  0 siblings, 1 reply; 101+ messages in thread
From: Jiri Kosina @ 2007-07-11  9:34 UTC (permalink / raw)
  To: Jeff Garzik
  Cc: Andrew Morton, Linus Torvalds, netdev, LKML, Chris Stromsoe,
	Stephen Hemminger

On Tue, 10 Jul 2007, Jeff Garzik wrote:

> Various minor updates.  The only thing of note is sk98lin driver removal.
> Please pull from 'upstream-linus' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

This is probably going to cause a new entry in regressions list, as at 
least Chris Stromsoe has reported bonding-related problems with skge that 
don't happen with sklin - 
http://www.uwsg.indiana.edu/hypermail/linux/kernel/0707.1/1158.html

-- 
Jiri Kosina

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-07-10 18:39 Jeff Garzik
  2007-07-11  9:34 ` Jiri Kosina
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2007-07-10 18:39 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML


Various minor updates.  The only thing of note is sk98lin driver removal.

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 Documentation/feature-removal-schedule.txt |    8 -
 Documentation/networking/00-INDEX          |    3 -
 Documentation/networking/sk98lin.txt       |  568 --
 MAINTAINERS                                |    7 +
 drivers/misc/eeprom_93cx6.c                |    6 +-
 drivers/net/3c59x.c                        |    2 +-
 drivers/net/8390.h                         |   11 +
 drivers/net/Kconfig                        |  116 +-
 drivers/net/Makefile                       |    4 +-
 drivers/net/atari_pamsnet.c                |   62 +-
 drivers/net/atl1/atl1_main.c               |    3 +-
 drivers/net/ax88796.c                      |  952 ++++
 drivers/net/bonding/bond_main.c            |   16 +-
 drivers/net/bonding/bonding.h              |    2 -
 drivers/net/cxgb3/cxgb3_main.c             |    5 +-
 drivers/net/e100.c                         |   12 +-
 drivers/net/ehea/ehea.h                    |    8 +-
 drivers/net/ehea/ehea_main.c               |   23 +-
 drivers/net/ioc3-eth.c                     |   41 +-
 drivers/net/macmace.c                      |    2 +-
 drivers/net/myri10ge/myri10ge.c            |    3 +-
 drivers/net/netxen/netxen_nic.h            |  103 -
 drivers/net/netxen/netxen_nic_main.c       |   97 +
 drivers/net/pcmcia/pcnet_cs.c              |    1 +
 drivers/net/phy/marvell.c                  |  123 +-
 drivers/net/ps3_gelic_net.c                | 1576 ++++++
 drivers/net/ps3_gelic_net.h                |  239 +
 drivers/net/rrunner.c                      |    2 +-
 drivers/net/s2io.c                         |    2 +-
 drivers/net/sis900.c                       |    2 +-
 drivers/net/sk98lin/Makefile               |   87 -
 drivers/net/sk98lin/h/lm80.h               |  179 -
 drivers/net/sk98lin/h/skaddr.h             |  285 -
 drivers/net/sk98lin/h/skcsum.h             |  213 -
 drivers/net/sk98lin/h/skdebug.h            |   74 -
 drivers/net/sk98lin/h/skdrv1st.h           |  188 -
 drivers/net/sk98lin/h/skdrv2nd.h           |  447 --
 drivers/net/sk98lin/h/skerror.h            |   55 -
 drivers/net/sk98lin/h/skgedrv.h            |   51 -
 drivers/net/sk98lin/h/skgehw.h             | 2126 -------
 drivers/net/sk98lin/h/skgehwt.h            |   48 -
 drivers/net/sk98lin/h/skgei2c.h            |  210 -
 drivers/net/sk98lin/h/skgeinit.h           |  797 ---
 drivers/net/sk98lin/h/skgepnm2.h           |  334 --
 drivers/net/sk98lin/h/skgepnmi.h           |  962 ----
 drivers/net/sk98lin/h/skgesirq.h           |  110 -
 drivers/net/sk98lin/h/ski2c.h              |  174 -
 drivers/net/sk98lin/h/skqueue.h            |   94 -
 drivers/net/sk98lin/h/skrlmt.h             |  438 --
 drivers/net/sk98lin/h/sktimer.h            |   63 -
 drivers/net/sk98lin/h/sktypes.h            |   69 -
 drivers/net/sk98lin/h/skversion.h          |   38 -
 drivers/net/sk98lin/h/skvpd.h              |  248 -
 drivers/net/sk98lin/h/xmac_ii.h            | 1579 ------
 drivers/net/sk98lin/skaddr.c               | 1788 ------
 drivers/net/sk98lin/skdim.c                |  742 ---
 drivers/net/sk98lin/skethtool.c            |  628 ---
 drivers/net/sk98lin/skge.c                 | 5211 ------------------
 drivers/net/sk98lin/skgehwt.c              |  171 -
 drivers/net/sk98lin/skgeinit.c             | 2005 -------
 drivers/net/sk98lin/skgemib.c              | 1075 ----
 drivers/net/sk98lin/skgepnmi.c             | 8210 ----------------------------
 drivers/net/sk98lin/skgesirq.c             | 2229 --------
 drivers/net/sk98lin/ski2c.c                | 1296 -----
 drivers/net/sk98lin/sklm80.c               |  141 -
 drivers/net/sk98lin/skqueue.c              |  179 -
 drivers/net/sk98lin/skrlmt.c               | 3257 -----------
 drivers/net/sk98lin/sktimer.c              |  250 -
 drivers/net/sk98lin/skvpd.c                | 1091 ----
 drivers/net/sk98lin/skxmac2.c              | 4160 --------------
 drivers/net/sky2.c                         |  449 ++-
 drivers/net/sky2.h                         |    4 +
 drivers/net/spider_net.c                   |   59 +-
 drivers/net/sunhme.c                       |    2 +-
 drivers/net/tokenring/3c359.c              |    2 +-
 drivers/net/ucc_geth.c                     |    2 +-
 drivers/net/usb/usbnet.c                   |    2 +-
 include/net/ax88796.h                      |   27 +
 net/ipv6/addrconf.c                        |    3 +
 79 files changed, 3531 insertions(+), 42320 deletions(-)
 delete mode 100644 Documentation/networking/sk98lin.txt
 create mode 100644 drivers/net/ax88796.c
 create mode 100644 drivers/net/ps3_gelic_net.c
 create mode 100644 drivers/net/ps3_gelic_net.h
 delete mode 100644 drivers/net/sk98lin/Makefile
 delete mode 100644 drivers/net/sk98lin/h/lm80.h
 delete mode 100644 drivers/net/sk98lin/h/skaddr.h
 delete mode 100644 drivers/net/sk98lin/h/skcsum.h
 delete mode 100644 drivers/net/sk98lin/h/skdebug.h
 delete mode 100644 drivers/net/sk98lin/h/skdrv1st.h
 delete mode 100644 drivers/net/sk98lin/h/skdrv2nd.h
 delete mode 100644 drivers/net/sk98lin/h/skerror.h
 delete mode 100644 drivers/net/sk98lin/h/skgedrv.h
 delete mode 100644 drivers/net/sk98lin/h/skgehw.h
 delete mode 100644 drivers/net/sk98lin/h/skgehwt.h
 delete mode 100644 drivers/net/sk98lin/h/skgei2c.h
 delete mode 100644 drivers/net/sk98lin/h/skgeinit.h
 delete mode 100644 drivers/net/sk98lin/h/skgepnm2.h
 delete mode 100644 drivers/net/sk98lin/h/skgepnmi.h
 delete mode 100644 drivers/net/sk98lin/h/skgesirq.h
 delete mode 100644 drivers/net/sk98lin/h/ski2c.h
 delete mode 100644 drivers/net/sk98lin/h/skqueue.h
 delete mode 100644 drivers/net/sk98lin/h/skrlmt.h
 delete mode 100644 drivers/net/sk98lin/h/sktimer.h
 delete mode 100644 drivers/net/sk98lin/h/sktypes.h
 delete mode 100644 drivers/net/sk98lin/h/skversion.h
 delete mode 100644 drivers/net/sk98lin/h/skvpd.h
 delete mode 100644 drivers/net/sk98lin/h/xmac_ii.h
 delete mode 100644 drivers/net/sk98lin/skaddr.c
 delete mode 100644 drivers/net/sk98lin/skdim.c
 delete mode 100644 drivers/net/sk98lin/skethtool.c
 delete mode 100644 drivers/net/sk98lin/skge.c
 delete mode 100644 drivers/net/sk98lin/skgehwt.c
 delete mode 100644 drivers/net/sk98lin/skgeinit.c
 delete mode 100644 drivers/net/sk98lin/skgemib.c
 delete mode 100644 drivers/net/sk98lin/skgepnmi.c
 delete mode 100644 drivers/net/sk98lin/skgesirq.c
 delete mode 100644 drivers/net/sk98lin/ski2c.c
 delete mode 100644 drivers/net/sk98lin/sklm80.c
 delete mode 100644 drivers/net/sk98lin/skqueue.c
 delete mode 100644 drivers/net/sk98lin/skrlmt.c
 delete mode 100644 drivers/net/sk98lin/sktimer.c
 delete mode 100644 drivers/net/sk98lin/skvpd.c
 delete mode 100644 drivers/net/sk98lin/skxmac2.c
 create mode 100644 include/net/ax88796.h

Adrian Bunk (5):
      sis900_mii_probe() must be __devinit
      tokenring/3c359.c:xl_init() must be __devinit
      rrunner.c:rr_init() must be __devinit
      sunhme.c:quattro_pci_find() must be __devinit
      bonding/bond_main.c: make 2 functions static

Alan Cox (1):
      IOC3: Switch to pci refcounting safe APIs

Alexey Dobriyan (2):
      macmace: use "unsigned long flags;"
      atl1: remove write-only var in tx handler

Ben Dooks (1):
      AX88796 network driver

David Graham (1):
      e100: Fix Tyan motherboard e100 not receiving IPMI commands

Francois Romieu (1):
      eeprom_93cx6: shorten pulse timing to match spec (bis)

Ishizaki Kou (1):
      spidernet: improve interrupt handling

Jan-Bernd Themann (1):
      eHEA: Capability flag for DLPAR support

Jay Vosburgh (1):
      bonding / ipv6: no addrconf for slaves separately from master

Jeff Garzik (2):
      Remove sk98lin ethernet driver.
      [netdrvr] Fix dependencies for ax88796 ne2k clone driver

Marcin Juszkiewicz (1):
      PCMCIA: add Socket Ethernet card into pcnet_cs

Masakazu Mokuno (1):
      ps3: gigabit ethernet driver for PS3, take3

Olof Johansson (2):
      phylib: cleanup marvell.c a bit
      phylib: Add Marvell 88E1112 phy id

Peter Korsgaard (1):
      Cleanup usbnet_probe() return value handling

Rolf Eike Beer (1):
      Fix typo in drivers/net/s2io.c

Steffen Klassert (1):
      3cSOHO100-TX needs EXTRA_PREAMBLE

Stephen Hemminger (13):
      sky2: restore workarounds for lost interrupts
      sky2: carrier management
      sky2: debug interface
      sky2: check for more work before leaving NAPI
      sky2: receive fill
      sky2: unmark as EXPERIMENTAL
      sky2: add support for read/write of EEPROM
      sky2: check drop truncated packets
      sky2: use roundup() macro
      sky2: use upper_32_bits() macro
      sky2: remove some leftover debug messages
      sky2: 1.16 version
      netxen: deinline and sparse fix

Timur Tabi (1):
      QE Ethernet driver writes to wrong register to mask interrupts

Yoann Padioleau (1):
      atari_pamsnet.c: old declaration ritchie style fix

vignesh babu (2):
      use is_power_of_2() in cxgb3/cxgb3_main.c
      Use is_power_of_2() in myri10ge/myri10ge.c

diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 51b369e..3a159da 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -248,14 +248,6 @@ Who:	Len Brown <len.brown@intel.com>
 
 ---------------------------
 
-What:   sk98lin network driver
-When:   July 2007
-Why:    In kernel tree version of driver is unmaintained. Sk98lin driver
-	replaced by the skge driver. 
-Who:    Stephen Hemminger <shemminger@osdl.org>
-
----------------------------
-
 What:	Compaq touchscreen device emulation
 When:	Oct 2007
 Files:	drivers/input/tsdev.c
diff --git a/Documentation/networking/00-INDEX b/Documentation/networking/00-INDEX
index 153d84d..d63f480 100644
--- a/Documentation/networking/00-INDEX
+++ b/Documentation/networking/00-INDEX
@@ -96,9 +96,6 @@ routing.txt
 	- the new routing mechanism
 shaper.txt
 	- info on the module that can shape/limit transmitted traffic.
-sk98lin.txt
-	- Marvell Yukon Chipset / SysKonnect SK-98xx compliant Gigabit
-	  Ethernet Adapter family driver info
 skfp.txt
 	- SysKonnect FDDI (SK-5xxx, Compaq Netelligent) driver info.
 smc9.txt
diff --git a/Documentation/networking/sk98lin.txt b/Documentation/networking/sk98lin.txt
deleted file mode 100644
index 8590a95..0000000
--- a/Documentation/networking/sk98lin.txt
+++ /dev/null
@@ -1,568 +0,0 @@
-(C)Copyright 1999-2004 Marvell(R).
-All rights reserved
-===========================================================================
-
-sk98lin.txt created 13-Feb-2004
-
-Readme File for sk98lin v6.23
-Marvell Yukon/SysKonnect SK-98xx Gigabit Ethernet Adapter family driver for LINUX
-
-This file contains
- 1  Overview
- 2  Required Files
- 3  Installation
-    3.1  Driver Installation
-    3.2  Inclusion of adapter at system start
- 4  Driver Parameters
-    4.1  Per-Port Parameters
-    4.2  Adapter Parameters
- 5  Large Frame Support
- 6  VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
- 7  Troubleshooting
-
-===========================================================================
-
-
-1  Overview
-===========
-
-The sk98lin driver supports the Marvell Yukon and SysKonnect 
-SK-98xx/SK-95xx compliant Gigabit Ethernet Adapter on Linux. It has 
-been tested with Linux on Intel/x86 machines.
-***
-
-
-2  Required Files
-=================
-
-The linux kernel source.
-No additional files required.
-***
-
-
-3  Installation
-===============
-
-It is recommended to download the latest version of the driver from the 
-SysKonnect web site www.syskonnect.com. If you have downloaded the latest
-driver, the Linux kernel has to be patched before the driver can be 
-installed. For details on how to patch a Linux kernel, refer to the 
-patch.txt file.
-
-3.1  Driver Installation
-------------------------
-
-The following steps describe the actions that are required to install
-the driver and to start it manually. These steps should be carried
-out for the initial driver setup. Once confirmed to be ok, they can
-be included in the system start.
-
-NOTE 1: To perform the following tasks you need 'root' access.
-
-NOTE 2: In case of problems, please read the section "Troubleshooting" 
-        below.
-
-The driver can either be integrated into the kernel or it can be compiled 
-as a module. Select the appropriate option during the kernel 
-configuration.
-
-Compile/use the driver as a module
-----------------------------------
-To compile the driver, go to the directory /usr/src/linux and
-execute the command "make menuconfig" or "make xconfig" and proceed as 
-follows:
-
-To integrate the driver permanently into the kernel, proceed as follows:
-
-1. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
-2. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" 
-   with (*) 
-3. Build a new kernel when the configuration of the above options is 
-   finished.
-4. Install the new kernel.
-5. Reboot your system.
-
-To use the driver as a module, proceed as follows:
-
-1. Enable 'loadable module support' in the kernel.
-2. For automatic driver start, enable the 'Kernel module loader'.
-3. Select the menu "Network device support" and then "Ethernet(1000Mbit)"
-4. Mark "Marvell Yukon Chipset / SysKonnect SK-98xx family support" 
-   with (M)
-5. Execute the command "make modules".
-6. Execute the command "make modules_install".
-   The appropriate modules will be installed.
-7. Reboot your system.
-
-
-Load the module manually
-------------------------
-To load the module manually, proceed as follows:
-
-1. Enter "modprobe sk98lin".
-2. If a Marvell Yukon or SysKonnect SK-98xx adapter is installed in 
-   your computer and you have a /proc file system, execute the command:
-   "ls /proc/net/sk98lin/" 
-   This should produce an output containing a line with the following 
-   format:
-   eth0   eth1  ...
-   which indicates that your adapter has been found and initialized.
-   
-   NOTE 1: If you have more than one Marvell Yukon or SysKonnect SK-98xx 
-           adapter installed, the adapters will be listed as 'eth0', 
-                   'eth1', 'eth2', etc.
-                   For each adapter, repeat steps 3 and 4 below.
-
-   NOTE 2: If you have other Ethernet adapters installed, your Marvell
-           Yukon or SysKonnect SK-98xx adapter will be mapped to the 
-                   next available number, e.g. 'eth1'. The mapping is executed 
-                   automatically.
-           The module installation message (displayed either in a system
-           log file or on the console) prints a line for each adapter 
-           found containing the corresponding 'ethX'.
-
-3. Select an IP address and assign it to the respective adapter by 
-   entering:
-   ifconfig eth0 <ip-address>
-   With this command, the adapter is connected to the Ethernet. 
-   
-   SK-98xx Gigabit Ethernet Server Adapters: The yellow LED on the adapter 
-   is now active, the link status LED of the primary port is active and 
-   the link status LED of the secondary port (on dual port adapters) is 
-   blinking (if the ports are connected to a switch or hub).
-   SK-98xx V2.0 Gigabit Ethernet Adapters: The link status LED is active.
-   In addition, you will receive a status message on the console stating
-   "ethX: network connection up using port Y" and showing the selected 
-   connection parameters (x stands for the ethernet device number 
-   (0,1,2, etc), y stands for the port name (A or B)).
-
-   NOTE: If you are in doubt about IP addresses, ask your network
-         administrator for assistance.
-  
-4. Your adapter should now be fully operational.
-   Use 'ping <otherstation>' to verify the connection to other computers 
-   on your network.
-5. To check the adapter configuration view /proc/net/sk98lin/[devicename].
-   For example by executing:    
-   "cat /proc/net/sk98lin/eth0" 
-
-Unload the module
------------------
-To stop and unload the driver modules, proceed as follows:
-
-1. Execute the command "ifconfig eth0 down".
-2. Execute the command "rmmod sk98lin".
-
-3.2  Inclusion of adapter at system start
------------------------------------------
-
-Since a large number of different Linux distributions are 
-available, we are unable to describe a general installation procedure
-for the driver module.
-Because the driver is now integrated in the kernel, installation should
-be easy, using the standard mechanism of your distribution.
-Refer to the distribution's manual for installation of ethernet adapters.
-
-***
-
-4  Driver Parameters
-====================
-
-Parameters can be set at the command line after the module has been 
-loaded with the command 'modprobe'.
-In some distributions, the configuration tools are able to pass parameters
-to the driver module.
-
-If you use the kernel module loader, you can set driver parameters
-in the file /etc/modprobe.conf (or /etc/modules.conf in 2.4 or earlier).
-To set the driver parameters in this file, proceed as follows:
-
-1. Insert a line of the form :
-   options sk98lin ...
-   For "...", the same syntax is required as described for the command
-   line parameters of modprobe below.
-2. To activate the new parameters, either reboot your computer
-   or 
-   unload and reload the driver.
-   The syntax of the driver parameters is:
-
-        modprobe sk98lin parameter=value1[,value2[,value3...]]
-
-   where value1 refers to the first adapter, value2 to the second etc.
-
-NOTE: All parameters are case sensitive. Write them exactly as shown 
-      below.
-
-Example:
-Suppose you have two adapters. You want to set auto-negotiation
-on the first adapter to ON and on the second adapter to OFF.
-You also want to set DuplexCapabilities on the first adapter
-to FULL, and on the second adapter to HALF.
-Then, you must enter:
-
-        modprobe sk98lin AutoNeg_A=On,Off DupCap_A=Full,Half
-
-NOTE: The number of adapters that can be configured this way is
-      limited in the driver (file skge.c, constant SK_MAX_CARD_PARAM).
-      The current limit is 16. If you happen to install
-      more adapters, adjust this and recompile.
-
-
-4.1  Per-Port Parameters
-------------------------
-
-These settings are available for each port on the adapter.
-In the following description, '?' stands for the port for
-which you set the parameter (A or B).
-
-Speed
------
-Parameter:    Speed_?
-Values:       10, 100, 1000, Auto
-Default:      Auto
-
-This parameter is used to set the speed capabilities. It is only valid 
-for the SK-98xx V2.0 copper adapters.
-Usually, the speed is negotiated between the two ports during link 
-establishment. If this fails, a port can be forced to a specific setting
-with this parameter.
-
-Auto-Negotiation
-----------------
-Parameter:    AutoNeg_?
-Values:       On, Off, Sense
-Default:      On
-  
-The "Sense"-mode automatically detects whether the link partner supports
-auto-negotiation or not.
-
-Duplex Capabilities
--------------------
-Parameter:    DupCap_?
-Values:       Half, Full, Both
-Default:      Both
-
-This parameters is only relevant if auto-negotiation for this port is 
-not set to "Sense". If auto-negotiation is set to "On", all three values
-are possible. If it is set to "Off", only "Full" and "Half" are allowed.
-This parameter is useful if your link partner does not support all
-possible combinations.
-
-Flow Control
-------------
-Parameter:    FlowCtrl_?
-Values:       Sym, SymOrRem, LocSend, None
-Default:      SymOrRem
-
-This parameter can be used to set the flow control capabilities the 
-port reports during auto-negotiation. It can be set for each port 
-individually.
-Possible modes:
-   -- Sym      = Symmetric: both link partners are allowed to send 
-                  PAUSE frames
-   -- SymOrRem = SymmetricOrRemote: both or only remote partner 
-                  are allowed to send PAUSE frames
-   -- LocSend  = LocalSend: only local link partner is allowed 
-                  to send PAUSE frames
-   -- None     = no link partner is allowed to send PAUSE frames
-  
-NOTE: This parameter is ignored if auto-negotiation is set to "Off".
-
-Role in Master-Slave-Negotiation (1000Base-T only)
---------------------------------------------------
-Parameter:    Role_?
-Values:       Auto, Master, Slave
-Default:      Auto
-
-This parameter is only valid for the SK-9821 and SK-9822 adapters.
-For two 1000Base-T ports to communicate, one must take the role of the
-master (providing timing information), while the other must be the 
-slave. Usually, this is negotiated between the two ports during link 
-establishment. If this fails, a port can be forced to a specific setting
-with this parameter.
-
-
-4.2  Adapter Parameters
------------------------
-
-Connection Type (SK-98xx V2.0 copper adapters only)
----------------
-Parameter:    ConType
-Values:       Auto, 100FD, 100HD, 10FD, 10HD
-Default:      Auto
-
-The parameter 'ConType' is a combination of all five per-port parameters
-within one single parameter. This simplifies the configuration of both ports
-of an adapter card! The different values of this variable reflect the most 
-meaningful combinations of port parameters.
-
-The following table shows the values of 'ConType' and the corresponding
-combinations of the per-port parameters:
-
-    ConType   |  DupCap   AutoNeg   FlowCtrl   Role             Speed
-    ----------+------------------------------------------------------
-    Auto      |  Both     On        SymOrRem   Auto             Auto
-    100FD     |  Full     Off       None       Auto (ignored)   100
-    100HD     |  Half     Off       None       Auto (ignored)   100
-    10FD      |  Full     Off       None       Auto (ignored)   10
-    10HD      |  Half     Off       None       Auto (ignored)   10
-
-Stating any other port parameter together with this 'ConType' variable
-will result in a merged configuration of those settings. This due to 
-the fact, that the per-port parameters (e.g. Speed_? ) have a higher
-priority than the combined variable 'ConType'.
-
-NOTE: This parameter is always used on both ports of the adapter card.
-
-Interrupt Moderation
---------------------
-Parameter:    Moderation
-Values:       None, Static, Dynamic
-Default:      None
-
-Interrupt moderation is employed to limit the maximum number of interrupts
-the driver has to serve. That is, one or more interrupts (which indicate any
-transmit or receive packet to be processed) are queued until the driver 
-processes them. When queued interrupts are to be served, is determined by the
-'IntsPerSec' parameter, which is explained later below.
-
-Possible modes:
-
-   -- None - No interrupt moderation is applied on the adapter card. 
-      Therefore, each transmit or receive interrupt is served immediately
-      as soon as it appears on the interrupt line of the adapter card.
-
-   -- Static - Interrupt moderation is applied on the adapter card. 
-      All transmit and receive interrupts are queued until a complete
-      moderation interval ends. If such a moderation interval ends, all
-      queued interrupts are processed in one big bunch without any delay.
-      The term 'static' reflects the fact, that interrupt moderation is
-      always enabled, regardless how much network load is currently 
-      passing via a particular interface. In addition, the duration of
-      the moderation interval has a fixed length that never changes while
-      the driver is operational.
-
-   -- Dynamic - Interrupt moderation might be applied on the adapter card,
-      depending on the load of the system. If the driver detects that the
-      system load is too high, the driver tries to shield the system against 
-      too much network load by enabling interrupt moderation. If - at a later
-      time - the CPU utilization decreases again (or if the network load is 
-      negligible) the interrupt moderation will automatically be disabled.
-
-Interrupt moderation should be used when the driver has to handle one or more
-interfaces with a high network load, which - as a consequence - leads also to a
-high CPU utilization. When moderation is applied in such high network load 
-situations, CPU load might be reduced by 20-30%.
-
-NOTE: The drawback of using interrupt moderation is an increase of the round-
-trip-time (RTT), due to the queueing and serving of interrupts at dedicated
-moderation times.
-
-Interrupts per second
----------------------
-Parameter:    IntsPerSec
-Values:       30...40000 (interrupts per second)
-Default:      2000
-
-This parameter is only used if either static or dynamic interrupt moderation
-is used on a network adapter card. Using this parameter if no moderation is
-applied will lead to no action performed.
-
-This parameter determines the length of any interrupt moderation interval. 
-Assuming that static interrupt moderation is to be used, an 'IntsPerSec' 
-parameter value of 2000 will lead to an interrupt moderation interval of
-500 microseconds. 
-
-NOTE: The duration of the moderation interval is to be chosen with care.
-At first glance, selecting a very long duration (e.g. only 100 interrupts per 
-second) seems to be meaningful, but the increase of packet-processing delay 
-is tremendous. On the other hand, selecting a very short moderation time might
-compensate the use of any moderation being applied.
-
-
-Preferred Port
---------------
-Parameter:    PrefPort
-Values:       A, B
-Default:      A
-
-This is used to force the preferred port to A or B (on dual-port network 
-adapters). The preferred port is the one that is used if both are detected
-as fully functional.
-
-RLMT Mode (Redundant Link Management Technology)
-------------------------------------------------
-Parameter:    RlmtMode
-Values:       CheckLinkState,CheckLocalPort, CheckSeg, DualNet
-Default:      CheckLinkState
-
-RLMT monitors the status of the port. If the link of the active port 
-fails, RLMT switches immediately to the standby link. The virtual link is 
-maintained as long as at least one 'physical' link is up. 
-
-Possible modes:
-
-   -- CheckLinkState - Check link state only: RLMT uses the link state
-      reported by the adapter hardware for each individual port to 
-      determine whether a port can be used for all network traffic or 
-      not.
-
-   -- CheckLocalPort - In this mode, RLMT monitors the network path 
-      between the two ports of an adapter by regularly exchanging packets
-      between them. This mode requires a network configuration in which 
-      the two ports are able to "see" each other (i.e. there must not be 
-      any router between the ports).
-
-   -- CheckSeg - Check local port and segmentation: This mode supports the
-      same functions as the CheckLocalPort mode and additionally checks 
-      network segmentation between the ports. Therefore, this mode is only
-      to be used if Gigabit Ethernet switches are installed on the network
-      that have been configured to use the Spanning Tree protocol. 
-
-   -- DualNet - In this mode, ports A and B are used as separate devices. 
-      If you have a dual port adapter, port A will be configured as eth0 
-      and port B as eth1. Both ports can be used independently with 
-      distinct IP addresses. The preferred port setting is not used. 
-      RLMT is turned off.
-   
-NOTE: RLMT modes CLP and CLPSS are designed to operate in configurations 
-      where a network path between the ports on one adapter exists. 
-      Moreover, they are not designed to work where adapters are connected
-      back-to-back.
-***
-
-
-5  Large Frame Support
-======================
-
-The driver supports large frames (also called jumbo frames). Using large 
-frames can result in an improved throughput if transferring large amounts 
-of data.
-To enable large frames, set the MTU (maximum transfer unit) of the 
-interface to the desired value (up to 9000), execute the following 
-command:
-      ifconfig eth0 mtu 9000
-This will only work if you have two adapters connected back-to-back
-or if you use a switch that supports large frames. When using a switch, 
-it should be configured to allow large frames and auto-negotiation should  
-be set to OFF. The setting must be configured on all adapters that can be 
-reached by the large frames. If one adapter is not set to receive large 
-frames, it will simply drop them.
-
-You can switch back to the standard ethernet frame size by executing the 
-following command:
-      ifconfig eth0 mtu 1500
-
-To permanently configure this setting, add a script with the 'ifconfig' 
-line to the system startup sequence (named something like "S99sk98lin" 
-in /etc/rc.d/rc2.d).
-***
-
-
-6  VLAN and Link Aggregation Support (IEEE 802.1, 802.1q, 802.3ad)
-==================================================================
-
-The Marvell Yukon/SysKonnect Linux drivers are able to support VLAN and 
-Link Aggregation according to IEEE standards 802.1, 802.1q, and 802.3ad. 
-These features are only available after installation of open source 
-modules available on the Internet:
-For VLAN go to: http://www.candelatech.com/~greear/vlan.html
-For Link Aggregation go to: http://www.st.rim.or.jp/~yumo
-
-NOTE: SysKonnect GmbH does not offer any support for these open source 
-      modules and does not take the responsibility for any kind of 
-      failures or problems arising in connection with these modules.
-
-NOTE: Configuring Link Aggregation on a SysKonnect dual link adapter may 
-      cause problems when unloading the driver.
-
-
-7  Troubleshooting
-==================
-
-If any problems occur during the installation process, check the 
-following list:
-
-
-Problem:  The SK-98xx adapter cannot be found by the driver.
-Solution: In /proc/pci search for the following entry:
-             'Ethernet controller: SysKonnect SK-98xx ...'
-          If this entry exists, the SK-98xx or SK-98xx V2.0 adapter has 
-          been found by the system and should be operational.
-          If this entry does not exist or if the file '/proc/pci' is not 
-          found, there may be a hardware problem or the PCI support may 
-          not be enabled in your kernel.
-          The adapter can be checked using the diagnostics program which 
-          is available on the SysKonnect web site:
-          www.syskonnect.com
-          
-          Some COMPAQ machines have problems dealing with PCI under Linux.
-          This problem is described in the 'PCI howto' document
-          (included in some distributions or available from the
-          web, e.g. at 'www.linux.org'). 
-
-
-Problem:  Programs such as 'ifconfig' or 'route' cannot be found or the 
-          error message 'Operation not permitted' is displayed.
-Reason:   You are not logged in as user 'root'.
-Solution: Logout and login as 'root' or change to 'root' via 'su'.
-
-
-Problem:  Upon use of the command 'ping <address>' the message
-          "ping: sendto: Network is unreachable" is displayed.
-Reason:   Your route is not set correctly.
-Solution: If you are using RedHat, you probably forgot to set up the 
-          route in the 'network configuration'.
-          Check the existing routes with the 'route' command and check 
-          if an entry for 'eth0' exists, and if so, if it is set correctly.
-
-
-Problem:  The driver can be started, the adapter is connected to the 
-          network, but you cannot receive or transmit any packets; 
-          e.g. 'ping' does not work.
-Reason:   There is an incorrect route in your routing table.
-Solution: Check the routing table with the command 'route' and read the 
-          manual help pages dealing with routes (enter 'man route').
-
-NOTE: Although the 2.2.x kernel versions generate the routing entry 
-      automatically, problems of this kind may occur here as well. We've 
-      come across a situation in which the driver started correctly at 
-      system start, but after the driver has been removed and reloaded,
-      the route of the adapter's network pointed to the 'dummy0'device 
-      and had to be corrected manually.
-
-
-Problem:  Your computer should act as a router between multiple 
-          IP subnetworks (using multiple adapters), but computers in 
-          other subnetworks cannot be reached.
-Reason:   Either the router's kernel is not configured for IP forwarding 
-          or the routing table and gateway configuration of at least one 
-          computer is not working.
-
-Problem:  Upon driver start, the following error message is displayed:
-          "eth0: -- ERROR --
-          Class: internal Software error
-          Nr:    0xcc
-          Msg:   SkGeInitPort() cannot init running ports"
-Reason:   You are using a driver compiled for single processor machines 
-          on a multiprocessor machine with SMP (Symmetric MultiProcessor) 
-          kernel.
-Solution: Configure your kernel appropriately and recompile the kernel or
-          the modules.
-
-
-
-If your problem is not listed here, please contact SysKonnect's technical
-support for help (linux@syskonnect.de).
-When contacting our technical support, please ensure that the following 
-information is available:
-- System Manufacturer and HW Informations (CPU, Memory... )
-- PCI-Boards in your system
-- Distribution
-- Kernel version
-- Driver version
-***
-
-
-
-***End of Readme File***
diff --git a/MAINTAINERS b/MAINTAINERS
index 2c1dfb2..0223d6d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2930,6 +2930,13 @@ M:	mikpe@it.uu.se
 L:	linux-ide@vger.kernel.org
 S:	Maintained
 
+PS3 NETWORK SUPPORT
+P:	Masakazu Mokuno
+M:	mokuno@sm.sony.co.jp
+L:	netdev@vger.kernel.org
+L:	cbe-oss-dev@ozlabs.org
+S:	Supported
+
 PS3 PLATFORM SUPPORT
 P:	Geoff Levand
 M:	geoffrey.levand@am.sony.com
diff --git a/drivers/misc/eeprom_93cx6.c b/drivers/misc/eeprom_93cx6.c
index ac515b0..ea55654 100644
--- a/drivers/misc/eeprom_93cx6.c
+++ b/drivers/misc/eeprom_93cx6.c
@@ -55,10 +55,10 @@ static inline void eeprom_93cx6_pulse_low(struct eeprom_93cx6 *eeprom)
 
 	/*
 	 * Add a short delay for the pulse to work.
-	 * According to the specifications the minimal time
-	 * should be 450ns so a 1us delay is sufficient.
+	 * According to the specifications the "maximum minimum"
+	 * time should be 450ns.
 	 */
-	udelay(1);
+	ndelay(450);
 }
 
 static void eeprom_93cx6_startup(struct eeprom_93cx6 *eeprom)
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index f26ca33..6deb20f 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -324,7 +324,7 @@ static struct vortex_chip_info {
 	{"3c980C Python-T",
 	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3cSOHO100-TX Hurricane",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 	{"3c555 Laptop Hurricane",
 	 PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, },
 	{"3c556 Laptop Tornado",
diff --git a/drivers/net/8390.h b/drivers/net/8390.h
index 414de5b..04ddec0 100644
--- a/drivers/net/8390.h
+++ b/drivers/net/8390.h
@@ -73,6 +73,9 @@ struct ei_device {
 	u32 *reg_offset;		/* Register mapping table */
 	spinlock_t page_lock;		/* Page register locks */
 	unsigned long priv;		/* Private field to store bus IDs etc. */
+#ifdef AX88796_PLATFORM
+	unsigned char rxcr_base;	/* default value for RXCR */
+#endif
 };
 
 /* The maximum number of 8390 interrupt service routines called per IRQ. */
@@ -86,11 +89,19 @@ struct ei_device {
 /* Some generic ethernet register configurations. */
 #define E8390_TX_IRQ_MASK	0xa	/* For register EN0_ISR */
 #define E8390_RX_IRQ_MASK	0x5
+
+#ifdef AX88796_PLATFORM
+#define E8390_RXCONFIG		(ei_status.rxcr_base | 0x04)
+#define E8390_RXOFF		(ei_status.rxcr_base | 0x20)
+#else
 #define E8390_RXCONFIG		0x4	/* EN0_RXCR: broadcasts, no multicast,errors */
 #define E8390_RXOFF		0x20	/* EN0_RXCR: Accept no packets */
+#endif
+
 #define E8390_TXCONFIG		0x00	/* EN0_TXCR: Normal transmit mode */
 #define E8390_TXOFF		0x02	/* EN0_TXCR: Transmitter off */
 
+
 /*  Register accessed at EN_CMD, the 8390 base addr.  */
 #define E8390_STOP	0x01	/* Stop and reset the chip */
 #define E8390_START	0x02	/* Start the chip, clear reset */
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5cc3d51..ec84684 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -197,6 +197,15 @@ config MACB
 
 source "drivers/net/arm/Kconfig"
 
+config AX88796
+	tristate "ASIX AX88796 NE2000 clone support"
+	depends on ARM || MIPS
+	select CRC32
+	select MII
+	help
+	  AX88796 driver, using platform bus to provide
+	  chip detection and resources
+
 config MACE
 	tristate "MACE (Power Mac ethernet) support"
 	depends on PPC_PMAC && PPC32
@@ -2105,7 +2114,7 @@ config SKGE
 	  with better performance and more complete ethtool support.
 
 	  It does not support the link failover and network management 
-	  features that "portable" vendor supplied sk98lin driver does.
+	  features available in the hardware.
 
 	  This driver supports adapters based on the original Yukon chipset:
 	  Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
@@ -2118,7 +2127,7 @@ config SKGE
 	  will be called skge.  This is recommended.
 
 config SKY2
-	tristate "SysKonnect Yukon2 support (EXPERIMENTAL)"
+	tristate "SysKonnect Yukon2 support"
 	depends on PCI
 	select CRC32
 	---help---
@@ -2133,92 +2142,15 @@ config SKY2
 	  To compile this driver as a module, choose M here: the module
 	  will be called sky2.  This is recommended.
 
-config SK98LIN
-	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)"
-	depends on PCI
-	---help---
-	  Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
-	  compliant Gigabit Ethernet Adapter.
-
-	  This driver supports the original Yukon chipset. This driver is
-	  deprecated and will be removed from the kernel in the near future,
-	  it has been replaced by the skge driver. skge is cleaner and
-	  seems to work better.
+config SKY2_DEBUG
+       bool "Debugging interface"
+       depends on SKY2 && DEBUG_FS
+       help
+	 This option adds the ability to dump driver state for debugging.
+	 The file debugfs/sky2/ethX displays the state of the internal
+	 transmit and receive rings.
 
-	  This driver does not support the newer Yukon2 chipset. A separate
-	  driver, sky2, is provided to support Yukon2-based adapters.
-
-	  The following adapters are supported by this driver:
-	    - 3Com 3C940 Gigabit LOM Ethernet Adapter
-	    - 3Com 3C941 Gigabit LOM Ethernet Adapter
-	    - Allied Telesyn AT-2970LX Gigabit Ethernet Adapter
-	    - Allied Telesyn AT-2970LX/2SC Gigabit Ethernet Adapter
-	    - Allied Telesyn AT-2970SX Gigabit Ethernet Adapter
-	    - Allied Telesyn AT-2970SX/2SC Gigabit Ethernet Adapter
-	    - Allied Telesyn AT-2970TX Gigabit Ethernet Adapter
-	    - Allied Telesyn AT-2970TX/2TX Gigabit Ethernet Adapter
-	    - Allied Telesyn AT-2971SX Gigabit Ethernet Adapter
-	    - Allied Telesyn AT-2971T Gigabit Ethernet Adapter
-	    - Belkin Gigabit Desktop Card 10/100/1000Base-T Adapter, Copper RJ-45
-	    - EG1032 v2 Instant Gigabit Network Adapter
-	    - EG1064 v2 Instant Gigabit Network Adapter
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Abit)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Albatron)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Asus)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (ECS)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Epox)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Foxconn)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Gigabyte)
-	    - Marvell 88E8001 Gigabit LOM Ethernet Adapter (Iwill)
-	    - Marvell 88E8050 Gigabit LOM Ethernet Adapter (Intel)
-	    - Marvell RDK-8001 Adapter
-	    - Marvell RDK-8002 Adapter
-	    - Marvell RDK-8003 Adapter
-	    - Marvell RDK-8004 Adapter
-	    - Marvell RDK-8006 Adapter
-	    - Marvell RDK-8007 Adapter
-	    - Marvell RDK-8008 Adapter
-	    - Marvell RDK-8009 Adapter
-	    - Marvell RDK-8010 Adapter
-	    - Marvell RDK-8011 Adapter
-	    - Marvell RDK-8012 Adapter
-	    - Marvell RDK-8052 Adapter
-	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (32 bit)
-	    - Marvell Yukon Gigabit Ethernet 10/100/1000Base-T Adapter (64 bit)
-	    - N-Way PCI-Bus Giga-Card 1000/100/10Mbps(L)
-	    - SK-9521 10/100/1000Base-T Adapter
-	    - SK-9521 V2.0 10/100/1000Base-T Adapter
-	    - SK-9821 Gigabit Ethernet Server Adapter (SK-NET GE-T)
-	    - SK-9821 V2.0 Gigabit Ethernet 10/100/1000Base-T Adapter
-	    - SK-9822 Gigabit Ethernet Server Adapter (SK-NET GE-T dual link)
-	    - SK-9841 Gigabit Ethernet Server Adapter (SK-NET GE-LX)
-	    - SK-9841 V2.0 Gigabit Ethernet 1000Base-LX Adapter
-	    - SK-9842 Gigabit Ethernet Server Adapter (SK-NET GE-LX dual link)
-	    - SK-9843 Gigabit Ethernet Server Adapter (SK-NET GE-SX)
-	    - SK-9843 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-	    - SK-9844 Gigabit Ethernet Server Adapter (SK-NET GE-SX dual link)
-	    - SK-9851 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-	    - SK-9861 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition)
-	    - SK-9861 V2.0 Gigabit Ethernet 1000Base-SX Adapter
-	    - SK-9862 Gigabit Ethernet Server Adapter (SK-NET GE-SX Volition dual link)
-	    - SK-9871 Gigabit Ethernet Server Adapter (SK-NET GE-ZX)
-	    - SK-9871 V2.0 Gigabit Ethernet 1000Base-ZX Adapter
-	    - SK-9872 Gigabit Ethernet Server Adapter (SK-NET GE-ZX dual link)
-	    - SMC EZ Card 1000 (SMC9452TXV.2)
-	  
-	  The adapters support Jumbo Frames.
-	  The dual link adapters support link-failover and dual port features.
-	  Both Marvell Yukon and SysKonnect SK-98xx/SK-95xx adapters support 
-	  the scatter-gather functionality with sendfile(). Please refer to 
-	  <file:Documentation/networking/sk98lin.txt> for more information about
-	  optional driver parameters.
-	  Questions concerning this driver may be addressed to:
-	      <linux@syskonnect.de>
-	  
-	  If you want to compile this driver as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/kbuild/modules.txt>. The module will
-	  be called sk98lin. This is recommended.
+	 If unsure, say N.
 
 config VIA_VELOCITY
 	tristate "VIA Velocity support"
@@ -2268,6 +2200,16 @@ config TSI108_ETH
 	     To compile this driver as a module, choose M here: the module
 	     will be called tsi108_eth.
 
+config GELIC_NET
+	tristate "PS3 Gigabit Ethernet driver"
+	depends on PPC_PS3
+	help
+	  This driver supports the network device on the PS3 game
+	  console.  This driver has built-in support for Ethernet.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called ps3_gelic.
+
 config GIANFAR
 	tristate "Gianfar Ethernet"
 	depends on 85xx || 83xx || PPC_86xx
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index eb62fb4..1bbcbed 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -60,10 +60,11 @@ obj-$(CONFIG_TIGON3) += tg3.o
 obj-$(CONFIG_BNX2) += bnx2.o
 spidernet-y += spider_net.o spider_net_ethtool.o
 obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
+obj-$(CONFIG_GELIC_NET) += ps3_gelic.o
+ps3_gelic-objs += ps3_gelic_net.o
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SKY2) += sky2.o
-obj-$(CONFIG_SK98LIN) += sk98lin/
 obj-$(CONFIG_SKFP) += skfp/
 obj-$(CONFIG_VIA_RHINE) += via-rhine.o
 obj-$(CONFIG_VIA_VELOCITY) += via-velocity.o
@@ -107,6 +108,7 @@ obj-$(CONFIG_NET_SB1250_MAC) += sb1250-mac.o
 obj-$(CONFIG_B44) += b44.o
 obj-$(CONFIG_FORCEDETH) += forcedeth.o
 obj-$(CONFIG_NE_H8300) += ne-h8300.o
+obj-$(CONFIG_AX88796) += ax88796.o
 
 obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
 obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c
index 5471440..f735637 100644
--- a/drivers/net/atari_pamsnet.c
+++ b/drivers/net/atari_pamsnet.c
@@ -295,10 +295,7 @@ int if_up = 0;
 /* Setup the DMA counter */
 
 static void
-setup_dma (address, rw_flag, num_blocks)
-	void *address;
-	unsigned rw_flag;
-	int num_blocks;
+setup_dma (void *address, unsigned rw_flag, int num_blocks)
 {
 	WRITEMODE((unsigned) rw_flag          | DMA_FDC | SEC_COUNT | REG_ACSI |
 		  A1);
@@ -317,9 +314,7 @@ setup_dma (address, rw_flag, num_blocks)
 /* Send the first byte of an command block */
 
 static int
-send_first (target, byte)
-	int target;
-	unsigned char byte;
+send_first (int target, unsigned char byte)
 {
 	rw = READ;
 	acsi_delay_end(COMMAND_DELAY);
@@ -338,10 +333,7 @@ send_first (target, byte)
 /* Send the rest of an command block */
 
 static int
-send_1_5 (lun, command, dma)
-	int lun;
-	unsigned char *command;
-	int dma;
+send_1_5 (int lun, unsigned char *command, int dma)
 {
 	int i, j;
 
@@ -371,8 +363,7 @@ get_status (void)
 /* Calculate the number of received bytes */
 
 static int
-calc_received (start_address)
-	void *start_address;
+calc_received (void *start_address)
 {
 	return (int)(
 		(((unsigned long)DMAHIGH << 16) | ((unsigned)DMAMID << 8) | DMALOW)
@@ -384,8 +375,7 @@ calc_received (start_address)
 /* start() starts the PAM's DMA adaptor */
 
 static void
-start (target)
-	int target;
+start (int target)
 {
 	send_first(target, START);
 }
@@ -393,8 +383,7 @@ start (target)
 /* stop() stops the PAM's DMA adaptor and returns a value of zero in case of success */
 
 static int
-stop (target)
-	int target;
+stop (int target)
 {
 	int ret = -1;
 	unsigned char cmd_buffer[5];
@@ -415,8 +404,7 @@ bad:
 /* testpkt() returns the number of received packets waiting in the queue */
 
 static int
-testpkt(target)
-	int target;
+testpkt(int target)
 {
 	int ret = -1;
 
@@ -431,9 +419,7 @@ bad:
 /* Please note: The buffer is for internal use only but must be defined!   */
 
 static int
-inquiry (target, buffer)
-	int target;
-	unsigned char *buffer;
+inquiry (int target, unsigned char *buffer)
 {
 	int ret = -1;
 	unsigned char *vbuffer = phys_to_virt((unsigned long)buffer);
@@ -468,9 +454,7 @@ bad:
  */
 
 static HADDR
-*read_hw_addr(target, buffer)
-	int target;
-	unsigned char *buffer;
+*read_hw_addr(int target, unsigned char *buffer)
 {
 	HADDR *ret = 0;
 	unsigned char cmd_buffer[5];
@@ -491,9 +475,7 @@ bad:
 }
 
 static irqreturn_t
-pamsnet_intr(irq, data, fp)
-	int irq;
-	void *data;
+pamsnet_intr(int irq, void *data)
 {
 	return IRQ_HANDLED;
 }
@@ -501,9 +483,7 @@ pamsnet_intr(irq, data, fp)
 /* receivepkt() loads a packet to a given buffer and returns its length */
 
 static int
-receivepkt (target, buffer)
-	int target;
-	unsigned char *buffer;
+receivepkt (int target, unsigned char *buffer)
 {
 	int ret = -1;
 	unsigned char cmd_buffer[5];
@@ -526,10 +506,7 @@ bad:
              successfully */
 
 static int
-sendpkt (target, buffer, length)
-	int target;
-	unsigned char *buffer;
-	int length;
+sendpkt (int target, unsigned char *buffer, int length)
 {
 	int ret = -1;
 	unsigned char cmd_buffer[5];
@@ -665,7 +642,8 @@ struct net_device * __init pamsnet_probe (int unit)
    there is non-reboot way to recover if something goes wrong.
  */
 static int
-pamsnet_open(struct net_device *dev) {
+pamsnet_open(struct net_device *dev)
+{
 	struct net_local *lp = netdev_priv(dev);
 
 	if (pamsnet_debug > 0)
@@ -694,7 +672,8 @@ pamsnet_open(struct net_device *dev) {
 }
 
 static int
-pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) {
+pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev)
+{
 	struct net_local *lp = netdev_priv(dev);
 	unsigned long flags;
 
@@ -741,7 +720,8 @@ pamsnet_send_packet(struct sk_buff *skb, struct net_device *dev) {
 /* We have a good packet(s), get it/them out of the buffers.
  */
 static void
-pamsnet_poll_rx(struct net_device *dev) {
+pamsnet_poll_rx(struct net_device *dev)
+{
 	struct net_local *lp = netdev_priv(dev);
 	int boguscount;
 	int pkt_len;
@@ -816,7 +796,8 @@ pamsnet_poll_rx(struct net_device *dev) {
  * passes them to the higher layers and restarts the timer.
  */
 static void
-pamsnet_tick(unsigned long data) {
+pamsnet_tick(unsigned long data)
+{
 	struct net_device	 *dev = (struct net_device *)data;
 	struct net_local *lp = netdev_priv(dev);
 
@@ -832,7 +813,8 @@ pamsnet_tick(unsigned long data) {
 /* The inverse routine to pamsnet_open().
  */
 static int
-pamsnet_close(struct net_device *dev) {
+pamsnet_close(struct net_device *dev)
+{
 	struct net_local *lp = netdev_priv(dev);
 
 	if (pamsnet_debug > 0)
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 6862c11..3bb40dd 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -634,14 +634,13 @@ static void atl1_intr_tx(struct atl1_adapter *adapter)
 	struct atl1_buffer *buffer_info;
 	u16 sw_tpd_next_to_clean;
 	u16 cmb_tpd_next_to_clean;
-	u8 update = 0;
 
 	sw_tpd_next_to_clean = atomic_read(&tpd_ring->next_to_clean);
 	cmb_tpd_next_to_clean = le16_to_cpu(adapter->cmb.cmb->tpd_cons_idx);
 
 	while (cmb_tpd_next_to_clean != sw_tpd_next_to_clean) {
 		struct tx_packet_desc *tpd;
-		update = 1;
+
 		tpd = ATL1_TPD_DESC(tpd_ring, sw_tpd_next_to_clean);
 		buffer_info = &tpd_ring->buffer_info[sw_tpd_next_to_clean];
 		if (buffer_info->dma) {
diff --git a/drivers/net/ax88796.c b/drivers/net/ax88796.c
new file mode 100644
index 0000000..d19874b
--- /dev/null
+++ b/drivers/net/ax88796.c
@@ -0,0 +1,952 @@
+/* drivers/net/ax88796.c
+ *
+ * Copyright 2005,2007 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * Asix AX88796 10/100 Ethernet controller support
+ *	Based on ne.c, by Donald Becker, et-al.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/isapnp.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+
+#include <net/ax88796.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+
+static int phy_debug = 0;
+
+/* Rename the lib8390.c functions to show that they are in this driver */
+#define __ei_open       ax_ei_open
+#define __ei_close      ax_ei_close
+#define __ei_poll	ax_ei_poll
+#define __ei_tx_timeout ax_ei_tx_timeout
+#define __ei_interrupt  ax_ei_interrupt
+#define ____alloc_ei_netdev ax__alloc_ei_netdev
+#define __NS8390_init   ax_NS8390_init
+
+/* force unsigned long back to 'void __iomem *' */
+#define ax_convert_addr(_a) ((void __force __iomem *)(_a))
+
+#define ei_inb(_a)	readb(ax_convert_addr(_a))
+#define ei_outb(_v, _a) writeb(_v, ax_convert_addr(_a))
+
+#define ei_inb_p(_a)	ei_inb(_a)
+#define ei_outb_p(_v, _a) ei_outb(_v, _a)
+
+/* define EI_SHIFT() to take into account our register offsets */
+#define EI_SHIFT(x)     (ei_local->reg_offset[(x)])
+
+/* Ensure we have our RCR base value */
+#define AX88796_PLATFORM
+
+static unsigned char version[] = "ax88796.c: Copyright 2005,2007 Simtec Electronics\n";
+
+#include "lib8390.c"
+
+#define DRV_NAME "ax88796"
+#define DRV_VERSION "1.00"
+
+/* from ne.c */
+#define NE_CMD		EI_SHIFT(0x00)
+#define NE_RESET	EI_SHIFT(0x1f)
+#define NE_DATAPORT	EI_SHIFT(0x10)
+
+#define NE1SM_START_PG	0x20	/* First page of TX buffer */
+#define NE1SM_STOP_PG 	0x40	/* Last page +1 of RX ring */
+#define NESM_START_PG	0x40	/* First page of TX buffer */
+#define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */
+
+/* device private data */
+
+struct ax_device {
+	struct timer_list	 mii_timer;
+	spinlock_t		 mii_lock;
+	struct mii_if_info	 mii;
+
+	u32			 msg_enable;
+	void __iomem		*map2;
+	struct platform_device	*dev;
+	struct resource		*mem;
+	struct resource		*mem2;
+	struct ax_plat_data	*plat;
+
+	unsigned char		 running;
+	unsigned char		 resume_open;
+
+	u32			 reg_offsets[0x20];
+};
+
+static inline struct ax_device *to_ax_dev(struct net_device *dev)
+{
+	struct ei_device *ei_local = netdev_priv(dev);
+	return (struct ax_device *)(ei_local+1);
+}
+
+/* ax_initial_check
+ *
+ * do an initial probe for the card to check wether it exists
+ * and is functional
+ */
+
+static int ax_initial_check(struct net_device *dev)
+{
+	struct ei_device *ei_local = netdev_priv(dev);
+	void __iomem *ioaddr = ei_local->mem;
+	int reg0;
+	int regd;
+
+	reg0 = ei_inb(ioaddr);
+	if (reg0 == 0xFF)
+		return -ENODEV;
+
+	ei_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
+	regd = ei_inb(ioaddr + 0x0d);
+	ei_outb(0xff, ioaddr + 0x0d);
+	ei_outb(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
+	ei_inb(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
+	if (ei_inb(ioaddr + EN0_COUNTER0) != 0) {
+		ei_outb(reg0, ioaddr);
+		ei_outb(regd, ioaddr + 0x0d);	/* Restore the old values. */
+		return -ENODEV;
+	}
+
+	return 0;
+}
+
+/* Hard reset the card.  This used to pause for the same period that a
+   8390 reset command required, but that shouldn't be necessary. */
+
+static void ax_reset_8390(struct net_device *dev)
+{
+	struct ei_device *ei_local = netdev_priv(dev);
+	unsigned long reset_start_time = jiffies;
+	void __iomem *addr = (void __iomem *)dev->base_addr;
+
+	if (ei_debug > 1)
+		printk(KERN_DEBUG "resetting the 8390 t=%ld...", jiffies);
+
+	ei_outb(ei_inb(addr + NE_RESET), addr + NE_RESET);
+
+	ei_status.txing = 0;
+	ei_status.dmaing = 0;
+
+	/* This check _should_not_ be necessary, omit eventually. */
+	while ((ei_inb(addr + EN0_ISR) & ENISR_RESET) == 0) {
+		if (jiffies - reset_start_time > 2*HZ/100) {
+			printk(KERN_WARNING "%s: %s did not complete.\n",
+			       __FUNCTION__, dev->name);
+			break;
+		}
+	}
+
+	ei_outb(ENISR_RESET, addr + EN0_ISR);	/* Ack intr. */
+}
+
+
+static void ax_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
+			    int ring_page)
+{
+	struct ei_device *ei_local = netdev_priv(dev);
+	void __iomem *nic_base = ei_local->mem;
+
+	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
+	if (ei_status.dmaing) {
+		printk(KERN_EMERG "%s: DMAing conflict in %s [DMAstat:%d][irqlock:%d].\n",
+			dev->name, __FUNCTION__,
+		       ei_status.dmaing, ei_status.irqlock);
+		return;
+	}
+
+	ei_status.dmaing |= 0x01;
+	ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+	ei_outb(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
+	ei_outb(0, nic_base + EN0_RCNTHI);
+	ei_outb(0, nic_base + EN0_RSARLO);		/* On page boundary */
+	ei_outb(ring_page, nic_base + EN0_RSARHI);
+	ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+	if (ei_status.word16)
+		readsw(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr)>>1);
+	else
+		readsb(nic_base + NE_DATAPORT, hdr, sizeof(struct e8390_pkt_hdr));
+
+	ei_outb(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
+	ei_status.dmaing &= ~0x01;
+
+	le16_to_cpus(&hdr->count);
+}
+
+
+/* Block input and output, similar to the Crynwr packet driver.  If you
+   are porting to a new ethercard, look at the packet driver source for hints.
+   The NEx000 doesn't share the on-board packet memory -- you have to put
+   the packet out through the "remote DMA" dataport using ei_outb. */
+
+static void ax_block_input(struct net_device *dev, int count,
+			   struct sk_buff *skb, int ring_offset)
+{
+	struct ei_device *ei_local = netdev_priv(dev);
+	void __iomem *nic_base = ei_local->mem;
+	char *buf = skb->data;
+
+	if (ei_status.dmaing) {
+		printk(KERN_EMERG "%s: DMAing conflict in ax_block_input "
+			"[DMAstat:%d][irqlock:%d].\n",
+			dev->name, ei_status.dmaing, ei_status.irqlock);
+		return;
+	}
+
+	ei_status.dmaing |= 0x01;
+
+	ei_outb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+	ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
+	ei_outb(count >> 8, nic_base + EN0_RCNTHI);
+	ei_outb(ring_offset & 0xff, nic_base + EN0_RSARLO);
+	ei_outb(ring_offset >> 8, nic_base + EN0_RSARHI);
+	ei_outb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+	if (ei_status.word16) {
+		readsw(nic_base + NE_DATAPORT, buf, count >> 1);
+		if (count & 0x01)
+			buf[count-1] = ei_inb(nic_base + NE_DATAPORT);
+
+	} else {
+		readsb(nic_base + NE_DATAPORT, buf, count);
+	}
+
+	ei_status.dmaing &= ~1;
+}
+
+static void ax_block_output(struct net_device *dev, int count,
+			    const unsigned char *buf, const int start_page)
+{
+	struct ei_device *ei_local = netdev_priv(dev);
+	void __iomem *nic_base = ei_local->mem;
+	unsigned long dma_start;
+
+	/* Round the count up for word writes.  Do we need to do this?
+	   What effect will an odd byte count have on the 8390?
+	   I should check someday. */
+
+	if (ei_status.word16 && (count & 0x01))
+		count++;
+
+	/* This *shouldn't* happen. If it does, it's the last thing you'll see */
+	if (ei_status.dmaing) {
+		printk(KERN_EMERG "%s: DMAing conflict in %s."
+			"[DMAstat:%d][irqlock:%d]\n",
+			dev->name, __FUNCTION__,
+		       ei_status.dmaing, ei_status.irqlock);
+		return;
+	}
+
+	ei_status.dmaing |= 0x01;
+	/* We should already be in page 0, but to be safe... */
+	ei_outb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+
+	ei_outb(ENISR_RDC, nic_base + EN0_ISR);
+
+	/* Now the normal output. */
+	ei_outb(count & 0xff, nic_base + EN0_RCNTLO);
+	ei_outb(count >> 8,   nic_base + EN0_RCNTHI);
+	ei_outb(0x00, nic_base + EN0_RSARLO);
+	ei_outb(start_page, nic_base + EN0_RSARHI);
+
+	ei_outb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+	if (ei_status.word16) {
+		writesw(nic_base + NE_DATAPORT, buf, count>>1);
+	} else {
+		writesb(nic_base + NE_DATAPORT, buf, count);
+	}
+
+	dma_start = jiffies;
+
+	while ((ei_inb(nic_base + EN0_ISR) & ENISR_RDC) == 0) {
+		if (jiffies - dma_start > 2*HZ/100) {		/* 20ms */
+			printk(KERN_WARNING "%s: timeout waiting for Tx RDC.\n", dev->name);
+			ax_reset_8390(dev);
+			ax_NS8390_init(dev,1);
+			break;
+		}
+	}
+
+	ei_outb(ENISR_RDC, nic_base + EN0_ISR);	/* Ack intr. */
+	ei_status.dmaing &= ~0x01;
+	return;
+}
+
+/* definitions for accessing MII/EEPROM interface */
+
+#define AX_MEMR			EI_SHIFT(0x14)
+#define AX_MEMR_MDC		(1<<0)
+#define AX_MEMR_MDIR		(1<<1)
+#define AX_MEMR_MDI		(1<<2)
+#define AX_MEMR_MDO		(1<<3)
+#define AX_MEMR_EECS		(1<<4)
+#define AX_MEMR_EEI		(1<<5)
+#define AX_MEMR_EEO		(1<<6)
+#define AX_MEMR_EECLK		(1<<7)
+
+/* ax_mii_ei_outbits
+ *
+ * write the specified set of bits to the phy
+*/
+
+static void
+ax_mii_ei_outbits(struct net_device *dev, unsigned int bits, int len)
+{
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+	void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
+	unsigned int memr;
+
+	/* clock low, data to output mode */
+	memr = ei_inb(memr_addr);
+	memr &= ~(AX_MEMR_MDC | AX_MEMR_MDIR);
+	ei_outb(memr, memr_addr);
+
+	for (len--; len >= 0; len--) {
+		if (bits & (1 << len))
+			memr |= AX_MEMR_MDO;
+		else
+			memr &= ~AX_MEMR_MDO;
+
+		ei_outb(memr, memr_addr);
+
+		/* clock high */
+
+		ei_outb(memr | AX_MEMR_MDC, memr_addr);
+		udelay(1);
+
+		/* clock low */
+		ei_outb(memr, memr_addr);
+	}
+
+	/* leaves the clock line low, mdir input */
+	memr |= AX_MEMR_MDIR;
+	ei_outb(memr, (void __iomem *)dev->base_addr + AX_MEMR);
+}
+
+/* ax_phy_ei_inbits
+ *
+ * read a specified number of bits from the phy
+*/
+
+static unsigned int
+ax_phy_ei_inbits(struct net_device *dev, int no)
+{
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+	void __iomem *memr_addr = (void __iomem *)dev->base_addr + AX_MEMR;
+	unsigned int memr;
+	unsigned int result = 0;
+
+	/* clock low, data to input mode */
+	memr = ei_inb(memr_addr);
+	memr &= ~AX_MEMR_MDC;
+	memr |= AX_MEMR_MDIR;
+	ei_outb(memr, memr_addr);
+
+	for (no--; no >= 0; no--) {
+		ei_outb(memr | AX_MEMR_MDC, memr_addr);
+
+		udelay(1);
+
+		if (ei_inb(memr_addr) & AX_MEMR_MDI)
+			result |= (1<<no);
+
+		ei_outb(memr, memr_addr);
+	}
+
+	return result;
+}
+
+/* ax_phy_issueaddr
+ *
+ * use the low level bit shifting routines to send the address
+ * and command to the specified phy
+*/
+
+static void
+ax_phy_issueaddr(struct net_device *dev, int phy_addr, int reg, int opc)
+{
+	if (phy_debug)
+		pr_debug("%s: dev %p, %04x, %04x, %d\n",
+			__FUNCTION__, dev, phy_addr, reg, opc);
+
+	ax_mii_ei_outbits(dev, 0x3f, 6);	/* pre-amble */
+	ax_mii_ei_outbits(dev, 1, 2);		/* frame-start */
+	ax_mii_ei_outbits(dev, opc, 2);		/* op code */
+	ax_mii_ei_outbits(dev, phy_addr, 5);	/* phy address */
+	ax_mii_ei_outbits(dev, reg, 5);		/* reg address */
+}
+
+static int
+ax_phy_read(struct net_device *dev, int phy_addr, int reg)
+{
+	struct ei_device *ei_local = (struct ei_device *) netdev_priv(dev);
+	unsigned long flags;
+ 	unsigned int result;
+
+      	spin_lock_irqsave(&ei_local->page_lock, flags);
+
+	ax_phy_issueaddr(dev, phy_addr, reg, 2);
+
+	result = ax_phy_ei_inbits(dev, 17);
+	result &= ~(3<<16);
+
+      	spin_unlock_irqrestore(&ei_local->page_lock, flags);
+
+	if (phy_debug)
+		pr_debug("%s: %04x.%04x => read %04x\n", __FUNCTION__,
+			 phy_addr, reg, result);
+
+	return result;
+}
+
+static void
+ax_phy_write(struct net_device *dev, int phy_addr, int reg, int value)
+{
+	struct ei_device *ei = (struct ei_device *) netdev_priv(dev);
+	unsigned long flags;
+
+	printk(KERN_DEBUG "%s: %p, %04x, %04x %04x\n",
+	       __FUNCTION__, dev, phy_addr, reg, value);
+
+      	spin_lock_irqsave(&ei->page_lock, flags);
+
+	ax_phy_issueaddr(dev, phy_addr, reg, 1);
+	ax_mii_ei_outbits(dev, 2, 2);		/* send TA */
+	ax_mii_ei_outbits(dev, value, 16);
+
+      	spin_unlock_irqrestore(&ei->page_lock, flags);
+}
+
+static void ax_mii_expiry(unsigned long data)
+{
+	struct net_device *dev = (struct net_device *)data;
+	struct ax_device  *ax = to_ax_dev(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ax->mii_lock, flags);
+	mii_check_media(&ax->mii, netif_msg_link(ax), 0);
+	spin_unlock_irqrestore(&ax->mii_lock, flags);
+
+	if (ax->running) {
+		ax->mii_timer.expires = jiffies + HZ*2;
+		add_timer(&ax->mii_timer);
+	}
+}
+
+static int ax_open(struct net_device *dev)
+{
+	struct ax_device  *ax = to_ax_dev(dev);
+	struct ei_device *ei_local = netdev_priv(dev);
+	int ret;
+
+	dev_dbg(ax->dev, "%s: open\n", dev->name);
+
+	ret = request_irq(dev->irq, ax_ei_interrupt, 0, dev->name, dev);
+	if (ret)
+		return ret;
+
+	ret = ax_ei_open(dev);
+	if (ret)
+		return ret;
+
+	/* turn the phy on (if turned off) */
+
+	ei_outb(ax->plat->gpoc_val, ei_local->mem + EI_SHIFT(0x17));
+	ax->running = 1;
+
+	/* start the MII timer */
+
+	init_timer(&ax->mii_timer);
+
+	ax->mii_timer.expires  = jiffies+1;
+	ax->mii_timer.data     = (unsigned long) dev;
+	ax->mii_timer.function = ax_mii_expiry;
+
+	add_timer(&ax->mii_timer);
+
+	return 0;
+}
+
+static int ax_close(struct net_device *dev)
+{
+	struct ax_device *ax = to_ax_dev(dev);
+	struct ei_device *ei_local = netdev_priv(dev);
+
+	dev_dbg(ax->dev, "%s: close\n", dev->name);
+
+	/* turn the phy off */
+
+	ei_outb(ax->plat->gpoc_val | (1<<6),
+	       ei_local->mem + EI_SHIFT(0x17));
+
+	ax->running = 0;
+	wmb();
+
+	del_timer_sync(&ax->mii_timer);
+	ax_ei_close(dev);
+
+	free_irq(dev->irq, dev);
+	return 0;
+}
+
+static int ax_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
+{
+	struct ax_device *ax = to_ax_dev(dev);
+	unsigned long flags;
+	int rc;
+
+	if (!netif_running(dev))
+		return -EINVAL;
+
+	spin_lock_irqsave(&ax->mii_lock, flags);
+	rc = generic_mii_ioctl(&ax->mii, if_mii(req), cmd, NULL);
+	spin_unlock_irqrestore(&ax->mii_lock, flags);
+
+	return rc;
+}
+
+/* ethtool ops */
+
+static void ax_get_drvinfo(struct net_device *dev,
+			   struct ethtool_drvinfo *info)
+{
+	struct ax_device *ax = to_ax_dev(dev);
+
+	strcpy(info->driver, DRV_NAME);
+	strcpy(info->version, DRV_VERSION);
+	strcpy(info->bus_info, ax->dev->name);
+}
+
+static int ax_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct ax_device *ax = to_ax_dev(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ax->mii_lock, flags);
+	mii_ethtool_gset(&ax->mii, cmd);
+	spin_lock_irqsave(&ax->mii_lock, flags);
+
+	return 0;
+}
+
+static int ax_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct ax_device *ax = to_ax_dev(dev);
+	unsigned long flags;
+	int rc;
+
+	spin_lock_irqsave(&ax->mii_lock, flags);
+	rc = mii_ethtool_sset(&ax->mii, cmd);
+	spin_lock_irqsave(&ax->mii_lock, flags);
+
+	return rc;
+}
+
+static int ax_nway_reset(struct net_device *dev)
+{
+	struct ax_device *ax = to_ax_dev(dev);
+	return mii_nway_restart(&ax->mii);
+}
+
+static u32 ax_get_link(struct net_device *dev)
+{
+	struct ax_device *ax = to_ax_dev(dev);
+	return mii_link_ok(&ax->mii);
+}
+
+static const struct ethtool_ops ax_ethtool_ops = {
+	.get_drvinfo		= ax_get_drvinfo,
+	.get_settings		= ax_get_settings,
+	.set_settings		= ax_set_settings,
+	.nway_reset		= ax_nway_reset,
+	.get_link		= ax_get_link,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
+};
+
+/* setup code */
+
+static void ax_initial_setup(struct net_device *dev, struct ei_device *ei_local)
+{
+	void __iomem *ioaddr = ei_local->mem;
+	struct ax_device *ax = to_ax_dev(dev);
+
+	/* Select page 0*/
+	ei_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, ioaddr + E8390_CMD);
+
+	/* set to byte access */
+	ei_outb(ax->plat->dcr_val & ~1, ioaddr + EN0_DCFG);
+	ei_outb(ax->plat->gpoc_val, ioaddr + EI_SHIFT(0x17));
+}
+
+/* ax_init_dev
+ *
+ * initialise the specified device, taking care to note the MAC
+ * address it may already have (if configured), ensure
+ * the device is ready to be used by lib8390.c and registerd with
+ * the network layer.
+ */
+
+static int ax_init_dev(struct net_device *dev, int first_init)
+{
+	struct ei_device *ei_local = netdev_priv(dev);
+	struct ax_device *ax = to_ax_dev(dev);
+	void __iomem *ioaddr = ei_local->mem;
+	unsigned int start_page;
+	unsigned int stop_page;
+	int ret;
+	int i;
+
+	ret = ax_initial_check(dev);
+	if (ret)
+		goto err_out;
+
+	/* setup goes here */
+
+	ax_initial_setup(dev, ei_local);
+
+	/* read the mac from the card prom if we need it */
+
+	if (first_init && ax->plat->flags & AXFLG_HAS_EEPROM) {
+		unsigned char SA_prom[32];
+
+		for(i = 0; i < sizeof(SA_prom); i+=2) {
+			SA_prom[i] = ei_inb(ioaddr + NE_DATAPORT);
+			SA_prom[i+1] = ei_inb(ioaddr + NE_DATAPORT);
+		}
+
+		if (ax->plat->wordlength == 2)
+			for (i = 0; i < 16; i++)
+				SA_prom[i] = SA_prom[i+i];
+
+		memcpy(dev->dev_addr,  SA_prom, 6);
+	}
+
+	if (ax->plat->wordlength == 2) {
+		/* We must set the 8390 for word mode. */
+		ei_outb(ax->plat->dcr_val, ei_local->mem + EN0_DCFG);
+		start_page = NESM_START_PG;
+		stop_page = NESM_STOP_PG;
+	} else {
+		start_page = NE1SM_START_PG;
+		stop_page = NE1SM_STOP_PG;
+	}
+
+	/* load the mac-address from the device if this is the
+	 * first time we've initialised */
+
+	if (first_init && ax->plat->flags & AXFLG_MAC_FROMDEV) {
+		ei_outb(E8390_NODMA + E8390_PAGE1 + E8390_STOP,
+			ei_local->mem + E8390_CMD); /* 0x61 */
+
+		for (i = 0 ; i < ETHER_ADDR_LEN ; i++)
+			dev->dev_addr[i] = ei_inb(ioaddr + EN1_PHYS_SHIFT(i));
+	}
+
+	ax_reset_8390(dev);
+
+	ei_status.name = "AX88796";
+	ei_status.tx_start_page = start_page;
+	ei_status.stop_page = stop_page;
+	ei_status.word16 = (ax->plat->wordlength == 2);
+	ei_status.rx_start_page = start_page + TX_PAGES;
+
+#ifdef PACKETBUF_MEMSIZE
+	 /* Allow the packet buffer size to be overridden by know-it-alls. */
+	ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
+#endif
+
+	ei_status.reset_8390	= &ax_reset_8390;
+	ei_status.block_input	= &ax_block_input;
+	ei_status.block_output	= &ax_block_output;
+	ei_status.get_8390_hdr	= &ax_get_8390_hdr;
+	ei_status.priv = 0;
+
+	dev->open		= ax_open;
+	dev->stop		= ax_close;
+	dev->do_ioctl		= ax_ioctl;
+	dev->ethtool_ops	= &ax_ethtool_ops;
+
+	ax->msg_enable		= NETIF_MSG_LINK;
+	ax->mii.phy_id_mask	= 0x1f;
+	ax->mii.reg_num_mask	= 0x1f;
+	ax->mii.phy_id		= 0x10;		/* onboard phy */
+	ax->mii.force_media	= 0;
+	ax->mii.full_duplex	= 0;
+	ax->mii.mdio_read	= ax_phy_read;
+	ax->mii.mdio_write	= ax_phy_write;
+	ax->mii.dev		= dev;
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = ax_ei_poll;
+#endif
+	ax_NS8390_init(dev, 0);
+
+	if (first_init) {
+		printk("AX88796: %dbit, irq %d, %lx, MAC: ",
+		       ei_status.word16 ? 16:8, dev->irq, dev->base_addr);
+
+		for (i = 0; i < ETHER_ADDR_LEN; i++)
+			printk("%2.2x%c", dev->dev_addr[i],
+			       (i < (ETHER_ADDR_LEN-1) ? ':' : ' '));
+
+		printk("\n");
+	}
+
+	ret = register_netdev(dev);
+	if (ret)
+		goto out_irq;
+
+	return 0;
+
+ out_irq:
+	/* cleanup irq */
+	free_irq(dev->irq, dev);
+ err_out:
+	return ret;
+}
+
+static int ax_remove(struct platform_device *_dev)
+{
+	struct net_device *dev = platform_get_drvdata(_dev);
+	struct ax_device  *ax;
+
+	ax = to_ax_dev(dev);
+
+	unregister_netdev(dev);
+	free_irq(dev->irq, dev);
+
+	iounmap(ei_status.mem);
+	release_resource(ax->mem);
+	kfree(ax->mem);
+
+	if (ax->map2) {
+		iounmap(ax->map2);
+		release_resource(ax->mem2);
+		kfree(ax->mem2);
+	}
+
+	free_netdev(dev);
+
+	return 0;
+}
+
+/* ax_probe
+ *
+ * This is the entry point when the platform device system uses to
+ * notify us of a new device to attach to. Allocate memory, find
+ * the resources and information passed, and map the necessary registers.
+*/
+
+static int ax_probe(struct platform_device *pdev)
+{
+	struct net_device *dev;
+	struct ax_device  *ax;
+	struct resource   *res;
+	size_t size;
+	int ret;
+
+	dev = ax__alloc_ei_netdev(sizeof(struct ax_device));
+	if (dev == NULL)
+		return -ENOMEM;
+
+	/* ok, let's setup our device */
+	ax = to_ax_dev(dev);
+
+	memset(ax, 0, sizeof(struct ax_device));
+
+	spin_lock_init(&ax->mii_lock);
+
+	ax->dev = pdev;
+	ax->plat = pdev->dev.platform_data;
+	platform_set_drvdata(pdev, dev);
+
+	ei_status.rxcr_base  = ax->plat->rcr_val;
+
+	/* find the platform resources */
+
+	dev->irq  = platform_get_irq(pdev, 0);
+	if (dev->irq < 0) {
+		dev_err(&pdev->dev, "no IRQ specified\n");
+		ret = -ENXIO;
+		goto exit_mem;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (res == NULL) {
+		dev_err(&pdev->dev, "no MEM specified\n");
+		ret = -ENXIO;
+		goto exit_mem;
+	}
+
+	size = (res->end - res->start) + 1;
+
+	/* setup the register offsets from either the platform data
+	 * or by using the size of the resource provided */
+
+	if (ax->plat->reg_offsets)
+		ei_status.reg_offset = ax->plat->reg_offsets;
+	else {
+		ei_status.reg_offset = ax->reg_offsets;
+		for (ret = 0; ret < 0x18; ret++)
+			ax->reg_offsets[ret] = (size / 0x18) * ret;
+	}
+
+	ax->mem = request_mem_region(res->start, size, pdev->name);
+	if (ax->mem == NULL) {
+		dev_err(&pdev->dev, "cannot reserve registers\n");
+ 		ret = -ENXIO;
+		goto exit_mem;
+	}
+
+	ei_status.mem = ioremap(res->start, size);
+	dev->base_addr = (long)ei_status.mem;
+
+	if (ei_status.mem == NULL) {
+		dev_err(&pdev->dev, "Cannot ioremap area (%08zx,%08zx)\n",
+			res->start, res->end);
+
+ 		ret = -ENXIO;
+		goto exit_req;
+	}
+
+	/* look for reset area */
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+	if (res == NULL) {
+		if (!ax->plat->reg_offsets) {
+			for (ret = 0; ret < 0x20; ret++)
+				ax->reg_offsets[ret] = (size / 0x20) * ret;
+		}
+
+		ax->map2 = NULL;
+	} else {
+ 		size = (res->end - res->start) + 1;
+
+		ax->mem2 = request_mem_region(res->start, size, pdev->name);
+		if (ax->mem == NULL) {
+			dev_err(&pdev->dev, "cannot reserve registers\n");
+			ret = -ENXIO;
+			goto exit_mem1;
+		}
+
+		ax->map2 = ioremap(res->start, size);
+		if (ax->map2 == NULL) {
+			dev_err(&pdev->dev, "cannot map reset register");
+			ret = -ENXIO;
+			goto exit_mem2;
+		}
+
+		ei_status.reg_offset[0x1f] = ax->map2 - ei_status.mem;
+	}
+
+	/* got resources, now initialise and register device */
+
+	ret = ax_init_dev(dev, 1);
+	if (!ret)
+		return 0;
+
+	if (ax->map2 == NULL)
+		goto exit_mem1;
+
+	iounmap(ax->map2);
+
+ exit_mem2:
+	release_resource(ax->mem2);
+	kfree(ax->mem2);
+
+ exit_mem1:
+	iounmap(ei_status.mem);
+
+ exit_req:
+	release_resource(ax->mem);
+	kfree(ax->mem);
+
+ exit_mem:
+	free_netdev(dev);
+
+	return ret;
+}
+
+/* suspend and resume */
+
+#ifdef CONFIG_PM
+static int ax_suspend(struct platform_device *dev, pm_message_t state)
+{
+	struct net_device *ndev = platform_get_drvdata(dev);
+	struct ax_device  *ax = to_ax_dev(ndev);
+
+	ax->resume_open = ax->running;
+
+	netif_device_detach(ndev);
+	ax_close(ndev);
+
+	return 0;
+}
+
+static int ax_resume(struct platform_device *pdev)
+{
+	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct ax_device  *ax = to_ax_dev(ndev);
+
+	ax_initial_setup(ndev, netdev_priv(ndev));
+	ax_NS8390_init(ndev, ax->resume_open);
+	netif_device_attach(ndev);
+
+	if (ax->resume_open)
+		ax_open(ndev);
+
+	return 0;
+}
+
+#else
+#define ax_suspend NULL
+#define ax_resume  NULL
+#endif
+
+static struct platform_driver axdrv = {
+	.driver	= {
+		.name		= "ax88796",
+		.owner		= THIS_MODULE,
+	},
+	.probe		= ax_probe,
+	.remove		= ax_remove,
+	.suspend	= ax_suspend,
+	.resume		= ax_resume,
+};
+
+static int __init axdrv_init(void)
+{
+	return platform_driver_register(&axdrv);
+}
+
+static void __exit axdrv_exit(void)
+{
+	platform_driver_unregister(&axdrv);
+}
+
+module_init(axdrv_init);
+module_exit(axdrv_exit);
+
+MODULE_DESCRIPTION("AX88796 10/100 Ethernet platform driver");
+MODULE_AUTHOR("Ben Dooks, <ben@simtec.co.uk>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 6287ffb..cb9cb30 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -187,7 +187,7 @@ static void bond_send_gratuitous_arp(struct bonding *bond);
 
 /*---------------------------- General routines -----------------------------*/
 
-const char *bond_mode_name(int mode)
+static const char *bond_mode_name(int mode)
 {
 	switch (mode) {
 	case BOND_MODE_ROUNDROBIN :
@@ -1224,7 +1224,8 @@ static void bond_detach_slave(struct bonding *bond, struct slave *slave)
 
 /*---------------------------------- IOCTL ----------------------------------*/
 
-int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev)
+static int bond_sethwaddr(struct net_device *bond_dev,
+			  struct net_device *slave_dev)
 {
 	dprintk("bond_dev=%p\n", bond_dev);
 	dprintk("slave_dev=%p\n", slave_dev);
@@ -1390,6 +1391,11 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 		goto err_free;
 	}
 
+	res = netdev_set_master(slave_dev, bond_dev);
+	if (res) {
+		dprintk("Error %d calling netdev_set_master\n", res);
+		goto err_close;
+	}
 	/* open the slave since the application closed it */
 	res = dev_open(slave_dev);
 	if (res) {
@@ -1397,12 +1403,6 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev)
 		goto err_restore_mac;
 	}
 
-	res = netdev_set_master(slave_dev, bond_dev);
-	if (res) {
-		dprintk("Error %d calling netdev_set_master\n", res);
-		goto err_close;
-	}
-
 	new_slave->dev = slave_dev;
 	slave_dev->priv_flags |= IFF_BONDING;
 
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index a891021..6dcbd25 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -301,13 +301,11 @@ int bond_create_slave_symlinks(struct net_device *master, struct net_device *sla
 void bond_destroy_slave_symlinks(struct net_device *master, struct net_device *slave);
 int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
 int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
-int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_dev);
 void bond_mii_monitor(struct net_device *bond_dev);
 void bond_loadbalance_arp_mon(struct net_device *bond_dev);
 void bond_activebackup_arp_mon(struct net_device *bond_dev);
 void bond_set_mode_ops(struct bonding *bond, int mode);
 int bond_parse_parm(char *mode_arg, struct bond_parm_tbl *tbl);
-const char *bond_mode_name(int mode);
 void bond_select_active_slave(struct bonding *bond);
 void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
 void bond_register_arp(struct bonding *);
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 15defe4..6fd1e52 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -43,6 +43,7 @@
 #include <linux/proc_fs.h>
 #include <linux/rtnetlink.h>
 #include <linux/firmware.h>
+#include <linux/log2.h>
 #include <asm/uaccess.h>
 
 #include "common.h"
@@ -1818,8 +1819,8 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
 			return -EBUSY;
 		if (copy_from_user(&m, useraddr, sizeof(m)))
 			return -EFAULT;
-		if (!m.rx_pg_sz || (m.rx_pg_sz & (m.rx_pg_sz - 1)) ||
-			!m.tx_pg_sz || (m.tx_pg_sz & (m.tx_pg_sz - 1)))
+		if (!is_power_of_2(m.rx_pg_sz) ||
+			!is_power_of_2(m.tx_pg_sz))
 			return -EINVAL;	/* not power of 2 */
 		if (!(m.rx_pg_sz & 0x14000))
 			return -EINVAL;	/* not 16KB or 64KB */
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 763810c..74ea637 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -159,7 +159,7 @@
 
 #define DRV_NAME		"e100"
 #define DRV_EXT			"-NAPI"
-#define DRV_VERSION		"3.5.17-k4"DRV_EXT
+#define DRV_VERSION		"3.5.23-k4"DRV_EXT
 #define DRV_DESCRIPTION		"Intel(R) PRO/100 Network Driver"
 #define DRV_COPYRIGHT		"Copyright(c) 1999-2006 Intel Corporation"
 #define PFX			DRV_NAME ": "
@@ -1024,10 +1024,16 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb)
 		config->mwi_enable = 0x1;	/* 1=enable, 0=disable */
 		config->standard_tcb = 0x0;	/* 1=standard, 0=extended */
 		config->rx_long_ok = 0x1;	/* 1=VLANs ok, 0=standard */
-		if(nic->mac >= mac_82559_D101M)
+		if (nic->mac >= mac_82559_D101M) {
 			config->tno_intr = 0x1;		/* TCO stats enable */
-		else
+			/* Enable TCO in extended config */
+			if (nic->mac >= mac_82551_10) {
+				config->byte_count = 0x20; /* extended bytes */
+				config->rx_d102_mode = 0x1; /* GMRC for TCO */
+			}
+		} else {
 			config->standard_stat_counter = 0x0;
+		}
 	}
 
 	DPRINTK(HW, DEBUG, "[00-07]=%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index abaf3ac..f03f070 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,13 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0065"
+#define DRV_VERSION	"EHEA_0067"
+
+/* EHEA capability flags */
+#define DLPAR_PORT_ADD_REM 1
+#define DLPAR_MEM_ADD 2
+#define DLPAR_MEM_REM 4
+#define EHEA_CAPABILITIES (DLPAR_PORT_ADD_REM)
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
 	| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index bdb5241..383144d 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2923,6 +2923,15 @@ static int check_module_parm(void)
 	return ret;
 }
 
+static ssize_t ehea_show_capabilities(struct device_driver *drv,
+				      char *buf)
+{
+	return sprintf(buf, "%d", EHEA_CAPABILITIES);
+}
+
+static DRIVER_ATTR(capabilities, S_IRUSR | S_IRGRP | S_IROTH,
+		   ehea_show_capabilities, NULL);
+
 int __init ehea_module_init(void)
 {
 	int ret;
@@ -2934,8 +2943,19 @@ int __init ehea_module_init(void)
 	if (ret)
 		goto out;
 	ret = ibmebus_register_driver(&ehea_driver);
-	if (ret)
+	if (ret) {
 		ehea_error("failed registering eHEA device driver on ebus");
+		goto out;
+	}
+
+	ret = driver_create_file(&ehea_driver.driver,
+				 &driver_attr_capabilities);
+	if (ret) {
+		ehea_error("failed to register capabilities attribute, ret=%d",
+			   ret);
+		ibmebus_unregister_driver(&ehea_driver);
+		goto out;
+	}
 
 out:
 	return ret;
@@ -2943,6 +2963,7 @@ out:
 
 static void __exit ehea_module_exit(void)
 {
+	driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
 	ibmebus_unregister_driver(&ehea_driver);
 }
 
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index f749e07..3ca1e8e 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -352,13 +352,12 @@ static u64 nic_find(struct ioc3 *ioc3, int *last)
 
 static int nic_init(struct ioc3 *ioc3)
 {
-	const char *type;
+	const char *unknown = "unknown";
+	const char *type = unknown;
 	u8 crc;
 	u8 serial[6];
 	int save = 0, i;
 
-	type = "unknown";
-
 	while (1) {
 		u64 reg;
 		reg = nic_find(ioc3, &save);
@@ -392,7 +391,7 @@ static int nic_init(struct ioc3 *ioc3)
 	}
 
 	printk("Found %s NIC", type);
-	if (type != "unknown") {
+	if (type != unknown) {
 		printk (" registration number %02x:%02x:%02x:%02x:%02x:%02x,"
 			" CRC %02x", serial[0], serial[1], serial[2],
 			serial[3], serial[4], serial[5], crc);
@@ -1103,20 +1102,28 @@ static int ioc3_close(struct net_device *dev)
  * MiniDINs; all other subdevices are left swinging in the wind, leave
  * them disabled.
  */
-static inline int ioc3_is_menet(struct pci_dev *pdev)
+
+static int ioc3_adjacent_is_ioc3(struct pci_dev *pdev, int slot)
+{
+	struct pci_dev *dev = pci_get_slot(pdev->bus, PCI_DEVFN(slot, 0));
+	int ret = 0;
+
+	if (dev) {
+		if (dev->vendor == PCI_VENDOR_ID_SGI &&
+			dev->device == PCI_DEVICE_ID_SGI_IOC3)
+			ret = 1;
+		pci_dev_put(dev);
+	}
+
+	return ret;
+}
+
+static int ioc3_is_menet(struct pci_dev *pdev)
 {
-	struct pci_dev *dev;
-
-	return pdev->bus->parent == NULL
-	       && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(0, 0)))
-	       && dev->vendor == PCI_VENDOR_ID_SGI
-	       && dev->device == PCI_DEVICE_ID_SGI_IOC3
-	       && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(1, 0)))
-	       && dev->vendor == PCI_VENDOR_ID_SGI
-	       && dev->device == PCI_DEVICE_ID_SGI_IOC3
-	       && (dev = pci_find_slot(pdev->bus->number, PCI_DEVFN(2, 0)))
-	       && dev->vendor == PCI_VENDOR_ID_SGI
-	       && dev->device == PCI_DEVICE_ID_SGI_IOC3;
+	return pdev->bus->parent == NULL &&
+	       ioc3_adjacent_is_ioc3(pdev, 0) &&
+	       ioc3_adjacent_is_ioc3(pdev, 1) &&
+	       ioc3_adjacent_is_ioc3(pdev, 2);
 }
 
 #ifdef CONFIG_SERIAL_8250
diff --git a/drivers/net/macmace.c b/drivers/net/macmace.c
index fef3193..9a343b9 100644
--- a/drivers/net/macmace.c
+++ b/drivers/net/macmace.c
@@ -577,7 +577,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
 	struct mace_data *mp = netdev_priv(dev);
 	volatile struct mace *mb = mp->mace;
 	int intr, fs;
-	unsigned int flags;
+	unsigned long flags;
 
 	/* don't want the dma interrupt handler to fire */
 	local_irq_save(flags);
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index d0cc122..e1732c1 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -60,6 +60,7 @@
 #include <linux/crc32.h>
 #include <linux/moduleparam.h>
 #include <linux/io.h>
+#include <linux/log2.h>
 #include <net/checksum.h>
 #include <asm/byteorder.h>
 #include <asm/io.h>
@@ -1804,7 +1805,7 @@ static int myri10ge_open(struct net_device *dev)
 	 */
 	big_pow2 = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD;
 	if (big_pow2 < MYRI10GE_ALLOC_SIZE / 2) {
-		while ((big_pow2 & (big_pow2 - 1)) != 0)
+		while (!is_power_of_2(big_pow2))
 			big_pow2++;
 		mgp->big_bytes = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD;
 	} else {
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 6195037..325269d 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1097,109 +1097,6 @@ int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
 int netxen_nic_set_mac(struct net_device *netdev, void *p);
 struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev);
 
-static inline void netxen_nic_disable_int(struct netxen_adapter *adapter)
-{
-	uint32_t	mask = 0x7ff;
-	int retries = 32;
-
-	DPRINTK(1, INFO, "Entered ISR Disable \n");
-
-	switch (adapter->portnum) {
-	case 0:
-		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
-		break;
-	case 1:
-		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
-		break;
-	case 2:
-		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
-		break;
-	case 3:
-		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
-		break;
-	}
-
-	if (adapter->intr_scheme != -1 &&
-		adapter->intr_scheme != INTR_SCHEME_PERPORT) {
-		writel(mask,
-			(void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
-	}
-
-	/* Window = 0 or 1 */
-	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
-		do {
-			writel(0xffffffff, (void *)
-				(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS)));
-			mask = readl((void *)
-					(pci_base_offset(adapter, ISR_INT_VECTOR)));
-			if (!(mask & 0x80))
-				break;
-			udelay(10);
-		} while (--retries);
-
-		if (!retries) {
-			printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
-					netxen_nic_driver_name);
-		}
-	}
-
-	DPRINTK(1, INFO, "Done with Disable Int\n");
-
-	return;
-}
-
-static inline void netxen_nic_enable_int(struct netxen_adapter *adapter)
-{
-	u32 mask;
-
-	DPRINTK(1, INFO, "Entered ISR Enable \n");
-
-	if (adapter->intr_scheme != -1 &&
-		adapter->intr_scheme != INTR_SCHEME_PERPORT) {
-		switch (adapter->ahw.board_type) {
-		case NETXEN_NIC_GBE:
-			mask  =  0x77b;
-			break;
-		case NETXEN_NIC_XGBE:
-			mask  =  0x77f;
-			break;
-		default:
-			mask  =  0x7ff;
-			break;
-		}
-
-		writel(mask,
-			(void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK)));
-	}
-	switch (adapter->portnum) {
-	case 0:
-		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
-		break;
-	case 1:
-		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
-		break;
-	case 2:
-		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
-		break;
-	case 3:
-		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
-		break;
-	}
-
-	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
-		mask = 0xbff;
-		if (adapter->intr_scheme != -1 &&
-			adapter->intr_scheme != INTR_SCHEME_PERPORT) {
-			writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
-		}
-		writel(mask,
-			(void *)(PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK)));
-	}
-
-	DPRINTK(1, INFO, "Done with enable Int\n");
-
-	return;
-}
 
 /*
  * NetXen Board information
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index a66ff58..56f8197 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -156,6 +156,103 @@ static inline void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter
 #define	ADAPTER_LIST_SIZE 12
 int netxen_cards_found;
 
+static void netxen_nic_disable_int(struct netxen_adapter *adapter)
+{
+	uint32_t	mask = 0x7ff;
+	int retries = 32;
+
+	DPRINTK(1, INFO, "Entered ISR Disable \n");
+
+	switch (adapter->portnum) {
+	case 0:
+		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
+		break;
+	case 1:
+		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
+		break;
+	case 2:
+		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
+		break;
+	case 3:
+		writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
+		break;
+	}
+
+	if (adapter->intr_scheme != -1 &&
+	    adapter->intr_scheme != INTR_SCHEME_PERPORT)
+		writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+
+	/* Window = 0 or 1 */
+	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+		do {
+			writel(0xffffffff,
+			       PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_STATUS));
+			mask = readl(pci_base_offset(adapter, ISR_INT_VECTOR));
+			if (!(mask & 0x80))
+				break;
+			udelay(10);
+		} while (--retries);
+
+		if (!retries) {
+			printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
+					netxen_nic_driver_name);
+		}
+	}
+
+	DPRINTK(1, INFO, "Done with Disable Int\n");
+}
+
+static void netxen_nic_enable_int(struct netxen_adapter *adapter)
+{
+	u32 mask;
+
+	DPRINTK(1, INFO, "Entered ISR Enable \n");
+
+	if (adapter->intr_scheme != -1 &&
+		adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+		switch (adapter->ahw.board_type) {
+		case NETXEN_NIC_GBE:
+			mask  =  0x77b;
+			break;
+		case NETXEN_NIC_XGBE:
+			mask  =  0x77f;
+			break;
+		default:
+			mask  =  0x7ff;
+			break;
+		}
+
+		writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
+	}
+
+	switch (adapter->portnum) {
+	case 0:
+		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
+		break;
+	case 1:
+		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
+		break;
+	case 2:
+		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
+		break;
+	case 3:
+		writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
+		break;
+	}
+
+	if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
+		mask = 0xbff;
+		if (adapter->intr_scheme != -1 &&
+			adapter->intr_scheme != INTR_SCHEME_PERPORT) {
+			writel(0X0, NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+		}
+		writel(mask,
+		       PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_TARGET_MASK));
+	}
+
+	DPRINTK(1, INFO, "Done with enable Int\n");
+}
+
 /*
  * netxen_nic_probe()
  *
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index f2613c2..63de89e 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1581,6 +1581,7 @@ static struct pcmcia_device_id pcnet_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1103),
 	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1121),
 	PCMCIA_DEVICE_PROD_ID12("2408LAN", "Ethernet", 0x352fff7f, 0x00b2e941),
+	PCMCIA_DEVICE_PROD_ID1234("Socket", "CF 10/100 Ethernet Card", "Revision B", "05/11/06", 0xb38bcc2e, 0x4de88352, 0xeaca6c8d, 0x7e57c22e),
 	PCMCIA_DEVICE_PROD_ID123("Cardwell", "PCMCIA", "ETHERNET", 0x9533672e, 0x281f1c5d, 0x3ff7175b),
 	PCMCIA_DEVICE_PROD_ID123("CNet  ", "CN30BC", "ETHERNET", 0x9fe55d3d, 0x85601198, 0x3ff7175b),
 	PCMCIA_DEVICE_PROD_ID123("Digital", "Ethernet", "Adapter", 0x9999ab35, 0x00b2e941, 0x4b0d829e),
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index fbe1104..d2ede5f 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -254,77 +254,84 @@ static int m88e1145_config_init(struct phy_device *phydev)
 	return 0;
 }
 
-static struct phy_driver m88e1101_driver = {
-	.phy_id = 0x01410c60,
-	.phy_id_mask = 0xfffffff0,
-	.name = "Marvell 88E1101",
-	.features = PHY_GBIT_FEATURES,
-	.flags = PHY_HAS_INTERRUPT,
-	.config_aneg = &marvell_config_aneg,
-	.read_status = &genphy_read_status,
-	.ack_interrupt = &marvell_ack_interrupt,
-	.config_intr = &marvell_config_intr,
-	.driver = {.owner = THIS_MODULE,},
-};
-
-static struct phy_driver m88e1111_driver = {
-	.phy_id = 0x01410cc0,
-	.phy_id_mask = 0xfffffff0,
-	.name = "Marvell 88E1111",
-	.features = PHY_GBIT_FEATURES,
-	.flags = PHY_HAS_INTERRUPT,
-	.config_aneg = &marvell_config_aneg,
-	.read_status = &genphy_read_status,
-	.ack_interrupt = &marvell_ack_interrupt,
-	.config_intr = &marvell_config_intr,
-	.config_init = &m88e1111_config_init,
-	.driver = {.owner = THIS_MODULE,},
-};
-
-static struct phy_driver m88e1145_driver = {
-	.phy_id = 0x01410cd0,
-	.phy_id_mask = 0xfffffff0,
-	.name = "Marvell 88E1145",
-	.features = PHY_GBIT_FEATURES,
-	.flags = PHY_HAS_INTERRUPT,
-	.config_init = &m88e1145_config_init,
-	.config_aneg = &marvell_config_aneg,
-	.read_status = &genphy_read_status,
-	.ack_interrupt = &marvell_ack_interrupt,
-	.config_intr = &marvell_config_intr,
-	.driver = {.owner = THIS_MODULE,},
+static struct phy_driver marvell_drivers[] = {
+	{
+		.phy_id = 0x01410c60,
+		.phy_id_mask = 0xfffffff0,
+		.name = "Marvell 88E1101",
+		.features = PHY_GBIT_FEATURES,
+		.flags = PHY_HAS_INTERRUPT,
+		.config_aneg = &marvell_config_aneg,
+		.read_status = &genphy_read_status,
+		.ack_interrupt = &marvell_ack_interrupt,
+		.config_intr = &marvell_config_intr,
+		.driver = {.owner = THIS_MODULE,},
+	},
+	{
+		.phy_id = 0x01410c90,
+		.phy_id_mask = 0xfffffff0,
+		.name = "Marvell 88E1112",
+		.features = PHY_GBIT_FEATURES,
+		.flags = PHY_HAS_INTERRUPT,
+		.config_init = &m88e1111_config_init,
+		.config_aneg = &marvell_config_aneg,
+		.read_status = &genphy_read_status,
+		.ack_interrupt = &marvell_ack_interrupt,
+		.config_intr = &marvell_config_intr,
+		.driver = {.owner = THIS_MODULE,},
+	},
+	{
+		.phy_id = 0x01410cc0,
+		.phy_id_mask = 0xfffffff0,
+		.name = "Marvell 88E1111",
+		.features = PHY_GBIT_FEATURES,
+		.flags = PHY_HAS_INTERRUPT,
+		.config_init = &m88e1111_config_init,
+		.config_aneg = &marvell_config_aneg,
+		.read_status = &genphy_read_status,
+		.ack_interrupt = &marvell_ack_interrupt,
+		.config_intr = &marvell_config_intr,
+		.driver = {.owner = THIS_MODULE,},
+	},
+	{
+		.phy_id = 0x01410cd0,
+		.phy_id_mask = 0xfffffff0,
+		.name = "Marvell 88E1145",
+		.features = PHY_GBIT_FEATURES,
+		.flags = PHY_HAS_INTERRUPT,
+		.config_init = &m88e1145_config_init,
+		.config_aneg = &marvell_config_aneg,
+		.read_status = &genphy_read_status,
+		.ack_interrupt = &marvell_ack_interrupt,
+		.config_intr = &marvell_config_intr,
+		.driver = {.owner = THIS_MODULE,},
+	}
 };
 
 static int __init marvell_init(void)
 {
 	int ret;
+	int i;
 
-	ret = phy_driver_register(&m88e1101_driver);
-	if (ret)
-		return ret;
+	for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) {
+		ret = phy_driver_register(&marvell_drivers[i]);
 
-	ret = phy_driver_register(&m88e1111_driver);
-	if (ret)
-		goto err1111;
-
-	ret = phy_driver_register(&m88e1145_driver);
-	if (ret)
-		goto err1145;
+		if (ret) {
+			while (i-- > 0)
+				phy_driver_unregister(&marvell_drivers[i]);
+			return ret;
+		}
+	}
 
 	return 0;
-
-err1145:
-	phy_driver_unregister(&m88e1111_driver);
-err1111:
-	phy_driver_unregister(&m88e1101_driver);
-	return ret;
 }
 
 static void __exit marvell_exit(void)
 {
-	phy_driver_unregister(&m88e1101_driver);
-	phy_driver_unregister(&m88e1111_driver);
-	phy_driver_unregister(&m88e1145_driver);
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++)
+		phy_driver_unregister(&marvell_drivers[i]);
 }
 
 module_init(marvell_init);
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
new file mode 100644
index 0000000..08d2506
--- /dev/null
+++ b/drivers/net/ps3_gelic_net.c
@@ -0,0 +1,1576 @@
+/*
+ *  PS3 gelic network driver.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation
+ *
+ * This file is based on: spider_net.c
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Authors : Utz Bacher <utz.bacher@de.ibm.com>
+ *           Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/if_vlan.h>
+
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+
+#include <linux/dma-mapping.h>
+#include <net/checksum.h>
+#include <asm/firmware.h>
+#include <asm/ps3.h>
+#include <asm/lv1call.h>
+
+#include "ps3_gelic_net.h"
+
+#define DRV_NAME "Gelic Network Driver"
+#define DRV_VERSION "1.0"
+
+MODULE_AUTHOR("SCE Inc.");
+MODULE_DESCRIPTION("Gelic Network driver");
+MODULE_LICENSE("GPL");
+
+static inline struct device *ctodev(struct gelic_net_card *card)
+{
+	return &card->dev->core;
+}
+static inline unsigned int bus_id(struct gelic_net_card *card)
+{
+	return card->dev->bus_id;
+}
+static inline unsigned int dev_id(struct gelic_net_card *card)
+{
+	return card->dev->dev_id;
+}
+
+/* set irq_mask */
+static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask)
+{
+	int status;
+
+	status = lv1_net_set_interrupt_mask(bus_id(card), dev_id(card),
+					    mask, 0);
+	if (status)
+		dev_info(ctodev(card),
+			 "lv1_net_set_interrupt_mask failed %d\n", status);
+	return status;
+}
+static inline void gelic_net_rx_irq_on(struct gelic_net_card *card)
+{
+	gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT);
+}
+static inline void gelic_net_rx_irq_off(struct gelic_net_card *card)
+{
+	gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT);
+}
+/**
+ * gelic_net_get_descr_status -- returns the status of a descriptor
+ * @descr: descriptor to look at
+ *
+ * returns the status as in the dmac_cmd_status field of the descriptor
+ */
+static enum gelic_net_descr_status
+gelic_net_get_descr_status(struct gelic_net_descr *descr)
+{
+	u32 cmd_status;
+
+	cmd_status = descr->dmac_cmd_status;
+	cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT;
+	return cmd_status;
+}
+
+/**
+ * gelic_net_set_descr_status -- sets the status of a descriptor
+ * @descr: descriptor to change
+ * @status: status to set in the descriptor
+ *
+ * changes the status to the specified value. Doesn't change other bits
+ * in the status
+ */
+static void gelic_net_set_descr_status(struct gelic_net_descr *descr,
+				       enum gelic_net_descr_status status)
+{
+	u32 cmd_status;
+
+	/* read the status */
+	cmd_status = descr->dmac_cmd_status;
+	/* clean the upper 4 bits */
+	cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO;
+	/* add the status to it */
+	cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT;
+	/* and write it back */
+	descr->dmac_cmd_status = cmd_status;
+	/*
+	 * dma_cmd_status field is used to indicate whether the descriptor
+	 * is valid or not.
+	 * Usually caller of this function wants to inform that to the
+	 * hardware, so we assure here the hardware sees the change.
+	 */
+	wmb();
+}
+
+/**
+ * gelic_net_free_chain - free descriptor chain
+ * @card: card structure
+ * @descr_in: address of desc
+ */
+static void gelic_net_free_chain(struct gelic_net_card *card,
+				 struct gelic_net_descr *descr_in)
+{
+	struct gelic_net_descr *descr;
+
+	for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) {
+		dma_unmap_single(ctodev(card), descr->bus_addr,
+				 GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL);
+		descr->bus_addr = 0;
+	}
+}
+
+/**
+ * gelic_net_init_chain - links descriptor chain
+ * @card: card structure
+ * @chain: address of chain
+ * @start_descr: address of descriptor array
+ * @no: number of descriptors
+ *
+ * we manage a circular list that mirrors the hardware structure,
+ * except that the hardware uses bus addresses.
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_init_chain(struct gelic_net_card *card,
+				struct gelic_net_descr_chain *chain,
+				struct gelic_net_descr *start_descr, int no)
+{
+	int i;
+	struct gelic_net_descr *descr;
+
+	descr = start_descr;
+	memset(descr, 0, sizeof(*descr) * no);
+
+	/* set up the hardware pointers in each descriptor */
+	for (i = 0; i < no; i++, descr++) {
+		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+		descr->bus_addr =
+			dma_map_single(ctodev(card), descr,
+				       GELIC_NET_DESCR_SIZE,
+				       DMA_BIDIRECTIONAL);
+
+		if (!descr->bus_addr)
+			goto iommu_error;
+
+		descr->next = descr + 1;
+		descr->prev = descr - 1;
+	}
+	/* make them as ring */
+	(descr - 1)->next = start_descr;
+	start_descr->prev = (descr - 1);
+
+	/* chain bus addr of hw descriptor */
+	descr = start_descr;
+	for (i = 0; i < no; i++, descr++) {
+		descr->next_descr_addr = descr->next->bus_addr;
+	}
+
+	chain->head = start_descr;
+	chain->tail = start_descr;
+
+	/* do not chain last hw descriptor */
+	(descr - 1)->next_descr_addr = 0;
+
+	return 0;
+
+iommu_error:
+	for (i--, descr--; 0 <= i; i--, descr--)
+		if (descr->bus_addr)
+			dma_unmap_single(ctodev(card), descr->bus_addr,
+					 GELIC_NET_DESCR_SIZE,
+					 DMA_BIDIRECTIONAL);
+	return -ENOMEM;
+}
+
+/**
+ * gelic_net_prepare_rx_descr - reinitializes a rx descriptor
+ * @card: card structure
+ * @descr: descriptor to re-init
+ *
+ * return 0 on succes, <0 on failure
+ *
+ * allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
+ * Activate the descriptor state-wise
+ */
+static int gelic_net_prepare_rx_descr(struct gelic_net_card *card,
+				      struct gelic_net_descr *descr)
+{
+	int offset;
+	unsigned int bufsize;
+
+	if (gelic_net_get_descr_status(descr) !=  GELIC_NET_DESCR_NOT_IN_USE) {
+		dev_info(ctodev(card), "%s: ERROR status \n", __func__);
+	}
+	/* we need to round up the buffer size to a multiple of 128 */
+	bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);
+
+	/* and we need to have it 128 byte aligned, therefore we allocate a
+	 * bit more */
+	descr->skb = netdev_alloc_skb(card->netdev,
+		bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+	if (!descr->skb) {
+		descr->buf_addr = 0; /* tell DMAC don't touch memory */
+		dev_info(ctodev(card),
+			 "%s:allocate skb failed !!\n", __func__);
+		return -ENOMEM;
+	}
+	descr->buf_size = bufsize;
+	descr->dmac_cmd_status = 0;
+	descr->result_size = 0;
+	descr->valid_size = 0;
+	descr->data_error = 0;
+
+	offset = ((unsigned long)descr->skb->data) &
+		(GELIC_NET_RXBUF_ALIGN - 1);
+	if (offset)
+		skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
+	/* io-mmu-map the skb */
+	descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data,
+					 GELIC_NET_MAX_MTU,
+					 DMA_FROM_DEVICE);
+	if (!descr->buf_addr) {
+		dev_kfree_skb_any(descr->skb);
+		descr->skb = NULL;
+		dev_info(ctodev(card),
+			 "%s:Could not iommu-map rx buffer\n", __func__);
+		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+		return -ENOMEM;
+	} else {
+		gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED);
+		return 0;
+	}
+}
+
+/**
+ * gelic_net_release_rx_chain - free all skb of rx descr
+ * @card: card structure
+ *
+ */
+static void gelic_net_release_rx_chain(struct gelic_net_card *card)
+{
+	struct gelic_net_descr *descr = card->rx_chain.head;
+
+	do {
+		if (descr->skb) {
+			dma_unmap_single(ctodev(card),
+					 descr->buf_addr,
+					 descr->skb->len,
+					 DMA_FROM_DEVICE);
+			descr->buf_addr = 0;
+			dev_kfree_skb_any(descr->skb);
+			descr->skb = NULL;
+			descr->dmac_cmd_status = GELIC_NET_DESCR_NOT_IN_USE;
+		}
+		descr = descr->next;
+	} while (descr != card->rx_chain.head);
+}
+
+/**
+ * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains
+ * @card: card structure
+ *
+ * fills all descriptors in the rx chain: allocates skbs
+ * and iommu-maps them.
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_fill_rx_chain(struct gelic_net_card *card)
+{
+	struct gelic_net_descr *descr = card->rx_chain.head;
+	int ret;
+
+	do {
+		if (!descr->skb) {
+			ret = gelic_net_prepare_rx_descr(card, descr);
+			if (ret)
+				goto rewind;
+		}
+		descr = descr->next;
+	} while (descr != card->rx_chain.head);
+
+	return 0;
+rewind:
+	gelic_net_release_rx_chain(card);
+	return ret;
+}
+
+/**
+ * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
+ * @card: card structure
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card)
+{
+	struct gelic_net_descr_chain *chain;
+	int ret;
+	chain = &card->rx_chain;
+	ret = gelic_net_fill_rx_chain(card);
+	chain->head = card->rx_top->prev; /* point to the last */
+	return ret;
+}
+
+/**
+ * gelic_net_release_tx_descr - processes a used tx descriptor
+ * @card: card structure
+ * @descr: descriptor to release
+ *
+ * releases a used tx descriptor (unmapping, freeing of skb)
+ */
+static void gelic_net_release_tx_descr(struct gelic_net_card *card,
+			    struct gelic_net_descr *descr)
+{
+	struct sk_buff *skb;
+
+
+	if (descr->data_status & (1 << GELIC_NET_TXDESC_TAIL)) {
+		/* 2nd descriptor */
+		skb = descr->skb;
+		dma_unmap_single(ctodev(card), descr->buf_addr, skb->len,
+				 DMA_TO_DEVICE);
+		dev_kfree_skb_any(skb);
+	} else {
+		dma_unmap_single(ctodev(card), descr->buf_addr,
+				 descr->buf_size, DMA_TO_DEVICE);
+	}
+
+	descr->buf_addr = 0;
+	descr->buf_size = 0;
+	descr->next_descr_addr = 0;
+	descr->result_size = 0;
+	descr->valid_size = 0;
+	descr->data_status = 0;
+	descr->data_error = 0;
+	descr->skb = NULL;
+
+	/* set descr status */
+	descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE;
+}
+
+/**
+ * gelic_net_release_tx_chain - processes sent tx descriptors
+ * @card: adapter structure
+ * @stop: net_stop sequence
+ *
+ * releases the tx descriptors that gelic has finished with
+ */
+static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
+{
+	struct gelic_net_descr_chain *tx_chain;
+	enum gelic_net_descr_status status;
+	int release = 0;
+
+	for (tx_chain = &card->tx_chain;
+	     tx_chain->head != tx_chain->tail && tx_chain->tail;
+	     tx_chain->tail = tx_chain->tail->next) {
+		status = gelic_net_get_descr_status(tx_chain->tail);
+		switch (status) {
+		case GELIC_NET_DESCR_RESPONSE_ERROR:
+		case GELIC_NET_DESCR_PROTECTION_ERROR:
+		case GELIC_NET_DESCR_FORCE_END:
+			if (printk_ratelimit())
+				dev_info(ctodev(card),
+					 "%s: forcing end of tx descriptor " \
+					 "with status %x\n",
+					 __func__, status);
+			card->netdev_stats.tx_dropped++;
+			break;
+
+		case GELIC_NET_DESCR_COMPLETE:
+			card->netdev_stats.tx_packets++;
+			card->netdev_stats.tx_bytes +=
+				tx_chain->tail->skb->len;
+			break;
+
+		case GELIC_NET_DESCR_CARDOWNED:
+			/* pending tx request */
+		default:
+			/* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
+			goto out;
+		}
+		gelic_net_release_tx_descr(card, tx_chain->tail);
+		release = 1;
+	}
+out:
+	if (!stop && release)
+		netif_wake_queue(card->netdev);
+}
+
+/**
+ * gelic_net_set_multi - sets multicast addresses and promisc flags
+ * @netdev: interface device structure
+ *
+ * gelic_net_set_multi configures multicast addresses as needed for the
+ * netdev interface. It also sets up multicast, allmulti and promisc
+ * flags appropriately
+ */
+static void gelic_net_set_multi(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	struct dev_mc_list *mc;
+	unsigned int i;
+	uint8_t *p;
+	u64 addr;
+	int status;
+
+	/* clear all multicast address */
+	status = lv1_net_remove_multicast_address(bus_id(card), dev_id(card),
+						  0, 1);
+	if (status)
+		dev_err(ctodev(card),
+			"lv1_net_remove_multicast_address failed %d\n",
+			status);
+	/* set broadcast address */
+	status = lv1_net_add_multicast_address(bus_id(card), dev_id(card),
+					       GELIC_NET_BROADCAST_ADDR, 0);
+	if (status)
+		dev_err(ctodev(card),
+			"lv1_net_add_multicast_address failed, %d\n",
+			status);
+
+	if (netdev->flags & IFF_ALLMULTI
+		|| netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */
+		status = lv1_net_add_multicast_address(bus_id(card),
+						       dev_id(card),
+						       0, 1);
+		if (status)
+			dev_err(ctodev(card),
+				"lv1_net_add_multicast_address failed, %d\n",
+				status);
+		return;
+	}
+
+	/* set multicast address */
+	for (mc = netdev->mc_list; mc; mc = mc->next) {
+		addr = 0;
+		p = mc->dmi_addr;
+		for (i = 0; i < ETH_ALEN; i++) {
+			addr <<= 8;
+			addr |= *p++;
+		}
+		status = lv1_net_add_multicast_address(bus_id(card),
+						       dev_id(card),
+						       addr, 0);
+		if (status)
+			dev_err(ctodev(card),
+				"lv1_net_add_multicast_address failed, %d\n",
+				status);
+	}
+}
+
+/**
+ * gelic_net_enable_rxdmac - enables the receive DMA controller
+ * @card: card structure
+ *
+ * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
+ * in the GDADMACCNTR register
+ */
+static inline void gelic_net_enable_rxdmac(struct gelic_net_card *card)
+{
+	int status;
+
+	status = lv1_net_start_rx_dma(bus_id(card), dev_id(card),
+				card->rx_chain.tail->bus_addr, 0);
+	if (status)
+		dev_info(ctodev(card),
+			 "lv1_net_start_rx_dma failed, status=%d\n", status);
+}
+
+/**
+ * gelic_net_disable_rxdmac - disables the receive DMA controller
+ * @card: card structure
+ *
+ * gelic_net_disable_rxdmac terminates processing on the DMA controller by
+ * turing off DMA and issueing a force end
+ */
+static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card)
+{
+	int status;
+
+	/* this hvc blocks until the DMA in progress really stopped */
+	status = lv1_net_stop_rx_dma(bus_id(card), dev_id(card), 0);
+	if (status)
+		dev_err(ctodev(card),
+			"lv1_net_stop_rx_dma faild, %d\n", status);
+}
+
+/**
+ * gelic_net_disable_txdmac - disables the transmit DMA controller
+ * @card: card structure
+ *
+ * gelic_net_disable_txdmac terminates processing on the DMA controller by
+ * turing off DMA and issueing a force end
+ */
+static inline void gelic_net_disable_txdmac(struct gelic_net_card *card)
+{
+	int status;
+
+	/* this hvc blocks until the DMA in progress really stopped */
+	status = lv1_net_stop_tx_dma(bus_id(card), dev_id(card), 0);
+	if (status)
+		dev_err(ctodev(card),
+			"lv1_net_stop_tx_dma faild, status=%d\n", status);
+}
+
+/**
+ * gelic_net_stop - called upon ifconfig down
+ * @netdev: interface device structure
+ *
+ * always returns 0
+ */
+static int gelic_net_stop(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	netif_poll_disable(netdev);
+	netif_stop_queue(netdev);
+
+	/* turn off DMA, force end */
+	gelic_net_disable_rxdmac(card);
+	gelic_net_disable_txdmac(card);
+
+	gelic_net_set_irq_mask(card, 0);
+
+	/* disconnect event port */
+	free_irq(card->netdev->irq, card->netdev);
+	ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
+	card->netdev->irq = NO_IRQ;
+
+	netif_carrier_off(netdev);
+
+	/* release chains */
+	gelic_net_release_tx_chain(card, 1);
+	gelic_net_release_rx_chain(card);
+
+	gelic_net_free_chain(card, card->tx_top);
+	gelic_net_free_chain(card, card->rx_top);
+
+	return 0;
+}
+
+/**
+ * gelic_net_get_next_tx_descr - returns the next available tx descriptor
+ * @card: device structure to get descriptor from
+ *
+ * returns the address of the next descriptor, or NULL if not available.
+ */
+static struct gelic_net_descr *
+gelic_net_get_next_tx_descr(struct gelic_net_card *card)
+{
+	if (!card->tx_chain.head)
+		return NULL;
+	/*  see if we can two consecutive free descrs */
+	if (card->tx_chain.tail != card->tx_chain.head->next &&
+	    gelic_net_get_descr_status(card->tx_chain.head) ==
+	    GELIC_NET_DESCR_NOT_IN_USE &&
+	    card->tx_chain.tail != card->tx_chain.head->next->next &&
+	    gelic_net_get_descr_status(card->tx_chain.head->next) ==
+	     GELIC_NET_DESCR_NOT_IN_USE )
+		return card->tx_chain.head;
+	else
+		return NULL;
+
+}
+
+/**
+ * gelic_net_set_txdescr_cmdstat - sets the tx descriptor command field
+ * @descr: descriptor structure to fill out
+ * @skb: packet to consider
+ * @middle: middle of frame
+ *
+ * fills out the command and status field of the descriptor structure,
+ * depending on hardware checksum settings. This function assumes a wmb()
+ * has executed before.
+ */
+static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr,
+					  struct sk_buff *skb, int middle)
+{
+	u32 eofr;
+
+	if (middle)
+		eofr = 0;
+	else
+		eofr = GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+
+	if (skb->ip_summed != CHECKSUM_PARTIAL)
+		descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS | eofr;
+	else {
+		/* is packet ip?
+		 * if yes: tcp? udp? */
+		if (skb->protocol == htons(ETH_P_IP)) {
+			if (ip_hdr(skb)->protocol == IPPROTO_TCP)
+				descr->dmac_cmd_status =
+					GELIC_NET_DMAC_CMDSTAT_TCPCS | eofr;
+			else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
+				descr->dmac_cmd_status =
+					GELIC_NET_DMAC_CMDSTAT_UDPCS | eofr;
+			else	/*
+				 * the stack should checksum non-tcp and non-udp
+				 * packets on his own: NETIF_F_IP_CSUM
+				 */
+				descr->dmac_cmd_status =
+					GELIC_NET_DMAC_CMDSTAT_NOCS | eofr;
+		}
+	}
+}
+
+/**
+ * gelic_net_prepare_tx_descr_v - get dma address of skb_data
+ * @card: card structure
+ * @descr: descriptor structure
+ * @skb: packet to use
+ *
+ * returns 0 on success, <0 on failure.
+ *
+ */
+static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
+					struct gelic_net_descr *descr,
+					struct sk_buff *skb)
+{
+	dma_addr_t buf[2];
+	unsigned int vlan_len;
+
+	if (skb->len < GELIC_NET_VLAN_POS)
+		return -EINVAL;
+
+	memcpy(&descr->vlan, skb->data, GELIC_NET_VLAN_POS);
+	if (card->vlan_index != -1) {
+		descr->vlan.h_vlan_proto = htons(ETH_P_8021Q); /* vlan 0x8100*/
+		descr->vlan.h_vlan_TCI = htons(card->vlan_id[card->vlan_index]);
+		vlan_len = GELIC_NET_VLAN_POS + VLAN_HLEN; /* VLAN_HLEN=4 */
+	} else
+		vlan_len = GELIC_NET_VLAN_POS; /* no vlan tag */
+
+	/* first descr */
+	buf[0] = dma_map_single(ctodev(card), &descr->vlan,
+			     vlan_len, DMA_TO_DEVICE);
+
+	if (!buf[0]) {
+		dev_err(ctodev(card),
+			"dma map 1 failed (%p, %i). Dropping packet\n",
+			skb->data, vlan_len);
+		return -ENOMEM;
+	}
+
+	descr->buf_addr = buf[0];
+	descr->buf_size = vlan_len;
+	descr->skb = skb; /* not used */
+	descr->data_status = 0;
+	gelic_net_set_txdescr_cmdstat(descr, skb, 1); /* not the frame end */
+
+	/* second descr */
+	card->tx_chain.head = card->tx_chain.head->next;
+	descr->next_descr_addr = descr->next->bus_addr;
+	descr = descr->next;
+	if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE)
+		/* XXX will be removed */
+		dev_err(ctodev(card), "descr is not free!\n");
+
+	buf[1] = dma_map_single(ctodev(card), skb->data + GELIC_NET_VLAN_POS,
+			     skb->len - GELIC_NET_VLAN_POS,
+			     DMA_TO_DEVICE);
+
+	if (!buf[1]) {
+		dev_err(ctodev(card),
+			"dma map 2 failed (%p, %i). Dropping packet\n",
+			skb->data + GELIC_NET_VLAN_POS,
+			skb->len - GELIC_NET_VLAN_POS);
+		dma_unmap_single(ctodev(card), buf[0], vlan_len,
+				 DMA_TO_DEVICE);
+		return -ENOMEM;
+	}
+
+	descr->buf_addr = buf[1];
+	descr->buf_size = skb->len - GELIC_NET_VLAN_POS;
+	descr->skb = skb;
+	descr->data_status = 0;
+	descr->next_descr_addr = 0; /* terminate hw descr */
+	gelic_net_set_txdescr_cmdstat(descr, skb, 0);
+
+	return 0;
+}
+
+/**
+ * gelic_net_kick_txdma - enables TX DMA processing
+ * @card: card structure
+ * @descr: descriptor address to enable TX processing at
+ *
+ */
+static int gelic_net_kick_txdma(struct gelic_net_card *card,
+				struct gelic_net_descr *descr)
+{
+	int status = -ENXIO;
+	int count = 10;
+
+	if (card->tx_dma_progress)
+		return 0;
+
+	if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) {
+		card->tx_dma_progress = 1;
+		/* sometimes we need retry here */
+		while (count--) {
+			status = lv1_net_start_tx_dma(bus_id(card),
+						      dev_id(card),
+						      descr->bus_addr, 0);
+			if (!status)
+				break;
+		}
+		if (!count)
+			dev_info(ctodev(card), "lv1_net_start_txdma failed," \
+				"status=%d %#lx\n",
+				 status, card->irq_status);
+	}
+	return status;
+}
+
+/**
+ * gelic_net_xmit - transmits a frame over the device
+ * @skb: packet to send out
+ * @netdev: interface device structure
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	struct gelic_net_descr *descr = NULL;
+	int result;
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->tx_dma_lock, flags);
+
+	gelic_net_release_tx_chain(card, 0);
+	if (!skb)
+		goto kick;
+	descr = gelic_net_get_next_tx_descr(card);
+	if (!descr) {
+		netif_stop_queue(netdev);
+		spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+		return NETDEV_TX_BUSY;
+	}
+	result = gelic_net_prepare_tx_descr_v(card, descr, skb);
+
+	if (result)
+		goto error;
+
+	card->tx_chain.head = card->tx_chain.head->next;
+
+	if (descr->prev)
+		descr->prev->next_descr_addr = descr->bus_addr;
+kick:
+	/*
+	 * as hardware descriptor is modified in the above lines,
+	 * ensure that the hardware sees it
+	 */
+	wmb();
+	if (gelic_net_kick_txdma(card, card->tx_chain.tail))
+		goto error;
+
+	netdev->trans_start = jiffies;
+	spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+	return NETDEV_TX_OK;
+
+error:
+	card->netdev_stats.tx_dropped++;
+	spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+	return NETDEV_TX_LOCKED;
+}
+
+/**
+ * gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on
+ * @descr: descriptor to process
+ * @card: card structure
+ *
+ * iommu-unmaps the skb, fills out skb structure and passes the data to the
+ * stack. The descriptor state is not changed.
+ */
+static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
+				 struct gelic_net_card *card)
+{
+	struct sk_buff *skb;
+	struct net_device *netdev;
+	u32 data_status, data_error;
+
+	data_status = descr->data_status;
+	data_error = descr->data_error;
+	netdev = card->netdev;
+	/* unmap skb buffer */
+	skb = descr->skb;
+	dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU,
+			 DMA_FROM_DEVICE);
+
+	skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size);
+	if (!descr->valid_size)
+		dev_info(ctodev(card), "buffer full %x %x %x\n",
+			 descr->result_size, descr->buf_size,
+			 descr->dmac_cmd_status);
+
+	descr->skb = NULL;
+	/*
+	 * the card put 2 bytes vlan tag in front
+	 * of the ethernet frame
+	 */
+	skb_pull(skb, 2);
+	skb->protocol = eth_type_trans(skb, netdev);
+
+	/* checksum offload */
+	if (card->rx_csum) {
+		if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) &&
+		    (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK)))
+			skb->ip_summed = CHECKSUM_UNNECESSARY;
+		else
+			skb->ip_summed = CHECKSUM_NONE;
+	} else
+		skb->ip_summed = CHECKSUM_NONE;
+
+	/* update netdevice statistics */
+	card->netdev_stats.rx_packets++;
+	card->netdev_stats.rx_bytes += skb->len;
+
+	/* pass skb up to stack */
+	netif_receive_skb(skb);
+}
+
+/**
+ * gelic_net_decode_one_descr - processes an rx descriptor
+ * @card: card structure
+ *
+ * returns 1 if a packet has been sent to the stack, otherwise 0
+ *
+ * processes an rx descriptor by iommu-unmapping the data buffer and passing
+ * the packet up to the stack
+ */
+static int gelic_net_decode_one_descr(struct gelic_net_card *card)
+{
+	enum gelic_net_descr_status status;
+	struct gelic_net_descr_chain *chain = &card->rx_chain;
+	struct gelic_net_descr *descr = chain->tail;
+	int dmac_chain_ended;
+
+	status = gelic_net_get_descr_status(descr);
+	/* is this descriptor terminated with next_descr == NULL? */
+	dmac_chain_ended =
+		descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS;
+
+	if (status == GELIC_NET_DESCR_CARDOWNED)
+		return 0;
+
+	if (status == GELIC_NET_DESCR_NOT_IN_USE) {
+		dev_dbg(ctodev(card), "dormant descr? %p\n", descr);
+		return 0;
+	}
+
+	if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) ||
+	    (status == GELIC_NET_DESCR_PROTECTION_ERROR) ||
+	    (status == GELIC_NET_DESCR_FORCE_END)) {
+		dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
+			 status);
+		card->netdev_stats.rx_dropped++;
+		goto refill;
+	}
+
+	if ((status != GELIC_NET_DESCR_COMPLETE) &&
+	    (status != GELIC_NET_DESCR_FRAME_END)) {
+		dev_dbg(ctodev(card), "RX descriptor with state %x\n",
+			status);
+		goto refill;
+	}
+
+	/* ok, we've got a packet in descr */
+	gelic_net_pass_skb_up(descr, card); /* 1: skb_up sccess */
+
+refill:
+	descr->next_descr_addr = 0; /* unlink the descr */
+
+	/* change the descriptor state: */
+	gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+
+	/* refill one desc
+	 * FIXME: this can fail, but for now, just leave this
+	 * descriptor without skb
+	 */
+	gelic_net_prepare_rx_descr(card, descr);
+	chain->head = descr;
+	chain->tail = descr->next;
+	descr->prev->next_descr_addr = descr->bus_addr;
+
+	if (dmac_chain_ended) {
+		gelic_net_enable_rxdmac(card);
+		dev_dbg(ctodev(card), "reenable rx dma\n");
+	}
+
+	return 1;
+}
+
+/**
+ * gelic_net_poll - NAPI poll function called by the stack to return packets
+ * @netdev: interface device structure
+ * @budget: number of packets we can pass to the stack at most
+ *
+ * returns 0 if no more packets available to the driver/stack. Returns 1,
+ * if the quota is exceeded, but the driver has still packets.
+ *
+ */
+static int gelic_net_poll(struct net_device *netdev, int *budget)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	int packets_to_do, packets_done = 0;
+	int no_more_packets = 0;
+
+	packets_to_do = min(*budget, netdev->quota);
+
+	while (packets_to_do) {
+		if (gelic_net_decode_one_descr(card)) {
+			packets_done++;
+			packets_to_do--;
+		} else {
+			/* no more packets for the stack */
+			no_more_packets = 1;
+			break;
+		}
+	}
+	netdev->quota -= packets_done;
+	*budget -= packets_done;
+	if (no_more_packets) {
+		netif_rx_complete(netdev);
+		gelic_net_rx_irq_on(card);
+		return 0;
+	} else
+		return 1;
+}
+
+/**
+ * gelic_net_get_stats - get interface statistics
+ * @netdev: interface device structure
+ *
+ * returns the interface statistics residing in the gelic_net_card struct
+ */
+static struct net_device_stats *gelic_net_get_stats(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	return &card->netdev_stats;
+}
+
+/**
+ * gelic_net_change_mtu - changes the MTU of an interface
+ * @netdev: interface device structure
+ * @new_mtu: new MTU value
+ *
+ * returns 0 on success, <0 on failure
+ */
+static int gelic_net_change_mtu(struct net_device *netdev, int new_mtu)
+{
+	/* no need to re-alloc skbs or so -- the max mtu is about 2.3k
+	 * and mtu is outbound only anyway */
+	if ((new_mtu < GELIC_NET_MIN_MTU) ||
+	    (new_mtu > GELIC_NET_MAX_MTU)) {
+		return -EINVAL;
+	}
+	netdev->mtu = new_mtu;
+	return 0;
+}
+
+/**
+ * gelic_net_interrupt - event handler for gelic_net
+ */
+static irqreturn_t gelic_net_interrupt(int irq, void *ptr)
+{
+	unsigned long flags;
+	struct net_device *netdev = ptr;
+	struct gelic_net_card *card = netdev_priv(netdev);
+	u64 status;
+
+	status = card->irq_status;
+
+	if (!status)
+		return IRQ_NONE;
+
+	if (status & GELIC_NET_RXINT) {
+		gelic_net_rx_irq_off(card);
+		netif_rx_schedule(netdev);
+	}
+
+	if (status & GELIC_NET_TXINT) {
+		spin_lock_irqsave(&card->tx_dma_lock, flags);
+		card->tx_dma_progress = 0;
+		spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+		/* start pending DMA */
+		gelic_net_xmit(NULL, netdev);
+	}
+	return IRQ_HANDLED;
+}
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/**
+ * gelic_net_poll_controller - artificial interrupt for netconsole etc.
+ * @netdev: interface device structure
+ *
+ * see Documentation/networking/netconsole.txt
+ */
+static void gelic_net_poll_controller(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	gelic_net_set_irq_mask(card, 0);
+	gelic_net_interrupt(netdev->irq, netdev);
+	gelic_net_set_irq_mask(card, card->ghiintmask);
+}
+#endif /* CONFIG_NET_POLL_CONTROLLER */
+
+/**
+ * gelic_net_open_device - open device and map dma region
+ * @card: card structure
+ */
+static int gelic_net_open_device(struct gelic_net_card *card)
+{
+	int result;
+
+	result = ps3_sb_event_receive_port_setup(card->dev, PS3_BINDING_CPU_ANY,
+		&card->netdev->irq);
+
+	if (result) {
+		dev_info(ctodev(card),
+			 "%s:%d: gelic_net_open_device failed (%d)\n",
+			 __func__, __LINE__, result);
+		result = -EPERM;
+		goto fail_alloc_irq;
+	}
+
+	result = request_irq(card->netdev->irq, gelic_net_interrupt,
+			     IRQF_DISABLED, "gelic network", card->netdev);
+
+	if (result) {
+		dev_info(ctodev(card), "%s:%d: request_irq failed (%d)\n",
+			__func__, __LINE__, result);
+		goto fail_request_irq;
+	}
+
+	return 0;
+
+fail_request_irq:
+	ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
+	card->netdev->irq = NO_IRQ;
+fail_alloc_irq:
+	return result;
+}
+
+
+/**
+ * gelic_net_open - called upon ifonfig up
+ * @netdev: interface device structure
+ *
+ * returns 0 on success, <0 on failure
+ *
+ * gelic_net_open allocates all the descriptors and memory needed for
+ * operation, sets up multicast list and enables interrupts
+ */
+static int gelic_net_open(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	dev_dbg(ctodev(card), " -> %s:%d\n", __func__, __LINE__);
+
+	gelic_net_open_device(card);
+
+	if (gelic_net_init_chain(card, &card->tx_chain,
+			card->descr, GELIC_NET_TX_DESCRIPTORS))
+		goto alloc_tx_failed;
+	if (gelic_net_init_chain(card, &card->rx_chain,
+				 card->descr + GELIC_NET_RX_DESCRIPTORS,
+				 GELIC_NET_RX_DESCRIPTORS))
+		goto alloc_rx_failed;
+
+	/* head of chain */
+	card->tx_top = card->tx_chain.head;
+	card->rx_top = card->rx_chain.head;
+	dev_dbg(ctodev(card), "descr rx %p, tx %p, size %#lx, num %#x\n",
+		card->rx_top, card->tx_top, sizeof(struct gelic_net_descr),
+		GELIC_NET_RX_DESCRIPTORS);
+	/* allocate rx skbs */
+	if (gelic_net_alloc_rx_skbs(card))
+		goto alloc_skbs_failed;
+
+	card->tx_dma_progress = 0;
+	card->ghiintmask = GELIC_NET_RXINT | GELIC_NET_TXINT;
+
+	gelic_net_set_irq_mask(card, card->ghiintmask);
+	gelic_net_enable_rxdmac(card);
+
+	netif_start_queue(netdev);
+	netif_carrier_on(netdev);
+	netif_poll_enable(netdev);
+
+	return 0;
+
+alloc_skbs_failed:
+	gelic_net_free_chain(card, card->rx_top);
+alloc_rx_failed:
+	gelic_net_free_chain(card, card->tx_top);
+alloc_tx_failed:
+	return -ENOMEM;
+}
+
+#ifdef GELIC_NET_ETHTOOL
+static void gelic_net_get_drvinfo (struct net_device *netdev,
+				   struct ethtool_drvinfo *info)
+{
+	strncpy(info->driver, DRV_NAME, sizeof(info->driver) - 1);
+	strncpy(info->version, DRV_VERSION, sizeof(info->version) - 1);
+}
+
+static int gelic_net_get_settings(struct net_device *netdev,
+				  struct ethtool_cmd *cmd)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	int status;
+	u64 v1, v2;
+	int speed, duplex;
+
+	speed = duplex = -1;
+	status = lv1_net_control(bus_id(card), dev_id(card),
+			GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
+			&v1, &v2);
+	if (status) {
+		/* link down */
+	} else {
+		if (v1 & GELIC_NET_FULL_DUPLEX) {
+			duplex = DUPLEX_FULL;
+		} else {
+			duplex = DUPLEX_HALF;
+		}
+
+		if (v1 & GELIC_NET_SPEED_10 ) {
+			speed = SPEED_10;
+		} else if (v1 & GELIC_NET_SPEED_100) {
+			speed = SPEED_100;
+		} else if (v1 & GELIC_NET_SPEED_1000) {
+			speed = SPEED_1000;
+		}
+	}
+	cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg |
+			SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |
+			SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |
+			SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full;
+	cmd->advertising = cmd->supported;
+	cmd->speed = speed;
+	cmd->duplex = duplex;
+	cmd->autoneg = AUTONEG_ENABLE; /* always enabled */
+	cmd->port = PORT_TP;
+
+	return 0;
+}
+
+static u32 gelic_net_get_link(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+	int status;
+	u64 v1, v2;
+	int link;
+
+	status = lv1_net_control(bus_id(card), dev_id(card),
+			GELIC_NET_GET_ETH_PORT_STATUS, GELIC_NET_PORT, 0, 0,
+			&v1, &v2);
+	if (status)
+		return 0; /* link down */
+
+	if (v1 & GELIC_NET_LINK_UP)
+		link = 1;
+	else
+		link = 0;
+
+	return link;
+}
+
+static int gelic_net_nway_reset(struct net_device *netdev)
+{
+	if (netif_running(netdev)) {
+		gelic_net_stop(netdev);
+		gelic_net_open(netdev);
+	}
+	return 0;
+}
+
+static u32 gelic_net_get_tx_csum(struct net_device *netdev)
+{
+	return (netdev->features & NETIF_F_IP_CSUM) != 0;
+}
+
+static int gelic_net_set_tx_csum(struct net_device *netdev, u32 data)
+{
+	if (data)
+		netdev->features |= NETIF_F_IP_CSUM;
+	else
+		netdev->features &= ~NETIF_F_IP_CSUM;
+
+	return 0;
+}
+
+static u32 gelic_net_get_rx_csum(struct net_device *netdev)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	return card->rx_csum;
+}
+
+static int gelic_net_set_rx_csum(struct net_device *netdev, u32 data)
+{
+	struct gelic_net_card *card = netdev_priv(netdev);
+
+	card->rx_csum = data;
+	return 0;
+}
+
+static struct ethtool_ops gelic_net_ethtool_ops = {
+	.get_drvinfo	= gelic_net_get_drvinfo,
+	.get_settings	= gelic_net_get_settings,
+	.get_link	= gelic_net_get_link,
+	.nway_reset	= gelic_net_nway_reset,
+	.get_tx_csum	= gelic_net_get_tx_csum,
+	.set_tx_csum	= gelic_net_set_tx_csum,
+	.get_rx_csum	= gelic_net_get_rx_csum,
+	.set_rx_csum	= gelic_net_set_rx_csum,
+};
+#endif
+
+/**
+ * gelic_net_tx_timeout_task - task scheduled by the watchdog timeout
+ * function (to be called not under interrupt status)
+ * @work: work is context of tx timout task
+ *
+ * called as task when tx hangs, resets interface (if interface is up)
+ */
+static void gelic_net_tx_timeout_task(struct work_struct *work)
+{
+	struct gelic_net_card *card =
+		container_of(work, struct gelic_net_card, tx_timeout_task);
+	struct net_device *netdev = card->netdev;
+
+	dev_info(ctodev(card), "%s:Timed out. Restarting... \n", __func__);
+
+	if (!(netdev->flags & IFF_UP))
+		goto out;
+
+	netif_device_detach(netdev);
+	gelic_net_stop(netdev);
+
+	gelic_net_open(netdev);
+	netif_device_attach(netdev);
+
+out:
+	atomic_dec(&card->tx_timeout_task_counter);
+}
+
+/**
+ * gelic_net_tx_timeout - called when the tx timeout watchdog kicks in.
+ * @netdev: interface device structure
+ *
+ * called, if tx hangs. Schedules a task that resets the interface
+ */
+static void gelic_net_tx_timeout(struct net_device *netdev)
+{
+	struct gelic_net_card *card;
+
+	card = netdev_priv(netdev);
+	atomic_inc(&card->tx_timeout_task_counter);
+	if (netdev->flags & IFF_UP)
+		schedule_work(&card->tx_timeout_task);
+	else
+		atomic_dec(&card->tx_timeout_task_counter);
+}
+
+/**
+ * gelic_net_setup_netdev_ops - initialization of net_device operations
+ * @netdev: net_device structure
+ *
+ * fills out function pointers in the net_device structure
+ */
+static void gelic_net_setup_netdev_ops(struct net_device *netdev)
+{
+	netdev->open = &gelic_net_open;
+	netdev->stop = &gelic_net_stop;
+	netdev->hard_start_xmit = &gelic_net_xmit;
+	netdev->get_stats = &gelic_net_get_stats;
+	netdev->set_multicast_list = &gelic_net_set_multi;
+	netdev->change_mtu = &gelic_net_change_mtu;
+	/* tx watchdog */
+	netdev->tx_timeout = &gelic_net_tx_timeout;
+	netdev->watchdog_timeo = GELIC_NET_WATCHDOG_TIMEOUT;
+	/* NAPI */
+	netdev->poll = &gelic_net_poll;
+	netdev->weight = GELIC_NET_NAPI_WEIGHT;
+#ifdef GELIC_NET_ETHTOOL
+	netdev->ethtool_ops = &gelic_net_ethtool_ops;
+#endif
+}
+
+/**
+ * gelic_net_setup_netdev - initialization of net_device
+ * @card: card structure
+ *
+ * Returns 0 on success or <0 on failure
+ *
+ * gelic_net_setup_netdev initializes the net_device structure
+ **/
+static int gelic_net_setup_netdev(struct gelic_net_card *card)
+{
+	struct net_device *netdev = card->netdev;
+	struct sockaddr addr;
+	unsigned int i;
+	int status;
+	u64 v1, v2;
+
+	SET_MODULE_OWNER(netdev);
+	SET_NETDEV_DEV(netdev, &card->dev->core);
+	spin_lock_init(&card->tx_dma_lock);
+
+	card->rx_csum = GELIC_NET_RX_CSUM_DEFAULT;
+
+	gelic_net_setup_netdev_ops(netdev);
+
+	netdev->features = NETIF_F_IP_CSUM;
+
+	status = lv1_net_control(bus_id(card), dev_id(card),
+				 GELIC_NET_GET_MAC_ADDRESS,
+				 0, 0, 0, &v1, &v2);
+	if (status || !is_valid_ether_addr((u8 *)&v1)) {
+		dev_info(ctodev(card),
+			 "%s:lv1_net_control GET_MAC_ADDR failed %d\n",
+			 __func__, status);
+		return -EINVAL;
+	}
+	v1 <<= 16;
+	memcpy(addr.sa_data, &v1, ETH_ALEN);
+	memcpy(netdev->dev_addr, addr.sa_data, ETH_ALEN);
+	dev_info(ctodev(card), "MAC addr %02x:%02x:%02x:%02x:%02x:%02x\n",
+		 netdev->dev_addr[0], netdev->dev_addr[1],
+		 netdev->dev_addr[2], netdev->dev_addr[3],
+		 netdev->dev_addr[4], netdev->dev_addr[5]);
+
+	card->vlan_index = -1;	/* no vlan */
+	for (i = 0; i < GELIC_NET_VLAN_MAX; i++) {
+		status = lv1_net_control(bus_id(card), dev_id(card),
+					GELIC_NET_GET_VLAN_ID,
+					i + 1, /* index; one based */
+					0, 0, &v1, &v2);
+		if (status == GELIC_NET_VLAN_NO_ENTRY) {
+			dev_dbg(ctodev(card),
+				"GELIC_VLAN_ID no entry:%d, VLAN disabled\n",
+				status);
+			card->vlan_id[i] = 0;
+		} else if (status) {
+			dev_dbg(ctodev(card),
+				"%s:GELIC_NET_VLAN_ID faild, status=%d\n",
+				__func__, status);
+			card->vlan_id[i] = 0;
+		} else {
+			card->vlan_id[i] = (u32)v1;
+			dev_dbg(ctodev(card), "vlan_id:%d, %lx\n", i, v1);
+		}
+	}
+	if (card->vlan_id[GELIC_NET_VLAN_WIRED - 1])
+		card->vlan_index = GELIC_NET_VLAN_WIRED - 1;
+
+	status = register_netdev(netdev);
+	if (status) {
+		dev_err(ctodev(card), "%s:Couldn't register net_device: %d\n",
+			__func__, status);
+		return status;
+	}
+
+	return 0;
+}
+
+/**
+ * gelic_net_alloc_card - allocates net_device and card structure
+ *
+ * returns the card structure or NULL in case of errors
+ *
+ * the card and net_device structures are linked to each other
+ */
+static struct gelic_net_card *gelic_net_alloc_card(void)
+{
+	struct net_device *netdev;
+	struct gelic_net_card *card;
+	size_t alloc_size;
+
+	alloc_size = sizeof (*card) +
+		sizeof (struct gelic_net_descr) * GELIC_NET_RX_DESCRIPTORS +
+		sizeof (struct gelic_net_descr) * GELIC_NET_TX_DESCRIPTORS;
+	/*
+	 * we assume private data is allocated 32 bytes (or more) aligned
+	 * so that gelic_net_descr should be 32 bytes aligned.
+	 * Current alloc_etherdev() does do it because NETDEV_ALIGN
+	 * is 32.
+	 * check this assumption here.
+	 */
+	BUILD_BUG_ON(NETDEV_ALIGN < 32);
+	BUILD_BUG_ON(offsetof(struct gelic_net_card, irq_status) % 8);
+	BUILD_BUG_ON(offsetof(struct gelic_net_card, descr) % 32);
+
+	netdev = alloc_etherdev(alloc_size);
+	if (!netdev)
+		return NULL;
+
+	card = netdev_priv(netdev);
+	card->netdev = netdev;
+	INIT_WORK(&card->tx_timeout_task, gelic_net_tx_timeout_task);
+	init_waitqueue_head(&card->waitq);
+	atomic_set(&card->tx_timeout_task_counter, 0);
+
+	return card;
+}
+
+/**
+ * ps3_gelic_driver_probe - add a device to the control of this driver
+ */
+static int ps3_gelic_driver_probe (struct ps3_system_bus_device *dev)
+{
+	struct gelic_net_card *card = gelic_net_alloc_card();
+	int result;
+
+	if (!card) {
+		dev_info(&dev->core, "gelic_net_alloc_card failed\n");
+		result = -ENOMEM;
+		goto fail_alloc_card;
+	}
+
+	ps3_system_bus_set_driver_data(dev, card);
+	card->dev = dev;
+
+	result = ps3_open_hv_device(dev);
+
+	if (result) {
+		dev_dbg(&dev->core, "ps3_open_hv_device failed\n");
+		goto fail_open;
+	}
+
+	result = ps3_dma_region_create(dev->d_region);
+
+	if (result) {
+		dev_dbg(&dev->core, "ps3_dma_region_create failed(%d)\n",
+			result);
+		BUG_ON("check region type");
+		goto fail_dma_region;
+	}
+
+	result = lv1_net_set_interrupt_status_indicator(bus_id(card),
+							dev_id(card),
+		ps3_mm_phys_to_lpar(__pa(&card->irq_status)),
+		0);
+
+	if (result) {
+		dev_dbg(&dev->core,
+			"lv1_net_set_interrupt_status_indicator failed: %s\n",
+			ps3_result(result));
+		result = -EIO;
+		goto fail_status_indicator;
+	}
+
+	result = gelic_net_setup_netdev(card);
+
+	if (result) {
+		dev_dbg(&dev->core, "%s:%d: ps3_dma_region_create failed: "
+			"(%d)\n", __func__, __LINE__, result);
+		goto fail_setup_netdev;
+	}
+
+	return 0;
+
+fail_setup_netdev:
+	lv1_net_set_interrupt_status_indicator(bus_id(card),
+					       bus_id(card),
+					       0 , 0);
+fail_status_indicator:
+	ps3_dma_region_free(dev->d_region);
+fail_dma_region:
+	ps3_close_hv_device(dev);
+fail_open:
+	ps3_system_bus_set_driver_data(dev, NULL);
+	free_netdev(card->netdev);
+fail_alloc_card:
+	return result;
+}
+
+/**
+ * ps3_gelic_driver_remove - remove a device from the control of this driver
+ */
+
+static int ps3_gelic_driver_remove (struct ps3_system_bus_device *dev)
+{
+	struct gelic_net_card *card = ps3_system_bus_get_driver_data(dev);
+
+	wait_event(card->waitq,
+		   atomic_read(&card->tx_timeout_task_counter) == 0);
+
+	lv1_net_set_interrupt_status_indicator(bus_id(card), dev_id(card),
+					       0 , 0);
+
+	unregister_netdev(card->netdev);
+	free_netdev(card->netdev);
+
+	ps3_system_bus_set_driver_data(dev, NULL);
+
+	ps3_dma_region_free(dev->d_region);
+
+	ps3_close_hv_device(dev);
+
+	return 0;
+}
+
+static struct ps3_system_bus_driver ps3_gelic_driver = {
+	.match_id = PS3_MATCH_ID_GELIC,
+	.probe = ps3_gelic_driver_probe,
+	.remove = ps3_gelic_driver_remove,
+	.shutdown = ps3_gelic_driver_remove,
+	.core.name = "ps3_gelic_driver",
+	.core.owner = THIS_MODULE,
+};
+
+static int __init ps3_gelic_driver_init (void)
+{
+	return firmware_has_feature(FW_FEATURE_PS3_LV1)
+		? ps3_system_bus_driver_register(&ps3_gelic_driver)
+		: -ENODEV;
+}
+
+static void __exit ps3_gelic_driver_exit (void)
+{
+	ps3_system_bus_driver_unregister(&ps3_gelic_driver);
+}
+
+module_init (ps3_gelic_driver_init);
+module_exit (ps3_gelic_driver_exit);
+
+MODULE_ALIAS(PS3_MODULE_ALIAS_GELIC);
+
diff --git a/drivers/net/ps3_gelic_net.h b/drivers/net/ps3_gelic_net.h
new file mode 100644
index 0000000..5e1c286
--- /dev/null
+++ b/drivers/net/ps3_gelic_net.h
@@ -0,0 +1,239 @@
+/*
+ *  PS3 Platfom gelic network driver.
+ *
+ * Copyright (C) 2007 Sony Computer Entertainment Inc.
+ * Copyright 2006, 2007 Sony Corporation.
+ *
+ * This file is based on: spider_net.h
+ *
+ * (C) Copyright IBM Corp. 2005
+ *
+ * Authors : Utz Bacher <utz.bacher@de.ibm.com>
+ *           Jens Osterkamp <Jens.Osterkamp@de.ibm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _GELIC_NET_H
+#define _GELIC_NET_H
+
+#define GELIC_NET_DRV_NAME "Gelic Network Driver"
+#define GELIC_NET_DRV_VERSION "1.0"
+
+#define GELIC_NET_ETHTOOL               /* use ethtool */
+
+/* ioctl */
+#define GELIC_NET_GET_MODE              (SIOCDEVPRIVATE + 0)
+#define GELIC_NET_SET_MODE              (SIOCDEVPRIVATE + 1)
+
+/* descriptors */
+#define GELIC_NET_RX_DESCRIPTORS        128 /* num of descriptors */
+#define GELIC_NET_TX_DESCRIPTORS        128 /* num of descriptors */
+
+#define GELIC_NET_MAX_MTU               2308
+#define GELIC_NET_MIN_MTU               64
+#define GELIC_NET_RXBUF_ALIGN           128
+#define GELIC_NET_RX_CSUM_DEFAULT       1 /* hw chksum */
+#define GELIC_NET_WATCHDOG_TIMEOUT      5*HZ
+#define GELIC_NET_NAPI_WEIGHT           (GELIC_NET_RX_DESCRIPTORS)
+#define GELIC_NET_BROADCAST_ADDR        0xffffffffffffL
+#define GELIC_NET_VLAN_POS              (VLAN_ETH_ALEN * 2)
+#define GELIC_NET_VLAN_MAX              4
+#define GELIC_NET_MC_COUNT_MAX          32 /* multicast address list */
+
+enum gelic_net_int0_status {
+	GELIC_NET_GDTDCEINT  = 24,
+	GELIC_NET_GRFANMINT  = 28,
+};
+
+/* GHIINT1STS bits */
+enum gelic_net_int1_status {
+	GELIC_NET_GDADCEINT = 14,
+};
+
+/* interrupt mask */
+#define GELIC_NET_TXINT                   (1L << (GELIC_NET_GDTDCEINT + 32))
+
+#define GELIC_NET_RXINT0                  (1L << (GELIC_NET_GRFANMINT + 32))
+#define GELIC_NET_RXINT1                  (1L << GELIC_NET_GDADCEINT)
+#define GELIC_NET_RXINT                   (GELIC_NET_RXINT0 | GELIC_NET_RXINT1)
+
+ /* RX descriptor data_status bits */
+#define GELIC_NET_RXDMADU	0x80000000 /* destination MAC addr unknown */
+#define GELIC_NET_RXLSTFBF	0x40000000 /* last frame buffer            */
+#define GELIC_NET_RXIPCHK	0x20000000 /* IP checksum performed        */
+#define GELIC_NET_RXTCPCHK	0x10000000 /* TCP/UDP checksup performed   */
+#define GELIC_NET_RXIPSPKT	0x08000000 /* IPsec packet   */
+#define GELIC_NET_RXIPSAHPRT	0x04000000 /* IPsec AH protocol performed */
+#define GELIC_NET_RXIPSESPPRT	0x02000000 /* IPsec ESP protocol performed */
+#define GELIC_NET_RXSESPAH	0x01000000 /*
+					    * IPsec ESP protocol auth
+					    * performed
+					    */
+
+#define GELIC_NET_RXWTPKT	0x00C00000 /*
+					    * wakeup trigger packet
+					    * 01: Magic Packet (TM)
+					    * 10: ARP packet
+					    * 11: Multicast MAC addr
+					    */
+#define GELIC_NET_RXVLNPKT	0x00200000 /* VLAN packet */
+/* bit 20..16 reserved */
+#define GELIC_NET_RXRECNUM	0x0000ff00 /* reception receipt number */
+/* bit 7..0 reserved */
+
+#define GELIC_NET_TXDESC_TAIL		0
+#define GELIC_NET_DATA_STATUS_CHK_MASK	(GELIC_NET_RXIPCHK | GELIC_NET_RXTCPCHK)
+
+/* RX descriptor data_error bits */
+/* bit 31 reserved */
+#define GELIC_NET_RXALNERR	0x40000000 /* alignement error 10/100M */
+#define GELIC_NET_RXOVERERR	0x20000000 /* oversize error */
+#define GELIC_NET_RXRNTERR	0x10000000 /* Runt error */
+#define GELIC_NET_RXIPCHKERR	0x08000000 /* IP checksum  error */
+#define GELIC_NET_RXTCPCHKERR	0x04000000 /* TCP/UDP checksum  error */
+#define GELIC_NET_RXUMCHSP	0x02000000 /* unmatched sp on sp */
+#define GELIC_NET_RXUMCHSPI	0x01000000 /* unmatched SPI on SAD */
+#define GELIC_NET_RXUMCHSAD	0x00800000 /* unmatched SAD */
+#define GELIC_NET_RXIPSAHERR	0x00400000 /* auth error on AH protocol
+					    * processing */
+#define GELIC_NET_RXIPSESPAHERR	0x00200000 /* auth error on ESP protocol
+					    * processing */
+#define GELIC_NET_RXDRPPKT	0x00100000 /* drop packet */
+#define GELIC_NET_RXIPFMTERR	0x00080000 /* IP packet format error */
+/* bit 18 reserved */
+#define GELIC_NET_RXDATAERR	0x00020000 /* IP packet format error */
+#define GELIC_NET_RXCALERR	0x00010000 /* cariier extension length
+					    * error */
+#define GELIC_NET_RXCREXERR	0x00008000 /* carrier extention error */
+#define GELIC_NET_RXMLTCST	0x00004000 /* multicast address frame */
+/* bit 13..0 reserved */
+#define GELIC_NET_DATA_ERROR_CHK_MASK		\
+	(GELIC_NET_RXIPCHKERR | GELIC_NET_RXTCPCHKERR)
+
+
+/* tx descriptor command and status */
+#define GELIC_NET_DMAC_CMDSTAT_NOCS       0xa0080000 /* middle of frame */
+#define GELIC_NET_DMAC_CMDSTAT_TCPCS      0xa00a0000
+#define GELIC_NET_DMAC_CMDSTAT_UDPCS      0xa00b0000
+#define GELIC_NET_DMAC_CMDSTAT_END_FRAME  0x00040000 /* end of frame */
+
+#define GELIC_NET_DMAC_CMDSTAT_RXDCEIS	  0x00000002 /* descriptor chain end
+						      * interrupt status */
+
+#define GELIC_NET_DMAC_CMDSTAT_CHAIN_END  0x00000002 /* RXDCEIS:DMA stopped */
+#define GELIC_NET_DMAC_CMDSTAT_NOT_IN_USE 0xb0000000
+#define GELIC_NET_DESCR_IND_PROC_SHIFT    28
+#define GELIC_NET_DESCR_IND_PROC_MASKO    0x0fffffff
+
+
+enum gelic_net_descr_status {
+	GELIC_NET_DESCR_COMPLETE            = 0x00, /* used in rx and tx */
+	GELIC_NET_DESCR_RESPONSE_ERROR      = 0x01, /* used in rx and tx */
+	GELIC_NET_DESCR_PROTECTION_ERROR    = 0x02, /* used in rx and tx */
+	GELIC_NET_DESCR_FRAME_END           = 0x04, /* used in rx */
+	GELIC_NET_DESCR_FORCE_END           = 0x05, /* used in rx and tx */
+	GELIC_NET_DESCR_CARDOWNED           = 0x0a, /* used in rx and tx */
+	GELIC_NET_DESCR_NOT_IN_USE                  /* any other value */
+};
+/* for lv1_net_control */
+#define GELIC_NET_GET_MAC_ADDRESS               0x0000000000000001
+#define GELIC_NET_GET_ETH_PORT_STATUS           0x0000000000000002
+#define GELIC_NET_SET_NEGOTIATION_MODE          0x0000000000000003
+#define GELIC_NET_GET_VLAN_ID                   0x0000000000000004
+
+#define GELIC_NET_LINK_UP                       0x0000000000000001
+#define GELIC_NET_FULL_DUPLEX                   0x0000000000000002
+#define GELIC_NET_AUTO_NEG                      0x0000000000000004
+#define GELIC_NET_SPEED_10                      0x0000000000000010
+#define GELIC_NET_SPEED_100                     0x0000000000000020
+#define GELIC_NET_SPEED_1000                    0x0000000000000040
+
+#define GELIC_NET_VLAN_ALL                      0x0000000000000001
+#define GELIC_NET_VLAN_WIRED                    0x0000000000000002
+#define GELIC_NET_VLAN_WIRELESS                 0x0000000000000003
+#define GELIC_NET_VLAN_PSP                      0x0000000000000004
+#define GELIC_NET_VLAN_PORT0                    0x0000000000000010
+#define GELIC_NET_VLAN_PORT1                    0x0000000000000011
+#define GELIC_NET_VLAN_PORT2                    0x0000000000000012
+#define GELIC_NET_VLAN_DAEMON_CLIENT_BSS        0x0000000000000013
+#define GELIC_NET_VLAN_LIBERO_CLIENT_BSS        0x0000000000000014
+#define GELIC_NET_VLAN_NO_ENTRY                 -6
+
+#define GELIC_NET_PORT                          2 /* for port status */
+
+/* size of hardware part of gelic descriptor */
+#define GELIC_NET_DESCR_SIZE	(32)
+struct gelic_net_descr {
+	/* as defined by the hardware */
+	u32 buf_addr;
+	u32 buf_size;
+	u32 next_descr_addr;
+	u32 dmac_cmd_status;
+	u32 result_size;
+	u32 valid_size;	/* all zeroes for tx */
+	u32 data_status;
+	u32 data_error;	/* all zeroes for tx */
+
+	/* used in the driver */
+	struct sk_buff *skb;
+	dma_addr_t bus_addr;
+	struct gelic_net_descr *next;
+	struct gelic_net_descr *prev;
+	struct vlan_ethhdr vlan;
+} __attribute__((aligned(32)));
+
+struct gelic_net_descr_chain {
+	/* we walk from tail to head */
+	struct gelic_net_descr *head;
+	struct gelic_net_descr *tail;
+};
+
+struct gelic_net_card {
+	struct net_device *netdev;
+	/*
+	 * hypervisor requires irq_status should be
+	 * 8 bytes aligned, but u64 member is
+	 * always disposed in that manner
+	 */
+	u64 irq_status;
+	u64 ghiintmask;
+
+	struct ps3_system_bus_device *dev;
+	u32 vlan_id[GELIC_NET_VLAN_MAX];
+	int vlan_index;
+
+	struct gelic_net_descr_chain tx_chain;
+	struct gelic_net_descr_chain rx_chain;
+	/* gurad dmac descriptor chain*/
+	spinlock_t chain_lock;
+
+	struct net_device_stats netdev_stats;
+	int rx_csum;
+	/* guard tx_dma_progress */
+	spinlock_t tx_dma_lock;
+	int tx_dma_progress;
+
+	struct work_struct tx_timeout_task;
+	atomic_t tx_timeout_task_counter;
+	wait_queue_head_t waitq;
+
+	struct gelic_net_descr *tx_top, *rx_top;
+	struct gelic_net_descr descr[0];
+};
+
+
+extern unsigned long p_to_lp(long pa);
+
+#endif /* _GELIC_NET_H */
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index 25c73d4..5c2e41f 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -516,7 +516,7 @@ static unsigned int write_eeprom(struct rr_private *rrpriv,
 }
 
 
-static int __init rr_init(struct net_device *dev)
+static int __devinit rr_init(struct net_device *dev)
 {
 	struct rr_private *rrpriv;
 	struct rr_regs __iomem *regs;
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 2d826ff..fa29a40 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -8036,7 +8036,7 @@ static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro,
 /**
  * s2io_io_error_detected - called when PCI error is detected
  * @pdev: Pointer to PCI device
- * @state: The current pci conneection state
+ * @state: The current pci connection state
  *
  * This function is called after a PCI bus error affecting
  * this device has been detected.
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 2cb2e15..7c6e480 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -573,7 +573,7 @@ static int __devinit sis900_probe(struct pci_dev *pci_dev,
  *	return error if it failed to found.
  */
 
-static int __init sis900_mii_probe(struct net_device * net_dev)
+static int __devinit sis900_mii_probe(struct net_device * net_dev)
 {
 	struct sis900_private * sis_priv = net_dev->priv;
 	const char *dev_name = pci_name(sis_priv->pci_dev);

=======================================================================
SNIP snip   obvious sk98lin driver removal patches   snip SNIP
=======================================================================

diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index b51d73c..a2f3215 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -39,6 +39,7 @@
 #include <linux/workqueue.h>
 #include <linux/if_vlan.h>
 #include <linux/prefetch.h>
+#include <linux/debugfs.h>
 #include <linux/mii.h>
 
 #include <asm/irq.h>
@@ -50,7 +51,7 @@
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"1.15"
+#define DRV_VERSION		"1.16"
 #define PFX			DRV_NAME " "
 
 /*
@@ -64,7 +65,6 @@
 #define RX_MAX_PENDING		(RX_LE_SIZE/6 - 2)
 #define RX_DEF_PENDING		RX_MAX_PENDING
 #define RX_SKB_ALIGN		8
-#define RX_BUF_WRITE		16
 
 #define TX_RING_SIZE		512
 #define TX_DEF_PENDING		(TX_RING_SIZE - 1)
@@ -77,6 +77,9 @@
 #define NAPI_WEIGHT		64
 #define PHY_RETRIES		1000
 
+#define SKY2_EEPROM_MAGIC	0x9955aabb
+
+
 #define RING_NEXT(x,s)	(((x)+1) & ((s)-1))
 
 static const u32 default_msg =
@@ -96,7 +99,7 @@ static int disable_msi = 0;
 module_param(disable_msi, int, 0);
 MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)");
 
-static int idle_timeout = 0;
+static int idle_timeout = 100;
 module_param(idle_timeout, int, 0);
 MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)");
 
@@ -890,24 +893,18 @@ static inline struct sky2_rx_le *sky2_next_rx(struct sky2_port *sky2)
 	return le;
 }
 
-/* Return high part of DMA address (could be 32 or 64 bit) */
-static inline u32 high32(dma_addr_t a)
-{
-	return sizeof(a) > sizeof(u32) ? (a >> 16) >> 16 : 0;
-}
-
 /* Build description to hardware for one receive segment */
 static void sky2_rx_add(struct sky2_port *sky2,  u8 op,
 			dma_addr_t map, unsigned len)
 {
 	struct sky2_rx_le *le;
-	u32 hi = high32(map);
+	u32 hi = upper_32_bits(map);
 
 	if (sky2->rx_addr64 != hi) {
 		le = sky2_next_rx(sky2);
 		le->addr = cpu_to_le32(hi);
 		le->opcode = OP_ADDR64 | HW_OWNER;
-		sky2->rx_addr64 = high32(map + len);
+		sky2->rx_addr64 = upper_32_bits(map + len);
 	}
 
 	le = sky2_next_rx(sky2);
@@ -1137,6 +1134,11 @@ nomem:
 	return NULL;
 }
 
+static inline void sky2_rx_update(struct sky2_port *sky2, unsigned rxq)
+{
+	sky2_put_idx(sky2->hw, rxq, sky2->rx_put);
+}
+
 /*
  * Allocate and setup receiver buffer pool.
  * Normal case this ends up creating one list element for skb
@@ -1172,8 +1174,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
 	rx_set_checksum(sky2);
 
 	/* Space needed for frame data + headers rounded up */
-	size = ALIGN(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8)
-		+ 8;
+	size = roundup(sky2->netdev->mtu + ETH_HLEN + VLAN_HLEN, 8);
 
 	/* Stopping point for hardware truncation */
 	thresh = (size - 8) / sizeof(u32);
@@ -1228,7 +1229,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
 	}
 
 	/* Tell chip about available buffers */
-	sky2_put_idx(hw, rxq, sky2->rx_put);
+	sky2_rx_update(sky2, rxq);
 	return 0;
 nomem:
 	sky2_rx_clean(sky2);
@@ -1265,6 +1266,8 @@ static int sky2_up(struct net_device *dev)
 	if (netif_msg_ifup(sky2))
 		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
 
+	netif_carrier_off(dev);
+
 	/* must be power of 2 */
 	sky2->tx_le = pci_alloc_consistent(hw->pdev,
 					   TX_RING_SIZE *
@@ -1415,14 +1418,15 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 
 	len = skb_headlen(skb);
 	mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
-	addr64 = high32(mapping);
+	addr64 = upper_32_bits(mapping);
 
 	/* Send high bits if changed or crosses boundary */
-	if (addr64 != sky2->tx_addr64 || high32(mapping + len) != sky2->tx_addr64) {
+	if (addr64 != sky2->tx_addr64 ||
+	    upper_32_bits(mapping + len) != sky2->tx_addr64) {
 		le = get_tx_le(sky2);
 		le->addr = cpu_to_le32(addr64);
 		le->opcode = OP_ADDR64 | HW_OWNER;
-		sky2->tx_addr64 = high32(mapping + len);
+		sky2->tx_addr64 = upper_32_bits(mapping + len);
 	}
 
 	/* Check for TCP Segmentation Offload */
@@ -1502,7 +1506,7 @@ static int sky2_xmit_frame(struct sk_buff *skb, struct net_device *dev)
 
 		mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
 				       frag->size, PCI_DMA_TODEVICE);
-		addr64 = high32(mapping);
+		addr64 = upper_32_bits(mapping);
 		if (addr64 != sky2->tx_addr64) {
 			le = get_tx_le(sky2);
 			le->addr = cpu_to_le32(addr64);
@@ -1572,13 +1576,13 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
 			if (unlikely(netif_msg_tx_done(sky2)))
 				printk(KERN_DEBUG "%s: tx done %u\n",
 				       dev->name, idx);
+
 			sky2->net_stats.tx_packets++;
 			sky2->net_stats.tx_bytes += re->skb->len;
 
 			dev_kfree_skb_any(re->skb);
+			sky2->tx_next = RING_NEXT(idx, TX_RING_SIZE);
 		}
-
-		le->opcode = 0;	/* paranoia */
 	}
 
 	sky2->tx_cons = idx;
@@ -1616,7 +1620,6 @@ static int sky2_down(struct net_device *dev)
 
 	/* Stop more packets from being queued */
 	netif_stop_queue(dev);
-	netif_carrier_off(dev);
 
 	/* Disable port IRQ */
 	imask = sky2_read32(hw, B0_IMSK);
@@ -1668,6 +1671,8 @@ static int sky2_down(struct net_device *dev)
 
 	sky2_phy_power(hw, port, 0);
 
+	netif_carrier_off(dev);
+
 	/* turn off LED's */
 	sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
 
@@ -1732,7 +1737,6 @@ static void sky2_link_up(struct sky2_port *sky2)
 	gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
 
 	netif_carrier_on(sky2->netdev);
-	netif_wake_queue(sky2->netdev);
 
 	/* Turn on link LED */
 	sky2_write8(hw, SK_REG(port, LNK_LED_REG),
@@ -1784,7 +1788,6 @@ static void sky2_link_down(struct sky2_port *sky2)
 	gma_write16(hw, port, GM_GP_CTRL, reg);
 
 	netif_carrier_off(sky2->netdev);
-	netif_stop_queue(sky2->netdev);
 
 	/* Turn on link LED */
 	sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF);
@@ -2055,8 +2058,6 @@ static struct sk_buff *receive_new(struct sky2_port *sky2,
 	struct sk_buff *skb, *nskb;
 	unsigned hdr_space = sky2->rx_data_size;
 
-	pr_debug(PFX "receive new length=%d\n", length);
-
 	/* Don't be tricky about reusing pages (yet) */
 	nskb = sky2_rx_alloc(sky2);
 	if (unlikely(!nskb))
@@ -2100,6 +2101,9 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
 	if (!(status & GMR_FS_RX_OK))
 		goto resubmit;
 
+	if (status >> 16 != length)
+		goto len_mismatch;
+
 	if (length < copybreak)
 		skb = receive_copy(sky2, re, length);
 	else
@@ -2109,6 +2113,11 @@ resubmit:
 
 	return skb;
 
+len_mismatch:
+	/* Truncation of overlength packets
+	   causes PHY length to not match MAC length */
+	++sky2->net_stats.rx_length_errors;
+
 error:
 	++sky2->net_stats.rx_errors;
 	if (status & GMR_FS_RX_FF_OV) {
@@ -2145,14 +2154,14 @@ static inline void sky2_tx_done(struct net_device *dev, u16 last)
 /* Process status response ring */
 static int sky2_status_intr(struct sky2_hw *hw, int to_do)
 {
-	struct sky2_port *sky2;
 	int work_done = 0;
-	unsigned buf_write[2] = { 0, 0 };
+	unsigned rx[2] = { 0, 0 };
 	u16 hwidx = sky2_read16(hw, STAT_PUT_IDX);
 
 	rmb();
 
 	while (hw->st_idx != hwidx) {
+		struct sky2_port *sky2;
 		struct sky2_status_le *le  = hw->st_le + hw->st_idx;
 		unsigned port = le->css & CSS_LINK_BIT;
 		struct net_device *dev;
@@ -2169,10 +2178,11 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
 
 		switch (le->opcode & ~HW_OWNER) {
 		case OP_RXSTAT:
+			++rx[port];
 			skb = sky2_receive(dev, length, status);
 			if (unlikely(!skb)) {
 				sky2->net_stats.rx_dropped++;
-				goto force_update;
+				break;
 			}
 
 			/* This chip reports checksum status differently */
@@ -2199,13 +2209,6 @@ static int sky2_status_intr(struct sky2_hw *hw, int to_do)
 #endif
 				netif_receive_skb(skb);
 
-			/* Update receiver after 16 frames */
-			if (++buf_write[port] == RX_BUF_WRITE) {
-force_update:
-				sky2_put_idx(hw, rxqaddr[port], sky2->rx_put);
-				buf_write[port] = 0;
-			}
-
 			/* Stop after net poll weight */
 			if (++work_done >= to_do)
 				goto exit_loop;
@@ -2261,24 +2264,18 @@ force_update:
 			if (net_ratelimit())
 				printk(KERN_WARNING PFX
 				       "unknown status opcode 0x%x\n", le->opcode);
-			goto exit_loop;
 		}
 	}
 
 	/* Fully processed status ring so clear irq */
 	sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-	mmiowb();
 
 exit_loop:
-	if (buf_write[0]) {
-		sky2 = netdev_priv(hw->dev[0]);
-		sky2_put_idx(hw, Q_R1, sky2->rx_put);
-	}
+	if (rx[0])
+		sky2_rx_update(netdev_priv(hw->dev[0]), Q_R1);
 
-	if (buf_write[1]) {
-		sky2 = netdev_priv(hw->dev[1]);
-		sky2_put_idx(hw, Q_R2, sky2->rx_put);
-	}
+	if (rx[1])
+		sky2_rx_update(netdev_priv(hw->dev[1]), Q_R2);
 
 	return work_done;
 }
@@ -2475,8 +2472,7 @@ static void sky2_err_intr(struct sky2_hw *hw, u32 status)
 static int sky2_poll(struct net_device *dev0, int *budget)
 {
 	struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw;
-	int work_limit = min(dev0->quota, *budget);
-	int work_done = 0;
+	int work_done;
 	u32 status = sky2_read32(hw, B0_Y2_SP_EISR);
 
 	if (unlikely(status & Y2_IS_ERROR))
@@ -2488,18 +2484,25 @@ static int sky2_poll(struct net_device *dev0, int *budget)
 	if (status & Y2_IS_IRQ_PHY2)
 		sky2_phy_intr(hw, 1);
 
-	work_done = sky2_status_intr(hw, work_limit);
-	if (work_done < work_limit) {
-		netif_rx_complete(dev0);
+	work_done = sky2_status_intr(hw, min(dev0->quota, *budget));
+	*budget -= work_done;
+	dev0->quota -= work_done;
 
-		/* end of interrupt, re-enables also acts as I/O synchronization */
-		sky2_read32(hw, B0_Y2_SP_LISR);
-		return 0;
-	} else {
-		*budget -= work_done;
-		dev0->quota -= work_done;
+	/* More work? */
+ 	if (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX))
 		return 1;
+
+	/* Bug/Errata workaround?
+	 * Need to kick the TX irq moderation timer.
+	 */
+	if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) {
+		sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP);
+		sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START);
 	}
+	netif_rx_complete(dev0);
+
+	sky2_read32(hw, B0_Y2_SP_LISR);
+	return 0;
 }
 
 static irqreturn_t sky2_intr(int irq, void *dev_id)
@@ -2723,8 +2726,6 @@ static void sky2_restart(struct work_struct *work)
 	struct net_device *dev;
 	int i, err;
 
-	dev_dbg(&hw->pdev->dev, "restarting\n");
-
 	del_timer_sync(&hw->idle_timer);
 
 	rtnl_lock();
@@ -3429,39 +3430,315 @@ static int sky2_set_tso(struct net_device *dev, u32 data)
 	return ethtool_op_set_tso(dev, data);
 }
 
+static int sky2_get_eeprom_len(struct net_device *dev)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	u16 reg2;
+
+	reg2 = sky2_pci_read32(sky2->hw, PCI_DEV_REG2);
+	return 1 << ( ((reg2 & PCI_VPD_ROM_SZ) >> 14) + 8);
+}
+
+static u32 sky2_vpd_read(struct sky2_hw *hw, int cap, u16 offset)
+{
+	sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset);
+
+	while (!(sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F))
+			cpu_relax();
+	return sky2_pci_read32(hw, cap + PCI_VPD_DATA);
+}
+
+static void sky2_vpd_write(struct sky2_hw *hw, int cap, u16 offset, u32 val)
+{
+	sky2_pci_write32(hw, cap + PCI_VPD_DATA, val);
+	sky2_pci_write16(hw, cap + PCI_VPD_ADDR, offset | PCI_VPD_ADDR_F);
+	do {
+		cpu_relax();
+	} while (sky2_pci_read16(hw, cap + PCI_VPD_ADDR) & PCI_VPD_ADDR_F);
+}
+
+static int sky2_get_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+			   u8 *data)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
+	int length = eeprom->len;
+	u16 offset = eeprom->offset;
+
+	if (!cap)
+		return -EINVAL;
+
+	eeprom->magic = SKY2_EEPROM_MAGIC;
+
+	while (length > 0) {
+		u32 val = sky2_vpd_read(sky2->hw, cap, offset);
+		int n = min_t(int, length, sizeof(val));
+
+		memcpy(data, &val, n);
+		length -= n;
+		data += n;
+		offset += n;
+	}
+	return 0;
+}
+
+static int sky2_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
+			   u8 *data)
+{
+	struct sky2_port *sky2 = netdev_priv(dev);
+	int cap = pci_find_capability(sky2->hw->pdev, PCI_CAP_ID_VPD);
+	int length = eeprom->len;
+	u16 offset = eeprom->offset;
+
+	if (!cap)
+		return -EINVAL;
+
+	if (eeprom->magic != SKY2_EEPROM_MAGIC)
+		return -EINVAL;
+
+	while (length > 0) {
+		u32 val;
+		int n = min_t(int, length, sizeof(val));
+
+		if (n < sizeof(val))
+			val = sky2_vpd_read(sky2->hw, cap, offset);
+		memcpy(&val, data, n);
+
+		sky2_vpd_write(sky2->hw, cap, offset, val);
+
+		length -= n;
+		data += n;
+		offset += n;
+	}
+	return 0;
+}
+
+
 static const struct ethtool_ops sky2_ethtool_ops = {
-	.get_settings = sky2_get_settings,
-	.set_settings = sky2_set_settings,
-	.get_drvinfo  = sky2_get_drvinfo,
-	.get_wol      = sky2_get_wol,
-	.set_wol      = sky2_set_wol,
-	.get_msglevel = sky2_get_msglevel,
-	.set_msglevel = sky2_set_msglevel,
-	.nway_reset   = sky2_nway_reset,
-	.get_regs_len = sky2_get_regs_len,
-	.get_regs = sky2_get_regs,
-	.get_link = ethtool_op_get_link,
-	.get_sg = ethtool_op_get_sg,
-	.set_sg = ethtool_op_set_sg,
-	.get_tx_csum = ethtool_op_get_tx_csum,
-	.set_tx_csum = sky2_set_tx_csum,
-	.get_tso = ethtool_op_get_tso,
-	.set_tso = sky2_set_tso,
-	.get_rx_csum = sky2_get_rx_csum,
-	.set_rx_csum = sky2_set_rx_csum,
-	.get_strings = sky2_get_strings,
-	.get_coalesce = sky2_get_coalesce,
-	.set_coalesce = sky2_set_coalesce,
-	.get_ringparam = sky2_get_ringparam,
-	.set_ringparam = sky2_set_ringparam,
+	.get_settings	= sky2_get_settings,
+	.set_settings	= sky2_set_settings,
+	.get_drvinfo	= sky2_get_drvinfo,
+	.get_wol	= sky2_get_wol,
+	.set_wol	= sky2_set_wol,
+	.get_msglevel	= sky2_get_msglevel,
+	.set_msglevel	= sky2_set_msglevel,
+	.nway_reset	= sky2_nway_reset,
+	.get_regs_len	= sky2_get_regs_len,
+	.get_regs	= sky2_get_regs,
+	.get_link	= ethtool_op_get_link,
+	.get_eeprom_len	= sky2_get_eeprom_len,
+	.get_eeprom	= sky2_get_eeprom,
+	.set_eeprom	= sky2_set_eeprom,
+	.get_sg 	= ethtool_op_get_sg,
+	.set_sg 	= ethtool_op_set_sg,
+	.get_tx_csum	= ethtool_op_get_tx_csum,
+	.set_tx_csum	= sky2_set_tx_csum,
+	.get_tso	= ethtool_op_get_tso,
+	.set_tso	= sky2_set_tso,
+	.get_rx_csum	= sky2_get_rx_csum,
+	.set_rx_csum	= sky2_set_rx_csum,
+	.get_strings	= sky2_get_strings,
+	.get_coalesce	= sky2_get_coalesce,
+	.set_coalesce	= sky2_set_coalesce,
+	.get_ringparam	= sky2_get_ringparam,
+	.set_ringparam	= sky2_set_ringparam,
 	.get_pauseparam = sky2_get_pauseparam,
 	.set_pauseparam = sky2_set_pauseparam,
-	.phys_id = sky2_phys_id,
+	.phys_id	= sky2_phys_id,
 	.get_stats_count = sky2_get_stats_count,
 	.get_ethtool_stats = sky2_get_ethtool_stats,
 	.get_perm_addr	= ethtool_op_get_perm_addr,
 };
 
+#ifdef CONFIG_SKY2_DEBUG
+
+static struct dentry *sky2_debug;
+
+static int sky2_debug_show(struct seq_file *seq, void *v)
+{
+	struct net_device *dev = seq->private;
+	const struct sky2_port *sky2 = netdev_priv(dev);
+	const struct sky2_hw *hw = sky2->hw;
+	unsigned port = sky2->port;
+	unsigned idx, last;
+	int sop;
+
+	if (!netif_running(dev))
+		return -ENETDOWN;
+
+	seq_printf(seq, "IRQ src=%x mask=%x control=%x\n",
+		   sky2_read32(hw, B0_ISRC),
+		   sky2_read32(hw, B0_IMSK),
+		   sky2_read32(hw, B0_Y2_SP_ICR));
+
+	netif_poll_disable(hw->dev[0]);
+	last = sky2_read16(hw, STAT_PUT_IDX);
+
+	if (hw->st_idx == last)
+		seq_puts(seq, "Status ring (empty)\n");
+	else {
+		seq_puts(seq, "Status ring\n");
+		for (idx = hw->st_idx; idx != last && idx < STATUS_RING_SIZE;
+		     idx = RING_NEXT(idx, STATUS_RING_SIZE)) {
+			const struct sky2_status_le *le = hw->st_le + idx;
+			seq_printf(seq, "[%d] %#x %d %#x\n",
+				   idx, le->opcode, le->length, le->status);
+		}
+		seq_puts(seq, "\n");
+	}
+
+	seq_printf(seq, "Tx ring pending=%u...%u report=%d done=%d\n",
+		   sky2->tx_cons, sky2->tx_prod,
+		   sky2_read16(hw, port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
+		   sky2_read16(hw, Q_ADDR(txqaddr[port], Q_DONE)));
+
+	/* Dump contents of tx ring */
+	sop = 1;
+	for (idx = sky2->tx_next; idx != sky2->tx_prod && idx < TX_RING_SIZE;
+	     idx = RING_NEXT(idx, TX_RING_SIZE)) {
+		const struct sky2_tx_le *le = sky2->tx_le + idx;
+		u32 a = le32_to_cpu(le->addr);
+
+		if (sop)
+			seq_printf(seq, "%u:", idx);
+		sop = 0;
+
+		switch(le->opcode & ~HW_OWNER) {
+		case OP_ADDR64:
+			seq_printf(seq, " %#x:", a);
+			break;
+		case OP_LRGLEN:
+			seq_printf(seq, " mtu=%d", a);
+			break;
+		case OP_VLAN:
+			seq_printf(seq, " vlan=%d", be16_to_cpu(le->length));
+			break;
+		case OP_TCPLISW:
+			seq_printf(seq, " csum=%#x", a);
+			break;
+		case OP_LARGESEND:
+			seq_printf(seq, " tso=%#x(%d)", a, le16_to_cpu(le->length));
+			break;
+		case OP_PACKET:
+			seq_printf(seq, " %#x(%d)", a, le16_to_cpu(le->length));
+			break;
+		case OP_BUFFER:
+			seq_printf(seq, " frag=%#x(%d)", a, le16_to_cpu(le->length));
+			break;
+		default:
+			seq_printf(seq, " op=%#x,%#x(%d)", le->opcode,
+				   a, le16_to_cpu(le->length));
+		}
+
+		if (le->ctrl & EOP) {
+			seq_putc(seq, '\n');
+			sop = 1;
+		}
+	}
+
+	seq_printf(seq, "\nRx ring hw get=%d put=%d last=%d\n",
+		   sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_GET_IDX)),
+		   last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)),
+		   sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX)));
+
+	netif_poll_enable(hw->dev[0]);
+	return 0;
+}
+
+static int sky2_debug_open(struct inode *inode, struct file *file)
+{
+	return single_open(file, sky2_debug_show, inode->i_private);
+}
+
+static const struct file_operations sky2_debug_fops = {
+	.owner		= THIS_MODULE,
+	.open		= sky2_debug_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= single_release,
+};
+
+/*
+ * Use network device events to create/remove/rename
+ * debugfs file entries
+ */
+static int sky2_device_event(struct notifier_block *unused,
+			     unsigned long event, void *ptr)
+{
+	struct net_device *dev = ptr;
+
+	if (dev->open == sky2_up) {
+		struct sky2_port *sky2 = netdev_priv(dev);
+
+		switch(event) {
+		case NETDEV_CHANGENAME:
+			if (!netif_running(dev))
+				break;
+			/* fallthrough */
+		case NETDEV_DOWN:
+		case NETDEV_GOING_DOWN:
+			if (sky2->debugfs) {
+				printk(KERN_DEBUG PFX "%s: remove debugfs\n",
+				       dev->name);
+				debugfs_remove(sky2->debugfs);
+				sky2->debugfs = NULL;
+			}
+
+			if (event != NETDEV_CHANGENAME)
+				break;
+			/* fallthrough for changename */
+		case NETDEV_UP:
+			if (sky2_debug) {
+				struct dentry *d;
+				d = debugfs_create_file(dev->name, S_IRUGO,
+							sky2_debug, dev,
+							&sky2_debug_fops);
+				if (d == NULL || IS_ERR(d))
+					printk(KERN_INFO PFX
+					       "%s: debugfs create failed\n",
+					       dev->name);
+				else
+					sky2->debugfs = d;
+			}
+			break;
+		}
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block sky2_notifier = {
+	.notifier_call = sky2_device_event,
+};
+
+
+static __init void sky2_debug_init(void)
+{
+	struct dentry *ent;
+
+	ent = debugfs_create_dir("sky2", NULL);
+	if (!ent || IS_ERR(ent))
+		return;
+
+	sky2_debug = ent;
+	register_netdevice_notifier(&sky2_notifier);
+}
+
+static __exit void sky2_debug_cleanup(void)
+{
+	if (sky2_debug) {
+		unregister_netdevice_notifier(&sky2_notifier);
+		debugfs_remove(sky2_debug);
+		sky2_debug = NULL;
+	}
+}
+
+#else
+#define sky2_debug_init()
+#define sky2_debug_cleanup()
+#endif
+
+
 /* Initialize network device */
 static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
 						     unsigned port,
@@ -3536,10 +3813,6 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
 	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port * 8, ETH_ALEN);
 	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	/* device is off until link detection */
-	netif_carrier_off(dev);
-	netif_stop_queue(dev);
-
 	return dev;
 }
 
@@ -3956,12 +4229,14 @@ static struct pci_driver sky2_driver = {
 
 static int __init sky2_init_module(void)
 {
+	sky2_debug_init();
 	return pci_register_driver(&sky2_driver);
 }
 
 static void __exit sky2_cleanup_module(void)
 {
 	pci_unregister_driver(&sky2_driver);
+	sky2_debug_cleanup();
 }
 
 module_init(sky2_init_module);
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 8df4643..dce4d27 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1998,6 +1998,7 @@ struct sky2_port {
 	struct sky2_tx_le    *tx_le;
 	u16		     tx_cons;		/* next le to check */
 	u16		     tx_prod;		/* next le to use */
+	u16		     tx_next;		/* debug only */
 	u32		     tx_addr64;
 	u16		     tx_pending;
 	u16		     tx_last_mss;
@@ -2028,6 +2029,9 @@ struct sky2_port {
  	enum flow_control    flow_mode;
  	enum flow_control    flow_status;
 
+#ifdef CONFIG_SKY2_DEBUG
+	struct dentry	     *debugfs;
+#endif
 	struct net_device_stats net_stats;
 
 };
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index f5abb52..590b12c 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -1441,11 +1441,17 @@ static void
 spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg)
 {
 	u32 error_reg1, error_reg2;
+	u32 mask_reg1, mask_reg2;
 	u32 i;
 	int show_error = 1;
 
 	error_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1STS);
 	error_reg2 = spider_net_read_reg(card, SPIDER_NET_GHIINT2STS);
+	mask_reg1 = spider_net_read_reg(card, SPIDER_NET_GHIINT1MSK);
+	mask_reg2 = spider_net_read_reg(card,SPIDER_NET_GHIINT2MSK);
+
+	error_reg1 &= mask_reg1;
+	error_reg2 &= mask_reg2;
 
 	/* check GHIINT0STS ************************************/
 	if (status_reg)
@@ -1673,9 +1679,11 @@ spider_net_interrupt(int irq, void *ptr)
 {
 	struct net_device *netdev = ptr;
 	struct spider_net_card *card = netdev_priv(netdev);
-	u32 status_reg;
+	u32 status_reg, mask_reg;
 
 	status_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0STS);
+	mask_reg = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK);
+	status_reg &= mask_reg;
 
 	if (!status_reg)
 		return IRQ_NONE;
@@ -1717,6 +1725,38 @@ spider_net_poll_controller(struct net_device *netdev)
 #endif /* CONFIG_NET_POLL_CONTROLLER */
 
 /**
+ * spider_net_enable_interrupts - enable interrupts
+ * @card: card structure
+ *
+ * spider_net_enable_interrupt enables several interrupts
+ */
+static void 
+spider_net_enable_interrupts(struct spider_net_card *card)
+{
+	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
+			     SPIDER_NET_INT0_MASK_VALUE);
+	spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,
+			     SPIDER_NET_INT1_MASK_VALUE);
+	spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
+			     SPIDER_NET_INT2_MASK_VALUE);
+}
+
+/**
+ * spider_net_disable_interrupts - disable interrupts
+ * @card: card structure
+ *
+ * spider_net_disable_interrupts disables all the interrupts
+ */
+static void 
+spider_net_disable_interrupts(struct spider_net_card *card)
+{
+	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
+	spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
+	spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
+	spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
+}
+
+/**
  * spider_net_init_card - initializes the card
  * @card: card structure
  *
@@ -1736,6 +1776,7 @@ spider_net_init_card(struct spider_net_card *card)
 	spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
 		spider_net_read_reg(card, SPIDER_NET_GMACOPEMD) | 0x4);
 
+	spider_net_disable_interrupts(card);
 }
 
 /**
@@ -1823,14 +1864,6 @@ spider_net_enable_card(struct spider_net_card *card)
 	spider_net_write_reg(card, SPIDER_NET_GMACOPEMD,
 			     SPIDER_NET_OPMODE_VALUE);
 
-	/* set interrupt mask registers */
-	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK,
-			     SPIDER_NET_INT0_MASK_VALUE);
-	spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK,
-			     SPIDER_NET_INT1_MASK_VALUE);
-	spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK,
-			     SPIDER_NET_INT2_MASK_VALUE);
-
 	spider_net_write_reg(card, SPIDER_NET_GDTDMACCNTR,
 			     SPIDER_NET_GDTBSTA);
 }
@@ -2007,6 +2040,8 @@ spider_net_open(struct net_device *netdev)
 	netif_carrier_on(netdev);
 	netif_poll_enable(netdev);
 
+	spider_net_enable_interrupts(card);
+
 	return 0;
 
 register_int_failed:
@@ -2179,11 +2214,7 @@ spider_net_stop(struct net_device *netdev)
 	del_timer_sync(&card->tx_timer);
 	del_timer_sync(&card->aneg_timer);
 
-	/* disable/mask all interrupts */
-	spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0);
-	spider_net_write_reg(card, SPIDER_NET_GHIINT1MSK, 0);
-	spider_net_write_reg(card, SPIDER_NET_GHIINT2MSK, 0);
-	spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
+	spider_net_disable_interrupts(card);
 
 	free_irq(netdev->irq, netdev);
 
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 51c3fe2..15146a1 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -2625,7 +2625,7 @@ static void quattro_sbus_free_irqs(void)
 #endif /* CONFIG_SBUS */
 
 #ifdef CONFIG_PCI
-static struct quattro * __init quattro_pci_find(struct pci_dev *pdev)
+static struct quattro * __devinit quattro_pci_find(struct pci_dev *pdev)
 {
 	struct pci_dev *bdev = pdev->bus->self;
 	struct quattro *qp;
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index e22a3f5..9f1b6ab 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -363,7 +363,7 @@ static int __devinit xl_probe(struct pci_dev *pdev,
 }
 
 
-static int __init xl_init(struct net_device *dev) 
+static int __devinit xl_init(struct net_device *dev) 
 {
     	struct xl_private *xl_priv = (struct xl_private *)dev->priv ;
 
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 18b731b..e4736a3 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -2276,7 +2276,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
 	phy_stop(phydev);
 
 	/* Mask all interrupts */
-	out_be32(ugeth->uccf->p_ucce, 0x00000000);
+	out_be32(ugeth->uccf->p_uccm, 0x00000000);
 
 	/* Clear all interrupts */
 	out_be32(ugeth->uccf->p_ucce, 0xffffffff);
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 86b6908..37bf4f2 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -1213,7 +1213,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
 			status = 0;
 
 	}
-	if (status == 0 && dev->status)
+	if (status >= 0 && dev->status)
 		status = init_status (dev, udev);
 	if (status < 0)
 		goto out3;
diff --git a/include/net/ax88796.h b/include/net/ax88796.h
new file mode 100644
index 0000000..ee786a0
--- /dev/null
+++ b/include/net/ax88796.h
@@ -0,0 +1,27 @@
+/* include/net/ax88796.h
+ *
+ * Copyright 2005 Simtec Electronics
+ *	Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#ifndef __NET_AX88796_PLAT_H
+#define __NET_AX88796_PLAT_H
+
+#define AXFLG_HAS_EEPROM		(1<<0)
+#define AXFLG_MAC_FROMDEV		(1<<1)	/* device already has MAC */
+
+struct ax_plat_data {
+	unsigned int	 flags;
+	unsigned char	 wordlength;		/* 1 or 2 */
+	unsigned char	 dcr_val;		/* default value for DCR */
+	unsigned char	 rcr_val;		/* default value for RCR */
+	unsigned char	 gpoc_val;		/* default value for GPOC */
+	u32		*reg_offsets;		/* register offsets */
+};
+
+#endif /* __NET_AX88796_PLAT_H */
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index f96ed76..79b79f3 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2268,6 +2268,9 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
 		break;
 	case NETDEV_UP:
 	case NETDEV_CHANGE:
+		if (dev->flags & IFF_SLAVE)
+			break;
+
 		if (event == NETDEV_UP) {
 			if (!netif_carrier_ok(dev)) {
 				/* device is not ready yet. */

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-05-18 21:54   ` Andrew Morton
  2007-05-18 22:16     ` Mariusz Kozlowski
@ 2007-05-18 22:19     ` Gene Heskett
  1 sibling, 0 replies; 101+ messages in thread
From: Gene Heskett @ 2007-05-18 22:19 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Mariusz Koz__owski, Jeff Garzik, Linus Torvalds, netdev, LKML

On Friday 18 May 2007, Andrew Morton wrote:
>On Fri, 18 May 2007 23:46:21 +0200
>
>Mariusz Koz__owski <m.kozlowski@tuxland.pl> wrote:
>> Hello,
>>
>> > diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
>> > index 7053026..111f23d 100644
>> > --- a/drivers/net/smc91x.h
>> > +++ b/drivers/net/smc91x.h
>> > @@ -279,6 +279,40 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
>>
>> ...
>>
>> > +#define SMC_outb(v, a, r) __ __
>> > __outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) +
>> > ((r)&~1))
>>
>> This one has unbalanced parenthesis.
>
>I dunno how you can tell - I can't count that high.
>
Try removing the one in front of the comma, it makes the count -1.  And I 
wrote, probably a good 20 years ago, a gizmo I called cntx that found that 
stuff for you.  I occasionally use it to run over a section of the kernel 
tree, but it rarely finds anything to fuss about.  And I really do need to 
make it handle shell expansions so you don't have write a quick script to 
have it scan everything in a directory.  However I suspect that most of you 
already have such a tool in your bag of tricks.

>Can this be programmed in C, rather than in cpp?
>-
>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at  http://www.tux.org/lkml/



-- 
Cheers, Gene
"There are four boxes to be used in defense of liberty:
 soap, ballot, jury, and ammo. Please use in that order."
-Ed Howdershelt (Author)
I'm definitely not in Omaha!

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-05-18 21:54   ` Andrew Morton
@ 2007-05-18 22:16     ` Mariusz Kozlowski
  2007-05-18 22:19     ` Gene Heskett
  1 sibling, 0 replies; 101+ messages in thread
From: Mariusz Kozlowski @ 2007-05-18 22:16 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Jeff Garzik, Linus Torvalds, netdev, LKML

> > > diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
> > > index 7053026..111f23d 100644
> > > --- a/drivers/net/smc91x.h
> > > +++ b/drivers/net/smc91x.h
> > > @@ -279,6 +279,40 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
> > 
> > ...
> > 
> > > +#define SMC_outb(v, a, r) __ __ __outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) + ((r)&~1))
> > 
> > This one has unbalanced parenthesis.
> > 
> 
> I dunno how you can tell - I can't count that high.

Me neither. Simple script does that for me ;) Not sure where exactly
the parenthesis is missing so I leave it up to someone (the author?)
who knows better.

Regards,

	Mariusz

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-05-18 21:46 ` Mariusz Kozłowski
@ 2007-05-18 21:54   ` Andrew Morton
  2007-05-18 22:16     ` Mariusz Kozlowski
  2007-05-18 22:19     ` Gene Heskett
  0 siblings, 2 replies; 101+ messages in thread
From: Andrew Morton @ 2007-05-18 21:54 UTC (permalink / raw)
  To: Mariusz Koz__owski; +Cc: Jeff Garzik, Linus Torvalds, netdev, LKML

On Fri, 18 May 2007 23:46:21 +0200
Mariusz Koz__owski <m.kozlowski@tuxland.pl> wrote:

> Hello, 
> 
> > diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
> > index 7053026..111f23d 100644
> > --- a/drivers/net/smc91x.h
> > +++ b/drivers/net/smc91x.h
> > @@ -279,6 +279,40 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
> 
> ...
> 
> > +#define SMC_outb(v, a, r) __ __ __outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) + ((r)&~1))
> 
> This one has unbalanced parenthesis.
> 

I dunno how you can tell - I can't count that high.

Can this be programmed in C, rather than in cpp?

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-05-08  6:33 Jeff Garzik
@ 2007-05-18 21:46 ` Mariusz Kozłowski
  2007-05-18 21:54   ` Andrew Morton
  0 siblings, 1 reply; 101+ messages in thread
From: Mariusz Kozłowski @ 2007-05-18 21:46 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Andrew Morton, Linus Torvalds, netdev, LKML

Hello, 

> diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
> index 7053026..111f23d 100644
> --- a/drivers/net/smc91x.h
> +++ b/drivers/net/smc91x.h
> @@ -279,6 +279,40 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)

...

> +#define SMC_outb(v, a, r)      outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) + ((r)&~1))

This one has unbalanced parenthesis.

Regards,

	Mariusz

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-05-11 21:58 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2007-05-11 21:58 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML


I went ahead and merged the drivers/atm Kconfig updates.

And this brings much-needed libertas updates.

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 drivers/atm/Kconfig                     |   32 +-
 drivers/net/Kconfig                     |   16 +-
 drivers/net/mlx4/eq.c                   |    2 +-
 drivers/net/netxen/netxen_nic_main.c    |    2 +-
 drivers/net/pcmcia/Kconfig              |   23 +-
 drivers/net/phy/Kconfig                 |   22 +-
 drivers/net/phy/davicom.c               |   34 +-
 drivers/net/s2io.c                      |  368 +++++++-
 drivers/net/s2io.h                      |   32 +
 drivers/net/skge.c                      |    9 +
 drivers/net/sky2.c                      |   53 +-
 drivers/net/spider_net.c                |    8 +-
 drivers/net/wan/Kconfig                 |   34 +-
 drivers/net/wireless/libertas/Makefile  |    9 -
 drivers/net/wireless/libertas/README    |  516 -----------
 drivers/net/wireless/libertas/assoc.c   |   41 +-
 drivers/net/wireless/libertas/cmd.c     |   23 +-
 drivers/net/wireless/libertas/cmdresp.c |    4 +-
 drivers/net/wireless/libertas/debugfs.c |   31 +-
 drivers/net/wireless/libertas/defs.h    |   52 +-
 drivers/net/wireless/libertas/dev.h     |   14 +-
 drivers/net/wireless/libertas/fw.c      |    9 +-
 drivers/net/wireless/libertas/if_usb.c  |    5 +-
 drivers/net/wireless/libertas/if_usb.h  |    2 -
 drivers/net/wireless/libertas/ioctl.c   | 1529 +------------------------------
 drivers/net/wireless/libertas/join.c    |  194 +----
 drivers/net/wireless/libertas/join.h    |    7 -
 drivers/net/wireless/libertas/main.c    |    7 +
 drivers/net/wireless/libertas/rx.c      |    4 +-
 drivers/net/wireless/libertas/scan.c    |  203 ++---
 drivers/net/wireless/libertas/scan.h    |   22 +-
 drivers/net/wireless/libertas/tx.c      |    2 +-
 drivers/net/wireless/libertas/version.h |    7 -
 drivers/net/wireless/libertas/wext.c    |  448 +--------
 drivers/net/wireless/libertas/wext.h    |   85 --
 35 files changed, 750 insertions(+), 3099 deletions(-)

Andrew Morton (2):
      netxen_nic_main don't use deprecated irq flags
      mlx4: don't use deprecated IRQ flags

Dan Williams (19):
      libertas: remove WPA_SUPPLICANT structure
      libertas: use <net/ieee80211.h> for MAX_WPA_IE_LEN
      libertas: fix size of SSID comparison in stop_adhoc check
      libertas: remove 8021xauthalgs private ioctl
      libertas: remove setauthalg private ioctl
      libertas: remove incorrect vi modelines
      libertas: remove custom encryption mode stuff
      libertas: remove setwpaie private ioctl
      libertas: remove WLAN_802_11_AUTHENTICATION_MODE
      libertas: remove WLAN_802_11_WEP_STATUS enum
      libertas: remove WLAN_802_11_NETWORK_INFRASTRUCTURE enum
      libertas: Get rid of version.h
      libertas: Purge non-mesh ioctls
      libertas: remove SUPPORT_BOOT_COMMAND
      libertas: Clean up debug defines
      libertas: make debugfs.c sparse-clean
      libertas: fix missing unlock in TX error path
      libertas: sparse fixes
      libertas: 64-bit cleanups

Ishizaki Kou (1):
      spidernet: remove unnecessary accesses to phy

Jan Engelhardt (5):
      Use menuconfig objects: PHY
      Use menuconfig objects: netdev
      Use menuconfig objects II - netdev/atm
      Use menuconfig objects II - netdev/pcmcia
      Use menuconfig objects II - netdev/wan

Kim Phillips (1):
      Add support for the Davicom DM9161A PHY

Sreenivasa Honnur (3):
      S2IO: getringparam ethtool option
      S2IO: statistics for memory allocation failuers
      S2IO: Statistics for link up/down and memory allocated/freed

Stephen Hemminger (4):
      sky2: fix oops on shutdown
      skge: crash on shutdown/suspend
      sky2: 88e8071 support not ready
      sky2: only disable 88e8056 on some boards

diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig
index 3368745..f5a47a4 100644
--- a/drivers/atm/Kconfig
+++ b/drivers/atm/Kconfig
@@ -2,19 +2,22 @@
 # ATM device configuration
 #
 
-menu "ATM drivers"
+menuconfig ATM_DRIVERS
+	bool "ATM drivers"
 	depends on NETDEVICES && ATM
+	default y
+
+if ATM_DRIVERS
 
 config ATM_DUMMY
 	tristate "Dummy ATM driver"
-	depends on ATM
 	help
 	  Dummy ATM driver. Useful for proxy signalling, testing,
 	  and development.  If unsure, say N.
 
 config ATM_TCP
 	tristate "ATM over TCP"
-	depends on INET && ATM
+	depends on INET
 	help
 	  ATM over TCP driver. Useful mainly for development and for
 	  experiments. If unsure, say N.
@@ -30,7 +33,7 @@ config ATM_LANAI
 
 config ATM_ENI
 	tristate "Efficient Networks ENI155P"
-	depends on PCI && ATM
+	depends on PCI
 	---help---
 	  Driver for the Efficient Networks ENI155p series and SMC ATM
 	  Power155 155 Mbps ATM adapters. Both, the versions with 512KB and
@@ -139,7 +142,7 @@ config ATM_ENI_BURST_RX_2W
 
 config ATM_FIRESTREAM
 	tristate "Fujitsu FireStream (FS50/FS155) "
-	depends on PCI && ATM
+	depends on PCI
 	help
 	  Driver for the Fujitsu FireStream 155 (MB86697) and
 	  FireStream 50 (MB86695) ATM PCI chips.
@@ -149,7 +152,7 @@ config ATM_FIRESTREAM
 
 config ATM_ZATM
 	tristate "ZeitNet ZN1221/ZN1225"
-	depends on PCI && ATM
+	depends on PCI
 	help
 	  Driver for the ZeitNet ZN1221 (MMF) and ZN1225 (UTP-5) 155 Mbps ATM
 	  adapters.
@@ -169,7 +172,7 @@ config ATM_ZATM_DEBUG
 
 config ATM_NICSTAR
 	tristate "IDT 77201 (NICStAR) (ForeRunnerLE)"
-	depends on PCI && ATM && !64BIT
+	depends on PCI && !64BIT
 	help
 	  The NICStAR chipset family is used in a large number of ATM NICs for
 	  25 and for 155 Mbps, including IDT cards and the Fore ForeRunnerLE
@@ -202,7 +205,7 @@ config ATM_NICSTAR_USE_IDT77105
 
 config ATM_IDT77252
 	tristate "IDT 77252 (NICStAR II)"
-	depends on PCI && ATM
+	depends on PCI
 	help
 	  Driver for the IDT 77252 ATM PCI chips.
 
@@ -237,7 +240,7 @@ config ATM_IDT77252_USE_SUNI
 
 config ATM_AMBASSADOR
 	tristate "Madge Ambassador (Collage PCI 155 Server)"
-	depends on PCI && ATM
+	depends on PCI
 	select BITREVERSE
 	help
 	  This is a driver for ATMizer based ATM card produced by Madge
@@ -262,7 +265,7 @@ config ATM_AMBASSADOR_DEBUG
 
 config ATM_HORIZON
 	tristate "Madge Horizon [Ultra] (Collage PCI 25 and Collage PCI 155 Client)"
-	depends on PCI && ATM
+	depends on PCI
 	help
 	  This is a driver for the Horizon chipset ATM adapter cards once
 	  produced by Madge Networks Ltd. Say Y (or M to compile as a module
@@ -286,7 +289,7 @@ config ATM_HORIZON_DEBUG
 
 config ATM_IA
 	tristate "Interphase ATM PCI x575/x525/x531"
-	depends on PCI && ATM && !64BIT
+	depends on PCI && !64BIT
 	---help---
 	  This is a driver for the Interphase (i)ChipSAR adapter cards
 	  which include a variety of variants in term of the size of the
@@ -319,7 +322,7 @@ config ATM_IA_DEBUG
 
 config ATM_FORE200E_MAYBE
 	tristate "FORE Systems 200E-series"
-	depends on (PCI || SBUS) && ATM
+	depends on PCI || SBUS
 	---help---
 	  This is a driver for the FORE Systems 200E-series ATM adapter
 	  cards. It simultaneously supports PCA-200E and SBA-200E models
@@ -436,7 +439,7 @@ config ATM_FORE200E
 
 config ATM_HE
 	tristate "ForeRunner HE Series"
-	depends on PCI && ATM
+	depends on PCI
 	help
 	  This is a driver for the Marconi ForeRunner HE-series ATM adapter
 	  cards. It simultaneously supports the 155 and 622 versions.
@@ -448,5 +451,4 @@ config ATM_HE_USE_SUNI
 	  Support for the S/UNI-Ultra and S/UNI-622 found in the ForeRunner
 	  HE cards.  This driver provides carrier detection some statistics.
 
-endmenu
-
+endif # ATM
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index fa489b1..8a7f9e9 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1898,8 +1898,12 @@ endmenu
 #	Gigabit Ethernet
 #
 
-menu "Ethernet (1000 Mbit)"
+menuconfig NETDEV_1000
+	bool "Ethernet (1000 Mbit)"
 	depends on !UML
+	default y
+
+if NETDEV_1000
 
 config ACENIC
 	tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
@@ -2326,14 +2330,18 @@ config ATL1
 	  To compile this driver as a module, choose M here.  The module
 	  will be called atl1.
 
-endmenu
+endif # NETDEV_1000
 
 #
 #	10 Gigabit Ethernet
 #
 
-menu "Ethernet (10000 Mbit)"
+menuconfig NETDEV_10000
+	bool "Ethernet (10000 Mbit)"
 	depends on !UML
+	default y
+
+if NETDEV_10000
 
 config CHELSIO_T1
         tristate "Chelsio 10Gb Ethernet support"
@@ -2507,7 +2515,7 @@ config MLX4_DEBUG
 	  debug_level module parameter (which can also be set after
 	  the driver is loaded through sysfs).
 
-endmenu
+endif # NETDEV_10000
 
 source "drivers/net/tokenring/Kconfig"
 
diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c
index acf1c80..af016d0 100644
--- a/drivers/net/mlx4/eq.c
+++ b/drivers/net/mlx4/eq.c
@@ -623,7 +623,7 @@ int __devinit mlx4_init_eq_table(struct mlx4_dev *dev)
 		priv->eq_table.eq[MLX4_EQ_CATAS].have_irq = 1;
 	} else {
 		err = request_irq(dev->pdev->irq, mlx4_interrupt,
-				  SA_SHIRQ, DRV_NAME, dev);
+				  IRQF_SHARED, DRV_NAME, dev);
 		if (err)
 			goto err_out_async;
 
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 4e32bb6..2c5c6d2 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -735,7 +735,7 @@ static int netxen_nic_open(struct net_device *netdev)
 		}
 		adapter->irq = adapter->ahw.pdev->irq;
 		err = request_irq(adapter->ahw.pdev->irq, netxen_intr,
-				  SA_SHIRQ | SA_SAMPLE_RANDOM, netdev->name,
+				  IRQF_SHARED|IRQF_SAMPLE_RANDOM, netdev->name,
 				  adapter);
 		if (err) {
 			printk(KERN_ERR "request_irq failed with: %d\n", err);
diff --git a/drivers/net/pcmcia/Kconfig b/drivers/net/pcmcia/Kconfig
index 74f8620..5d658bc 100644
--- a/drivers/net/pcmcia/Kconfig
+++ b/drivers/net/pcmcia/Kconfig
@@ -2,11 +2,9 @@
 # PCMCIA Network device configuration
 #
 
-menu "PCMCIA network device support"
-	depends on NETDEVICES && PCMCIA!=n
-
-config NET_PCMCIA
+menuconfig NET_PCMCIA
 	bool "PCMCIA network device support"
+	depends on PCMCIA
 	---help---
 	  Say Y if you would like to include support for any PCMCIA or CardBus
 	  network adapters, then say Y to the driver for your particular card
@@ -21,9 +19,10 @@ config NET_PCMCIA
 
 	  If unsure, say N.
 
+if NET_PCMCIA
+
 config PCMCIA_3C589
 	tristate "3Com 3c589 PCMCIA support"
-	depends on NET_PCMCIA && PCMCIA
 	help
 	  Say Y here if you intend to attach a 3Com 3c589 or compatible PCMCIA
 	  (PC-card) Ethernet card to your computer.
@@ -33,7 +32,6 @@ config PCMCIA_3C589
 
 config PCMCIA_3C574
 	tristate "3Com 3c574 PCMCIA support"
-	depends on NET_PCMCIA && PCMCIA
 	help
 	  Say Y here if you intend to attach a 3Com 3c574 or compatible PCMCIA
 	  (PC-card) Fast Ethernet card to your computer.
@@ -43,7 +41,6 @@ config PCMCIA_3C574
 
 config PCMCIA_FMVJ18X
 	tristate "Fujitsu FMV-J18x PCMCIA support"
-	depends on NET_PCMCIA && PCMCIA
 	select CRC32
 	help
 	  Say Y here if you intend to attach a Fujitsu FMV-J18x or compatible
@@ -54,7 +51,6 @@ config PCMCIA_FMVJ18X
 
 config PCMCIA_PCNET
 	tristate "NE2000 compatible PCMCIA support"
-	depends on NET_PCMCIA && PCMCIA
 	select CRC32
 	help
 	  Say Y here if you intend to attach an NE2000 compatible PCMCIA
@@ -65,7 +61,6 @@ config PCMCIA_PCNET
 
 config PCMCIA_NMCLAN
 	tristate "New Media PCMCIA support"
-	depends on NET_PCMCIA && PCMCIA
 	help
 	  Say Y here if you intend to attach a New Media Ethernet or LiveWire
 	  PCMCIA (PC-card) Ethernet card to your computer.
@@ -75,7 +70,6 @@ config PCMCIA_NMCLAN
 
 config PCMCIA_SMC91C92
 	tristate "SMC 91Cxx PCMCIA support"
-	depends on NET_PCMCIA && PCMCIA
 	select CRC32
 	select MII
 	help
@@ -87,7 +81,6 @@ config PCMCIA_SMC91C92
 
 config PCMCIA_XIRC2PS
 	tristate "Xircom 16-bit PCMCIA support"
-	depends on NET_PCMCIA && PCMCIA
 	help
 	  Say Y here if you intend to attach a Xircom 16-bit PCMCIA (PC-card)
 	  Ethernet or Fast Ethernet card to your computer.
@@ -97,7 +90,6 @@ config PCMCIA_XIRC2PS
 
 config PCMCIA_AXNET
 	tristate "Asix AX88190 PCMCIA support"
-	depends on NET_PCMCIA && PCMCIA
 	---help---
 	  Say Y here if you intend to attach an Asix AX88190-based PCMCIA
 	  (PC-card) Fast Ethernet card to your computer.  These cards are
@@ -109,7 +101,7 @@ config PCMCIA_AXNET
 
 config ARCNET_COM20020_CS
 	tristate "COM20020 ARCnet PCMCIA support"
-	depends on NET_PCMCIA && ARCNET_COM20020 && PCMCIA
+	depends on ARCNET_COM20020
 	help
 	  Say Y here if you intend to attach this type of ARCnet PCMCIA card
 	  to your computer.
@@ -119,7 +111,7 @@ config ARCNET_COM20020_CS
 
 config PCMCIA_IBMTR
 	tristate "IBM PCMCIA tokenring adapter support"
-	depends on NET_PCMCIA && IBMTR!=y && TR && PCMCIA && !64BIT
+	depends on IBMTR!=y && TR && !64BIT
 	help
 	  Say Y here if you intend to attach this type of Token Ring PCMCIA
 	  card to your computer. You then also need to say Y to "Token Ring
@@ -128,5 +120,4 @@ config PCMCIA_IBMTR
 	  To compile this driver as a module, choose M here: the module will be
 	  called ibmtr_cs.
 
-endmenu
-
+endif # NET_PCMCIA
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
index c0d3101..09b6f25 100644
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -2,70 +2,61 @@
 # PHY Layer Configuration
 #
 
-menu "PHY device support"
-	depends on !S390
-
-config PHYLIB
+menuconfig PHYLIB
 	tristate "PHY Device support and infrastructure"
+	depends on !S390
 	depends on NET_ETHERNET && (BROKEN || !S390)
 	help
 	  Ethernet controllers are usually attached to PHY
 	  devices.  This option provides infrastructure for
 	  managing PHY devices.
 
+if PHYLIB
+
 comment "MII PHY device drivers"
-	depends on PHYLIB
 
 config MARVELL_PHY
 	tristate "Drivers for Marvell PHYs"
-	depends on PHYLIB
 	---help---
 	  Currently has a driver for the 88E1011S
 	
 config DAVICOM_PHY
 	tristate "Drivers for Davicom PHYs"
-	depends on PHYLIB
 	---help---
 	  Currently supports dm9161e and dm9131
 
 config QSEMI_PHY
 	tristate "Drivers for Quality Semiconductor PHYs"
-	depends on PHYLIB
 	---help---
 	  Currently supports the qs6612
 
 config LXT_PHY
 	tristate "Drivers for the Intel LXT PHYs"
-	depends on PHYLIB
 	---help---
 	  Currently supports the lxt970, lxt971
 
 config CICADA_PHY
 	tristate "Drivers for the Cicada PHYs"
-	depends on PHYLIB
 	---help---
 	  Currently supports the cis8204
+
 config VITESSE_PHY
         tristate "Drivers for the Vitesse PHYs"
-        depends on PHYLIB
         ---help---
           Currently supports the vsc8244
 
 config SMSC_PHY
 	tristate "Drivers for SMSC PHYs"
-	depends on PHYLIB
 	---help---
 	  Currently supports the LAN83C185 PHY
 
 config BROADCOM_PHY
 	tristate "Drivers for Broadcom PHYs"
-	depends on PHYLIB
 	---help---
 	  Currently supports the BCM5411, BCM5421 and BCM5461 PHYs.
 
 config FIXED_PHY
 	tristate "Drivers for PHY emulation on fixed speed/link"
-	depends on PHYLIB
 	---help---
 	  Adds the driver to PHY layer to cover the boards that do not have any PHY bound,
 	  but with the ability to manipulate the speed/link in software. The relevant MII
@@ -80,5 +71,4 @@ config FIXED_MII_100_FDX
 	bool "Emulation for 100M Fdx fixed PHY behavior"
 	depends on FIXED_PHY
 
-endmenu
-
+endif # PHYLIB
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c
index 519baa3..7ed632d 100644
--- a/drivers/net/phy/davicom.c
+++ b/drivers/net/phy/davicom.c
@@ -139,7 +139,7 @@ static int dm9161_ack_interrupt(struct phy_device *phydev)
 	return (err < 0) ? err : 0;
 }
 
-static struct phy_driver dm9161_driver = {
+static struct phy_driver dm9161e_driver = {
 	.phy_id		= 0x0181b880,
 	.name		= "Davicom DM9161E",
 	.phy_id_mask	= 0x0ffffff0,
@@ -147,7 +147,18 @@ static struct phy_driver dm9161_driver = {
 	.config_init	= dm9161_config_init,
 	.config_aneg	= dm9161_config_aneg,
 	.read_status	= genphy_read_status,
-	.driver 	= { .owner = THIS_MODULE,},
+	.driver		= { .owner = THIS_MODULE,},
+};
+
+static struct phy_driver dm9161a_driver = {
+	.phy_id		= 0x0181b8a0,
+	.name		= "Davicom DM9161A",
+	.phy_id_mask	= 0x0ffffff0,
+	.features	= PHY_BASIC_FEATURES,
+	.config_init	= dm9161_config_init,
+	.config_aneg	= dm9161_config_aneg,
+	.read_status	= genphy_read_status,
+	.driver		= { .owner = THIS_MODULE,},
 };
 
 static struct phy_driver dm9131_driver = {
@@ -160,31 +171,38 @@ static struct phy_driver dm9131_driver = {
 	.read_status	= genphy_read_status,
 	.ack_interrupt	= dm9161_ack_interrupt,
 	.config_intr	= dm9161_config_intr,
-	.driver 	= { .owner = THIS_MODULE,},
+	.driver		= { .owner = THIS_MODULE,},
 };
 
 static int __init davicom_init(void)
 {
 	int ret;
 
-	ret = phy_driver_register(&dm9161_driver);
+	ret = phy_driver_register(&dm9161e_driver);
 	if (ret)
 		goto err1;
 
-	ret = phy_driver_register(&dm9131_driver);
+	ret = phy_driver_register(&dm9161a_driver);
 	if (ret)
 		goto err2;
+
+	ret = phy_driver_register(&dm9131_driver);
+	if (ret)
+		goto err3;
 	return 0;
 
- err2:	
-	phy_driver_unregister(&dm9161_driver);
+ err3:
+	phy_driver_unregister(&dm9161a_driver);
+ err2:
+	phy_driver_unregister(&dm9161e_driver);
  err1:
 	return ret;
 }
 
 static void __exit davicom_exit(void)
 {
-	phy_driver_unregister(&dm9161_driver);
+	phy_driver_unregister(&dm9161e_driver);
+	phy_driver_unregister(&dm9161a_driver);
 	phy_driver_unregister(&dm9131_driver);
 }
 
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 290e1c1..e3e6d41 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -84,7 +84,7 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "2.0.22.1"
+#define DRV_VERSION "2.0.23.1"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
@@ -281,6 +281,28 @@ static char ethtool_driver_stats_keys[][ETH_GSTRING_LEN] = {
 	("lro_out_of_sequence_pkts"),
 	("lro_flush_due_to_max_pkts"),
 	("lro_avg_aggr_pkts"),
+	("mem_alloc_fail_cnt"),
+	("watchdog_timer_cnt"),
+	("mem_allocated"),
+	("mem_freed"),
+	("link_up_cnt"),
+	("link_down_cnt"),
+	("link_up_time"),
+	("link_down_time"),
+	("tx_tcode_buf_abort_cnt"),
+	("tx_tcode_desc_abort_cnt"),
+	("tx_tcode_parity_err_cnt"),
+	("tx_tcode_link_loss_cnt"),
+	("tx_tcode_list_proc_err_cnt"),
+	("rx_tcode_parity_err_cnt"),
+	("rx_tcode_abort_cnt"),
+	("rx_tcode_parity_abort_cnt"),
+	("rx_tcode_rda_fail_cnt"),
+	("rx_tcode_unkn_prot_cnt"),
+	("rx_tcode_fcs_err_cnt"),
+	("rx_tcode_buf_size_err_cnt"),
+	("rx_tcode_rxd_corrupt_cnt"),
+	("rx_tcode_unkn_err_cnt")
 };
 
 #define S2IO_XENA_STAT_LEN sizeof(ethtool_xena_stats_keys)/ ETH_GSTRING_LEN
@@ -490,6 +512,7 @@ static int init_shared_mem(struct s2io_nic *nic)
 
 	struct mac_info *mac_control;
 	struct config_param *config;
+	unsigned long long mem_allocated = 0;
 
 	mac_control = &nic->mac_control;
 	config = &nic->config;
@@ -519,6 +542,7 @@ static int init_shared_mem(struct s2io_nic *nic)
 				  "Malloc failed for list_info\n");
 			return -ENOMEM;
 		}
+		mem_allocated += list_holder_size;
 		memset(mac_control->fifos[i].list_info, 0, list_holder_size);
 	}
 	for (i = 0; i < config->tx_fifo_num; i++) {
@@ -565,6 +589,7 @@ static int init_shared_mem(struct s2io_nic *nic)
 					DBG_PRINT(INFO_DBG, "failed for TxDL\n");
 					return -ENOMEM;
 				}
+				mem_allocated += PAGE_SIZE;
 			}
 			while (k < lst_per_page) {
 				int l = (j * lst_per_page) + k;
@@ -582,6 +607,7 @@ static int init_shared_mem(struct s2io_nic *nic)
 	nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL);
 	if (!nic->ufo_in_band_v)
 		return -ENOMEM;
+	 mem_allocated += (size * sizeof(u64));
 
 	/* Allocation and initialization of RXDs in Rings */
 	size = 0;
@@ -639,6 +665,7 @@ static int init_shared_mem(struct s2io_nic *nic)
 				rx_blocks->block_virt_addr = tmp_v_addr;
 				return -ENOMEM;
 			}
+			mem_allocated += size;
 			memset(tmp_v_addr, 0, size);
 			rx_blocks->block_virt_addr = tmp_v_addr;
 			rx_blocks->block_dma_addr = tmp_p_addr;
@@ -647,6 +674,8 @@ static int init_shared_mem(struct s2io_nic *nic)
 						  GFP_KERNEL);
 			if (!rx_blocks->rxds)
 				return -ENOMEM;
+			mem_allocated += 
+			(sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);
 			for (l=0; l<rxd_count[nic->rxd_mode];l++) {
 				rx_blocks->rxds[l].virt_addr =
 					rx_blocks->block_virt_addr +
@@ -689,6 +718,7 @@ static int init_shared_mem(struct s2io_nic *nic)
 				     GFP_KERNEL);
 			if (!mac_control->rings[i].ba)
 				return -ENOMEM;
+			mem_allocated +=(sizeof(struct buffAdd *) * blk_cnt);
 			for (j = 0; j < blk_cnt; j++) {
 				int k = 0;
 				mac_control->rings[i].ba[j] =
@@ -697,6 +727,8 @@ static int init_shared_mem(struct s2io_nic *nic)
 						GFP_KERNEL);
 				if (!mac_control->rings[i].ba[j])
 					return -ENOMEM;
+				mem_allocated += (sizeof(struct buffAdd) *  \
+					(rxd_count[nic->rxd_mode] + 1));
 				while (k != rxd_count[nic->rxd_mode]) {
 					ba = &mac_control->rings[i].ba[j][k];
 
@@ -704,6 +736,8 @@ static int init_shared_mem(struct s2io_nic *nic)
 					    (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
 					if (!ba->ba_0_org)
 						return -ENOMEM;
+					mem_allocated += 
+						(BUF0_LEN + ALIGN_SIZE);
 					tmp = (unsigned long)ba->ba_0_org;
 					tmp += ALIGN_SIZE;
 					tmp &= ~((unsigned long) ALIGN_SIZE);
@@ -713,6 +747,8 @@ static int init_shared_mem(struct s2io_nic *nic)
 					    (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
 					if (!ba->ba_1_org)
 						return -ENOMEM;
+					mem_allocated 
+						+= (BUF1_LEN + ALIGN_SIZE);
 					tmp = (unsigned long) ba->ba_1_org;
 					tmp += ALIGN_SIZE;
 					tmp &= ~((unsigned long) ALIGN_SIZE);
@@ -736,6 +772,7 @@ static int init_shared_mem(struct s2io_nic *nic)
 		 */
 		return -ENOMEM;
 	}
+	mem_allocated += size;
 	mac_control->stats_mem_sz = size;
 
 	tmp_v_addr = mac_control->stats_mem;
@@ -743,7 +780,7 @@ static int init_shared_mem(struct s2io_nic *nic)
 	memset(tmp_v_addr, 0, size);
 	DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name,
 		  (unsigned long long) tmp_p_addr);
-
+	mac_control->stats_info->sw_stat.mem_allocated += mem_allocated;
 	return SUCCESS;
 }
 
@@ -757,12 +794,14 @@ static int init_shared_mem(struct s2io_nic *nic)
 static void free_shared_mem(struct s2io_nic *nic)
 {
 	int i, j, blk_cnt, size;
+	u32 ufo_size = 0;
 	void *tmp_v_addr;
 	dma_addr_t tmp_p_addr;
 	struct mac_info *mac_control;
 	struct config_param *config;
 	int lst_size, lst_per_page;
 	struct net_device *dev = nic->dev;
+	int page_num = 0;
 
 	if (!nic)
 		return;
@@ -774,8 +813,9 @@ static void free_shared_mem(struct s2io_nic *nic)
 	lst_per_page = PAGE_SIZE / lst_size;
 
 	for (i = 0; i < config->tx_fifo_num; i++) {
-		int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
-						lst_per_page);
+		ufo_size += config->tx_cfg[i].fifo_len;
+		page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len,
+							lst_per_page);
 		for (j = 0; j < page_num; j++) {
 			int mem_blks = (j * lst_per_page);
 			if (!mac_control->fifos[i].list_info)
@@ -790,6 +830,8 @@ static void free_shared_mem(struct s2io_nic *nic)
 					    mac_control->fifos[i].
 					    list_info[mem_blks].
 					    list_phy_addr);
+			nic->mac_control.stats_info->sw_stat.mem_freed 
+						+= PAGE_SIZE;
 		}
 		/* If we got a zero DMA address during allocation,
 		 * free the page now
@@ -803,8 +845,12 @@ static void free_shared_mem(struct s2io_nic *nic)
 				dev->name);
 			DBG_PRINT(INIT_DBG, "Virtual address %p\n",
 				mac_control->zerodma_virt_addr);
+			nic->mac_control.stats_info->sw_stat.mem_freed 
+						+= PAGE_SIZE;
 		}
 		kfree(mac_control->fifos[i].list_info);
+		nic->mac_control.stats_info->sw_stat.mem_freed += 
+		(nic->config.tx_cfg[i].fifo_len *sizeof(struct list_info_hold));
 	}
 
 	size = SIZE_OF_BLOCK;
@@ -819,7 +865,10 @@ static void free_shared_mem(struct s2io_nic *nic)
 				break;
 			pci_free_consistent(nic->pdev, size,
 					    tmp_v_addr, tmp_p_addr);
+			nic->mac_control.stats_info->sw_stat.mem_freed += size;
 			kfree(mac_control->rings[i].rx_blocks[j].rxds);
+			nic->mac_control.stats_info->sw_stat.mem_freed += 
+			( sizeof(struct rxd_info)* rxd_count[nic->rxd_mode]);
 		}
 	}
 
@@ -836,12 +885,20 @@ static void free_shared_mem(struct s2io_nic *nic)
 					struct buffAdd *ba =
 						&mac_control->rings[i].ba[j][k];
 					kfree(ba->ba_0_org);
+					nic->mac_control.stats_info->sw_stat.\
+					mem_freed += (BUF0_LEN + ALIGN_SIZE);
 					kfree(ba->ba_1_org);
+					nic->mac_control.stats_info->sw_stat.\
+					mem_freed += (BUF1_LEN + ALIGN_SIZE);
 					k++;
 				}
 				kfree(mac_control->rings[i].ba[j]);
+				nic->mac_control.stats_info->sw_stat.mem_freed 				+= (sizeof(struct buffAdd) * 
+				(rxd_count[nic->rxd_mode] + 1));
 			}
 			kfree(mac_control->rings[i].ba);
+			nic->mac_control.stats_info->sw_stat.mem_freed += 
+			(sizeof(struct buffAdd *) * blk_cnt);
 		}
 	}
 
@@ -850,9 +907,14 @@ static void free_shared_mem(struct s2io_nic *nic)
 				    mac_control->stats_mem_sz,
 				    mac_control->stats_mem,
 				    mac_control->stats_mem_phy);
+		nic->mac_control.stats_info->sw_stat.mem_freed += 
+			mac_control->stats_mem_sz;
 	}
-	if (nic->ufo_in_band_v)
+	if (nic->ufo_in_band_v) {
 		kfree(nic->ufo_in_band_v);
+		nic->mac_control.stats_info->sw_stat.mem_freed 
+			+= (ufo_size * sizeof(u64));
+	}
 }
 
 /**
@@ -2122,10 +2184,12 @@ static void free_tx_buffers(struct s2io_nic *nic)
 
 	for (i = 0; i < config->tx_fifo_num; i++) {
 		for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) {
-			txdp = (struct TxD *) mac_control->fifos[i].list_info[j].
-			    list_virt_addr;
+			txdp = (struct TxD *) \
+			mac_control->fifos[i].list_info[j].list_virt_addr;
 			skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j);
 			if (skb) {
+				nic->mac_control.stats_info->sw_stat.mem_freed 
+					+= skb->truesize;
 				dev_kfree_skb(skb);
 				cnt++;
 			}
@@ -2186,11 +2250,14 @@ static int fill_rxd_3buf(struct s2io_nic *nic, struct RxD_t *rxdp, struct \
 	/* skb_shinfo(skb)->frag_list will have L4 data payload */
 	skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE);
 	if (skb_shinfo(skb)->frag_list == NULL) {
+		nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
 		DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
 		return -ENOMEM ;
 	}
 	frag_list = skb_shinfo(skb)->frag_list;
 	skb->truesize += frag_list->truesize;
+	nic->mac_control.stats_info->sw_stat.mem_allocated 
+		+= frag_list->truesize;
 	frag_list->next = NULL;
 	tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
 	frag_list->data = tmp;
@@ -2319,8 +2386,12 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
 				wmb();
 				first_rxdp->Control_1 |= RXD_OWN_XENA;
 			}
+			nic->mac_control.stats_info->sw_stat. \
+				mem_alloc_fail_cnt++;
 			return -ENOMEM ;
 		}
+		nic->mac_control.stats_info->sw_stat.mem_allocated 
+			+= skb->truesize;
 		if (nic->rxd_mode == RXD_MODE_1) {
 			/* 1 buffer mode - normal operation mode */
 			memset(rxdp, 0, sizeof(struct RxD1));
@@ -2328,7 +2399,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
 			((struct RxD1*)rxdp)->Buffer0_ptr = pci_map_single
 			    (nic->pdev, skb->data, size - NET_IP_ALIGN,
 				PCI_DMA_FROMDEVICE);
-			rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
+			rxdp->Control_2 = 
+				SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN);
 
 		} else if (nic->rxd_mode >= RXD_MODE_3A) {
 			/*
@@ -2342,7 +2414,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
 			 * payload
 			 */
 
-			/* save the buffer pointers to avoid frequent dma mapping */
+			/* save buffer pointers to avoid frequent dma mapping */
 			Buffer0_ptr = ((struct RxD3*)rxdp)->Buffer0_ptr;
 			Buffer1_ptr = ((struct RxD3*)rxdp)->Buffer1_ptr;
 			memset(rxdp, 0, sizeof(struct RxD3));
@@ -2364,7 +2436,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
 					   PCI_DMA_FROMDEVICE);
 			else
 				pci_dma_sync_single_for_device(nic->pdev,
-				    (dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr,
+				(dma_addr_t) ((struct RxD3*)rxdp)->Buffer0_ptr,
 				    BUF0_LEN, PCI_DMA_FROMDEVICE);
 			rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
 			if (nic->rxd_mode == RXD_MODE_3B) {
@@ -2391,6 +2463,8 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
 			} else {
 				/* 3 buffer mode */
 				if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) {
+					nic->mac_control.stats_info->sw_stat.\
+					mem_freed += skb->truesize;
 					dev_kfree_skb_irq(skb);
 					if (first_rxdp) {
 						wmb();
@@ -2491,6 +2565,7 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
 				PCI_DMA_FROMDEVICE);
 			memset(rxdp, 0, sizeof(struct RxD3));
 		}
+		sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
 		dev_kfree_skb(skb);
 		atomic_dec(&sp->rx_bufs_left[ring_no]);
 	}
@@ -2820,13 +2895,35 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
 				nic->mac_control.stats_info->sw_stat.
 						parity_err_cnt++;
 			}
-			if ((err >> 48) == 0xA) {
-				DBG_PRINT(TX_DBG, "TxD returned due \
-						to loss of link\n");
-			}
-			else {
-				DBG_PRINT(ERR_DBG, "***TxD error %llx\n", err);
-			}
+
+			/* update t_code statistics */
+			err >>= 48;
+			switch(err) {
+				case 2:
+					nic->mac_control.stats_info->sw_stat.
+							tx_buf_abort_cnt++;
+				break;
+
+				case 3:
+					nic->mac_control.stats_info->sw_stat.
+							tx_desc_abort_cnt++;
+				break;
+
+				case 7:
+					nic->mac_control.stats_info->sw_stat.
+							tx_parity_err_cnt++;
+				break;
+
+				case 10:
+					nic->mac_control.stats_info->sw_stat.
+							tx_link_loss_cnt++;
+				break;
+
+				case 15:
+					nic->mac_control.stats_info->sw_stat.
+							tx_list_proc_err_cnt++;
+				break;
+                        }
 		}
 
 		skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset);
@@ -2839,6 +2936,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data)
 
 		/* Updating the statistics block */
 		nic->stats.tx_bytes += skb->len;
+		nic->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
 		dev_kfree_skb_irq(skb);
 
 		get_info.offset++;
@@ -3314,7 +3412,9 @@ static void s2io_reset(struct s2io_nic * sp)
 	u16 subid, pci_cmd;
 	int i;
 	u16 val16;
-	unsigned long long reset_cnt = 0;
+	unsigned long long up_cnt, down_cnt, up_time, down_time, reset_cnt;
+	unsigned long long mem_alloc_cnt, mem_free_cnt, watchdog_cnt;
+
 	DBG_PRINT(INIT_DBG,"%s - Resetting XFrame card %s\n",
 			__FUNCTION__, sp->dev->name);
 
@@ -3380,11 +3480,26 @@ new_way:
 
 	/* Reset device statistics maintained by OS */
 	memset(&sp->stats, 0, sizeof (struct net_device_stats));
-	/* save reset count */
+	
+	up_cnt = sp->mac_control.stats_info->sw_stat.link_up_cnt;
+	down_cnt = sp->mac_control.stats_info->sw_stat.link_down_cnt;
+	up_time = sp->mac_control.stats_info->sw_stat.link_up_time;
+	down_time = sp->mac_control.stats_info->sw_stat.link_down_time;
 	reset_cnt = sp->mac_control.stats_info->sw_stat.soft_reset_cnt;
+	mem_alloc_cnt = sp->mac_control.stats_info->sw_stat.mem_allocated;
+	mem_free_cnt = sp->mac_control.stats_info->sw_stat.mem_freed;
+	watchdog_cnt = sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt;
+	/* save link up/down time/cnt, reset/memory/watchdog cnt */
 	memset(sp->mac_control.stats_info, 0, sizeof(struct stat_block));
-	/* restore reset count */
+	/* restore link up/down time/cnt, reset/memory/watchdog cnt */
+	sp->mac_control.stats_info->sw_stat.link_up_cnt = up_cnt;
+	sp->mac_control.stats_info->sw_stat.link_down_cnt = down_cnt;
+	sp->mac_control.stats_info->sw_stat.link_up_time = up_time;
+	sp->mac_control.stats_info->sw_stat.link_down_time = down_time;
 	sp->mac_control.stats_info->sw_stat.soft_reset_cnt = reset_cnt;
+	sp->mac_control.stats_info->sw_stat.mem_allocated = mem_alloc_cnt;
+	sp->mac_control.stats_info->sw_stat.mem_freed = mem_free_cnt;
+	sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt = watchdog_cnt;
 
 	/* SXE-002: Configure link and activity LED to turn it off */
 	subid = sp->pdev->subsystem_device;
@@ -3672,19 +3787,29 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
 	nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry),
 			       GFP_KERNEL);
 	if (nic->entries == NULL) {
-		DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+		DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \
+			__FUNCTION__);
+		nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
 		return -ENOMEM;
 	}
-	memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+	nic->mac_control.stats_info->sw_stat.mem_allocated 
+		+= (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+	memset(nic->entries, 0,MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
 
 	nic->s2io_entries =
 		kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry),
 				   GFP_KERNEL);
 	if (nic->s2io_entries == NULL) {
-		DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+		DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", 
+			__FUNCTION__);
+		nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
 		kfree(nic->entries);
+		nic->mac_control.stats_info->sw_stat.mem_freed 
+			+= (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
 		return -ENOMEM;
 	}
+	 nic->mac_control.stats_info->sw_stat.mem_allocated 
+		+= (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
 	memset(nic->s2io_entries, 0,
 	       MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
 
@@ -3708,7 +3833,8 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
 		rx_mat = readq(&bar0->rx_mat);
 		for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
 			rx_mat |= RX_MAT_SET(j, msix_indx);
-			nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+			nic->s2io_entries[msix_indx].arg 
+				= &nic->mac_control.rings[j];
 			nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
 			nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
 		}
@@ -3717,7 +3843,8 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
 		tx_mat = readq(&bar0->tx_mat0_n[7]);
 		for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
 			tx_mat |= TX_MAT_SET(i, msix_indx);
-			nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+			nic->s2io_entries[msix_indx].arg 
+				= &nic->mac_control.rings[j];
 			nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
 			nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
 		}
@@ -3734,7 +3861,11 @@ static int s2io_enable_msi_x(struct s2io_nic *nic)
 	if (ret) {
 		DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
 		kfree(nic->entries);
+		nic->mac_control.stats_info->sw_stat.mem_freed 
+			+= (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
 		kfree(nic->s2io_entries);
+		nic->mac_control.stats_info->sw_stat.mem_freed 
+		+= (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
 		nic->entries = NULL;
 		nic->s2io_entries = NULL;
 		nic->avail_msix_vectors = 0;
@@ -3802,10 +3933,16 @@ static int s2io_open(struct net_device *dev)
 
 hw_init_failed:
 	if (sp->intr_type == MSI_X) {
-		if (sp->entries)
+		if (sp->entries) {
 			kfree(sp->entries);
-		if (sp->s2io_entries)
+			sp->mac_control.stats_info->sw_stat.mem_freed 
+			+= (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+		}
+		if (sp->s2io_entries) {
 			kfree(sp->s2io_entries);
+			sp->mac_control.stats_info->sw_stat.mem_freed 
+			+= (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
+		}
 	}
 	return err;
 }
@@ -3866,6 +4003,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 	config = &sp->config;
 
 	DBG_PRINT(TX_DBG, "%s: In Neterion Tx routine\n", dev->name);
+
+	if (unlikely(skb->len <= 0)) {
+		DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name);
+		dev_kfree_skb_any(skb);
+		return 0;
+}
+
 	spin_lock_irqsave(&sp->tx_lock, flags);
 	if (atomic_read(&sp->card_state) == CARD_DOWN) {
 		DBG_PRINT(TX_DBG, "%s: Card going down for reset\n",
@@ -3876,7 +4020,6 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	queue = 0;
-
 	/* Get Fifo number to Transmit based on vlan priority */
 	if (sp->vlgrp && vlan_tx_tag_present(skb)) {
 		vlan_tag = vlan_tx_tag_get(skb);
@@ -3900,14 +4043,6 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 		return 0;
 	}
 
-	/* A buffer with no data will be dropped */
-	if (!skb->len) {
-		DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name);
-		dev_kfree_skb(skb);
-		spin_unlock_irqrestore(&sp->tx_lock, flags);
-		return 0;
-	}
-
 	offload_type = s2io_offload_type(skb);
 	if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) {
 		txdp->Control_1 |= TXD_TCP_LSO_EN;
@@ -4003,7 +4138,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 			  put_off, get_off);
 		netif_stop_queue(dev);
 	}
-
+	mac_control->stats_info->sw_stat.mem_allocated += skb->truesize;
 	dev->trans_start = jiffies;
 	spin_unlock_irqrestore(&sp->tx_lock, flags);
 
@@ -4775,6 +4910,40 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data)
 	return 0;
 }
 
+static void s2io_ethtool_gringparam(struct net_device *dev,
+                                    struct ethtool_ringparam *ering)
+{
+	struct s2io_nic *sp = dev->priv;
+	int i,tx_desc_count=0,rx_desc_count=0;
+
+	if (sp->rxd_mode == RXD_MODE_1)
+		ering->rx_max_pending = MAX_RX_DESC_1;
+	else if (sp->rxd_mode == RXD_MODE_3B)
+		ering->rx_max_pending = MAX_RX_DESC_2;
+	else if (sp->rxd_mode == RXD_MODE_3A)
+		ering->rx_max_pending = MAX_RX_DESC_3;
+
+	ering->tx_max_pending = MAX_TX_DESC;
+	for (i = 0 ; i < sp->config.tx_fifo_num ; i++) {
+		tx_desc_count += sp->config.tx_cfg[i].fifo_len;
+	}
+	DBG_PRINT(INFO_DBG,"\nmax txds : %d\n",sp->config.max_txds);
+	ering->tx_pending = tx_desc_count;
+	rx_desc_count = 0;
+	for (i = 0 ; i < sp->config.rx_ring_num ; i++) {
+		rx_desc_count += sp->config.rx_cfg[i].num_rxd;
+	}
+	ering->rx_pending = rx_desc_count;
+
+	ering->rx_mini_max_pending = 0;
+	ering->rx_mini_pending = 0;
+	if(sp->rxd_mode == RXD_MODE_1)
+		ering->rx_jumbo_max_pending = MAX_RX_DESC_1;
+	else if (sp->rxd_mode == RXD_MODE_3B)
+		ering->rx_jumbo_max_pending = MAX_RX_DESC_2;
+	ering->rx_jumbo_pending = rx_desc_count;
+}
+
 /**
  * s2io_ethtool_getpause_data -Pause frame frame generation and reception.
  * @sp : private member of the device structure, which is a pointer to the
@@ -4981,8 +5150,11 @@ static void s2io_vpd_read(struct s2io_nic *nic)
 	strcpy(nic->serial_num, "NOT AVAILABLE");
 
 	vpd_data = kmalloc(256, GFP_KERNEL);
-	if (!vpd_data)
+	if (!vpd_data) {
+		nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++;
 		return;
+	}
+	nic->mac_control.stats_info->sw_stat.mem_allocated += 256;
 
 	for (i = 0; i < 256; i +=4 ) {
 		pci_write_config_byte(nic->pdev, (vpd_addr + 2), i);
@@ -5022,6 +5194,7 @@ static void s2io_vpd_read(struct s2io_nic *nic)
 		memcpy(nic->product_name, &vpd_data[3], vpd_data[1]);
 	}
 	kfree(vpd_data);
+	nic->mac_control.stats_info->sw_stat.mem_freed += 256;
 }
 
 /**
@@ -5742,6 +5915,30 @@ static void s2io_get_ethtool_stats(struct net_device *dev,
 	}
 	else
 		tmp_stats[i++] = 0;
+	tmp_stats[i++] = stat_info->sw_stat.mem_alloc_fail_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.watchdog_timer_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.mem_allocated;
+	tmp_stats[i++] = stat_info->sw_stat.mem_freed;
+	tmp_stats[i++] = stat_info->sw_stat.link_up_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.link_down_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.link_up_time;
+	tmp_stats[i++] = stat_info->sw_stat.link_down_time;
+
+	tmp_stats[i++] = stat_info->sw_stat.tx_buf_abort_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.tx_desc_abort_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.tx_parity_err_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.tx_link_loss_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.tx_list_proc_err_cnt;
+
+	tmp_stats[i++] = stat_info->sw_stat.rx_parity_err_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.rx_abort_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.rx_parity_abort_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.rx_rda_fail_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.rx_unkn_prot_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.rx_fcs_err_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.rx_buf_size_err_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.rx_rxd_corrupt_cnt;
+	tmp_stats[i++] = stat_info->sw_stat.rx_unkn_err_cnt;
 }
 
 static int s2io_ethtool_get_regs_len(struct net_device *dev)
@@ -5854,6 +6051,7 @@ static const struct ethtool_ops netdev_ethtool_ops = {
 	.get_eeprom_len = s2io_get_eeprom_len,
 	.get_eeprom = s2io_ethtool_geeprom,
 	.set_eeprom = s2io_ethtool_seeprom,
+	.get_ringparam = s2io_ethtool_gringparam,
 	.get_pauseparam = s2io_ethtool_getpause_data,
 	.set_pauseparam = s2io_ethtool_setpause_data,
 	.get_rx_csum = s2io_ethtool_get_rx_csum,
@@ -5962,7 +6160,7 @@ static void s2io_tasklet(unsigned long dev_addr)
 			if (ret == -ENOMEM) {
 				DBG_PRINT(INFO_DBG, "%s: Out of ",
 					  dev->name);
-				DBG_PRINT(ERR_DBG, "memory in tasklet\n");
+				DBG_PRINT(INFO_DBG, "memory in tasklet\n");
 				break;
 			} else if (ret == -EFILL) {
 				DBG_PRINT(INFO_DBG,
@@ -6077,9 +6275,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
 			*skb = dev_alloc_skb(size);
 			if (!(*skb)) {
 				DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
-				DBG_PRINT(INFO_DBG, "memory to allocate SKBs\n");
+				DBG_PRINT(INFO_DBG, "memory to allocate ");
+				DBG_PRINT(INFO_DBG, "1 buf mode SKBs\n");
+				sp->mac_control.stats_info->sw_stat. \
+					mem_alloc_fail_cnt++;
 				return -ENOMEM ;
 			}
+			sp->mac_control.stats_info->sw_stat.mem_allocated 
+				+= (*skb)->truesize;
 			/* storing the mapped addr in a temp variable
 			 * such it will be used for next rxd whose
 			 * Host Control is NULL
@@ -6099,10 +6302,15 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
 		} else {
 			*skb = dev_alloc_skb(size);
 			if (!(*skb)) {
-				DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n",
-					dev->name);
+				DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
+				DBG_PRINT(INFO_DBG, "memory to allocate ");
+				DBG_PRINT(INFO_DBG, "2 buf mode SKBs\n");
+				sp->mac_control.stats_info->sw_stat. \
+					mem_alloc_fail_cnt++;
 				return -ENOMEM;
 			}
+			sp->mac_control.stats_info->sw_stat.mem_allocated 
+				+= (*skb)->truesize;
 			((struct RxD3*)rxdp)->Buffer2_ptr = *temp2 =
 				pci_map_single(sp->pdev, (*skb)->data,
 					       dev->mtu + 4,
@@ -6126,10 +6334,15 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
 		} else {
 			*skb = dev_alloc_skb(size);
 			if (!(*skb)) {
-				DBG_PRINT(INFO_DBG, "%s: dev_alloc_skb failed\n",
-					  dev->name);
+				DBG_PRINT(INFO_DBG, "%s: Out of ", dev->name);
+				DBG_PRINT(INFO_DBG, "memory to allocate ");
+				DBG_PRINT(INFO_DBG, "3 buf mode SKBs\n");
+				sp->mac_control.stats_info->sw_stat. \
+					mem_alloc_fail_cnt++;
 				return -ENOMEM;
 			}
+			sp->mac_control.stats_info->sw_stat.mem_allocated 
+				+= (*skb)->truesize;
 			((struct RxD3*)rxdp)->Buffer0_ptr = *temp0 =
 				pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN,
 					       PCI_DMA_FROMDEVICE);
@@ -6147,10 +6360,14 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
 			if (skb_shinfo(*skb)->frag_list == NULL) {
 				DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \
 					  failed\n ", dev->name);
+				sp->mac_control.stats_info->sw_stat. \
+					mem_alloc_fail_cnt++;
 				return -ENOMEM ;
 			}
 			frag_list = skb_shinfo(*skb)->frag_list;
 			frag_list->next = NULL;
+			sp->mac_control.stats_info->sw_stat.mem_allocated 
+				+= frag_list->truesize;
 			/*
 			 * Buffer-2 receives L4 data payload
 			 */
@@ -6566,6 +6783,7 @@ static void s2io_tx_watchdog(struct net_device *dev)
 	struct s2io_nic *sp = dev->priv;
 
 	if (netif_carrier_ok(dev)) {
+		sp->mac_control.stats_info->sw_stat.watchdog_timer_cnt++;
 		schedule_work(&sp->rst_timer_task);
 		sp->mac_control.stats_info->sw_stat.soft_reset_cnt++;
 	}
@@ -6606,7 +6824,53 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 		if (err & 0x1) {
 			sp->mac_control.stats_info->sw_stat.parity_err_cnt++;
 		}
+		err >>= 48;
+		switch(err) {
+			case 1:
+				sp->mac_control.stats_info->sw_stat.
+				rx_parity_err_cnt++;
+			break;
 
+			case 2:
+				sp->mac_control.stats_info->sw_stat.
+				rx_abort_cnt++;
+			break;
+
+			case 3:
+				sp->mac_control.stats_info->sw_stat.
+				rx_parity_abort_cnt++;
+			break;
+
+			case 4:
+				sp->mac_control.stats_info->sw_stat.
+				rx_rda_fail_cnt++;
+			break;
+
+			case 5:
+				sp->mac_control.stats_info->sw_stat.
+				rx_unkn_prot_cnt++;
+			break;
+
+			case 6:
+				sp->mac_control.stats_info->sw_stat.
+				rx_fcs_err_cnt++;
+			break;
+
+			case 7:
+				sp->mac_control.stats_info->sw_stat.
+				rx_buf_size_err_cnt++;
+			break;
+
+			case 8:
+				sp->mac_control.stats_info->sw_stat.
+				rx_rxd_corrupt_cnt++;
+			break;
+
+			case 15:
+				sp->mac_control.stats_info->sw_stat.
+				rx_unkn_err_cnt++;
+			break;
+		}
 		/*
 		* Drop the packet if bad transfer code. Exception being
 		* 0x5, which could be due to unsupported IPv6 extension header.
@@ -6614,10 +6878,12 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 		* Note that in this case, since checksum will be incorrect,
 		* stack will validate the same.
 		*/
-		if (err && ((err >> 48) != 0x5)) {
+		if (err != 0x5) {
 			DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n",
 				dev->name, err);
 			sp->stats.rx_crc_errors++;
+			sp->mac_control.stats_info->sw_stat.mem_freed 
+				+= skb->truesize;
 			dev_kfree_skb(skb);
 			atomic_dec(&sp->rx_bufs_left[ring_no]);
 			rxdp->Host_Control = 0;
@@ -6627,7 +6893,6 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 
 	/* Updating statistics */
 	rxdp->Host_Control = 0;
-	sp->stats.rx_packets++;
 	if (sp->rxd_mode == RXD_MODE_1) {
 		int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
 
@@ -6731,7 +6996,7 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp)
 	} else {
 		skb->ip_summed = CHECKSUM_NONE;
 	}
-
+	sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize;
 	if (!sp->lro) {
 		skb->protocol = eth_type_trans(skb, dev);
 		if ((sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2) &&
@@ -6780,12 +7045,21 @@ static void s2io_link(struct s2io_nic * sp, int link)
 		if (link == LINK_DOWN) {
 			DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
 			netif_carrier_off(dev);
+			if(sp->mac_control.stats_info->sw_stat.link_up_cnt)
+			sp->mac_control.stats_info->sw_stat.link_up_time = 
+				jiffies - sp->start_time;
+			sp->mac_control.stats_info->sw_stat.link_down_cnt++;
 		} else {
 			DBG_PRINT(ERR_DBG, "%s: Link Up\n", dev->name);
+			if (sp->mac_control.stats_info->sw_stat.link_down_cnt)
+			sp->mac_control.stats_info->sw_stat.link_down_time = 
+				jiffies - sp->start_time;
+			sp->mac_control.stats_info->sw_stat.link_up_cnt++;
 			netif_carrier_on(dev);
 		}
 	}
 	sp->last_link_state = link;
+	sp->start_time = jiffies;
 }
 
 /**
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index a656d18..54baa0b 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -95,6 +95,32 @@ struct swStat {
 	unsigned long long flush_max_pkts;
 	unsigned long long sum_avg_pkts_aggregated;
 	unsigned long long num_aggregations;
+	/* Other statistics */
+	unsigned long long mem_alloc_fail_cnt;
+	unsigned long long watchdog_timer_cnt;
+	unsigned long long mem_allocated;
+	unsigned long long mem_freed;
+	unsigned long long link_up_cnt;
+	unsigned long long link_down_cnt;
+	unsigned long long link_up_time;
+	unsigned long long link_down_time;
+
+	/* Transfer Code statistics */
+	unsigned long long tx_buf_abort_cnt;
+	unsigned long long tx_desc_abort_cnt;
+	unsigned long long tx_parity_err_cnt;
+	unsigned long long tx_link_loss_cnt;
+	unsigned long long tx_list_proc_err_cnt;
+
+	unsigned long long rx_parity_err_cnt;
+	unsigned long long rx_abort_cnt;
+	unsigned long long rx_parity_abort_cnt;
+	unsigned long long rx_rda_fail_cnt;
+	unsigned long long rx_unkn_prot_cnt;
+	unsigned long long rx_fcs_err_cnt;
+	unsigned long long rx_buf_size_err_cnt;
+	unsigned long long rx_rxd_corrupt_cnt;
+	unsigned long long rx_unkn_err_cnt;
 };
 
 /* Xpak releated alarm and warnings */
@@ -308,6 +334,11 @@ struct stat_block {
 #define MAX_TX_FIFOS 8
 #define MAX_RX_RINGS 8
 
+#define MAX_RX_DESC_1  (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 )
+#define MAX_RX_DESC_2  (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
+#define MAX_RX_DESC_3  (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 )
+#define MAX_TX_DESC    (MAX_AVAILABLE_TXDS)
+
 /* FIFO mappings for all possible number of fifos configured */
 static int fifo_map[][MAX_TX_FIFOS] = {
 	{0, 0, 0, 0, 0, 0, 0, 0},
@@ -819,6 +850,7 @@ struct s2io_nic {
 #define	LINK_UP		2
 
 	int task_flag;
+	unsigned long long start_time;
 #define CARD_DOWN 1
 #define CARD_UP 2
 	atomic_t card_state;
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index e048957..7766929 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3802,6 +3802,9 @@ static int skge_suspend(struct pci_dev *pdev, pm_message_t state)
 	struct skge_hw *hw  = pci_get_drvdata(pdev);
 	int i, err, wol = 0;
 
+	if (!hw)
+		return 0;
+
 	err = pci_save_state(pdev);
 	if (err)
 		return err;
@@ -3830,6 +3833,9 @@ static int skge_resume(struct pci_dev *pdev)
 	struct skge_hw *hw  = pci_get_drvdata(pdev);
 	int i, err;
 
+	if (!hw)
+		return 0;
+
 	err = pci_set_power_state(pdev, PCI_D0);
 	if (err)
 		goto out;
@@ -3868,6 +3874,9 @@ static void skge_shutdown(struct pci_dev *pdev)
 	struct skge_hw *hw  = pci_get_drvdata(pdev);
 	int i, wol = 0;
 
+	if (!hw)
+		return;
+
 	for (i = 0; i < hw->ports; i++) {
 		struct net_device *dev = hw->dev[i];
 		struct skge_port *skge = netdev_priv(dev);
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index a307310..104e204 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -40,6 +40,7 @@
 #include <linux/if_vlan.h>
 #include <linux/prefetch.h>
 #include <linux/mii.h>
+#include <linux/dmi.h>
 
 #include <asm/irq.h>
 
@@ -130,7 +131,7 @@ static const struct pci_device_id sky2_id_table[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) }, /* 88EC042 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
-	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
+//	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
 	{ 0 }
 };
 
@@ -150,6 +151,8 @@ static const char *yukon2_name[] = {
 	"FE",		/* 0xb7 */
 };
 
+static int dmi_blacklisted;
+
 /* Access to external PHY */
 static int gm_phy_write(struct sky2_hw *hw, unsigned port, u16 reg, u16 val)
 {
@@ -2531,6 +2534,17 @@ static int __devinit sky2_init(struct sky2_hw *hw)
 		return -EOPNOTSUPP;
 	}
 
+
+	/* Some Gigabyte motherboards have 88e8056 but cause problems
+	 * There is some unresolved hardware related problem that causes
+	 * descriptor errors and receive data corruption.
+	 */
+	if (hw->chip_id == CHIP_ID_YUKON_EC_U && dmi_blacklisted) {
+		dev_err(&hw->pdev->dev,
+			"88E8056 on this motherboard not supported\n");
+		return -EOPNOTSUPP;
+	}
+
 	hw->pmd_type = sky2_read8(hw, B2_PMD_TYP);
 	hw->ports = 1;
 	t8 = sky2_read8(hw, B2_Y2_HW_RES);
@@ -3578,17 +3592,6 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
 		goto err_out;
 	}
 
-	/* Some Gigabyte motherboards have 88e8056 but cause problems
-	 * There is some unresolved hardware related problem that causes
-	 * descriptor errors and receive data corruption.
-	 */
-	if (pdev->vendor == PCI_VENDOR_ID_MARVELL &&
-	    pdev->device == 0x4364 && pdev->subsystem_vendor == 0x1458) {
-		dev_err(&pdev->dev,
-			"88E8056 on Gigabyte motherboards not supported\n");
-		goto err_out_disable;
-	}
-
 	err = pci_request_regions(pdev, DRV_NAME);
 	if (err) {
 		dev_err(&pdev->dev, "cannot obtain PCI resources\n");
@@ -3732,6 +3735,7 @@ err_out_free_regions:
 err_out_disable:
 	pci_disable_device(pdev);
 err_out:
+	pci_set_drvdata(pdev, NULL);
 	return err;
 }
 
@@ -3784,6 +3788,9 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state)
 	struct sky2_hw *hw = pci_get_drvdata(pdev);
 	int i, wol = 0;
 
+	if (!hw)
+		return 0;
+
 	del_timer_sync(&hw->idle_timer);
 	netif_poll_disable(hw->dev[0]);
 
@@ -3815,6 +3822,9 @@ static int sky2_resume(struct pci_dev *pdev)
 	struct sky2_hw *hw = pci_get_drvdata(pdev);
 	int i, err;
 
+	if (!hw)
+		return 0;
+
 	err = pci_set_power_state(pdev, PCI_D0);
 	if (err)
 		goto out;
@@ -3861,6 +3871,9 @@ static void sky2_shutdown(struct pci_dev *pdev)
 	struct sky2_hw *hw = pci_get_drvdata(pdev);
 	int i, wol = 0;
 
+	if (!hw)
+		return;
+
 	del_timer_sync(&hw->idle_timer);
 	netif_poll_disable(hw->dev[0]);
 
@@ -3897,8 +3910,24 @@ static struct pci_driver sky2_driver = {
 	.shutdown = sky2_shutdown,
 };
 
+static struct dmi_system_id __initdata broken_dmi_table[] = {
+	{
+		.ident = "Gigabyte 965P-S3",
+		.matches = {
+			DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."),
+			DMI_MATCH(DMI_PRODUCT_NAME, "965P-S3"),
+
+		},
+	},
+	{ }
+};
+
 static int __init sky2_init_module(void)
 {
+	/* Look for sick motherboards */
+	if (dmi_check_system(broken_dmi_table))
+		dmi_blacklisted = 1;
+
 	return pci_register_driver(&sky2_driver);
 }
 
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index c15e972..108adbf 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -175,12 +175,10 @@ spider_net_setup_aneg(struct spider_net_card *card)
 {
 	struct mii_phy *phy = &card->phy;
 	u32 advertise = 0;
-	u16 bmcr, bmsr, stat1000, estat;
+	u16 bmsr, estat;
 
-	bmcr     = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMCR);
-	bmsr     = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
-	stat1000 = spider_net_read_phy(card->netdev, phy->mii_id, MII_STAT1000);
-	estat    = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS);
+	bmsr  = spider_net_read_phy(card->netdev, phy->mii_id, MII_BMSR);
+	estat = spider_net_read_phy(card->netdev, phy->mii_id, MII_ESTATUS);
 
 	if (bmsr & BMSR_10HALF)
 		advertise |= ADVERTISED_10baseT_Half;
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 8897f53..4fc8681 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -2,10 +2,7 @@
 # wan devices configuration
 #
 
-menu "Wan interfaces"
-	depends on NETDEVICES
-
-config WAN
+menuconfig WAN
 	bool "Wan interfaces support"
 	---help---
 	  Wide Area Networks (WANs), such as X.25, Frame Relay and leased
@@ -23,10 +20,12 @@ config WAN
 
 	  If unsure, say N.
 
+if WAN
+
 # There is no way to detect a comtrol sv11 - force it modular for now.
 config HOSTESS_SV11
 	tristate "Comtrol Hostess SV-11 support"
-	depends on WAN && ISA && m && ISA_DMA_API && INET
+	depends on ISA && m && ISA_DMA_API && INET
 	help
 	  Driver for Comtrol Hostess SV-11 network card which
 	  operates on low speed synchronous serial links at up to
@@ -38,7 +37,7 @@ config HOSTESS_SV11
 # The COSA/SRP driver has not been tested as non-modular yet.
 config COSA
 	tristate "COSA/SRP sync serial boards support"
-	depends on WAN && ISA && m && ISA_DMA_API
+	depends on ISA && m && ISA_DMA_API
 	---help---
 	  Driver for COSA and SRP synchronous serial boards.
 
@@ -62,7 +61,7 @@ config COSA
 #
 config LANMEDIA
 	tristate "LanMedia Corp. SSI/V.35, T1/E1, HSSI, T3 boards"
-	depends on WAN && PCI
+	depends on PCI
 	---help---
 	  Driver for the following Lan Media family of serial boards:
 
@@ -89,7 +88,7 @@ config LANMEDIA
 # There is no way to detect a Sealevel board. Force it modular
 config SEALEVEL_4021
 	tristate "Sealevel Systems 4021 support"
-	depends on WAN && ISA && m && ISA_DMA_API && INET
+	depends on ISA && m && ISA_DMA_API && INET
 	help
 	  This is a driver for the Sealevel Systems ACB 56 serial I/O adapter.
 
@@ -99,7 +98,6 @@ config SEALEVEL_4021
 # Generic HDLC
 config HDLC
 	tristate "Generic HDLC layer"
-	depends on WAN
 	help
 	  Say Y to this option if your Linux box contains a WAN (Wide Area
 	  Network) card supported by this driver and you are planning to
@@ -167,7 +165,7 @@ config HDLC_X25
 	  If unsure, say N.
 
 comment "X.25/LAPB support is disabled"
-	depends on WAN && HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
+	depends on HDLC && (LAPB!=m || HDLC!=m) && LAPB!=y
 
 config PCI200SYN
 	tristate "Goramo PCI200SYN support"
@@ -230,10 +228,10 @@ config PC300_MLPPP
 	  Multilink PPP over the PC300 synchronous communication boards.
 
 comment "Cyclades-PC300 MLPPP support is disabled."
-	depends on WAN && HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
+	depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
 
 comment "Refer to the file README.mlppp, provided by PC300 package."
-	depends on WAN && HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
+	depends on HDLC && PC300 && (PPP=n || !PPP_MULTILINK || PPP_SYNC_TTY=n || !HDLC_PPP)
 
 config PC300TOO
 	tristate "Cyclades PC300 RSV/X21 alternative support"
@@ -338,7 +336,6 @@ config DSCC4_PCI_RST
 
 config DLCI
 	tristate "Frame Relay DLCI support"
-	depends on WAN
 	---help---
 	  Support for the Frame Relay protocol.
 
@@ -385,7 +382,7 @@ config SDLA
 # Wan router core.
 config WAN_ROUTER_DRIVERS
 	tristate "WAN router drivers"
-	depends on WAN && WAN_ROUTER
+	depends on WAN_ROUTER
 	---help---
 	  Connect LAN to WAN via Linux box.
 
@@ -440,7 +437,7 @@ config CYCLOMX_X25
 # X.25 network drivers
 config LAPBETHER
 	tristate "LAPB over Ethernet driver (EXPERIMENTAL)"
-	depends on WAN && LAPB && X25
+	depends on LAPB && X25
 	---help---
 	  Driver for a pseudo device (typically called /dev/lapb0) which allows
 	  you to open an LAPB point-to-point connection to some other computer
@@ -456,7 +453,7 @@ config LAPBETHER
 
 config X25_ASY
 	tristate "X.25 async driver (EXPERIMENTAL)"
-	depends on WAN && LAPB && X25
+	depends on LAPB && X25
 	---help---
 	  Send and receive X.25 frames over regular asynchronous serial
 	  lines such as telephone lines equipped with ordinary modems.
@@ -471,7 +468,7 @@ config X25_ASY
 
 config SBNI
 	tristate "Granch SBNI12 Leased Line adapter support"
-	depends on WAN && X86
+	depends on X86
 	---help---
 	  Driver for ISA SBNI12-xx cards which are low cost alternatives to
 	  leased line modems.
@@ -497,5 +494,4 @@ config SBNI_MULTILINE
 
 	  If unsure, say N.
 
-endmenu
-
+endif # WAN
diff --git a/drivers/net/wireless/libertas/Makefile b/drivers/net/wireless/libertas/Makefile
index 19c9350..56a8ea1 100644
--- a/drivers/net/wireless/libertas/Makefile
+++ b/drivers/net/wireless/libertas/Makefile
@@ -1,5 +1,3 @@
-# EXTRA_CFLAGS += -Wpacked
-
 usb8xxx-objs := main.o fw.o wext.o \
 		rx.o tx.o cmd.o 	  \
 		cmdresp.o scan.o	  \
@@ -7,13 +5,6 @@ usb8xxx-objs := main.o fw.o wext.o \
 		ioctl.o debugfs.o	  \
 		ethtool.o assoc.o
 
-ifeq ($(CONFIG_LIBERTAS_USB_DEBUG), y)
-EXTRA_CFLAGS += -DDEBUG -DPROC_DEBUG
-endif
-
-
-# This is needed to support the newer boot2 bootloader (v >= 3104)
-EXTRA_CFLAGS += -DSUPPORT_BOOT_COMMAND
 usb8xxx-objs += if_bootcmd.o
 usb8xxx-objs += if_usb.o
 
diff --git a/drivers/net/wireless/libertas/README b/drivers/net/wireless/libertas/README
index 688da4c..3785772 100644
--- a/drivers/net/wireless/libertas/README
+++ b/drivers/net/wireless/libertas/README
@@ -40,64 +40,11 @@ NAME
 SYNOPSIS
 	iwpriv <ethX> <command> [sub-command] ...
 
-	iwpriv ethX version
-	iwpriv ethX scantype [sub-command]
-	iwpriv ethX getSNR <n>
-	iwpriv ethX getNF <n>
-	iwpriv ethX getRSSI <n>
-	iwpriv ethX setrxant <n>
-	iwpriv ethX getrxant
-	iwpriv ethX settxant <n>
-	iwpriv ethX gettxant
-	iwpriv ethX authalgs <n>
-	iwpriv ethX pre-TBTT <n>
-	iwpriv ethX 8021xauthalgs <n>
-	iwpriv ethX encryptionmode <n>
 	iwpriv ethX setregioncode <n>
 	iwpriv ethX getregioncode
-	iwpriv ethX setbcnavg <n>
-	iwpriv ethX getbcnavg
-	iwpriv ethX setdataavg <n>
-	iwpriv ethX setlisteninter <n>
-	iwpriv ethX getlisteninter
-	iwpriv ethX setmultipledtim <n>
-	iwpriv ethX getmultipledtim
-	iwpriv ethX atimwindow <n>
-	iwpriv ethX deauth
-	iwpriv ethX adhocstop
-	iwpriv ethX radioon
-	iwpriv ethX radiooff
-	iwpriv ethX reasso-on
-	iwpriv ethX reasso-off
-	iwpriv ethX scanmode  [sub-command]
-	iwpriv ethX setwpaie <n>
-	iwpriv ethX wlanidle-off
-	iwpriv ethX wlanidle-on
-	iwpriv ethX getcis
-	iwpriv ethX getlog
-	iwpriv ethX getadhocstatus
-	iwpriv ethX adhocgrate <n>
-
-Version 4 Command:
-	iwpriv ethX inactvityto <n>
-	iwpriv ethX sleeppd <n>
-	iwpriv ethX enable11d <n>
-	iwpriv ethX tpccfg <n>
-	iwpriv ethX powercfg <n>
-	iwpriv ethX setafc <n>
-	iwpriv ethX getafc
 
 Version 5 Command:
 	iwpriv ethX ledgpio <n>
-	iwpriv ethX scanprobes <n>
-	iwpriv ethX lolisteninter <n>
-	iwpriv ethX rateadapt <n> <m>
-	iwpriv ethX txcontrol <n>
-	iwpriv ethX psnullinterval <n>
-	iwpriv ethX prescan <n>
-	iwpriv ethX getrxinfo
-	iwpriv ethX gettxrate
-	iwpriv ethX beaconinterval
 
 BT Commands:
 	The blinding table (BT) contains a list of mac addresses that should be
@@ -150,114 +97,6 @@ DESCRIPTION
 	The ethX parameter specifies the network device that is to be used to
 		perform this command on. it could be eth0, eth1 etc.
 
-version
-	This is used to get the current version of the driver and the firmware.
-
-scantype
-	This command is used to set the scan type to be used by the driver in
-	the scan command. This setting will not be used while performing a scan
-	for a specific SSID, as it is always done with scan type being active.
-
-	where the sub-commands are: -
-			active 	-- to set the scan type to active
-			passive -- to set the scan type to passive
-			get 	-- to get the scan type set in the driver
-
-getSNR
-	This command gets the average and non average value of Signal to Noise
-	Ratio of Beacon and Data.
-
-	where value is:-
-			0 	-- Beacon non-average.
-			1 	-- Beacon average.
-			2 	-- Data non-average.
-			3 	-- Data average.
-
-	If no value is given, all four values are returned in the order mentioned
-	above.
-
-	Note: This command is available only when STA is connected.
-
-getRSSI
-	This command gets the average and non average value os Receive Signal
-	Strength of Beacon and Data.
-
-	where value is:-
-			0 	-- Beacon non-average.
-			1 	-- Beacon average.
-			2 	-- Data non-average.
-			3 	-- Data average.
-
-	Note: This command is available only when STA is connected.
-
-getNF
-	This command gets the average and non average value of Noise Floor of
-	Beacon and Data.
-
-	where value is:-
-			0 	-- Beacon non-average.
-			1 	-- Beacon average.
-			2 	-- Data non-average.
-			3 	-- Data average.
-
-	Note: This command is available only when STA is connected.
-
-setrxant
-	This command is used to set the mode for Rx antenna.
-
-	The options that can be sent are:-
-			1 	-- Antenna 1.
-			2 	-- Antenna 2.
-			0xFFFF 	-- Diversity.
-
-	Usage:
-		iwpriv ethX setrxant 0x01: select Antenna 1.
-
-getrxant
-	This command is used to get the mode for Rx antenna.
-
-
-settxant
-	This command is used to set the mode for Tx antenna.
-		The options that can be sent are:-
-			1 	-- Antenna 1.
-			2 	-- Antenna 2.
-			0xFFFF 	-- Diversity.
-	Usage:
-		iwpriv ethX settxant 0x01: select Antenna 1.
-
-gettxant
-	This command is used to get the mode for Tx antenna.
-
-authalgs
-	This command is used by the WPA supplicant to set the authentication
-	algorithms in the station.
-
-8021xauthalgs
-	This command is used by the WPA supplicant to set the 8021.x authentication algorithm type
-	station.
-
-	where values can be:-
-			1 	-- None
-			2 	-- LEAP
-			4 	-- TLS
-			8 	-- TTLs
-			16	-- MD5
-
-
-encryptionmode
-	This command is used by the WPA supplicant to set the encryption algorithm.
-
-	where values can be:-
-			0 	-- NONE
-			1 	-- WEP40
-			2 	-- TKIP
-			3 	-- CCMP
-			4 	-- WEP104
-
-pre-TBTT
-	This command is used to set pre-TBTT time period where value is in microseconds.
-
 setregioncode
 	This command is used to set the region code in the station.
 	where value is 'region code' for various regions like
@@ -270,114 +109,6 @@ getregioncode
 	This command is used to get the region code information set in the
 	station.
 
-setbcnavg
-	Set the weighting factor for calculating RSSI.
-
-getbcnavg
-	Get weighting factor for calculating RSSI.
-
-setdataavg
-	Set the weighting factor for calculating SNR.
-
-setlisteninter
-	This command is used to set the listen interval in the
-	station.
-
-	where the value ranges between 1 - 255
-
-getlisteninter
-	This command is used to get the listen interval value set in the
-	station.
-
-setmultipledtim
-	This command is used to set the multiple dtim value in the
-	station.
-		where the value is 1,2,3,4,5,0xfffe
-		0xfffe means the firmware will use listen interval in association
-		command for waking up
-
-getmultipledtim
-	This command is used to get the multiple dtim value set in the station.
-
-atimwindow
-	This command is used to set the atim value in the
-	station.
-
-	where the value ranges between 0 - 50
-
-deauth
-	This command is used to send the de-authentication to the AP with which
-	the station is associated. This command is valid only when
-	station is in Infrastructure mode.
-
-	Note: This command is available only when STA is connected.
-
-adhocstop
-	This command is used to stop beacon transmission from the station and
-	go into idle state in ad-hoc mode.
-
-	Note: This command is available only when STA is connected.
-
-radioon
-	This command is used to turn on the RF antenna.
-
-radiooff
-	This command is sued to turn off the RF antenna.
-
-scanmode
-	This command is used to set the station to scan for either IBSS
-	networks or BSS networks or both BSS and IBSS networks. This
-	command can be used with sub commands,
-
-	where the value for
-			bss 	-- Scan All the BSS networks.
-			ibss 	-- Scan All the IBSS networks.
-			any 	-- Scan both BSS and IBSS networks.
-
-
-
-setwpaie
-	This command is used by WPA supplicant to send the WPA-IE to the driver.
-
-wlanidle-off
-	This command is used to get into idle state.
-
-	Note: This command is available only when STA is connected.
-
-wlanidle-on
-	This command is used to get off the idle state.
-
-	Note: This command is available only when STA is connected.
-
-
-getlog
-	This command is used to get the 802.11 statistics available in the
-		station.
-
-	Note: This command is available only when STA is connected.
-
-getadhocstatus
-	This command is used to get the ad-hoc Network Status.
-
-	The various status codes are:
-		AdhocStarted
-		AdhocJoined
-		AdhocIdle
-		InfraMode
-		AutoUnknownMode
-
-	Note: This command is available only when STA is connected.
-
-adhocgrate
-	This command is used to enable(1) g_rate, Disable(0) g_rate
-	and request(2) the status which g_rate is disabled/enabled,
-	for Ad-hoc creator.
-
-	where value is:-
-		0	-- Disabled
-		1	-- Enabled
-		2	-- Get
-
 ledgpio
 	This command is used to set/get LEDs.
 
@@ -400,253 +131,6 @@ ledgpio
 	Note: LED0 is invalid
 	Note: Maximum Number of LEDs are 16.
 
-inactivityto
-	This command is used by the host to set/get the inactivity timeout value,
-	which specifies when WLAN device is put to sleep.
-
-	Usage:
-		iwpriv ethX inactivityto [<timeout>]
-
-	where the parameter are:
-		timeout: timeout value in milliseconds.
-
-	Example:
-		iwpriv eth1 inactivityto
-			"get the timeout value"
-
-		iwpriv eth1 inactivityto X
-			"set timeout value to X ms"
-
-
-sleeppd
-	This command is used to configure the sleep period of the WLAN device.
-
-	Usage:
-		iwpriv ethX sleeppd [<sleep period>]
-
-	where the parameter are:
-		Period: sleep period in milliseconds. Range 10~60.
-
-	Example:
-		iwpriv eth1 sleeppd 10
-			"set period as 10 ms"
-		iwpriv eth1 sleeppd
-			"get the sleep period configuration"
-
-enable11d
-	This command is used to control 11d
-	where value is:-
-		1	-- Enabled
-		0	-- Disabled
-		2	-- Get
-
-
-
-
-tpccfg
-	Enables or disables automatic transmit power control.
-
-	The first parameter turns this feature on (1) or off (0).  When turning
-	on, the user must also supply four more parameters in the following
-	order:
-		-UseSNR (Use SNR (in addition to PER) for TPC algorithm),
-		-P0 (P0 power level for TPC),
-		-P1 (P1 power level for TPC),
-		-P2 (P2 power level for TPC).
-
-	Usage:
-		iwpriv ethX tpccfg: Get current configuration
-		iwpriv ethX tpccfg 0: disable auto TPC
-		iwpriv ethX tpccfg 0x01 0x00 0x05 0x0a 0x0d: enable auto TPC; do not use SNR;
-							     P0=0x05; P1=0x0a; P2=0x0d;
-		iwpriv ethX tpccfg 0x01 0x01 0x05 0x0a 0x0d: enable auto TPC; use SNR;
-							     P0=0x05; P1=0x0a; P2=0x0d.
-
-powercfg
-	Enables or disables power adaptation.
-
-	The first parameter turns this feature on (1) or off (0).  When turning
-	on, the user must also supply three more parameters in the following
-	order:
-		-P0 (P0 power level for Power Adaptation),
-		-P1 (P1 power level for Power Adaptation),
-		-P2 (P2 power level for Power Adaptation).
-
-	Usage:
-		iwpriv ethX powercfg: Get current configuration
-		iwpriv ethX powercfg 0: disable power adaptation
-		iwpriv ethX powercfg 1 0x0d 0x0f 0x12: enable power adaptation;
-						       P0=0x0d; P1=0x0f; P2=0x12.
-
-getafc
-	This command returns automatic frequency control parameters.  It returns
-	three integers:
-		-P0: automatic is on (1), or off (0),
-		-P1: current timing offset in PPM (part per million), and
-		-P2: current frequency offset in PPM.
-
-setafc
-	Set automatic frequency control options.
-
-	The first parameter turns automatic on (1) or off (0).
-	The user must supply two more parameters in either case, in the following
-  order:
-
-  When auto is on:
-
-		-P0 (automatic adjustment frequency threshold in PPM),
-		-P1 (automatic adjustment period in beacon period),
-
-  When auto is off:
-
-		-P0 (manual adjustment timing offset in PPM), and
-		-P1 (manual adjustment frequency offset in PPM).
-
-	Usage:
-		iwpriv ethX setafc 0 10 10: manual adjustment, both timing and frequcncy
-    offset are 10 PPM.
-
-		iwpriv ethX setafc 1 10 10 enable afc, automatic adjustment,
-    frequency threshold 10 PPM, for every 10 beacon periods.
-
-
-
-scanprobes
-	This command sets number of probe requests per channel.
-
-	Usage:
-		iwpriv ethX scanprobes 3 (set scan probes to 3)
-		iwpriv ethX scanprobes   (get scan probes)
-
-lolisteninter
-	This command sets the value of listen interval.
-
-	Usage:
-	iwpriv ethX lolisteninter 234 (set the lolisteninter to 234)
-	iwpriv ethX lolisteninter     (get the lolisteninter value)
-
-rateadapt
-	This command sets the data rates bitmap.
-	Where <n>
-		0: Disable auto rate adapt
-		1: Enable auto rate adapt
-
-	      <m>
-		 data rate bitmap
-			Bit	Data rate
-			0	1 Mbps
-			1	2 Mbps
-			2	5.5 Mbps
-			3	11 Mbps
-			4	Reserved
-			5	6 Mbps
-			6	9 Mbps
-			7	12 Mbps
-			8	18 Mbps
-			9	24 Mbps
-			10	36 Mbps
-			11	48 Mbps
-			12	54 Mbps
-			12-15	Reserved
-
-	Usage:
-	iwpriv ethX rateadapt
-			read the currect data rate setting
-	iwpriv ethX rateadapt 1 0x07
-			enable auto data rate adapt and
-			data rates are 1Mbps, 2Mbsp and 5.5Mbps
-
-
-txcontrol
-	This command is used to set the Tx rate, ack policy, and retry limit on a per packet basis.
-
-	Where value <n> is:
-	    if bit[4] == 1:
-		bit[3:0]        -- 0   1   2   3   4   5   6   7   8   9   10   11   12   13-16
-		Data Rate(Mbps) -- 1   2   5.5 11  Rsv 6   9   12  18  24  36   48   54   Rsv
-
-	    bit[12:8]
-		if bit[12] == 1, bit[11:8] specifies the Tx retry limit.
-
-	    bit[14:13] specifies per packet ack policy:
-		bit[14:13]
-		     1  0	use immediate ack policy for this packet
-		     1  1       use no ack policy for this packet
-		     0  x	use the per-packet ack policy setting
-
-	Usage:
-	iwpriv ethX txcontrol 0x7513
-			Use no-ack policy, 5 retires for Tx, 11Mbps rate
-
-
-
-psnullinterval
-	This command is used to set/request NULL package interval for Power Save
-	under infrastructure mode.
-
-	where value is:-
-		-1	-- Disabled
-		n>0	-- Set interval as n (seconds)
-
-prescan
-	This command is used to enable (1)/disable(0) auto prescan before assoicate to the ap
-
-	where value is:-
-		0	-- Disabled
-		1	-- Enabled
-		2       -- Get
-
-getrxinfo
-	This command gets non average value of Signal to Noise Ratio of Data and rate index.
-
-	The following table shows RateIndex and Rate
-
-		     RateIndex	Data rate
-			0	1 Mbps
-			1	2 Mbps
-			2	5.5 Mbps
-			3	11 Mbps
-			4	Reserved
-			5	6 Mbps
-			6	9 Mbps
-			7	12 Mbps
-			8	18 Mbps
-			9	24 Mbps
-			10	36 Mbps
-			11	48 Mbps
-			12	54 Mbps
-			13-15	Reserved
-
-gettxrate
-	This command gets current Tx rate index of the first packet associated with Rate Adaptation.
-
-	The following table shows RateIndex and Rate
-
-		     RateIndex	Data rate
-			0	1 Mbps
-			1	2 Mbps
-			2	5.5 Mbps
-			3	11 Mbps
-			4	Reserved
-			5	6 Mbps
-			6	9 Mbps
-			7	12 Mbps
-			8	18 Mbps
-			9	24 Mbps
-			10	36 Mbps
-			11	48 Mbps
-			12	54 Mbps
-			13-15	Reserved
-
-bcninterval
-	This command is used to sets beacon interval in adhoc mode when an argument is given, and gets current adhoc
-	beacon interval when no argument is given. The valid beacon interval is between 20 - 1000,
-	default beacon interval is 100.
-
-	Usage:
-		iwpriv ethX bcninterval 100  (set adhoc beacon interval to 100)
-		iwpriv ethX bcninterval      (get adhoc beacon interval)
-
 fwt_add
 	This command is used to insert an entry into the FWT table. The list of
 	parameters must follow the following structure:
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index b55c7f5..c260bd1 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -23,13 +23,13 @@ static int assoc_helper_essid(wlan_private *priv,
 	ENTER();
 
 	lbs_pr_debug(1, "New SSID requested: %s\n", assoc_req->ssid.ssid);
-	if (assoc_req->mode == wlan802_11infrastructure) {
+	if (assoc_req->mode == IW_MODE_INFRA) {
 		if (adapter->prescan) {
 			libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 1);
 		}
 
 		i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid,
-				NULL, wlan802_11infrastructure);
+				NULL, IW_MODE_INFRA);
 		if (i >= 0) {
 			lbs_pr_debug(1,
 			       "SSID found in scan list ... associating...\n");
@@ -44,7 +44,7 @@ static int assoc_helper_essid(wlan_private *priv,
 			lbs_pr_debug(1, "SSID '%s' not found; cannot associate\n",
 				assoc_req->ssid.ssid);
 		}
-	} else if (assoc_req->mode == wlan802_11ibss) {
+	} else if (assoc_req->mode == IW_MODE_ADHOC) {
 		/* Scan for the network, do not save previous results.  Stale
 		 *   scan data will cause us to join a non-existant adhoc network
 		 */
@@ -52,7 +52,7 @@ static int assoc_helper_essid(wlan_private *priv,
 
 		/* Search for the requested SSID in the scan table */
 		i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, NULL,
-				wlan802_11ibss);
+				IW_MODE_ADHOC);
 		if (i >= 0) {
 			lbs_pr_debug(1, "SSID found at %d in List, so join\n", ret);
 			libertas_join_adhoc_network(priv, &adapter->scantable[i]);
@@ -90,10 +90,10 @@ static int assoc_helper_bssid(wlan_private *priv,
 		goto out;
 	}
 
-	if (assoc_req->mode == wlan802_11infrastructure) {
+	if (assoc_req->mode == IW_MODE_INFRA) {
 		ret = wlan_associate(priv, &adapter->scantable[i]);
 		lbs_pr_debug(1, "ASSOC: return from wlan_associate(bssd) was %d\n", ret);
-	} else if (assoc_req->mode == wlan802_11ibss) {
+	} else if (assoc_req->mode == IW_MODE_ADHOC) {
 		libertas_join_adhoc_network(priv, &adapter->scantable[i]);
 	}
 	memcpy(&assoc_req->ssid, &adapter->scantable[i].ssid,
@@ -142,23 +142,23 @@ static int assoc_helper_mode(wlan_private *priv,
 
 	ENTER();
 
-	if (assoc_req->mode == adapter->inframode) {
+	if (assoc_req->mode == adapter->mode) {
 		LEAVE();
 		return 0;
 	}
 
-	if (assoc_req->mode == wlan802_11infrastructure) {
+	if (assoc_req->mode == IW_MODE_INFRA) {
 		if (adapter->psstate != PS_STATE_FULL_POWER)
 			libertas_ps_wakeup(priv, cmd_option_waitforrsp);
 		adapter->psmode = wlan802_11powermodecam;
 	}
 
-	adapter->inframode = assoc_req->mode;
+	adapter->mode = assoc_req->mode;
 	ret = libertas_prepare_and_send_command(priv,
 				    cmd_802_11_snmp_mib,
 				    0, cmd_option_waitforrsp,
 				    OID_802_11_INFRASTRUCTURE_MODE,
-				    (void *) assoc_req->mode);
+				    (void *) (size_t) assoc_req->mode);
 
 	LEAVE();
 	return ret;
@@ -196,7 +196,7 @@ static int assoc_helper_wep_keys(wlan_private *priv,
 		goto out;
 
 	/* enable/disable the MAC's WEP packet filter */
-	if (assoc_req->secinfo.WEPstatus == wlan802_11WEPenabled)
+	if (assoc_req->secinfo.wep_enabled)
 		adapter->currentpacketfilter |= cmd_act_mac_wep_enable;
 	else
 		adapter->currentpacketfilter &= ~cmd_act_mac_wep_enable;
@@ -300,8 +300,7 @@ static int should_deauth_infrastructure(wlan_adapter *adapter,
 	}
 
 	if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) {
-		if (adapter->secinfo.authmode !=
-		    assoc_req->secinfo.authmode) {
+		if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) {
 			lbs_pr_debug(1, "Deauthenticating due to updated security "
 				"info in configuration request.\n");
 			return 1;
@@ -316,7 +315,7 @@ static int should_deauth_infrastructure(wlan_adapter *adapter,
 
 	/* FIXME: deal with 'auto' mode somehow */
 	if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
-		if (assoc_req->mode != wlan802_11infrastructure)
+		if (assoc_req->mode != IW_MODE_INFRA)
 			return 1;
 	}
 
@@ -333,12 +332,12 @@ static int should_stop_adhoc(wlan_adapter *adapter,
 	if (adapter->curbssparams.ssid.ssidlength != assoc_req->ssid.ssidlength)
 		return 1;
 	if (memcmp(adapter->curbssparams.ssid.ssid, assoc_req->ssid.ssid,
-			sizeof(struct WLAN_802_11_SSID)))
+			adapter->curbssparams.ssid.ssidlength))
 		return 1;
 
 	/* FIXME: deal with 'auto' mode somehow */
 	if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) {
-		if (assoc_req->mode != wlan802_11ibss)
+		if (assoc_req->mode != IW_MODE_ADHOC)
 			return 1;
 	}
 
@@ -382,7 +381,7 @@ void wlan_association_worker(struct work_struct *work)
 	}
 
 	if (find_any_ssid) {
-		enum WLAN_802_11_NETWORK_INFRASTRUCTURE new_mode;
+		u8 new_mode;
 
 		ret = libertas_find_best_network_SSID(priv, &assoc_req->ssid,
 				assoc_req->mode, &new_mode);
@@ -393,7 +392,7 @@ void wlan_association_worker(struct work_struct *work)
 		}
 
 		/* Ensure we switch to the mode of the AP */
-		if (assoc_req->mode == wlan802_11autounknown) {
+		if (assoc_req->mode == IW_MODE_AUTO) {
 			set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
 			assoc_req->mode = new_mode;
 		}
@@ -403,7 +402,7 @@ void wlan_association_worker(struct work_struct *work)
 	 * Check if the attributes being changing require deauthentication
 	 * from the currently associated infrastructure access point.
 	 */
-	if (adapter->inframode == wlan802_11infrastructure) {
+	if (adapter->mode == IW_MODE_INFRA) {
 		if (should_deauth_infrastructure(adapter, assoc_req)) {
 			ret = libertas_send_deauthentication(priv);
 			if (ret) {
@@ -412,7 +411,7 @@ void wlan_association_worker(struct work_struct *work)
 					ret);
 			}
 		}
-	} else if (adapter->inframode == wlan802_11ibss) {
+	} else if (adapter->mode == IW_MODE_ADHOC) {
 		if (should_stop_adhoc(adapter, assoc_req)) {
 			ret = libertas_stop_adhoc_network(priv);
 			if (ret) {
@@ -543,7 +542,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter)
 		assoc_req->channel = adapter->curbssparams.channel;
 
 	if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags))
-		assoc_req->mode = adapter->inframode;
+		assoc_req->mode = adapter->mode;
 
 	if (!test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) {
 		memcpy(&assoc_req->bssid, adapter->curbssparams.bssid,
diff --git a/drivers/net/wireless/libertas/cmd.c b/drivers/net/wireless/libertas/cmd.c
index bfdac58..de9cb46 100644
--- a/drivers/net/wireless/libertas/cmd.c
+++ b/drivers/net/wireless/libertas/cmd.c
@@ -381,15 +381,16 @@ static int wlan_cmd_802_11_snmp_mib(wlan_private * priv,
 	switch (cmd_oid) {
 	case OID_802_11_INFRASTRUCTURE_MODE:
 	{
-		enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode =
-			(enum WLAN_802_11_NETWORK_INFRASTRUCTURE) pdata_buf;
+		u8 mode = (u8) (size_t) pdata_buf;
 		pSNMPMIB->querytype = cpu_to_le16(cmd_act_set);
 		pSNMPMIB->oid = cpu_to_le16((u16) desired_bsstype_i);
 		pSNMPMIB->bufsize = sizeof(u8);
-		if (mode == wlan802_11infrastructure)
-			ucTemp = SNMP_MIB_VALUE_INFRA;
-		else
+		if (mode == IW_MODE_ADHOC) {
 			ucTemp = SNMP_MIB_VALUE_ADHOC;
+		} else {
+			/* Infra and Auto modes */
+			ucTemp = SNMP_MIB_VALUE_INFRA;
+		}
 
 		memmove(pSNMPMIB->value, &ucTemp, sizeof(u8));
 
@@ -947,8 +948,8 @@ void libertas_queue_cmd(wlan_adapter * adapter, struct cmd_ctrl_node *cmdnode, u
 
 	spin_unlock_irqrestore(&adapter->driver_lock, flags);
 
-	lbs_pr_debug(1, "QUEUE_CMD: Inserted node=0x%x, cmd=0x%x in cmdpendingq\n",
-	       (u32) cmdnode,
+	lbs_pr_debug(1, "QUEUE_CMD: Inserted node=%p, cmd=0x%x in cmdpendingq\n",
+	       cmdnode,
 	       ((struct cmd_ds_gen*)cmdnode->bufvirtualaddr)->command);
 
 done:
@@ -976,8 +977,8 @@ static int DownloadcommandToStation(wlan_private * priv,
 	ENTER();
 
 	if (!adapter || !cmdnode) {
-		lbs_pr_debug(1, "DNLD_CMD: adapter = %#x, cmdnode = %#x\n",
-		       (int)adapter, (int)cmdnode);
+		lbs_pr_debug(1, "DNLD_CMD: adapter = %p, cmdnode = %p\n",
+		       adapter, cmdnode);
 		if (cmdnode) {
 			spin_lock_irqsave(&adapter->driver_lock, flags);
 			__libertas_cleanup_and_insert_cmd(priv, cmdnode);
@@ -1174,8 +1175,8 @@ int libertas_prepare_and_send_command(wlan_private * priv,
 
 	cmdptr = (struct cmd_ds_command *)cmdnode->bufvirtualaddr;
 
-	lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr =0x%x, command=0x%X\n",
-	       (u32) cmdptr, cmd_no);
+	lbs_pr_debug(1, "PREP_CMD: Val of cmd ptr=%p, command=0x%X\n",
+	       cmdptr, cmd_no);
 
 	if (!cmdptr) {
 		lbs_pr_debug(1, "PREP_CMD: bufvirtualaddr of cmdnode is NULL\n");
diff --git a/drivers/net/wireless/libertas/cmdresp.c b/drivers/net/wireless/libertas/cmdresp.c
index cdb012c..c864540 100644
--- a/drivers/net/wireless/libertas/cmdresp.c
+++ b/drivers/net/wireless/libertas/cmdresp.c
@@ -72,8 +72,6 @@ void libertas_mac_event_disconnected(wlan_private * priv)
 	adapter->secinfo.WPAenabled = 0;
 	adapter->secinfo.WPA2enabled = 0;
 	adapter->wpa_ie_len = 0;
-	adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE;
-	adapter->secinfo.Encryptionmode = CIPHER_NONE;
 
 	adapter->connect_status = libertas_disconnected;
 
@@ -811,7 +809,7 @@ int libertas_process_rx_command(wlan_private * priv)
 		if (result) {
 			lbs_pr_debug(1, "CMD_RESP: PS command failed- %#x \n",
 			       resp->result);
-			if (adapter->inframode == wlan802_11ibss) {
+			if (adapter->mode == IW_MODE_ADHOC) {
 				/*
 				 * We should not re-try enter-ps command in
 				 * ad-hoc mode. It takes place in
diff --git a/drivers/net/wireless/libertas/debugfs.c b/drivers/net/wireless/libertas/debugfs.c
index 51dfd20..7d7bc5e 100644
--- a/drivers/net/wireless/libertas/debugfs.c
+++ b/drivers/net/wireless/libertas/debugfs.c
@@ -7,6 +7,7 @@
 #include "dev.h"
 #include "decl.h"
 #include "host.h"
+#include "debugfs.h"
 
 static struct dentry *libertas_dir = NULL;
 static char *szStates[] = {
@@ -276,7 +277,7 @@ static void libertas_parse_ssid(char *buf, size_t count,
 	if (!end)
 		end = buf + count - 1;
 
-	size = min(IW_ESSID_MAX_SIZE, end - hold);
+	size = min((size_t)IW_ESSID_MAX_SIZE, (size_t) (end - hold));
 	strncpy(scan_cfg->specificSSID, hold, size);
 
 	return;
@@ -1648,7 +1649,7 @@ struct libertas_debugfs_files {
 	struct file_operations fops;
 };
 
-struct libertas_debugfs_files debugfs_files[] = {
+static struct libertas_debugfs_files debugfs_files[] = {
 	{ "info", 0444, FOPS(libertas_dev_info, write_file_dummy), },
 	{ "getscantable", 0444, FOPS(libertas_getscantable,
 					write_file_dummy), },
@@ -1658,7 +1659,7 @@ struct libertas_debugfs_files debugfs_files[] = {
 	{ "setuserscan", 0600, FOPS(NULL, libertas_setuserscan), },
 };
 
-struct libertas_debugfs_files debugfs_events_files[] = {
+static struct libertas_debugfs_files debugfs_events_files[] = {
 	{"low_rssi", 0644, FOPS(libertas_lowrssi_read,
 				libertas_lowrssi_write), },
 	{"low_snr", 0644, FOPS(libertas_lowsnr_read,
@@ -1673,7 +1674,7 @@ struct libertas_debugfs_files debugfs_events_files[] = {
 				libertas_highsnr_write), },
 };
 
-struct libertas_debugfs_files debugfs_regs_files[] = {
+static struct libertas_debugfs_files debugfs_regs_files[] = {
 	{"rdmac", 0644, FOPS(libertas_rdmac_read, libertas_rdmac_write), },
 	{"wrmac", 0600, FOPS(NULL, libertas_wrmac_write), },
 	{"rdbbp", 0644, FOPS(libertas_rdbbp_read, libertas_rdbbp_write), },
@@ -1778,7 +1779,7 @@ void libertas_debugfs_remove_one(wlan_private *priv)
 struct debug_data {
 	char name[32];
 	u32 size;
-	u32 addr;
+	size_t addr;
 };
 
 /* To debug any member of wlan_adapter, simply add one line here.
@@ -1825,6 +1826,8 @@ static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
 			val = *((u16 *) d[i].addr);
 		else if (d[i].size == 4)
 			val = *((u32 *) d[i].addr);
+		else if (d[i].size == 8)
+			val = *((u64 *) d[i].addr);
 
 		pos += sprintf(p + pos, "%s=%d\n", d[i].name, val);
 	}
@@ -1844,7 +1847,7 @@ static ssize_t wlan_debugfs_read(struct file *file, char __user *userbuf,
  *  @param data    data to write
  *  @return 	   number of data
  */
-static int wlan_debugfs_write(struct file *f, const char __user *buf,
+static ssize_t wlan_debugfs_write(struct file *f, const char __user *buf,
 			    size_t cnt, loff_t *ppos)
 {
 	int r, i;
@@ -1886,12 +1889,14 @@ static int wlan_debugfs_write(struct file *f, const char __user *buf,
 				*((u16 *) d[i].addr) = (u16) r;
 			else if (d[i].size == 4)
 				*((u32 *) d[i].addr) = (u32) r;
+			else if (d[i].size == 8)
+				*((u64 *) d[i].addr) = (u64) r;
 			break;
 		} while (1);
 	}
 	kfree(pdata);
 
-	return cnt;
+	return (ssize_t)cnt;
 }
 
 static struct file_operations libertas_debug_fops = {
@@ -1916,20 +1921,10 @@ void libertas_debug_init(wlan_private * priv, struct net_device *dev)
 		return;
 
 	for (i = 0; i < num_of_items; i++)
-		items[i].addr += (u32) priv->adapter;
+		items[i].addr += (size_t) priv->adapter;
 
 	priv->debugfs_debug = debugfs_create_file("debug", 0644,
 						  priv->debugfs_dir, &items[0],
 						  &libertas_debug_fops);
 }
 
-/**
- *  @brief remove proc file
- *
- *  @param priv	   pointer wlan_private
- *  @return 	   N/A
- */
-void libertas_debug_remove(wlan_private * priv)
-{
-	debugfs_remove(priv->debugfs_debug);
-}
diff --git a/drivers/net/wireless/libertas/defs.h b/drivers/net/wireless/libertas/defs.h
index fb1478c..80dd9ea 100644
--- a/drivers/net/wireless/libertas/defs.h
+++ b/drivers/net/wireless/libertas/defs.h
@@ -9,6 +9,11 @@
 
 extern unsigned int libertas_debug;
 
+#ifdef CONFIG_LIBERTAS_DEBUG
+#define DEBUG
+#define PROC_DEBUG
+#endif
+
 #define DRV_NAME		"usb8xxx"
 
 #define lbs_pr_info(format, args...) \
@@ -223,31 +228,6 @@ enum SNRNF_DATA {
 	MAX_TYPE_AVG
 };
 
-/** WLAN_802_11_AUTH_ALG*/
-enum WLAN_802_11_AUTH_ALG {
-	AUTH_ALG_OPEN_SYSTEM = 1,
-	AUTH_ALG_SHARED_KEY = 2,
-	AUTH_ALG_NETWORK_EAP = 8,
-};
-
-/** WLAN_802_1X_AUTH_ALG */
-enum WLAN_802_1X_AUTH_ALG {
-	WLAN_1X_AUTH_ALG_NONE = 1,
-	WLAN_1X_AUTH_ALG_LEAP = 2,
-	WLAN_1X_AUTH_ALG_TLS = 4,
-	WLAN_1X_AUTH_ALG_TTLS = 8,
-	WLAN_1X_AUTH_ALG_MD5 = 16,
-};
-
-/** WLAN_802_11_ENCRYPTION_MODE */
-enum WLAN_802_11_ENCRYPTION_MODE {
-	CIPHER_NONE,
-	CIPHER_WEP40,
-	CIPHER_TKIP,
-	CIPHER_CCMP,
-	CIPHER_WEP104,
-};
-
 /** WLAN_802_11_POWER_MODE */
 enum WLAN_802_11_POWER_MODE {
 	wlan802_11powermodecam,
@@ -292,28 +272,6 @@ enum mv_ms_type {
 	MVMS_EVENT
 };
 
-/** WLAN_802_11_NETWORK_INFRASTRUCTURE */
-enum WLAN_802_11_NETWORK_INFRASTRUCTURE {
-	wlan802_11ibss,
-	wlan802_11infrastructure,
-	wlan802_11autounknown,
-	/*defined as upper bound */
-	wlan802_11infrastructuremax
-};
-
-/** WLAN_802_11_AUTHENTICATION_MODE */
-enum WLAN_802_11_AUTHENTICATION_MODE {
-	wlan802_11authmodeopen = 0x00,
-	wlan802_11authmodeshared = 0x01,
-	wlan802_11authmodenetworkEAP = 0x80,
-};
-
-/** WLAN_802_11_WEP_STATUS */
-enum WLAN_802_11_WEP_STATUS {
-	wlan802_11WEPenabled,
-	wlan802_11WEPdisabled,
-};
-
 /** SNMP_MIB_INDEX_e */
 enum SNMP_MIB_INDEX_e {
 	desired_bsstype_i = 0,
diff --git a/drivers/net/wireless/libertas/dev.h b/drivers/net/wireless/libertas/dev.h
index b1f876f..e8b9020 100644
--- a/drivers/net/wireless/libertas/dev.h
+++ b/drivers/net/wireless/libertas/dev.h
@@ -10,6 +10,7 @@
 #include <linux/wireless.h>
 #include <linux/ethtool.h>
 #include <linux/debugfs.h>
+#include <net/ieee80211.h>
 
 #include "defs.h"
 #include "scan.h"
@@ -56,10 +57,8 @@ struct region_channel {
 struct wlan_802_11_security {
 	u8 WPAenabled;
 	u8 WPA2enabled;
-	enum WLAN_802_11_WEP_STATUS WEPstatus;
-	enum WLAN_802_11_AUTHENTICATION_MODE authmode;
-	enum WLAN_802_1X_AUTH_ALG auth1xalg;
-	enum WLAN_802_11_ENCRYPTION_MODE Encryptionmode;
+	u8 wep_enabled;
+	u8 auth_mode;
 };
 
 /** Current Basic Service Set State Structure */
@@ -184,7 +183,7 @@ struct assoc_request {
 
 	struct WLAN_802_11_SSID ssid;
 	u8 channel;
-	enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode;
+	u8 mode;
 	u8 bssid[ETH_ALEN];
 
 	/** WEP keys */
@@ -198,7 +197,6 @@ struct assoc_request {
 	struct wlan_802_11_security secinfo;
 
 	/** WPA Information Elements*/
-#define MAX_WPA_IE_LEN 64
 	u8 wpa_ie[MAX_WPA_IE_LEN];
 	u8 wpa_ie_len;
 };
@@ -254,7 +252,8 @@ struct _wlan_adapter {
 	/** current ssid/bssid related parameters*/
 	struct current_bss_params curbssparams;
 
-	enum WLAN_802_11_NETWORK_INFRASTRUCTURE inframode;
+	/* IW_MODE_* */
+	u8 mode;
 
 	struct bss_descriptor *pattemptedbssdesc;
 
@@ -339,7 +338,6 @@ struct _wlan_adapter {
 	struct WLAN_802_11_KEY wpa_unicast_key;
 
 	/** WPA Information Elements*/
-#define MAX_WPA_IE_LEN 64
 	u8 wpa_ie[MAX_WPA_IE_LEN];
 	u8 wpa_ie_len;
 
diff --git a/drivers/net/wireless/libertas/fw.c b/drivers/net/wireless/libertas/fw.c
index b194a45..441123c 100644
--- a/drivers/net/wireless/libertas/fw.c
+++ b/drivers/net/wireless/libertas/fw.c
@@ -194,16 +194,13 @@ static void wlan_init_adapter(wlan_private * priv)
 	adapter->scanmode = cmd_bss_type_any;
 
 	/* 802.11 specific */
-	adapter->secinfo.WEPstatus = wlan802_11WEPdisabled;
+	adapter->secinfo.wep_enabled = 0;
 	for (i = 0; i < sizeof(adapter->wep_keys) / sizeof(adapter->wep_keys[0]);
 	     i++)
 		memset(&adapter->wep_keys[i], 0, sizeof(struct WLAN_802_11_KEY));
 	adapter->wep_tx_keyidx = 0;
-	adapter->secinfo.WEPstatus = wlan802_11WEPdisabled;
-	adapter->secinfo.authmode = wlan802_11authmodeopen;
-	adapter->secinfo.auth1xalg = WLAN_1X_AUTH_ALG_NONE;
-	adapter->secinfo.Encryptionmode = CIPHER_NONE;
-	adapter->inframode = wlan802_11infrastructure;
+	adapter->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
+	adapter->mode = IW_MODE_INFRA;
 
 	adapter->assoc_req = NULL;
 
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c
index 695fb6a..ae6f72a 100644
--- a/drivers/net/wireless/libertas/if_usb.c
+++ b/drivers/net/wireless/libertas/if_usb.c
@@ -388,7 +388,7 @@ static int __if_usb_submit_rx_urb(wlan_private * priv,
 	usb_fill_bulk_urb(cardp->rx_urb, cardp->udev,
 			  usb_rcvbulkpipe(cardp->udev,
 					  cardp->bulk_in_endpointAddr),
-			  skb->tail + IPFIELD_ALIGN_OFFSET,
+			  (void *) (skb->tail + (size_t) IPFIELD_ALIGN_OFFSET),
 			  MRVDRV_ETH_RX_PACKET_BUFFER_SIZE, callbackfn,
 			  rinfo);
 
@@ -626,6 +626,7 @@ static void if_usb_receive(struct urb *urb)
 			    cardp->usb_event_cause);
 		if (cardp->usb_event_cause & 0xffff0000) {
 			libertas_send_tx_feedback(priv);
+			spin_unlock(&priv->adapter->driver_lock);
 			break;
 		}
 		cardp->usb_event_cause = le32_to_cpu(cardp->usb_event_cause) << 3;
@@ -775,7 +776,6 @@ restart:
 		return -1;
 	}
 
-#ifdef SUPPORT_BOOT_COMMAND
 	cardp->bootcmdresp = 0;
 	do {
 		int j = 0;
@@ -796,7 +796,6 @@ restart:
 		}
 		return -1;
 	}
-#endif
 
 	i = 0;
 	priv->adapter->fw_ready = 0;
diff --git a/drivers/net/wireless/libertas/if_usb.h b/drivers/net/wireless/libertas/if_usb.h
index 7851167..170dfe6 100644
--- a/drivers/net/wireless/libertas/if_usb.h
+++ b/drivers/net/wireless/libertas/if_usb.h
@@ -12,7 +12,6 @@
 #define USB8388_VID_2	0x05a3
 #define USB8388_PID_2	0x8388
 
-#ifdef SUPPORT_BOOT_COMMAND
 #define BOOT_CMD_FW_BY_USB     0x01
 #define BOOT_CMD_FW_IN_EEPROM  0x02
 #define BOOT_CMD_UPDATE_BOOT2  0x03
@@ -36,7 +35,6 @@ struct bootcmdrespStr
 	u8  u8result;
 	u8  au8dumy[2];
 };
-#endif /* SUPPORT_BOOT_COMMAND */
 
 /* read callback private data */
 struct read_cb_info {
diff --git a/drivers/net/wireless/libertas/ioctl.c b/drivers/net/wireless/libertas/ioctl.c
index 82b3964..a8f76c3 100644
--- a/drivers/net/wireless/libertas/ioctl.c
+++ b/drivers/net/wireless/libertas/ioctl.c
@@ -27,95 +27,6 @@
 
 #define WAIT_FOR_SCAN_RRESULT_MAX_TIME (10 * HZ)
 
-static int setrxantenna(wlan_private * priv, int mode)
-{
-	int ret = 0;
-	wlan_adapter *adapter = priv->adapter;
-
-	if (mode != RF_ANTENNA_1 && mode != RF_ANTENNA_2
-	    && mode != RF_ANTENNA_AUTO) {
-		return -EINVAL;
-	}
-
-	adapter->rxantennamode = mode;
-
-	lbs_pr_debug(1, "SET RX Antenna mode to 0x%04x\n", adapter->rxantennamode);
-
-	ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
-				    cmd_act_set_rx,
-				    cmd_option_waitforrsp, 0,
-				    &adapter->rxantennamode);
-	return ret;
-}
-
-static int settxantenna(wlan_private * priv, int mode)
-{
-	int ret = 0;
-	wlan_adapter *adapter = priv->adapter;
-
-	if ((mode != RF_ANTENNA_1) && (mode != RF_ANTENNA_2)
-	    && (mode != RF_ANTENNA_AUTO)) {
-		return -EINVAL;
-	}
-
-	adapter->txantennamode = mode;
-
-	lbs_pr_debug(1, "SET TX Antenna mode to 0x%04x\n", adapter->txantennamode);
-
-	ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
-				    cmd_act_set_tx,
-				    cmd_option_waitforrsp, 0,
-				    &adapter->txantennamode);
-
-	return ret;
-}
-
-static int getrxantenna(wlan_private * priv, char *buf)
-{
-	int ret = 0;
-	wlan_adapter *adapter = priv->adapter;
-
-	// clear it, so we will know if the value
-	// returned below is correct or not.
-	adapter->rxantennamode = 0;
-
-	ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
-				    cmd_act_get_rx,
-				    cmd_option_waitforrsp, 0, NULL);
-
-	if (ret) {
-		LEAVE();
-		return ret;
-	}
-
-	lbs_pr_debug(1, "Get Rx Antenna mode:0x%04x\n", adapter->rxantennamode);
-
-	return sprintf(buf, "0x%04x", adapter->rxantennamode) + 1;
-}
-
-static int gettxantenna(wlan_private * priv, char *buf)
-{
-	int ret = 0;
-	wlan_adapter *adapter = priv->adapter;
-
-	// clear it, so we will know if the value
-	// returned below is correct or not.
-	adapter->txantennamode = 0;
-
-	ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_antenna,
-				    cmd_act_get_tx,
-				    cmd_option_waitforrsp, 0, NULL);
-
-	if (ret) {
-		LEAVE();
-		return ret;
-	}
-
-	lbs_pr_debug(1, "Get Tx Antenna mode:0x%04x\n", adapter->txantennamode);
-
-	return sprintf(buf, "0x%04x", adapter->txantennamode) + 1;
-}
-
 static int wlan_set_region(wlan_private * priv, u16 region_code)
 {
 	int i;
@@ -144,998 +55,6 @@ static int wlan_set_region(wlan_private * priv, u16 region_code)
 	return 0;
 }
 
-/**
- *  @brief Get/Set Firmware wakeup method
- *
- *  @param priv		A pointer to wlan_private structure
- *  @param wrq	   	A pointer to user data
- *  @return 	   	0--success, otherwise fail
- */
-static int wlan_txcontrol(wlan_private * priv, struct iwreq *wrq)
-{
-	wlan_adapter *adapter = priv->adapter;
-	int data;
-	ENTER();
-
-	if ((int)wrq->u.data.length == 0) {
-		if (copy_to_user
-		    (wrq->u.data.pointer, &adapter->pkttxctrl, sizeof(u32))) {
-			lbs_pr_alert("copy_to_user failed!\n");
-			return -EFAULT;
-		}
-	} else {
-		if ((int)wrq->u.data.length > 1) {
-			lbs_pr_alert("ioctl too many args!\n");
-			return -EFAULT;
-		}
-		if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
-			lbs_pr_alert("Copy from user failed\n");
-			return -EFAULT;
-		}
-
-		adapter->pkttxctrl = (u32) data;
-	}
-
-	wrq->u.data.length = 1;
-
-	LEAVE();
-	return 0;
-}
-
-/**
- *  @brief Get/Set NULL Package generation interval
- *
- *  @param priv		A pointer to wlan_private structure
- *  @param wrq	   	A pointer to user data
- *  @return 	   	0--success, otherwise fail
- */
-static int wlan_null_pkt_interval(wlan_private * priv, struct iwreq *wrq)
-{
-	wlan_adapter *adapter = priv->adapter;
-	int data;
-	ENTER();
-
-	if ((int)wrq->u.data.length == 0) {
-		data = adapter->nullpktinterval;
-
-		if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
-			lbs_pr_alert( "copy_to_user failed!\n");
-			return -EFAULT;
-		}
-	} else {
-		if ((int)wrq->u.data.length > 1) {
-			lbs_pr_alert( "ioctl too many args!\n");
-			return -EFAULT;
-		}
-		if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
-			lbs_pr_debug(1, "Copy from user failed\n");
-			return -EFAULT;
-		}
-
-		adapter->nullpktinterval = data;
-	}
-
-	wrq->u.data.length = 1;
-
-	LEAVE();
-	return 0;
-}
-
-static int wlan_get_rxinfo(wlan_private * priv, struct iwreq *wrq)
-{
-	wlan_adapter *adapter = priv->adapter;
-	int data[2];
-	ENTER();
-	data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
-	data[1] = adapter->rxpd_rate;
-	if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
-		lbs_pr_debug(1, "Copy to user failed\n");
-		return -EFAULT;
-	}
-	wrq->u.data.length = 2;
-	LEAVE();
-	return 0;
-}
-
-static int wlan_get_snr(wlan_private * priv, struct iwreq *wrq)
-{
-	int ret = 0;
-	wlan_adapter *adapter = priv->adapter;
-	int data[4];
-
-	ENTER();
-	memset(data, 0, sizeof(data));
-	if (wrq->u.data.length) {
-		if (copy_from_user(data, wrq->u.data.pointer,
-		     min_t(size_t, wrq->u.data.length, 4) * sizeof(int)))
-			return -EFAULT;
-	}
-	if ((wrq->u.data.length == 0) || (data[0] == 0) || (data[0] == 1)) {
-		if (adapter->connect_status == libertas_connected) {
-			ret = libertas_prepare_and_send_command(priv,
-						    cmd_802_11_rssi,
-						    0,
-						    cmd_option_waitforrsp,
-						    0, NULL);
-
-			if (ret) {
-				LEAVE();
-				return ret;
-			}
-		}
-	}
-
-	if (wrq->u.data.length == 0) {
-		data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG];
-		data[1] = adapter->SNR[TYPE_BEACON][TYPE_AVG];
-		data[2] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
-		data[3] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
-		if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 4))
-			return -EFAULT;
-		wrq->u.data.length = 4;
-	} else if (data[0] == 0) {
-		data[0] = adapter->SNR[TYPE_BEACON][TYPE_NOAVG];
-		if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
-			return -EFAULT;
-		wrq->u.data.length = 1;
-	} else if (data[0] == 1) {
-		data[0] = adapter->SNR[TYPE_BEACON][TYPE_AVG];
-		if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
-			return -EFAULT;
-		wrq->u.data.length = 1;
-	} else if (data[0] == 2) {
-		data[0] = adapter->SNR[TYPE_RXPD][TYPE_NOAVG];
-		if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
-			return -EFAULT;
-		wrq->u.data.length = 1;
-	} else if (data[0] == 3) {
-		data[0] = adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
-		if (copy_to_user(wrq->u.data.pointer, data, sizeof(int)))
-			return -EFAULT;
-		wrq->u.data.length = 1;
-	} else
-		return -ENOTSUPP;
-
-	LEAVE();
-	return 0;
-}
-
-static int wlan_beacon_interval(wlan_private * priv, struct iwreq *wrq)
-{
-	int data;
-	wlan_adapter *adapter = priv->adapter;
-
-	if (wrq->u.data.length > 0) {
-		if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int)))
-			return -EFAULT;
-
-		lbs_pr_debug(1, "WLAN SET BEACON INTERVAL: %d\n", data);
-		if ((data > MRVDRV_MAX_BEACON_INTERVAL)
-		    || (data < MRVDRV_MIN_BEACON_INTERVAL))
-			return -ENOTSUPP;
-		adapter->beaconperiod = data;
-	}
-	data = adapter->beaconperiod;
-	if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int)))
-		return -EFAULT;
-
-	wrq->u.data.length = 1;
-
-	return 0;
-}
-
-static int wlan_get_rssi(wlan_private * priv, struct iwreq *wrq)
-{
-	int ret = 0;
-	wlan_adapter *adapter = priv->adapter;
-	int temp;
-	int data = 0;
-	int *val;
-
-	ENTER();
-	data = SUBCMD_DATA(wrq);
-	if ((data == 0) || (data == 1)) {
-		ret = libertas_prepare_and_send_command(priv,
-					    cmd_802_11_rssi,
-					    0, cmd_option_waitforrsp,
-					    0, NULL);
-		if (ret) {
-			LEAVE();
-			return ret;
-		}
-	}
-
-	switch (data) {
-	case 0:
-
-		temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_NOAVG],
-				adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
-		break;
-	case 1:
-		temp = CAL_RSSI(adapter->SNR[TYPE_BEACON][TYPE_AVG],
-				adapter->NF[TYPE_BEACON][TYPE_AVG]);
-		break;
-	case 2:
-		temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_NOAVG],
-				adapter->NF[TYPE_RXPD][TYPE_NOAVG]);
-		break;
-	case 3:
-		temp = CAL_RSSI(adapter->SNR[TYPE_RXPD][TYPE_AVG] / AVG_SCALE,
-				adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE);
-		break;
-	default:
-		return -ENOTSUPP;
-	}
-	val = (int *)wrq->u.name;
-	*val = temp;
-
-	LEAVE();
-	return 0;
-}
-
-static int wlan_get_nf(wlan_private * priv, struct iwreq *wrq)
-{
-	int ret = 0;
-	wlan_adapter *adapter = priv->adapter;
-	int temp;
-	int data = 0;
-	int *val;
-
-	data = SUBCMD_DATA(wrq);
-	if ((data == 0) || (data == 1)) {
-		ret = libertas_prepare_and_send_command(priv,
-					    cmd_802_11_rssi,
-					    0, cmd_option_waitforrsp,
-					    0, NULL);
-
-		if (ret) {
-			LEAVE();
-			return ret;
-		}
-	}
-
-	switch (data) {
-	case 0:
-		temp = adapter->NF[TYPE_BEACON][TYPE_NOAVG];
-		break;
-	case 1:
-		temp = adapter->NF[TYPE_BEACON][TYPE_AVG];
-		break;
-	case 2:
-		temp = adapter->NF[TYPE_RXPD][TYPE_NOAVG];
-		break;
-	case 3:
-		temp = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
-		break;
-	default:
-		return -ENOTSUPP;
-	}
-
-	temp = CAL_NF(temp);
-
-	lbs_pr_debug(1, "%s: temp = %d\n", __FUNCTION__, temp);
-	val = (int *)wrq->u.name;
-	*val = temp;
-	return 0;
-}
-
-static int wlan_get_txrate_ioctl(wlan_private * priv, struct ifreq *req)
-{
-	wlan_adapter *adapter = priv->adapter;
-	int *pdata;
-	struct iwreq *wrq = (struct iwreq *)req;
-	int ret = 0;
-	adapter->txrate = 0;
-	lbs_pr_debug(1, "wlan_get_txrate_ioctl\n");
-	ret = libertas_prepare_and_send_command(priv, cmd_802_11_tx_rate_query,
-				    cmd_act_get, cmd_option_waitforrsp,
-				    0, NULL);
-	if (ret)
-		return ret;
-
-	pdata = (int *)wrq->u.name;
-	*pdata = (int)adapter->txrate;
-	return 0;
-}
-
-static int wlan_get_adhoc_status_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-	char status[64];
-	wlan_adapter *adapter = priv->adapter;
-
-	memset(status, 0, sizeof(status));
-
-	switch (adapter->inframode) {
-	case wlan802_11ibss:
-		if (adapter->connect_status == libertas_connected) {
-			if (adapter->adhoccreate)
-				memcpy(&status, "AdhocStarted", sizeof(status));
-			else
-				memcpy(&status, "AdhocJoined", sizeof(status));
-		} else {
-			memcpy(&status, "AdhocIdle", sizeof(status));
-		}
-		break;
-	case wlan802_11infrastructure:
-		memcpy(&status, "Inframode", sizeof(status));
-		break;
-	default:
-		memcpy(&status, "AutoUnknownmode", sizeof(status));
-		break;
-	}
-
-	lbs_pr_debug(1, "status = %s\n", status);
-	wrq->u.data.length = strlen(status) + 1;
-
-	if (wrq->u.data.pointer) {
-		if (copy_to_user(wrq->u.data.pointer,
-				 &status, wrq->u.data.length))
-			return -EFAULT;
-	}
-
-	LEAVE();
-	return 0;
-}
-
-/**
- *  @brief Set/Get WPA IE
- *  @param priv                 A pointer to wlan_private structure
- *  @param req			A pointer to ifreq structure
- *  @return 	   		0 --success, otherwise fail
- */
-static int wlan_setwpaie_ioctl(wlan_private * priv, struct ifreq *req)
-{
-	struct iwreq *wrq = (struct iwreq *)req;
-	wlan_adapter *adapter = priv->adapter;
-	int ret = 0;
-
-	ENTER();
-
-	if (wrq->u.data.length) {
-		if (wrq->u.data.length > sizeof(adapter->wpa_ie)) {
-			lbs_pr_debug(1, "failed to copy WPA IE, too big \n");
-			return -EFAULT;
-		}
-		if (copy_from_user(adapter->wpa_ie, wrq->u.data.pointer,
-				   wrq->u.data.length)) {
-			lbs_pr_debug(1, "failed to copy WPA IE \n");
-			return -EFAULT;
-		}
-		adapter->wpa_ie_len = wrq->u.data.length;
-		lbs_pr_debug(1, "Set wpa_ie_len=%d IE=%#x\n", adapter->wpa_ie_len,
-		       adapter->wpa_ie[0]);
-		lbs_dbg_hex("wpa_ie", adapter->wpa_ie, adapter->wpa_ie_len);
-		if (adapter->wpa_ie[0] == WPA_IE)
-			adapter->secinfo.WPAenabled = 1;
-		else if (adapter->wpa_ie[0] == WPA2_IE)
-			adapter->secinfo.WPA2enabled = 1;
-		else {
-			adapter->secinfo.WPAenabled = 0;
-			adapter->secinfo.WPA2enabled = 0;
-		}
-	} else {
-		memset(adapter->wpa_ie, 0, sizeof(adapter->wpa_ie));
-		adapter->wpa_ie_len = wrq->u.data.length;
-		lbs_pr_debug(1, "Reset wpa_ie_len=%d IE=%#x\n",
-		       adapter->wpa_ie_len, adapter->wpa_ie[0]);
-		adapter->secinfo.WPAenabled = 0;
-		adapter->secinfo.WPA2enabled = 0;
-	}
-
-	// enable/disable RSN in firmware if WPA is enabled/disabled
-	// depending on variable adapter->secinfo.WPAenabled is set or not
-	ret = libertas_prepare_and_send_command(priv, cmd_802_11_enable_rsn,
-				    cmd_act_set, cmd_option_waitforrsp,
-				    0, NULL);
-
-	LEAVE();
-	return ret;
-}
-
-/**
- *  @brief Set Auto prescan
- *  @param priv                 A pointer to wlan_private structure
- *  @param wrq			A pointer to iwreq structure
- *  @return 	   		0 --success, otherwise fail
- */
-static int wlan_subcmd_setprescan_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-	int data;
-	wlan_adapter *adapter = priv->adapter;
-	int *val;
-
-	data = SUBCMD_DATA(wrq);
-	lbs_pr_debug(1, "WLAN_SUBCMD_SET_PRESCAN %d\n", data);
-	adapter->prescan = data;
-
-	val = (int *)wrq->u.name;
-	*val = data;
-	return 0;
-}
-
-static int wlan_set_multiple_dtim_ioctl(wlan_private * priv, struct ifreq *req)
-{
-	struct iwreq *wrq = (struct iwreq *)req;
-	u32 mdtim;
-	int idata;
-	int ret = -EINVAL;
-
-	ENTER();
-
-	idata = SUBCMD_DATA(wrq);
-	mdtim = (u32) idata;
-	if (((mdtim >= MRVDRV_MIN_MULTIPLE_DTIM)
-	     && (mdtim <= MRVDRV_MAX_MULTIPLE_DTIM))
-	    || (mdtim == MRVDRV_IGNORE_MULTIPLE_DTIM)) {
-		priv->adapter->multipledtim = mdtim;
-		ret = 0;
-	}
-	if (ret)
-		lbs_pr_debug(1, "Invalid parameter, multipledtim not changed.\n");
-
-	LEAVE();
-	return ret;
-}
-
-/**
- *  @brief Set authentication mode
- *  @param priv                 A pointer to wlan_private structure
- *  @param req			A pointer to ifreq structure
- *  @return 	   		0 --success, otherwise fail
- */
-static int wlan_setauthalg_ioctl(wlan_private * priv, struct ifreq *req)
-{
-	int alg;
-	struct iwreq *wrq = (struct iwreq *)req;
-	wlan_adapter *adapter = priv->adapter;
-
-	if (wrq->u.data.flags == 0) {
-		//from iwpriv subcmd
-		alg = SUBCMD_DATA(wrq);
-	} else {
-		//from wpa_supplicant subcmd
-		if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(alg))) {
-			lbs_pr_debug(1, "Copy from user failed\n");
-			return -EFAULT;
-		}
-	}
-
-	lbs_pr_debug(1, "auth alg is %#x\n", alg);
-
-	switch (alg) {
-	case AUTH_ALG_SHARED_KEY:
-		adapter->secinfo.authmode = wlan802_11authmodeshared;
-		break;
-	case AUTH_ALG_NETWORK_EAP:
-		adapter->secinfo.authmode =
-		    wlan802_11authmodenetworkEAP;
-		break;
-	case AUTH_ALG_OPEN_SYSTEM:
-	default:
-		adapter->secinfo.authmode = wlan802_11authmodeopen;
-		break;
-	}
-	return 0;
-}
-
-/**
- *  @brief Set 802.1x authentication mode
- *  @param priv                 A pointer to wlan_private structure
- *  @param req			A pointer to ifreq structure
- *  @return 	   		0 --success, otherwise fail
- */
-static int wlan_set8021xauthalg_ioctl(wlan_private * priv, struct ifreq *req)
-{
-	int alg;
-	struct iwreq *wrq = (struct iwreq *)req;
-
-	if (wrq->u.data.flags == 0) {
-		//from iwpriv subcmd
-		alg = SUBCMD_DATA(wrq);
-	} else {
-		//from wpa_supplicant subcmd
-		if (copy_from_user(&alg, wrq->u.data.pointer, sizeof(int))) {
-			lbs_pr_debug(1, "Copy from user failed\n");
-			return -EFAULT;
-		}
-	}
-	lbs_pr_debug(1, "802.1x auth alg is %#x\n", alg);
-	priv->adapter->secinfo.auth1xalg = alg;
-	return 0;
-}
-
-static int wlan_setencryptionmode_ioctl(wlan_private * priv, struct ifreq *req)
-{
-	int mode;
-	struct iwreq *wrq = (struct iwreq *)req;
-
-	ENTER();
-
-	if (wrq->u.data.flags == 0) {
-		//from iwpriv subcmd
-		mode = SUBCMD_DATA(wrq);
-	} else {
-		//from wpa_supplicant subcmd
-		if (copy_from_user(&mode, wrq->u.data.pointer, sizeof(int))) {
-			lbs_pr_debug(1, "Copy from user failed\n");
-			return -EFAULT;
-		}
-	}
-	lbs_pr_debug(1, "encryption mode is %#x\n", mode);
-	priv->adapter->secinfo.Encryptionmode = mode;
-
-	LEAVE();
-	return 0;
-}
-
-static void adjust_mtu(wlan_private * priv)
-{
-	int mtu_increment = 0;
-
-	if (priv->adapter->linkmode == WLAN_LINKMODE_802_11)
-		mtu_increment += sizeof(struct ieee80211_hdr_4addr);
-
-	if (priv->adapter->radiomode == WLAN_RADIOMODE_RADIOTAP)
-		mtu_increment += max(sizeof(struct tx_radiotap_hdr),
-				     sizeof(struct rx_radiotap_hdr));
-	priv->wlan_dev.netdev->mtu = ETH_FRAME_LEN
-	    - sizeof(struct ethhdr)
-	    + mtu_increment;
-}
-
-/**
- *  @brief Set Link-Layer Layer mode
- *  @param priv                 A pointer to wlan_private structure
- *  @param req			A pointer to ifreq structure
- *  @return 	   		0 --success, otherwise fail
- */
-static int wlan_set_linkmode_ioctl(wlan_private * priv, struct ifreq *req)
-{
-	int mode;
-
-	mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
-
-	switch (mode) {
-	case WLAN_LINKMODE_802_3:
-		priv->adapter->linkmode = mode;
-		break;
-	case WLAN_LINKMODE_802_11:
-		priv->adapter->linkmode = mode;
-		break;
-	default:
-		lbs_pr_info("usb8388-5: invalid link-layer mode (%#x)\n",
-		       mode);
-		return -EINVAL;
-		break;
-	}
-	lbs_pr_debug(1, "usb8388-5: link-layer mode is %#x\n", mode);
-
-	adjust_mtu(priv);
-
-	return 0;
-}
-
-/**
- *  @brief Set Radio header mode
- *  @param priv                 A pointer to wlan_private structure
- *  @param req			A pointer to ifreq structure
- *  @return 	   		0 --success, otherwise fail
- */
-static int wlan_set_radiomode_ioctl(wlan_private * priv, struct ifreq *req)
-{
-	int mode;
-
-	mode = (int)((struct ifreq *)((u8 *) req + 4))->ifr_data;
-
-	switch (mode) {
-	case WLAN_RADIOMODE_NONE:
-		priv->adapter->radiomode = mode;
-		break;
-	case WLAN_RADIOMODE_RADIOTAP:
-		priv->adapter->radiomode = mode;
-		break;
-	default:
-		lbs_pr_debug(1, "usb8388-5: invalid radio header mode (%#x)\n",
-		       mode);
-		return -EINVAL;
-	}
-	lbs_pr_debug(1, "usb8388-5: radio-header mode is %#x\n", mode);
-
-	adjust_mtu(priv);
-	return 0;
-}
-
-/**
- *  @brief Set Debug header mode
- *  @param priv                 A pointer to wlan_private structure
- *  @param req			A pointer to ifreq structure
- *  @return 	   		0 --success, otherwise fail
- */
-static int wlan_set_debugmode_ioctl(wlan_private * priv, struct ifreq *req)
-{
-	priv->adapter->debugmode = (int)((struct ifreq *)
-					 ((u8 *) req + 4))->ifr_data;
-	return 0;
-}
-
-static int wlan_subcmd_getrxantenna_ioctl(wlan_private * priv,
-					  struct ifreq *req)
-{
-	int len;
-	char buf[8];
-	struct iwreq *wrq = (struct iwreq *)req;
-
-	lbs_pr_debug(1, "WLAN_SUBCMD_GETRXANTENNA\n");
-	len = getrxantenna(priv, buf);
-
-	wrq->u.data.length = len;
-	if (wrq->u.data.pointer) {
-		if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
-			lbs_pr_debug(1, "CopyToUser failed\n");
-			return -EFAULT;
-		}
-	}
-
-	return 0;
-}
-
-static int wlan_subcmd_gettxantenna_ioctl(wlan_private * priv,
-					  struct ifreq *req)
-{
-	int len;
-	char buf[8];
-	struct iwreq *wrq = (struct iwreq *)req;
-
-	lbs_pr_debug(1, "WLAN_SUBCMD_GETTXANTENNA\n");
-	len = gettxantenna(priv, buf);
-
-	wrq->u.data.length = len;
-	if (wrq->u.data.pointer) {
-		if (copy_to_user(wrq->u.data.pointer, &buf, len)) {
-			lbs_pr_debug(1, "CopyToUser failed\n");
-			return -EFAULT;
-		}
-	}
-	return 0;
-}
-
-/**
- *  @brief Get the MAC TSF value from the firmware
- *
- *  @param priv         A pointer to wlan_private structure
- *  @param wrq          A pointer to iwreq structure containing buffer
- *                      space to store a TSF value retrieved from the firmware
- *
- *  @return             0 if successful; IOCTL error code otherwise
- */
-static int wlan_get_tsf_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-	u64 tsfval;
-	int ret;
-
-	ret = libertas_prepare_and_send_command(priv,
-				    cmd_get_tsf,
-				    0, cmd_option_waitforrsp, 0, &tsfval);
-
-	lbs_pr_debug(1, "IOCTL: Get TSF = 0x%016llx\n", tsfval);
-
-	if (ret != 0) {
-		lbs_pr_debug(1, "IOCTL: Get TSF; command exec failed\n");
-		ret = -EFAULT;
-	} else {
-		if (copy_to_user(wrq->u.data.pointer,
-				 &tsfval,
-				 min_t(size_t, wrq->u.data.length,
-				     sizeof(tsfval))) != 0) {
-
-			lbs_pr_debug(1, "IOCTL: Get TSF; Copy to user failed\n");
-			ret = -EFAULT;
-		} else {
-			ret = 0;
-		}
-	}
-	return ret;
-}
-
-/**
- *  @brief Get/Set adapt rate
- *  @param priv                 A pointer to wlan_private structure
- *  @param wrq			A pointer to iwreq structure
- *  @return 	   		0 --success, otherwise fail
- */
-static int wlan_adapt_rateset(wlan_private * priv, struct iwreq *wrq)
-{
-	int ret;
-	wlan_adapter *adapter = priv->adapter;
-	int data[2];
-
-	memset(data, 0, sizeof(data));
-	if (!wrq->u.data.length) {
-		lbs_pr_debug(1, "Get ADAPT RATE SET\n");
-		ret = libertas_prepare_and_send_command(priv,
-					    cmd_802_11_rate_adapt_rateset,
-					    cmd_act_get,
-					    cmd_option_waitforrsp, 0, NULL);
-		data[0] = adapter->enablehwauto;
-		data[1] = adapter->ratebitmap;
-		if (copy_to_user(wrq->u.data.pointer, data, sizeof(int) * 2)) {
-			lbs_pr_debug(1, "Copy to user failed\n");
-			return -EFAULT;
-		}
-#define GET_TWO_INT	2
-		wrq->u.data.length = GET_TWO_INT;
-	} else {
-		lbs_pr_debug(1, "Set ADAPT RATE SET\n");
-		if (wrq->u.data.length > 2)
-			return -EINVAL;
-		if (copy_from_user
-		    (data, wrq->u.data.pointer,
-		     sizeof(int) * wrq->u.data.length)) {
-			lbs_pr_debug(1, "Copy from user failed\n");
-			return -EFAULT;
-		}
-
-		adapter->enablehwauto = data[0];
-		adapter->ratebitmap = data[1];
-		ret = libertas_prepare_and_send_command(priv,
-					    cmd_802_11_rate_adapt_rateset,
-					    cmd_act_set,
-					    cmd_option_waitforrsp, 0, NULL);
-	}
-	return ret;
-}
-
-/**
- *  @brief Get/Set inactivity timeout
- *  @param priv                 A pointer to wlan_private structure
- *  @param wrq			A pointer to iwreq structure
- *  @return 	   		0 --success, otherwise fail
- */
-static int wlan_inactivity_timeout(wlan_private * priv, struct iwreq *wrq)
-{
-	int ret;
-	int data = 0;
-	u16 timeout = 0;
-
-	ENTER();
-	if (wrq->u.data.length > 1)
-		return -ENOTSUPP;
-
-	if (wrq->u.data.length == 0) {
-		/* Get */
-		ret = libertas_prepare_and_send_command(priv,
-					    cmd_802_11_inactivity_timeout,
-					    cmd_act_get,
-					    cmd_option_waitforrsp, 0,
-					    &timeout);
-		data = timeout;
-		if (copy_to_user(wrq->u.data.pointer, &data, sizeof(int))) {
-			lbs_pr_debug(1, "Copy to user failed\n");
-			return -EFAULT;
-		}
-	} else {
-		/* Set */
-		if (copy_from_user(&data, wrq->u.data.pointer, sizeof(int))) {
-			lbs_pr_debug(1, "Copy from user failed\n");
-			return -EFAULT;
-		}
-
-		timeout = data;
-		ret = libertas_prepare_and_send_command(priv,
-					    cmd_802_11_inactivity_timeout,
-					    cmd_act_set,
-					    cmd_option_waitforrsp, 0,
-					    &timeout);
-	}
-
-	wrq->u.data.length = 1;
-
-	LEAVE();
-	return ret;
-}
-
-static int wlan_do_getlog_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-	int ret;
-	char buf[GETLOG_BUFSIZE - 1];
-	wlan_adapter *adapter = priv->adapter;
-
-	lbs_pr_debug(1, " GET STATS\n");
-
-	ret = libertas_prepare_and_send_command(priv, cmd_802_11_get_log,
-				    0, cmd_option_waitforrsp, 0, NULL);
-
-	if (ret) {
-		return ret;
-	}
-
-	if (wrq->u.data.pointer) {
-		sprintf(buf, "\n  mcasttxframe %u failed %u retry %u "
-			"multiretry %u framedup %u "
-			"rtssuccess %u rtsfailure %u ackfailure %u\n"
-			"rxfrag %u mcastrxframe %u fcserror %u "
-			"txframe %u wepundecryptable %u ",
-			adapter->logmsg.mcasttxframe,
-			adapter->logmsg.failed,
-			adapter->logmsg.retry,
-			adapter->logmsg.multiretry,
-			adapter->logmsg.framedup,
-			adapter->logmsg.rtssuccess,
-			adapter->logmsg.rtsfailure,
-			adapter->logmsg.ackfailure,
-			adapter->logmsg.rxfrag,
-			adapter->logmsg.mcastrxframe,
-			adapter->logmsg.fcserror,
-			adapter->logmsg.txframe,
-			adapter->logmsg.wepundecryptable);
-		wrq->u.data.length = strlen(buf) + 1;
-		if (copy_to_user(wrq->u.data.pointer, buf, wrq->u.data.length)) {
-			lbs_pr_debug(1, "Copy to user failed\n");
-			return -EFAULT;
-		}
-	}
-
-	return 0;
-}
-
-static int wlan_scan_type_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-	u8 buf[12];
-	u8 *option[] = { "active", "passive", "get", };
-	int i, max_options = (sizeof(option) / sizeof(option[0]));
-	int ret = 0;
-	wlan_adapter *adapter = priv->adapter;
-
-	if (priv->adapter->enable11d) {
-		lbs_pr_debug(1, "11D: Cannot set scantype when 11D enabled\n");
-		return -EFAULT;
-	}
-
-	memset(buf, 0, sizeof(buf));
-
-	if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
-							 wrq->u.data.length)))
-		return -EFAULT;
-
-	lbs_pr_debug(1, "Scan type Option = %s\n", buf);
-
-	buf[sizeof(buf) - 1] = '\0';
-
-	for (i = 0; i < max_options; i++) {
-		if (!strcmp(buf, option[i]))
-			break;
-	}
-
-	switch (i) {
-	case 0:
-		adapter->scantype = cmd_scan_type_active;
-		break;
-	case 1:
-		adapter->scantype = cmd_scan_type_passive;
-		break;
-	case 2:
-		wrq->u.data.length = strlen(option[adapter->scantype]) + 1;
-
-		if (copy_to_user(wrq->u.data.pointer,
-				 option[adapter->scantype],
-				 wrq->u.data.length)) {
-			lbs_pr_debug(1, "Copy to user failed\n");
-			ret = -EFAULT;
-		}
-
-		break;
-	default:
-		lbs_pr_debug(1, "Invalid Scan type Ioctl Option\n");
-		ret = -EINVAL;
-		break;
-	}
-
-	return ret;
-}
-
-static int wlan_scan_mode_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-	wlan_adapter *adapter = priv->adapter;
-	u8 buf[12];
-	u8 *option[] = { "bss", "ibss", "any", "get" };
-	int i, max_options = (sizeof(option) / sizeof(option[0]));
-	int ret = 0;
-
-	ENTER();
-
-	memset(buf, 0, sizeof(buf));
-
-	if (copy_from_user(buf, wrq->u.data.pointer, min_t(size_t, sizeof(buf),
-							 wrq->u.data.length))) {
-		lbs_pr_debug(1, "Copy from user failed\n");
-		return -EFAULT;
-	}
-
-	lbs_pr_debug(1, "Scan mode Option = %s\n", buf);
-
-	buf[sizeof(buf) - 1] = '\0';
-
-	for (i = 0; i < max_options; i++) {
-		if (!strcmp(buf, option[i]))
-			break;
-	}
-
-	switch (i) {
-
-	case 0:
-		adapter->scanmode = cmd_bss_type_bss;
-		break;
-	case 1:
-		adapter->scanmode = cmd_bss_type_ibss;
-		break;
-	case 2:
-		adapter->scanmode = cmd_bss_type_any;
-		break;
-	case 3:
-
-		wrq->u.data.length = strlen(option[adapter->scanmode - 1]) + 1;
-
-		lbs_pr_debug(1, "Get Scan mode Option = %s\n",
-		       option[adapter->scanmode - 1]);
-
-		lbs_pr_debug(1, "Scan mode length %d\n", wrq->u.data.length);
-
-		if (copy_to_user(wrq->u.data.pointer,
-				 option[adapter->scanmode - 1],
-				 wrq->u.data.length)) {
-			lbs_pr_debug(1, "Copy to user failed\n");
-			ret = -EFAULT;
-		}
-		lbs_pr_debug(1, "GET Scan type Option after copy = %s\n",
-		       (char *)wrq->u.data.pointer);
-
-		break;
-
-	default:
-		lbs_pr_debug(1, "Invalid Scan mode Ioctl Option\n");
-		ret = -EINVAL;
-		break;
-	}
-
-	LEAVE();
-	return ret;
-}
-
-/**
- *  @brief Get/Set Adhoc G Rate
- *
- *  @param priv		A pointer to wlan_private structure
- *  @param wrq	   	A pointer to user data
- *  @return 	   	0--success, otherwise fail
- */
-static int wlan_do_set_grate_ioctl(wlan_private * priv, struct iwreq *wrq)
-{
-	wlan_adapter *adapter = priv->adapter;
-	int data, data1;
-	int *val;
-
-	ENTER();
-
-	data1 = SUBCMD_DATA(wrq);
-	switch (data1) {
-	case 0:
-		adapter->adhoc_grate_enabled = 0;
-		break;
-	case 1:
-		adapter->adhoc_grate_enabled = 1;
-		break;
-	case 2:
-		break;
-	default:
-		return -EINVAL;
-	}
-	data = adapter->adhoc_grate_enabled;
-	val = (int *)wrq->u.name;
-	*val = data;
-	LEAVE();
-	return 0;
-}
-
 static inline int hex2int(char c)
 {
 	if (c >= '0' && c <= '9')
@@ -1761,6 +680,7 @@ static int wlan_fwt_list_neighbor_ioctl(wlan_private * priv, struct ifreq *req)
  */
 static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
 {
+	struct iwreq *wrq = (struct iwreq *)req;
 	static struct cmd_ds_fwt_access fwt_access;
 	int ret;
 
@@ -1776,7 +696,7 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
 				    (void *)&fwt_access);
 
 	if (ret == 0)
-		req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
+		wrq->u.param.value = le32_to_cpu(fwt_access.references);
 	else
 		return -EFAULT;
 
@@ -1792,6 +712,7 @@ static int wlan_fwt_cleanup_ioctl(wlan_private * priv, struct ifreq *req)
  */
 static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
 {
+	struct iwreq *wrq = (struct iwreq *)req;
 	static struct cmd_ds_fwt_access fwt_access;
 	int ret;
 
@@ -1807,7 +728,7 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
 				    (void *)&fwt_access);
 
 	if (ret == 0)
-		req->ifr_data = (char *)(le32_to_cpu(fwt_access.references));
+		wrq->u.param.value = le32_to_cpu(fwt_access.references);
 	else
 		return -EFAULT;
 
@@ -1823,6 +744,7 @@ static int wlan_fwt_time_ioctl(wlan_private * priv, struct ifreq *req)
  */
 static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
 {
+	struct iwreq *wrq = (struct iwreq *)req;
 	struct cmd_ds_mesh_access mesh_access;
 	int ret;
 
@@ -1835,9 +757,8 @@ static int wlan_mesh_get_ttl_ioctl(wlan_private * priv, struct ifreq *req)
 				    cmd_option_waitforrsp, 0,
 				    (void *)&mesh_access);
 
-	if (ret == 0) {
-		req->ifr_data = (char *)(le32_to_cpu(mesh_access.data[0]));
-	}
+	if (ret == 0)
+		wrq->u.param.value = le32_to_cpu(mesh_access.data[0]);
 	else
 		return -EFAULT;
 
@@ -1898,36 +819,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 
 	lbs_pr_debug(1, "libertas_do_ioctl: ioctl cmd = 0x%x\n", cmd);
 	switch (cmd) {
-	case WLANSCAN_TYPE:
-		lbs_pr_debug(1, "Scan type Ioctl\n");
-		ret = wlan_scan_type_ioctl(priv, wrq);
-		break;
-
 	case WLAN_SETNONE_GETNONE:	/* set WPA mode on/off ioctl #20 */
 		switch (wrq->u.data.flags) {
-		case WLANDEAUTH:
-			lbs_pr_debug(1, "Deauth\n");
-			libertas_send_deauth(priv);
-			break;
-
-		case WLANADHOCSTOP:
-			lbs_pr_debug(1, "Adhoc stop\n");
-			ret = libertas_do_adhocstop_ioctl(priv);
-			break;
-
-		case WLANRADIOON:
-			wlan_radio_ioctl(priv, 1);
-			break;
-
-		case WLANRADIOOFF:
-			wlan_radio_ioctl(priv, 0);
-			break;
-		case WLANWLANIDLEON:
-			libertas_idle_on(priv);
-			break;
-		case WLANWLANIDLEOFF:
-			libertas_idle_off(priv);
-			break;
 		case WLAN_SUBCMD_BT_RESET:	/* bt_reset */
 			wlan_bt_reset_ioctl(priv);
 			break;
@@ -1937,162 +830,19 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 		}		/* End of switch */
 		break;
 
-	case WLANSETWPAIE:
-		ret = wlan_setwpaie_ioctl(priv, req);
-		break;
-	case WLAN_SETINT_GETINT:
-		/* The first 4 bytes of req->ifr_data is sub-ioctl number
-		 * after 4 bytes sits the payload.
-		 */
-		subcmd = (int)req->ifr_data;	//from iwpriv subcmd
-		switch (subcmd) {
-		case WLANNF:
-			ret = wlan_get_nf(priv, wrq);
-			break;
-		case WLANRSSI:
-			ret = wlan_get_rssi(priv, wrq);
-			break;
-		case WLANENABLE11D:
-			ret = libertas_cmd_enable_11d(priv, wrq);
-			break;
-		case WLANADHOCGRATE:
-			ret = wlan_do_set_grate_ioctl(priv, wrq);
-			break;
-		case WLAN_SUBCMD_SET_PRESCAN:
-			ret = wlan_subcmd_setprescan_ioctl(priv, wrq);
-			break;
-		}
-		break;
-
-	case WLAN_SETONEINT_GETONEINT:
-		switch (wrq->u.data.flags) {
-		case WLAN_BEACON_INTERVAL:
-			ret = wlan_beacon_interval(priv, wrq);
-			break;
-
-		case WLAN_LISTENINTRVL:
-			if (!wrq->u.data.length) {
-				int data;
-				lbs_pr_debug(1, "Get locallisteninterval value\n");
-#define GET_ONE_INT	1
-				data = adapter->locallisteninterval;
-				if (copy_to_user(wrq->u.data.pointer,
-						 &data, sizeof(int))) {
-					lbs_pr_debug(1, "Copy to user failed\n");
-					return -EFAULT;
-				}
-
-				wrq->u.data.length = GET_ONE_INT;
-			} else {
-				int data;
-				if (copy_from_user
-				    (&data, wrq->u.data.pointer, sizeof(int))) {
-					lbs_pr_debug(1, "Copy from user failed\n");
-					return -EFAULT;
-				}
-
-				lbs_pr_debug(1, "Set locallisteninterval = %d\n",
-				       data);
-#define MAX_U16_VAL	65535
-				if (data > MAX_U16_VAL) {
-					lbs_pr_debug(1, "Exceeds U16 value\n");
-					return -EINVAL;
-				}
-				adapter->locallisteninterval = data;
-			}
-			break;
-		case WLAN_TXCONTROL:
-			ret = wlan_txcontrol(priv, wrq);	//adds for txcontrol ioctl
-			break;
-
-		case WLAN_NULLPKTINTERVAL:
-			ret = wlan_null_pkt_interval(priv, wrq);
-			break;
-
-		default:
-			ret = -EOPNOTSUPP;
-			break;
-		}
-		break;
-
 	case WLAN_SETONEINT_GETNONE:
 		/* The first 4 bytes of req->ifr_data is sub-ioctl number
 		 * after 4 bytes sits the payload.
 		 */
-		subcmd = wrq->u.data.flags;	//from wpa_supplicant subcmd
-
+		subcmd = wrq->u.data.flags;
 		if (!subcmd)
-			subcmd = (int)req->ifr_data;	//from iwpriv subcmd
+			subcmd = (int)wrq->u.param.value;
 
 		switch (subcmd) {
-		case WLAN_SUBCMD_SETRXANTENNA:	/* SETRXANTENNA */
-			idata = SUBCMD_DATA(wrq);
-			ret = setrxantenna(priv, idata);
-			break;
-		case WLAN_SUBCMD_SETTXANTENNA:	/* SETTXANTENNA */
-			idata = SUBCMD_DATA(wrq);
-			ret = settxantenna(priv, idata);
-			break;
-		case WLAN_SET_ATIM_WINDOW:
-			adapter->atimwindow = SUBCMD_DATA(wrq);
-			adapter->atimwindow = min_t(__u16, adapter->atimwindow, 50);
-			break;
-		case WLANSETBCNAVG:
-			adapter->bcn_avg_factor = SUBCMD_DATA(wrq);
-			if (adapter->bcn_avg_factor == 0)
-				adapter->bcn_avg_factor =
-				    DEFAULT_BCN_AVG_FACTOR;
-			if (adapter->bcn_avg_factor > DEFAULT_BCN_AVG_FACTOR)
-				adapter->bcn_avg_factor =
-				    DEFAULT_BCN_AVG_FACTOR;
-			break;
-		case WLANSETDATAAVG:
-			adapter->data_avg_factor = SUBCMD_DATA(wrq);
-			if (adapter->data_avg_factor == 0)
-				adapter->data_avg_factor =
-				    DEFAULT_DATA_AVG_FACTOR;
-			if (adapter->data_avg_factor > DEFAULT_DATA_AVG_FACTOR)
-				adapter->data_avg_factor =
-				    DEFAULT_DATA_AVG_FACTOR;
-			break;
 		case WLANSETREGION:
 			idata = SUBCMD_DATA(wrq);
 			ret = wlan_set_region(priv, (u16) idata);
 			break;
-
-		case WLAN_SET_LISTEN_INTERVAL:
-			idata = SUBCMD_DATA(wrq);
-			adapter->listeninterval = (u16) idata;
-			break;
-
-		case WLAN_SET_MULTIPLE_DTIM:
-			ret = wlan_set_multiple_dtim_ioctl(priv, req);
-			break;
-
-		case WLANSETAUTHALG:
-			ret = wlan_setauthalg_ioctl(priv, req);
-			break;
-
-		case WLANSET8021XAUTHALG:
-			ret = wlan_set8021xauthalg_ioctl(priv, req);
-			break;
-
-		case WLANSETENCRYPTIONMODE:
-			ret = wlan_setencryptionmode_ioctl(priv, req);
-			break;
-
-		case WLAN_SET_LINKMODE:
-			ret = wlan_set_linkmode_ioctl(priv, req);
-			break;
-
-		case WLAN_SET_RADIOMODE:
-			ret = wlan_set_radiomode_ioctl(priv, req);
-			break;
-
-		case WLAN_SET_DEBUGMODE:
-			ret = wlan_set_debugmode_ioctl(priv, req);
-			break;
-
 		case WLAN_SUBCMD_MESH_SET_TTL:
 			idata = SUBCMD_DATA(wrq);
 			ret = wlan_mesh_set_ttl_ioctl(priv, idata);
@@ -2105,38 +855,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 
 		break;
 
-	case WLAN_SETNONE_GETTWELVE_CHAR:	/* Get Antenna settings */
-		/*
-		 * We've not used IW_PRIV_TYPE_FIXED so sub-ioctl number is
-		 * in flags of iwreq structure, otherwise it will be in
-		 * mode member of iwreq structure.
-		 */
-		switch ((int)wrq->u.data.flags) {
-		case WLAN_SUBCMD_GETRXANTENNA:	/* Get Rx Antenna */
-			ret = wlan_subcmd_getrxantenna_ioctl(priv, req);
-			break;
-
-		case WLAN_SUBCMD_GETTXANTENNA:	/* Get Tx Antenna */
-			ret = wlan_subcmd_gettxantenna_ioctl(priv, req);
-			break;
-
-		case WLAN_GET_TSF:
-			ret = wlan_get_tsf_ioctl(priv, wrq);
-			break;
-		}
-		break;
-
 	case WLAN_SET128CHAR_GET128CHAR:
 		switch ((int)wrq->u.data.flags) {
-
-		case WLANSCAN_MODE:
-			lbs_pr_debug(1, "Scan mode Ioctl\n");
-			ret = wlan_scan_mode_ioctl(priv, wrq);
-			break;
-
-		case WLAN_GET_ADHOC_STATUS:
-			ret = wlan_get_adhoc_status_ioctl(priv, wrq);
-			break;
 		case WLAN_SUBCMD_BT_ADD:
 			ret = wlan_bt_add_ioctl(priv, req);
 			break;
@@ -2168,41 +888,11 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 		break;
 
 	case WLAN_SETNONE_GETONEINT:
-		switch ((int)req->ifr_data) {
-		case WLANGETBCNAVG:
-			pdata = (int *)wrq->u.name;
-			*pdata = (int)adapter->bcn_avg_factor;
-			break;
-
+		switch (wrq->u.param.value) {
 		case WLANGETREGION:
 			pdata = (int *)wrq->u.name;
 			*pdata = (int)adapter->regioncode;
 			break;
-
-		case WLAN_GET_LISTEN_INTERVAL:
-			pdata = (int *)wrq->u.name;
-			*pdata = (int)adapter->listeninterval;
-			break;
-
-		case WLAN_GET_LINKMODE:
-			req->ifr_data = (char *)((u32) adapter->linkmode);
-			break;
-
-		case WLAN_GET_RADIOMODE:
-			req->ifr_data = (char *)((u32) adapter->radiomode);
-			break;
-
-		case WLAN_GET_DEBUGMODE:
-			req->ifr_data = (char *)((u32) adapter->debugmode);
-			break;
-
-		case WLAN_GET_MULTIPLE_DTIM:
-			pdata = (int *)wrq->u.name;
-			*pdata = (int)adapter->multipledtim;
-			break;
-		case WLAN_GET_TX_RATE:
-			ret = wlan_get_txrate_ioctl(priv, req);
-			break;
 		case WLAN_SUBCMD_FWT_CLEANUP:	/* fwt_cleanup */
 			ret = wlan_fwt_cleanup_ioctl(priv, req);
 			break;
@@ -2222,196 +912,8 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 
 		break;
 
-	case WLANGETLOG:
-		ret = wlan_do_getlog_ioctl(priv, wrq);
-		break;
-
 	case WLAN_SET_GET_SIXTEEN_INT:
 		switch ((int)wrq->u.data.flags) {
-		case WLAN_TPCCFG:
-			{
-				int data[5];
-				struct cmd_ds_802_11_tpc_cfg cfg;
-				memset(&cfg, 0, sizeof(cfg));
-				if ((wrq->u.data.length > 1)
-				    && (wrq->u.data.length != 5))
-					return -1;
-
-				if (wrq->u.data.length == 0) {
-					cfg.action =
-					    cpu_to_le16
-					    (cmd_act_get);
-				} else {
-					if (copy_from_user
-					    (data, wrq->u.data.pointer,
-					     sizeof(int) * 5)) {
-						lbs_pr_debug(1,
-						       "Copy from user failed\n");
-						return -EFAULT;
-					}
-
-					cfg.action =
-					    cpu_to_le16
-					    (cmd_act_set);
-					cfg.enable = data[0];
-					cfg.usesnr = data[1];
-					cfg.P0 = data[2];
-					cfg.P1 = data[3];
-					cfg.P2 = data[4];
-				}
-
-				ret =
-				    libertas_prepare_and_send_command(priv,
-							  cmd_802_11_tpc_cfg,
-							  0,
-							  cmd_option_waitforrsp,
-							  0, (void *)&cfg);
-
-				data[0] = cfg.enable;
-				data[1] = cfg.usesnr;
-				data[2] = cfg.P0;
-				data[3] = cfg.P1;
-				data[4] = cfg.P2;
-				if (copy_to_user
-				    (wrq->u.data.pointer, data,
-				     sizeof(int) * 5)) {
-					lbs_pr_debug(1, "Copy to user failed\n");
-					return -EFAULT;
-				}
-
-				wrq->u.data.length = 5;
-			}
-			break;
-
-		case WLAN_POWERCFG:
-			{
-				int data[4];
-				struct cmd_ds_802_11_pwr_cfg cfg;
-				memset(&cfg, 0, sizeof(cfg));
-				if ((wrq->u.data.length > 1)
-				    && (wrq->u.data.length != 4))
-					return -1;
-				if (wrq->u.data.length == 0) {
-					cfg.action =
-					    cpu_to_le16
-					    (cmd_act_get);
-				} else {
-					if (copy_from_user
-					    (data, wrq->u.data.pointer,
-					     sizeof(int) * 4)) {
-						lbs_pr_debug(1,
-						       "Copy from user failed\n");
-						return -EFAULT;
-					}
-
-					cfg.action =
-					    cpu_to_le16
-					    (cmd_act_set);
-					cfg.enable = data[0];
-					cfg.PA_P0 = data[1];
-					cfg.PA_P1 = data[2];
-					cfg.PA_P2 = data[3];
-				}
-				ret =
-				    libertas_prepare_and_send_command(priv,
-							  cmd_802_11_pwr_cfg,
-							  0,
-							  cmd_option_waitforrsp,
-							  0, (void *)&cfg);
-				data[0] = cfg.enable;
-				data[1] = cfg.PA_P0;
-				data[2] = cfg.PA_P1;
-				data[3] = cfg.PA_P2;
-				if (copy_to_user
-				    (wrq->u.data.pointer, data,
-				     sizeof(int) * 4)) {
-					lbs_pr_debug(1, "Copy to user failed\n");
-					return -EFAULT;
-				}
-
-				wrq->u.data.length = 4;
-			}
-			break;
-		case WLAN_AUTO_FREQ_SET:
-			{
-				int data[3];
-				struct cmd_ds_802_11_afc afc;
-				memset(&afc, 0, sizeof(afc));
-				if (wrq->u.data.length != 3)
-					return -1;
-				if (copy_from_user
-				    (data, wrq->u.data.pointer,
-				     sizeof(int) * 3)) {
-					lbs_pr_debug(1, "Copy from user failed\n");
-					return -EFAULT;
-				}
-				afc.afc_auto = data[0];
-
-				if (afc.afc_auto != 0) {
-					afc.threshold = data[1];
-					afc.period = data[2];
-				} else {
-					afc.timing_offset = data[1];
-					afc.carrier_offset = data[2];
-				}
-				ret =
-				    libertas_prepare_and_send_command(priv,
-							  cmd_802_11_set_afc,
-							  0,
-							  cmd_option_waitforrsp,
-							  0, (void *)&afc);
-			}
-			break;
-		case WLAN_AUTO_FREQ_GET:
-			{
-				int data[3];
-				struct cmd_ds_802_11_afc afc;
-				memset(&afc, 0, sizeof(afc));
-				ret =
-				    libertas_prepare_and_send_command(priv,
-							  cmd_802_11_get_afc,
-							  0,
-							  cmd_option_waitforrsp,
-							  0, (void *)&afc);
-				data[0] = afc.afc_auto;
-				data[1] = afc.timing_offset;
-				data[2] = afc.carrier_offset;
-				if (copy_to_user
-				    (wrq->u.data.pointer, data,
-				     sizeof(int) * 3)) {
-					lbs_pr_debug(1, "Copy to user failed\n");
-					return -EFAULT;
-				}
-
-				wrq->u.data.length = 3;
-			}
-			break;
-		case WLAN_SCANPROBES:
-			{
-				int data;
-				if (wrq->u.data.length > 0) {
-					if (copy_from_user
-					    (&data, wrq->u.data.pointer,
-					     sizeof(int))) {
-						lbs_pr_debug(1,
-						       "Copy from user failed\n");
-						return -EFAULT;
-					}
-
-					adapter->scanprobes = data;
-				} else {
-					data = adapter->scanprobes;
-					if (copy_to_user
-					    (wrq->u.data.pointer, &data,
-					     sizeof(int))) {
-						lbs_pr_debug(1,
-						       "Copy to user failed\n");
-						return -EFAULT;
-					}
-				}
-				wrq->u.data.length = 1;
-			}
-			break;
 		case WLAN_LED_GPIO_CTRL:
 			{
 				int i;
@@ -2475,17 +977,6 @@ int libertas_do_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 				wrq->u.data.length = gpio->header.len;
 			}
 			break;
-		case WLAN_ADAPT_RATESET:
-			ret = wlan_adapt_rateset(priv, wrq);
-			break;
-		case WLAN_INACTIVITY_TIMEOUT:
-			ret = wlan_inactivity_timeout(priv, wrq);
-			break;
-		case WLANSNR:
-			ret = wlan_get_snr(priv, wrq);
-			break;
-		case WLAN_GET_RXINFO:
-			ret = wlan_get_rxinfo(priv, wrq);
 		}
 		break;
 
diff --git a/drivers/net/wireless/libertas/join.c b/drivers/net/wireless/libertas/join.c
index 11682cb..d4926b8 100644
--- a/drivers/net/wireless/libertas/join.c
+++ b/drivers/net/wireless/libertas/join.c
@@ -15,6 +15,8 @@
 #include "join.h"
 #include "dev.h"
 
+#define AD_HOC_CAP_PRIVACY_ON 1
+
 /**
  *  @brief This function finds out the common rates between rate1 and rate2.
  *
@@ -85,7 +87,7 @@ int libertas_send_deauth(wlan_private * priv)
 	wlan_adapter *adapter = priv->adapter;
 	int ret = 0;
 
-	if (adapter->inframode == wlan802_11infrastructure &&
+	if (adapter->mode == IW_MODE_INFRA &&
 	    adapter->connect_status == libertas_connected)
 		ret = libertas_send_deauthentication(priv);
 	else
@@ -94,20 +96,6 @@ int libertas_send_deauth(wlan_private * priv)
 	return ret;
 }
 
-int libertas_do_adhocstop_ioctl(wlan_private * priv)
-{
-	wlan_adapter *adapter = priv->adapter;
-	int ret = 0;
-
-	if (adapter->inframode == wlan802_11ibss &&
-	    adapter->connect_status == libertas_connected)
-		ret = libertas_stop_adhoc_network(priv);
-	else
-		ret = -ENOTSUPP;
-
-	return ret;
-}
-
 /**
  *  @brief Associate to a specific BSS discovered in a scan
  *
@@ -207,8 +195,7 @@ int libertas_join_adhoc_network(wlan_private * priv, struct bss_descriptor * pbs
 	/* check if the requested SSID is already joined */
 	if (adapter->curbssparams.ssid.ssidlength
 	    && !libertas_SSID_cmp(&pbssdesc->ssid, &adapter->curbssparams.ssid)
-	    && (adapter->curbssparams.bssdescriptor.inframode ==
-		wlan802_11ibss)) {
+	    && (adapter->mode == IW_MODE_ADHOC)) {
 
         lbs_pr_debug(1,
 		       "ADHOC_J_CMD: New ad-hoc SSID is the same as current, "
@@ -261,130 +248,6 @@ int libertas_send_deauthentication(wlan_private * priv)
 }
 
 /**
- *  @brief Set Idle Off
- *
- *  @param priv         A pointer to wlan_private structure
- *  @return             0 --success, otherwise fail
- */
-int libertas_idle_off(wlan_private * priv)
-{
-	wlan_adapter *adapter = priv->adapter;
-	int ret = 0;
-	const u8 zeromac[] = { 0, 0, 0, 0, 0, 0 };
-	int i;
-
-	ENTER();
-
-	if (adapter->connect_status == libertas_disconnected) {
-		if (adapter->inframode == wlan802_11infrastructure) {
-			if (memcmp(adapter->previousbssid, zeromac,
-				   sizeof(zeromac)) != 0) {
-
-				lbs_pr_debug(1, "Previous SSID = %s\n",
-				       adapter->previousssid.ssid);
-				lbs_pr_debug(1, "Previous BSSID = "
-				       "%02x:%02x:%02x:%02x:%02x:%02x:\n",
-				       adapter->previousbssid[0],
-				       adapter->previousbssid[1],
-				       adapter->previousbssid[2],
-				       adapter->previousbssid[3],
-				       adapter->previousbssid[4],
-				       adapter->previousbssid[5]);
-
-				i = libertas_find_SSID_in_list(adapter,
-						   &adapter->previousssid,
-						   adapter->previousbssid,
-						   adapter->inframode);
-
-				if (i < 0) {
-					libertas_send_specific_BSSID_scan(priv,
-							      adapter->
-							      previousbssid,
-							      1);
-					i = libertas_find_SSID_in_list(adapter,
-							   &adapter->
-							   previousssid,
-							   adapter->
-							   previousbssid,
-							   adapter->
-							   inframode);
-				}
-
-				if (i < 0) {
-					/* If the BSSID could not be found, try just the SSID */
-					i = libertas_find_SSID_in_list(adapter,
-							   &adapter->
-							   previousssid, NULL,
-							   adapter->
-							   inframode);
-				}
-
-				if (i < 0) {
-					libertas_send_specific_SSID_scan(priv,
-							     &adapter->
-							     previousssid,
-							     1);
-					i = libertas_find_SSID_in_list(adapter,
-							   &adapter->
-							   previousssid, NULL,
-							   adapter->
-							   inframode);
-				}
-
-				if (i >= 0) {
-					ret =
-					    wlan_associate(priv,
-							   &adapter->
-							   scantable[i]);
-				}
-			}
-		} else if (adapter->inframode == wlan802_11ibss) {
-			ret = libertas_prepare_and_send_command(priv,
-						    cmd_802_11_ad_hoc_start,
-						    0,
-						    cmd_option_waitforrsp,
-						    0, &adapter->previousssid);
-		}
-	}
-	/* else it is connected */
-
-	lbs_pr_debug(1, "\nwlanidle is off");
-	LEAVE();
-	return ret;
-}
-
-/**
- *  @brief Set Idle On
- *
- *  @param priv         A pointer to wlan_private structure
- *  @return             0 --success, otherwise fail
- */
-int libertas_idle_on(wlan_private * priv)
-{
-	wlan_adapter *adapter = priv->adapter;
-	int ret = 0;
-
-	if (adapter->connect_status == libertas_connected) {
-		if (adapter->inframode == wlan802_11infrastructure) {
-			lbs_pr_debug(1, "Previous SSID = %s\n",
-			       adapter->previousssid.ssid);
-			memmove(&adapter->previousssid,
-				&adapter->curbssparams.ssid,
-				sizeof(struct WLAN_802_11_SSID));
-			libertas_send_deauth(priv);
-
-		} else if (adapter->inframode == wlan802_11ibss) {
-			ret = libertas_stop_adhoc_network(priv);
-		}
-
-	}
-
-	lbs_pr_debug(1, "\nwlanidle is on");
-
-	return ret;
-}
-
-/**
  *  @brief This function prepares command of authenticate.
  *
  *  @param priv      A pointer to wlan_private structure
@@ -398,22 +261,39 @@ int libertas_cmd_80211_authenticate(wlan_private * priv,
 				 void *pdata_buf)
 {
 	wlan_adapter *adapter = priv->adapter;
-	struct cmd_ds_802_11_authenticate *pauthenticate =
-	    &cmd->params.auth;
+	struct cmd_ds_802_11_authenticate *pauthenticate = &cmd->params.auth;
+	int ret = -1;
 	u8 *bssid = pdata_buf;
 
 	cmd->command = cpu_to_le16(cmd_802_11_authenticate);
-	cmd->size =
-	    cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
-			     + S_DS_GEN);
+	cmd->size = cpu_to_le16(sizeof(struct cmd_ds_802_11_authenticate)
+	                        + S_DS_GEN);
+
+	/* translate auth mode to 802.11 defined wire value */
+	switch (adapter->secinfo.auth_mode) {
+	case IW_AUTH_ALG_OPEN_SYSTEM:
+		pauthenticate->authtype = 0x00;
+		break;
+	case IW_AUTH_ALG_SHARED_KEY:
+		pauthenticate->authtype = 0x01;
+		break;
+	case IW_AUTH_ALG_LEAP:
+		pauthenticate->authtype = 0x80;
+		break;
+	default:
+		lbs_pr_debug(1, "AUTH_CMD: invalid auth alg 0x%X\n",
+		             adapter->secinfo.auth_mode);
+		goto out;
+	}
 
-	pauthenticate->authtype = adapter->secinfo.authmode;
 	memcpy(pauthenticate->macaddr, bssid, ETH_ALEN);
 
 	lbs_pr_debug(1, "AUTH_CMD: Bssid is : %x:%x:%x:%x:%x:%x\n",
 	       bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]);
+	ret = 0;
 
-	return 0;
+out:
+	return ret;
 }
 
 int libertas_cmd_80211_deauthenticate(wlan_private * priv,
@@ -550,7 +430,7 @@ int libertas_cmd_80211_associate(wlan_private * priv,
 	lbs_pr_debug(1, "ASSOC_CMD: rates->header.len = %d\n", rates->header.len);
 
 	/* set IBSS field */
-	if (pbssdesc->inframode == wlan802_11infrastructure) {
+	if (pbssdesc->mode == IW_MODE_INFRA) {
 #define CAPINFO_ESS_MODE 1
 		passo->capinfo.ess = CAPINFO_ESS_MODE;
 	}
@@ -624,7 +504,7 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
 
 	/* set the BSS type */
 	adhs->bsstype = cmd_bss_type_ibss;
-	pbssdesc->inframode = wlan802_11ibss;
+	pbssdesc->mode = IW_MODE_ADHOC;
 	adhs->beaconperiod = adapter->beaconperiod;
 
 	/* set Physical param set */
@@ -666,15 +546,12 @@ int libertas_cmd_80211_ad_hoc_start(wlan_private * priv,
 	adhs->probedelay = cpu_to_le16(cmd_scan_probe_delay_time);
 
 	/* set up privacy in adapter->scantable[i] */
-	if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled) {
-
-#define AD_HOC_CAP_PRIVACY_ON 1
-		lbs_pr_debug(1, "ADHOC_S_CMD: WEPstatus set, privacy to WEP\n");
+	if (adapter->secinfo.wep_enabled) {
+		lbs_pr_debug(1, "ADHOC_S_CMD: WEP enabled, setting privacy on\n");
 		pbssdesc->privacy = wlan802_11privfilter8021xWEP;
 		adhs->cap.privacy = AD_HOC_CAP_PRIVACY_ON;
 	} else {
-		lbs_pr_debug(1, "ADHOC_S_CMD: WEPstatus NOT set, Setting "
-		       "privacy to ACCEPT ALL\n");
+		lbs_pr_debug(1, "ADHOC_S_CMD: WEP disabled, setting privacy off\n");
 		pbssdesc->privacy = wlan802_11privfilteracceptall;
 	}
 
@@ -786,9 +663,6 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
 	       padhocjoin->bssdescriptor.BSSID[5],
 	       padhocjoin->bssdescriptor.SSID);
 
-	lbs_pr_debug(1, "ADHOC_J_CMD: Data Rate = %x\n",
-	       (u32) padhocjoin->bssdescriptor.datarates);
-
 	/* failtimeout */
 	padhocjoin->failtimeout = cpu_to_le16(MRVDRV_ASSOCIATION_TIME_OUT);
 
@@ -832,7 +706,7 @@ int libertas_cmd_80211_ad_hoc_join(wlan_private * priv,
 	padhocjoin->bssdescriptor.ssparamset.ibssparamset.atimwindow =
 	    cpu_to_le16(pbssdesc->atimwindow);
 
-	if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled) {
+	if (adapter->secinfo.wep_enabled) {
 		padhocjoin->bssdescriptor.cap.privacy = AD_HOC_CAP_PRIVACY_ON;
 	}
 
diff --git a/drivers/net/wireless/libertas/join.h b/drivers/net/wireless/libertas/join.h
index 8efa245..115f5a8 100644
--- a/drivers/net/wireless/libertas/join.h
+++ b/drivers/net/wireless/libertas/join.h
@@ -1,6 +1,3 @@
-/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
-
 /**
   * Interface for the wlan infrastructure and adhoc join routines
   *
@@ -40,10 +37,6 @@ extern int libertas_ret_80211_disassociate(wlan_private * priv,
 extern int libertas_ret_80211_associate(wlan_private * priv,
 				     struct cmd_ds_command *resp);
 
-extern int libertas_idle_on(wlan_private * priv);
-extern int libertas_idle_off(wlan_private * priv);
-
-extern int libertas_do_adhocstop_ioctl(wlan_private * priv);
 extern int libertas_reassociation_thread(void *data);
 
 struct WLAN_802_11_SSID;
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index dcbf102..b9b25ce 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -21,6 +21,13 @@
 #include "debugfs.h"
 #include "assoc.h"
 
+#define DRIVER_RELEASE_VERSION "320.p0"
+const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
+#ifdef  DEBUG
+    "-dbg"
+#endif
+    "";
+
 #ifdef ENABLE_PM
 static struct pm_dev *wlan_pm_dev = NULL;
 #endif
diff --git a/drivers/net/wireless/libertas/rx.c b/drivers/net/wireless/libertas/rx.c
index 7e3f78f..d17924f 100644
--- a/drivers/net/wireless/libertas/rx.c
+++ b/drivers/net/wireless/libertas/rx.c
@@ -210,7 +210,7 @@ int libertas_process_rxed_packet(wlan_private * priv, struct sk_buff *skb)
 		goto done;
 	}
 
-	lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n",
+	lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n",
 	       skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
 
 	lbs_dbg_hex("RX Data: Dest", p_rx_pkt->eth803_hdr.dest_addr,
@@ -364,7 +364,7 @@ static int process_rxed_802_11_packet(wlan_private * priv, struct sk_buff *skb)
 		priv->stats.rx_errors++;
 	}
 
-	lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %d = %d\n",
+	lbs_pr_debug(1, "RX Data: skb->len - sizeof(RxPd) = %d - %zd = %zd\n",
 	       skb->len, sizeof(struct rxpd), skb->len - sizeof(struct rxpd));
 
 	/* create the exported radio header */
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index e187062..3c0b1a2 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -1,6 +1,3 @@
-/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
-
 /**
   * Functions implementing wlan scan IOCTL and firmware command APIs
   *
@@ -87,118 +84,95 @@
  *
  *  @return        Index in scantable, or error code if negative
  */
-static int is_network_compatible(wlan_adapter * adapter, int index, int mode)
+static int is_network_compatible(wlan_adapter * adapter, int index, u8 mode)
 {
 	ENTER();
 
-	if (adapter->scantable[index].inframode == mode) {
-		if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+	if (adapter->scantable[index].mode == mode) {
+		if (   !adapter->secinfo.wep_enabled
 		    && !adapter->secinfo.WPAenabled
 		    && !adapter->secinfo.WPA2enabled
-		    && adapter->scantable[index].wpa_supplicant.wpa_ie[0] !=
-		    WPA_IE
-		    && adapter->scantable[index].wpa2_supplicant.wpa_ie[0] !=
-		    WPA2_IE && adapter->secinfo.Encryptionmode == CIPHER_NONE
+		    && adapter->scantable[index].wpa_ie[0] != WPA_IE
+		    && adapter->scantable[index].rsn_ie[0] != WPA2_IE
 		    && !adapter->scantable[index].privacy) {
 			/* no security */
 			LEAVE();
 			return index;
-		} else if (adapter->secinfo.WEPstatus == wlan802_11WEPenabled
+		} else if (   adapter->secinfo.wep_enabled
 			   && !adapter->secinfo.WPAenabled
 			   && !adapter->secinfo.WPA2enabled
 			   && adapter->scantable[index].privacy) {
 			/* static WEP enabled */
 			LEAVE();
 			return index;
-		} else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+		} else if (   !adapter->secinfo.wep_enabled
 			   && adapter->secinfo.WPAenabled
 			   && !adapter->secinfo.WPA2enabled
-			   && (adapter->scantable[index].wpa_supplicant.
-			       wpa_ie[0]
-			       == WPA_IE)
+			   && (adapter->scantable[index].wpa_ie[0] == WPA_IE)
 			   /* privacy bit may NOT be set in some APs like LinkSys WRT54G
 			      && adapter->scantable[index].privacy */
 		    ) {
 			/* WPA enabled */
-            lbs_pr_debug(1,
+			lbs_pr_debug(1,
 			       "is_network_compatible() WPA: index=%d wpa_ie=%#x "
-			       "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x "
+			       "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
 			       "privacy=%#x\n", index,
-			       adapter->scantable[index].wpa_supplicant.
-			       wpa_ie[0],
-			       adapter->scantable[index].wpa2_supplicant.
-			       wpa_ie[0],
-			       (adapter->secinfo.WEPstatus ==
-				wlan802_11WEPenabled) ? "e" : "d",
-			       (adapter->secinfo.WPAenabled) ? "e" : "d",
-			       (adapter->secinfo.WPA2enabled) ? "e" : "d",
-			       adapter->secinfo.Encryptionmode,
+			       adapter->scantable[index].wpa_ie[0],
+			       adapter->scantable[index].rsn_ie[0],
+			       adapter->secinfo.wep_enabled ? "e" : "d",
+			       adapter->secinfo.WPAenabled ? "e" : "d",
+			       adapter->secinfo.WPA2enabled ? "e" : "d",
 			       adapter->scantable[index].privacy);
 			LEAVE();
 			return index;
-		} else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+		} else if (   !adapter->secinfo.wep_enabled
 			   && !adapter->secinfo.WPAenabled
 			   && adapter->secinfo.WPA2enabled
-			   && (adapter->scantable[index].wpa2_supplicant.
-			       wpa_ie[0]
-			       == WPA2_IE)
+			   && (adapter->scantable[index].rsn_ie[0] == WPA2_IE)
 			   /* privacy bit may NOT be set in some APs like LinkSys WRT54G
 			      && adapter->scantable[index].privacy */
 		    ) {
 			/* WPA2 enabled */
-            lbs_pr_debug(1,
+			lbs_pr_debug(1,
 			       "is_network_compatible() WPA2: index=%d wpa_ie=%#x "
-			       "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x "
+			       "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s "
 			       "privacy=%#x\n", index,
-			       adapter->scantable[index].wpa_supplicant.
-			       wpa_ie[0],
-			       adapter->scantable[index].wpa2_supplicant.
-			       wpa_ie[0],
-			       (adapter->secinfo.WEPstatus ==
-				wlan802_11WEPenabled) ? "e" : "d",
-			       (adapter->secinfo.WPAenabled) ? "e" : "d",
-			       (adapter->secinfo.WPA2enabled) ? "e" : "d",
-			       adapter->secinfo.Encryptionmode,
+			       adapter->scantable[index].wpa_ie[0],
+			       adapter->scantable[index].rsn_ie[0],
+			       adapter->secinfo.wep_enabled ? "e" : "d",
+			       adapter->secinfo.WPAenabled ? "e" : "d",
+			       adapter->secinfo.WPA2enabled ? "e" : "d",
 			       adapter->scantable[index].privacy);
 			LEAVE();
 			return index;
-		} else if (adapter->secinfo.WEPstatus == wlan802_11WEPdisabled
+		} else if (   !adapter->secinfo.wep_enabled
 			   && !adapter->secinfo.WPAenabled
 			   && !adapter->secinfo.WPA2enabled
-			   && (adapter->scantable[index].wpa_supplicant.
-			       wpa_ie[0]
-			       != WPA_IE)
-			   && (adapter->scantable[index].wpa2_supplicant.
-			       wpa_ie[0]
-			       != WPA2_IE)
-			   && adapter->secinfo.Encryptionmode != CIPHER_NONE
+			   && (adapter->scantable[index].wpa_ie[0] != WPA_IE)
+			   && (adapter->scantable[index].rsn_ie[0] != WPA2_IE)
 			   && adapter->scantable[index].privacy) {
 			/* dynamic WEP enabled */
-            lbs_pr_debug(1,
+			lbs_pr_debug(1,
 			       "is_network_compatible() dynamic WEP: index=%d "
-			       "wpa_ie=%#x wpa2_ie=%#x Encmode=%#x privacy=%#x\n",
+			       "wpa_ie=%#x wpa2_ie=%#x privacy=%#x\n",
 			       index,
-			       adapter->scantable[index].wpa_supplicant.
-			       wpa_ie[0],
-			       adapter->scantable[index].wpa2_supplicant.
-			       wpa_ie[0], adapter->secinfo.Encryptionmode,
+			       adapter->scantable[index].wpa_ie[0],
+			       adapter->scantable[index].rsn_ie[0],
 			       adapter->scantable[index].privacy);
 			LEAVE();
 			return index;
 		}
 
 		/* security doesn't match */
-        lbs_pr_debug(1,
+		lbs_pr_debug(1,
 		       "is_network_compatible() FAILED: index=%d wpa_ie=%#x "
-		       "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s Encmode=%#x privacy=%#x\n",
+		       "wpa2_ie=%#x WEP=%s WPA=%s WPA2=%s privacy=%#x\n",
 		       index,
-		       adapter->scantable[index].wpa_supplicant.wpa_ie[0],
-		       adapter->scantable[index].wpa2_supplicant.wpa_ie[0],
-		       (adapter->secinfo.WEPstatus ==
-			wlan802_11WEPenabled) ? "e" : "d",
-		       (adapter->secinfo.WPAenabled) ? "e" : "d",
-		       (adapter->secinfo.WPA2enabled) ? "e" : "d",
-		       adapter->secinfo.Encryptionmode,
+		       adapter->scantable[index].wpa_ie[0],
+		       adapter->scantable[index].rsn_ie[0],
+		       adapter->secinfo.wep_enabled ? "e" : "d",
+		       adapter->secinfo.WPAenabled ? "e" : "d",
+		       adapter->secinfo.WPA2enabled ? "e" : "d",
 		       adapter->scantable[index].privacy);
 		LEAVE();
 		return -ECONNREFUSED;
@@ -924,8 +898,6 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
 	u8 founddatarateie;
 	int bytesleftforcurrentbeacon;
 
-	struct WPA_SUPPLICANT *pwpa_supplicant;
-	struct WPA_SUPPLICANT *pwpa2_supplicant;
 	struct IE_WPA *pIe;
 	const u8 oui01[4] = { 0x00, 0x50, 0xf2, 0x01 };
 
@@ -962,9 +934,6 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
 
 	bytesleftforcurrentbeacon = beaconsize;
 
-	pwpa_supplicant = &pBSSEntry->wpa_supplicant;
-	pwpa2_supplicant = &pBSSEntry->wpa2_supplicant;
-
 	memcpy(pBSSEntry->macaddress, pcurrentptr, ETH_ALEN);
 	lbs_pr_debug(1, "InterpretIE: AP MAC Addr-%x:%x:%x:%x:%x:%x\n",
 	       pBSSEntry->macaddress[0], pBSSEntry->macaddress[1],
@@ -1027,9 +996,9 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
 	}
 
 	if (pcap->ibss == 1) {
-		pBSSEntry->inframode = wlan802_11ibss;
+		pBSSEntry->mode = IW_MODE_ADHOC;
 	} else {
-		pBSSEntry->inframode = wlan802_11infrastructure;
+		pBSSEntry->mode = IW_MODE_INFRA;
 	}
 
 	/* process variable IE */
@@ -1116,7 +1085,7 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
 			    sizeof(pcountryinfo->countrycode)
 			    || pcountryinfo->len > 254) {
 				lbs_pr_debug(1, "InterpretIE: 11D- Err "
-				       "CountryInfo len =%d min=%d max=254\n",
+				       "CountryInfo len =%d min=%zd max=254\n",
 				       pcountryinfo->len,
 				       sizeof(pcountryinfo->countrycode));
 				LEAVE();
@@ -1160,27 +1129,27 @@ static int InterpretBSSDescriptionWithIE(struct bss_descriptor * pBSSEntry,
 #define IE_ID_LEN_FIELDS_BYTES 2
 			pIe = (struct IE_WPA *)pcurrentptr;
 
-			if (!memcmp(pIe->oui, oui01, sizeof(oui01))) {
-				pwpa_supplicant->wpa_ie_len
-				    = min_t(size_t, elemlen + IE_ID_LEN_FIELDS_BYTES,
-					  sizeof(pwpa_supplicant->wpa_ie));
-				memcpy(pwpa_supplicant->wpa_ie,
-				       pcurrentptr,
-				       pwpa_supplicant->wpa_ie_len);
-				lbs_dbg_hex("InterpretIE: Resp WPA_IE",
-					pwpa_supplicant->wpa_ie, elemlen);
-			}
+			if (memcmp(pIe->oui, oui01, sizeof(oui01)))
+				break;
+
+			pBSSEntry->wpa_ie_len = min_t(size_t,
+				elemlen + IE_ID_LEN_FIELDS_BYTES,
+				sizeof(pBSSEntry->wpa_ie));
+			memcpy(pBSSEntry->wpa_ie, pcurrentptr,
+				pBSSEntry->wpa_ie_len);
+			lbs_dbg_hex("InterpretIE: Resp WPA_IE",
+				pBSSEntry->wpa_ie, elemlen);
 			break;
 		case WPA2_IE:
 			pIe = (struct IE_WPA *)pcurrentptr;
-			pwpa2_supplicant->wpa_ie_len
-			    = min_t(size_t, elemlen + IE_ID_LEN_FIELDS_BYTES,
-				  sizeof(pwpa2_supplicant->wpa_ie));
-			memcpy(pwpa2_supplicant->wpa_ie,
-			       pcurrentptr, pwpa2_supplicant->wpa_ie_len);
 
+			pBSSEntry->rsn_ie_len = min_t(size_t,
+				elemlen + IE_ID_LEN_FIELDS_BYTES,
+				sizeof(pBSSEntry->rsn_ie));
+			memcpy(pBSSEntry->rsn_ie, pcurrentptr,
+				pBSSEntry->rsn_ie_len);
 			lbs_dbg_hex("InterpretIE: Resp WPA2_IE",
-				pwpa2_supplicant->wpa_ie, elemlen);
+				pBSSEntry->rsn_ie, elemlen);
 			break;
 		case TIM:
 			break;
@@ -1227,7 +1196,7 @@ int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1, struct WLAN_802_11_SSID *s
  *
  *  @return         index in BSSID list, or error return code (< 0)
  */
-int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode)
+int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode)
 {
 	int ret = -ENETUNREACH;
 	int i;
@@ -1247,8 +1216,8 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode)
 	for (i = 0; ret < 0 && i < adapter->numinscantable; i++) {
 		if (!memcmp(adapter->scantable[i].macaddress, bssid, ETH_ALEN)) {
 			switch (mode) {
-			case wlan802_11infrastructure:
-			case wlan802_11ibss:
+			case IW_MODE_INFRA:
+			case IW_MODE_ADHOC:
 				ret = is_network_compatible(adapter, i, mode);
 				break;
 			default:
@@ -1272,7 +1241,7 @@ int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode)
  *  @return         index in BSSID list
  */
 int libertas_find_SSID_in_list(wlan_adapter * adapter,
-		   struct WLAN_802_11_SSID *ssid, u8 * bssid, int mode)
+		   struct WLAN_802_11_SSID *ssid, u8 * bssid, u8 mode)
 {
 	int net = -ENETUNREACH;
 	u8 bestrssi = 0;
@@ -1287,8 +1256,8 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
 		     !memcmp(adapter->scantable[i].
 			     macaddress, bssid, ETH_ALEN))) {
 			switch (mode) {
-			case wlan802_11infrastructure:
-			case wlan802_11ibss:
+			case IW_MODE_INFRA:
+			case IW_MODE_ADHOC:
 				j = is_network_compatible(adapter, i, mode);
 
 				if (j >= 0) {
@@ -1311,7 +1280,7 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
 					}
 				}
 				break;
-			case wlan802_11autounknown:
+			case IW_MODE_AUTO:
 			default:
 				if (SCAN_RSSI(adapter->scantable[i].rssi)
 				    > bestrssi) {
@@ -1338,8 +1307,7 @@ int libertas_find_SSID_in_list(wlan_adapter * adapter,
  *
  *  @return         index in BSSID list
  */
-int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
-                                    enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode)
+int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode)
 {
 	int bestnet = -ENETUNREACH;
 	u8 bestrssi = 0;
@@ -1351,8 +1319,8 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
 
 	for (i = 0; i < adapter->numinscantable; i++) {
 		switch (mode) {
-		case wlan802_11infrastructure:
-		case wlan802_11ibss:
+		case IW_MODE_INFRA:
+		case IW_MODE_ADHOC:
 			if (is_network_compatible(adapter, i, mode) >= 0) {
 				if (SCAN_RSSI(adapter->scantable[i].rssi) >
 				    bestrssi) {
@@ -1363,7 +1331,7 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
 				}
 			}
 			break;
-		case wlan802_11autounknown:
+		case IW_MODE_AUTO:
 		default:
 			if (SCAN_RSSI(adapter->scantable[i].rssi) > bestrssi) {
 				bestrssi =
@@ -1388,8 +1356,7 @@ int libertas_find_best_SSID_in_list(wlan_adapter * adapter,
  */
 int libertas_find_best_network_SSID(wlan_private * priv,
                                     struct WLAN_802_11_SSID *pSSID,
-                                    enum WLAN_802_11_NETWORK_INFRASTRUCTURE preferred_mode,
-                                    enum WLAN_802_11_NETWORK_INFRASTRUCTURE *out_mode)
+                                    u8 preferred_mode, u8 *out_mode)
 {
 	wlan_adapter *adapter = priv->adapter;
 	int ret = 0;
@@ -1414,7 +1381,7 @@ int libertas_find_best_network_SSID(wlan_private * priv,
 	preqbssid = &adapter->scantable[i];
 	memcpy(pSSID, &preqbssid->ssid,
 	       sizeof(struct WLAN_802_11_SSID));
-	*out_mode = preqbssid->inframode;
+	*out_mode = preqbssid->mode;
 
 	if (!pSSID->ssidlength) {
 		ret = -1;
@@ -1584,7 +1551,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
 	for (i = 0; i < adapter->numinscantable; i++) {
 		if ((current_ev + MAX_SCAN_CELL_SIZE) >= end_buf) {
 			lbs_pr_debug(1, "i=%d break out: current_ev=%p end_buf=%p "
-			       "MAX_SCAN_CELL_SIZE=%d\n",
+			       "MAX_SCAN_CELL_SIZE=%zd\n",
 			       i, current_ev, end_buf, MAX_SCAN_CELL_SIZE);
 			break;
 		}
@@ -1632,7 +1599,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
 
 		//Add mode
 		iwe.cmd = SIOCGIWMODE;
-		iwe.u.mode = adapter->scantable[i].inframode + 1;
+		iwe.u.mode = adapter->scantable[i].mode;
 		iwe.len = IW_EV_UINT_LEN;
 		current_ev =
 		    iwe_stream_add_event(current_ev, end_buf, &iwe, iwe.len);
@@ -1666,7 +1633,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
 			iwe.u.qual.noise =
 			    CAL_NF(adapter->NF[TYPE_BEACON][TYPE_NOAVG]);
 		}
-		if ((adapter->inframode == wlan802_11ibss) &&
+		if ((adapter->mode == IW_MODE_ADHOC) &&
 		    !libertas_SSID_cmp(&adapter->curbssparams.ssid,
 			     &adapter->scantable[i].ssid)
 		    && adapter->adhoccreate) {
@@ -1731,7 +1698,7 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
 						 end_buf, &iwe, iwe.len);
 
 		}
-		if ((adapter->scantable[i].inframode == wlan802_11ibss)
+		if ((adapter->scantable[i].mode == IW_MODE_ADHOC)
 		    && !libertas_SSID_cmp(&adapter->curbssparams.ssid,
 				&adapter->scantable[i].ssid)
 		    && adapter->adhoccreate) {
@@ -1745,30 +1712,24 @@ int libertas_get_scan(struct net_device *dev, struct iw_request_info *info,
 		/* Add new value to event */
 		current_val = current_ev + IW_EV_LCP_LEN;
 
-		if (adapter->scantable[i].wpa2_supplicant.wpa_ie[0] == WPA2_IE) {
+		if (adapter->scantable[i].rsn_ie[0] == WPA2_IE) {
 			memset(&iwe, 0, sizeof(iwe));
 			memset(buf, 0, sizeof(buf));
-			memcpy(buf, adapter->scantable[i].
-						wpa2_supplicant.wpa_ie,
-					adapter->scantable[i].wpa2_supplicant.
-						wpa_ie_len);
+			memcpy(buf, adapter->scantable[i].rsn_ie,
+					adapter->scantable[i].rsn_ie_len);
 			iwe.cmd = IWEVGENIE;
-			iwe.u.data.length = adapter->scantable[i].
-					wpa2_supplicant.wpa_ie_len;
+			iwe.u.data.length = adapter->scantable[i].rsn_ie_len;
 			iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
 			current_ev = iwe_stream_add_point(current_ev, end_buf,
 					&iwe, buf);
 		}
-		if (adapter->scantable[i].wpa_supplicant.wpa_ie[0] == WPA_IE) {
+		if (adapter->scantable[i].wpa_ie[0] == WPA_IE) {
 			memset(&iwe, 0, sizeof(iwe));
 			memset(buf, 0, sizeof(buf));
-			memcpy(buf, adapter->scantable[i].
-						wpa_supplicant.wpa_ie,
-					adapter->scantable[i].wpa_supplicant.
-						wpa_ie_len);
+			memcpy(buf, adapter->scantable[i].wpa_ie,
+					adapter->scantable[i].wpa_ie_len);
 			iwe.cmd = IWEVGENIE;
-			iwe.u.data.length = adapter->scantable[i].
-					wpa_supplicant.wpa_ie_len;
+			iwe.u.data.length = adapter->scantable[i].wpa_ie_len;
 			iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
 			current_ev = iwe_stream_add_point(current_ev, end_buf,
 					&iwe, buf);
diff --git a/drivers/net/wireless/libertas/scan.h b/drivers/net/wireless/libertas/scan.h
index d93aa7f..405f4f0 100644
--- a/drivers/net/wireless/libertas/scan.h
+++ b/drivers/net/wireless/libertas/scan.h
@@ -1,6 +1,3 @@
-/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
-/* vi: set expandtab shiftwidth=4 tabstop=4 textwidth=78: */
-
 /**
   * Interface for the wlan network scan routines
   *
@@ -10,6 +7,7 @@
 #ifndef _WLAN_SCAN_H
 #define _WLAN_SCAN_H
 
+#include <net/ieee80211.h>
 #include "hostcmd.h"
 
 /**
@@ -155,7 +153,7 @@ struct bss_descriptor {
 
 	u32 atimwindow;
 
-	enum WLAN_802_11_NETWORK_INFRASTRUCTURE inframode;
+	u8 mode;
 	u8 libertas_supported_rates[WLAN_SUPPORTED_RATES];
 
 	int extra_ie;
@@ -170,22 +168,22 @@ struct bss_descriptor {
 
 	struct ieeetypes_countryinfofullset countryinfo;
 
-	struct WPA_SUPPLICANT wpa_supplicant;
-	struct WPA_SUPPLICANT wpa2_supplicant;
-
+	u8 wpa_ie[MAX_WPA_IE_LEN];
+	size_t wpa_ie_len;
+	u8 rsn_ie[MAX_WPA_IE_LEN];
+	size_t rsn_ie_len;
 };
 
 extern int libertas_SSID_cmp(struct WLAN_802_11_SSID *ssid1,
 		   struct WLAN_802_11_SSID *ssid2);
 extern int libertas_find_SSID_in_list(wlan_adapter * adapter, struct WLAN_802_11_SSID *ssid,
-			  u8 * bssid, int mode);
-int libertas_find_best_SSID_in_list(wlan_adapter * adapter, enum WLAN_802_11_NETWORK_INFRASTRUCTURE mode);
-extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, int mode);
+			  u8 * bssid, u8 mode);
+int libertas_find_best_SSID_in_list(wlan_adapter * adapter, u8 mode);
+extern int libertas_find_BSSID_in_list(wlan_adapter * adapter, u8 * bssid, u8 mode);
 
 int libertas_find_best_network_SSID(wlan_private * priv,
 			struct WLAN_802_11_SSID *pSSID,
-			enum WLAN_802_11_NETWORK_INFRASTRUCTURE preferred_mode,
-			enum WLAN_802_11_NETWORK_INFRASTRUCTURE *out_mode);
+			u8 preferred_mode, u8 *out_mode);
 
 extern int libertas_send_specific_SSID_scan(wlan_private * priv,
 				struct WLAN_802_11_SSID *prequestedssid,
diff --git a/drivers/net/wireless/libertas/tx.c b/drivers/net/wireless/libertas/tx.c
index 82d0622..d4b1347 100644
--- a/drivers/net/wireless/libertas/tx.c
+++ b/drivers/net/wireless/libertas/tx.c
@@ -78,7 +78,7 @@ static int SendSinglePacket(wlan_private * priv, struct sk_buff *skb)
 			 min_t(unsigned int, skb->len, 100));
 
 	if (!skb->len || (skb->len > MRVDRV_ETH_TX_PACKET_BUFFER_SIZE)) {
-		lbs_pr_debug(1, "Tx error: Bad skb length %d : %d\n",
+		lbs_pr_debug(1, "Tx error: Bad skb length %d : %zd\n",
 		       skb->len, MRVDRV_ETH_TX_PACKET_BUFFER_SIZE);
 		ret = -1;
 		goto done;
diff --git a/drivers/net/wireless/libertas/version.h b/drivers/net/wireless/libertas/version.h
index e86f65a..8b13789 100644
--- a/drivers/net/wireless/libertas/version.h
+++ b/drivers/net/wireless/libertas/version.h
@@ -1,8 +1 @@
-#define DRIVER_RELEASE_VERSION "320.p0"
-const char libertas_driver_version[] = "COMM-USB8388-" DRIVER_RELEASE_VERSION
-#ifdef  DEBUG
-    "-dbg"
-#endif
-    "";
-
 
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index 4a52336..69f52b6 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -17,7 +17,6 @@
 #include "defs.h"
 #include "dev.h"
 #include "join.h"
-#include "version.h"
 #include "wext.h"
 #include "assoc.h"
 
@@ -233,7 +232,7 @@ static int changeadhocchannel(wlan_private * priv, int channel)
 
 		// find out the BSSID that matches the current SSID
 		i = libertas_find_SSID_in_list(adapter, &curadhocssid, NULL,
-				   wlan802_11ibss);
+				   IW_MODE_ADHOC);
 
 		if (i >= 0) {
 			lbs_pr_debug(1, "SSID found at %d in List,"
@@ -316,13 +315,11 @@ static int get_active_data_rates(wlan_adapter * adapter,
 	ENTER();
 
 	if (adapter->connect_status != libertas_connected) {
-		if (adapter->inframode == wlan802_11infrastructure) {
-			//Infra. mode
+		if (adapter->mode == IW_MODE_INFRA) {
 			lbs_pr_debug(1, "Infra\n");
 			k = copyrates(rates, k, libertas_supported_rates,
 				      sizeof(libertas_supported_rates));
 		} else {
-			//ad-hoc mode
 			lbs_pr_debug(1, "Adhoc G\n");
 			k = copyrates(rates, k, libertas_adhoc_rates_g,
 				      sizeof(libertas_adhoc_rates_g));
@@ -586,20 +583,7 @@ static int wlan_get_mode(struct net_device *dev,
 
 	ENTER();
 
-	switch (adapter->inframode) {
-	case wlan802_11ibss:
-		*uwrq = IW_MODE_ADHOC;
-		break;
-
-	case wlan802_11infrastructure:
-		*uwrq = IW_MODE_INFRA;
-		break;
-
-	default:
-	case wlan802_11autounknown:
-		*uwrq = IW_MODE_AUTO;
-		break;
-	}
+	*uwrq = adapter->mode;
 
 	LEAVE();
 	return 0;
@@ -1002,149 +986,18 @@ static const struct iw_priv_args wlan_private_args[] = {
 	/*
 	 * { cmd, set_args, get_args, name }
 	 */
-	{
-	 WLANSCAN_TYPE,
-	 IW_PRIV_TYPE_CHAR | 8,
-	 IW_PRIV_TYPE_CHAR | 8,
-	 "scantype"},
-
-	{
-	 WLAN_SETINT_GETINT,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 ""},
-	{
-	 WLANNF,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "getNF"},
-	{
-	 WLANRSSI,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "getRSSI"},
-	{
-	 WLANENABLE11D,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "enable11d"},
-	{
-	 WLANADHOCGRATE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "adhocgrate"},
-
-	{
-	 WLAN_SUBCMD_SET_PRESCAN,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "prescan"},
-	{
-	 WLAN_SETONEINT_GETONEINT,
-	 IW_PRIV_TYPE_INT | 1,
-	 IW_PRIV_TYPE_INT | 1,
-	 ""},
-	{
-	 WLAN_BEACON_INTERVAL,
-	 IW_PRIV_TYPE_INT | 1,
-	 IW_PRIV_TYPE_INT | 1,
-	 "bcninterval"},
-	{
-	 WLAN_LISTENINTRVL,
-	 IW_PRIV_TYPE_INT | 1,
-	 IW_PRIV_TYPE_INT | 1,
-	 "lolisteninter"},
-	{
-	 WLAN_TXCONTROL,
-	 IW_PRIV_TYPE_INT | 1,
-	 IW_PRIV_TYPE_INT | 1,
-	 "txcontrol"},
-	{
-	 WLAN_NULLPKTINTERVAL,
-	 IW_PRIV_TYPE_INT | 1,
-	 IW_PRIV_TYPE_INT | 1,
-	 "psnullinterval"},
 	/* Using iwpriv sub-command feature */
 	{
 	 WLAN_SETONEINT_GETNONE,	/* IOCTL: 24 */
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 	 IW_PRIV_TYPE_NONE,
 	 ""},
-
-	{
-	 WLAN_SUBCMD_SETRXANTENNA,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "setrxant"},
-	{
-	 WLAN_SUBCMD_SETTXANTENNA,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "settxant"},
-	{
-	 WLANSETAUTHALG,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "authalgs",
-	 },
-	{
-	 WLANSET8021XAUTHALG,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "8021xauthalgs",
-	 },
-	{
-	 WLANSETENCRYPTIONMODE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "encryptionmode",
-	 },
 	{
 	 WLANSETREGION,
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 	 IW_PRIV_TYPE_NONE,
 	 "setregioncode"},
 	{
-	 WLAN_SET_LISTEN_INTERVAL,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "setlisteninter"},
-	{
-	 WLAN_SET_MULTIPLE_DTIM,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "setmultipledtim"},
-	{
-	 WLAN_SET_ATIM_WINDOW,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "atimwindow"},
-	{
-	 WLANSETBCNAVG,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "setbcnavg"},
-	{
-	 WLANSETDATAAVG,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "setdataavg"},
-	{
-	 WLAN_SET_LINKMODE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "linkmode"},
-	{
-	 WLAN_SET_RADIOMODE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "radiomode"},
-	{
-	 WLAN_SET_DEBUGMODE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 IW_PRIV_TYPE_NONE,
-	 "debugmode"},
-	{
 	 WLAN_SUBCMD_MESH_SET_TTL,
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 	 IW_PRIV_TYPE_NONE,
@@ -1160,41 +1013,6 @@ static const struct iw_priv_args wlan_private_args[] = {
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 	 "getregioncode"},
 	{
-	 WLAN_GET_LISTEN_INTERVAL,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "getlisteninter"},
-	{
-	 WLAN_GET_MULTIPLE_DTIM,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "getmultipledtim"},
-	{
-	 WLAN_GET_TX_RATE,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "gettxrate"},
-	{
-	 WLANGETBCNAVG,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "getbcnavg"},
-	{
-	 WLAN_GET_LINKMODE,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "get_linkmode"},
-	{
-	 WLAN_GET_RADIOMODE,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "get_radiomode"},
-	{
-	 WLAN_GET_DEBUGMODE,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-	 "get_debugmode"},
-	{
 	 WLAN_SUBCMD_FWT_CLEANUP,
 	 IW_PRIV_TYPE_NONE,
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
@@ -1210,61 +1028,11 @@ static const struct iw_priv_args wlan_private_args[] = {
 	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
 	 "mesh_get_ttl"},
 	{
-	 WLAN_SETNONE_GETTWELVE_CHAR,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_CHAR | 12,
-	 ""},
-	{
-	 WLAN_SUBCMD_GETRXANTENNA,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_CHAR | 12,
-	 "getrxant"},
-	{
-	 WLAN_SUBCMD_GETTXANTENNA,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_CHAR | 12,
-	 "gettxant"},
-	{
-	 WLAN_GET_TSF,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_CHAR | 12,
-	 "gettsf"},
-	{
 	 WLAN_SETNONE_GETNONE,
 	 IW_PRIV_TYPE_NONE,
 	 IW_PRIV_TYPE_NONE,
 	 ""},
 	{
-	 WLANDEAUTH,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_NONE,
-	 "deauth"},
-	{
-	 WLANADHOCSTOP,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_NONE,
-	 "adhocstop"},
-	{
-	 WLANRADIOON,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_NONE,
-	 "radioon"},
-	{
-	 WLANRADIOOFF,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_NONE,
-	 "radiooff"},
-	{
-	 WLANWLANIDLEON,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_NONE,
-	 "wlanidle-on"},
-	{
-	 WLANWLANIDLEOFF,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_NONE,
-	 "wlanidle-off"},
-	{
 	 WLAN_SUBCMD_FWT_RESET,
 	 IW_PRIV_TYPE_NONE,
 	 IW_PRIV_TYPE_NONE,
@@ -1327,90 +1095,15 @@ static const struct iw_priv_args wlan_private_args[] = {
 	 IW_PRIV_TYPE_CHAR | 128,
 	 "fwt_list_route"},
 	{
-	 WLANSCAN_MODE,
-	 IW_PRIV_TYPE_CHAR | 128,
-	 IW_PRIV_TYPE_CHAR | 128,
-	 "scanmode"},
-	{
-	 WLAN_GET_ADHOC_STATUS,
-	 IW_PRIV_TYPE_CHAR | 128,
-	 IW_PRIV_TYPE_CHAR | 128,
-	 "getadhocstatus"},
-	{
-	 WLAN_SETNONE_GETWORDCHAR,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_CHAR | 128,
-	 ""},
-	{
-	 WLANSETWPAIE,
-	 IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 24,
-	 IW_PRIV_TYPE_NONE,
-	 "setwpaie"},
-	{
-	 WLANGETLOG,
-	 IW_PRIV_TYPE_NONE,
-	 IW_PRIV_TYPE_CHAR | GETLOG_BUFSIZE,
-	 "getlog"},
-	{
 	 WLAN_SET_GET_SIXTEEN_INT,
 	 IW_PRIV_TYPE_INT | 16,
 	 IW_PRIV_TYPE_INT | 16,
 	 ""},
 	{
-	 WLAN_TPCCFG,
-	 IW_PRIV_TYPE_INT | 16,
-	 IW_PRIV_TYPE_INT | 16,
-	 "tpccfg"},
-	{
-	 WLAN_POWERCFG,
-	 IW_PRIV_TYPE_INT | 16,
-	 IW_PRIV_TYPE_INT | 16,
-	 "powercfg"},
-	{
-	 WLAN_AUTO_FREQ_SET,
-	 IW_PRIV_TYPE_INT | 16,
-	 IW_PRIV_TYPE_INT | 16,
-	 "setafc"},
-	{
-	 WLAN_AUTO_FREQ_GET,
-	 IW_PRIV_TYPE_INT | 16,
-	 IW_PRIV_TYPE_INT | 16,
-	 "getafc"},
-	{
-	 WLAN_SCANPROBES,
-	 IW_PRIV_TYPE_INT | 16,
-	 IW_PRIV_TYPE_INT | 16,
-	 "scanprobes"},
-	{
 	 WLAN_LED_GPIO_CTRL,
 	 IW_PRIV_TYPE_INT | 16,
 	 IW_PRIV_TYPE_INT | 16,
 	 "ledgpio"},
-	{
-	 WLAN_ADAPT_RATESET,
-	 IW_PRIV_TYPE_INT | 16,
-	 IW_PRIV_TYPE_INT | 16,
-	 "rateadapt"},
-	{
-	 WLAN_INACTIVITY_TIMEOUT,
-	 IW_PRIV_TYPE_INT | 16,
-	 IW_PRIV_TYPE_INT | 16,
-	 "inactivityto"},
-	{
-	 WLANSNR,
-	 IW_PRIV_TYPE_INT | 16,
-	 IW_PRIV_TYPE_INT | 16,
-	 "getSNR"},
-	{
-	 WLAN_GET_RATE,
-	 IW_PRIV_TYPE_INT | 16,
-	 IW_PRIV_TYPE_INT | 16,
-	 "getrate"},
-	{
-	 WLAN_GET_RXINFO,
-	 IW_PRIV_TYPE_INT | 16,
-	 IW_PRIV_TYPE_INT | 16,
-	 "getrxinfo"},
 };
 
 static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
@@ -1434,7 +1127,7 @@ static struct iw_statistics *wlan_get_wireless_stats(struct net_device *dev)
 
 	ENTER();
 
-	priv->wstats.status = adapter->inframode;
+	priv->wstats.status = adapter->mode;
 
 	/* If we're not associated, all quality values are meaningless */
 	if (adapter->connect_status != libertas_connected)
@@ -1568,13 +1261,12 @@ static int wlan_set_freq(struct net_device *dev, struct iw_request_info *info,
 		if (!cfp) {
 			rc = -EINVAL;
 		} else {
-			if (adapter->inframode == wlan802_11ibss) {
+			if (adapter->mode == IW_MODE_ADHOC) {
 				rc = changeadhocchannel(priv, channel);
 				/*  If station is WEP enabled, send the
 				 *  command to set WEP in firmware
 				 */
-				if (adapter->secinfo.WEPstatus ==
-				    wlan802_11WEPenabled) {
+				if (adapter->secinfo.wep_enabled) {
 					lbs_pr_debug(1, "set_freq: WEP enabled\n");
 					ret = libertas_prepare_and_send_command(priv,
 								    cmd_802_11_set_wep,
@@ -1716,49 +1408,31 @@ static int wlan_set_mode(struct net_device *dev,
 	wlan_private *priv = dev->priv;
 	wlan_adapter *adapter = priv->adapter;
 	struct assoc_request * assoc_req;
-	enum WLAN_802_11_NETWORK_INFRASTRUCTURE new_mode;
 
 	ENTER();
 
-	switch (*uwrq) {
-	case IW_MODE_ADHOC:
-		lbs_pr_debug(1, "Wanted mode is ad-hoc: current datarate=%#x\n",
-		       adapter->datarate);
-		new_mode = wlan802_11ibss;
-		adapter->adhocchannel = DEFAULT_AD_HOC_CHANNEL;
-		break;
-
-	case IW_MODE_INFRA:
-		lbs_pr_debug(1, "Wanted mode is Infrastructure\n");
-		new_mode = wlan802_11infrastructure;
-		break;
-
-	case IW_MODE_AUTO:
-		lbs_pr_debug(1, "Wanted mode is Auto\n");
-		new_mode = wlan802_11autounknown;
-		break;
-
-	default:
-		lbs_pr_debug(1, "Wanted mode is Unknown: 0x%x\n", *uwrq);
-		return -EINVAL;
+	if (   (*uwrq != IW_MODE_ADHOC)
+	    && (*uwrq != IW_MODE_INFRA)
+	    && (*uwrq != IW_MODE_AUTO)) {
+		lbs_pr_debug(1, "Invalid mode: 0x%x\n", *uwrq);
+		ret = -EINVAL;
+		goto out;
 	}
 
 	mutex_lock(&adapter->lock);
 	assoc_req = wlan_get_association_request(adapter);
 	if (!assoc_req) {
 		ret = -ENOMEM;
+		wlan_cancel_association_work(priv);
 	} else {
-		assoc_req->mode = new_mode;
-	}
-
-	if (ret == 0) {
+		assoc_req->mode = *uwrq;
 		set_bit(ASSOC_FLAG_MODE, &assoc_req->flags);
 		wlan_postpone_association_work(priv);
-	} else {
-		wlan_cancel_association_work(priv);
+		lbs_pr_debug(1, "Switching to mode: 0x%x\n", *uwrq);
 	}
 	mutex_unlock(&adapter->lock);
 
+out:
 	LEAVE();
 	return ret;
 }
@@ -1789,13 +1463,13 @@ static int wlan_get_encode(struct net_device *dev,
 	dwrq->flags = 0;
 
 	/* Authentication method */
-	switch (adapter->secinfo.authmode) {
-	case wlan802_11authmodeopen:
+	switch (adapter->secinfo.auth_mode) {
+	case IW_AUTH_ALG_OPEN_SYSTEM:
 		dwrq->flags = IW_ENCODE_OPEN;
 		break;
 
-	case wlan802_11authmodeshared:
-	case wlan802_11authmodenetworkEAP:
+	case IW_AUTH_ALG_SHARED_KEY:
+	case IW_AUTH_ALG_LEAP:
 		dwrq->flags = IW_ENCODE_RESTRICTED;
 		break;
 	default:
@@ -1803,8 +1477,9 @@ static int wlan_get_encode(struct net_device *dev,
 		break;
 	}
 
-	if ((adapter->secinfo.WEPstatus == wlan802_11WEPenabled)
-	    || adapter->secinfo.WPAenabled || adapter->secinfo.WPA2enabled) {
+	if (   adapter->secinfo.wep_enabled
+	    || adapter->secinfo.WPAenabled
+	    || adapter->secinfo.WPA2enabled) {
 		dwrq->flags &= ~IW_ENCODE_DISABLED;
 	} else {
 		dwrq->flags |= IW_ENCODE_DISABLED;
@@ -1818,8 +1493,7 @@ static int wlan_get_encode(struct net_device *dev,
 	if (index < 0)
 		index = adapter->wep_tx_keyidx;
 
-	if ((adapter->wep_keys[index].len) &&
-	    (adapter->secinfo.WEPstatus == wlan802_11WEPenabled)) {
+	if ((adapter->wep_keys[index].len) && adapter->secinfo.wep_enabled) {
 		memcpy(extra, adapter->wep_keys[index].key,
 		       adapter->wep_keys[index].len);
 		dwrq->length = adapter->wep_keys[index].len;
@@ -1903,7 +1577,7 @@ static int wlan_set_wep_key(struct assoc_request *assoc_req,
 		assoc_req->wep_tx_keyidx = index;
 	}
 
-	assoc_req->secinfo.WEPstatus = wlan802_11WEPenabled;
+	assoc_req->secinfo.wep_enabled = 1;
 
 	LEAVE();
 	return 0;
@@ -1932,10 +1606,10 @@ static void disable_wep(struct assoc_request *assoc_req)
 	int i;
 
 	/* Set Open System auth mode */
-	assoc_req->secinfo.authmode = wlan802_11authmodeopen;
+	assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
 
 	/* Clear WEP keys and mark WEP as disabled */
-	assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
+	assoc_req->secinfo.wep_enabled = 0;
 	for (i = 0; i < 4; i++)
 		assoc_req->wep_keys[i].len = 0;
 
@@ -1987,8 +1661,7 @@ static int wlan_set_encode(struct net_device *dev,
 	/* If WEP isn't enabled, or if there is no key data but a valid
 	 * index, set the TX key.
 	 */
-	if ((assoc_req->secinfo.WEPstatus != wlan802_11WEPenabled)
-	    || (dwrq->length == 0 && !is_default))
+	if (!assoc_req->secinfo.wep_enabled || (dwrq->length == 0 && !is_default))
 		set_tx_key = 1;
 
 	ret = wlan_set_wep_key(assoc_req, extra, dwrq->length, index, set_tx_key);
@@ -2001,9 +1674,9 @@ static int wlan_set_encode(struct net_device *dev,
 		set_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags);
 
 	if (dwrq->flags & IW_ENCODE_RESTRICTED) {
-		assoc_req->secinfo.authmode = wlan802_11authmodeshared;
+		assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
 	} else if (dwrq->flags & IW_ENCODE_OPEN) {
-		assoc_req->secinfo.authmode = wlan802_11authmodeopen;
+		assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
 	}
 
 out:
@@ -2056,30 +1729,31 @@ static int wlan_get_encodeext(struct net_device *dev,
 
 	if (!ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY &&
 	    ext->alg != IW_ENCODE_ALG_WEP) {
-		if (index != 0 || adapter->inframode != wlan802_11infrastructure)
+		if (index != 0 || adapter->mode != IW_MODE_INFRA)
 			goto out;
 	}
 
 	dwrq->flags = index + 1;
 	memset(ext, 0, sizeof(*ext));
 
-	if ((adapter->secinfo.WEPstatus == wlan802_11WEPdisabled)
-	    && !adapter->secinfo.WPAenabled && !adapter->secinfo.WPA2enabled) {
+	if (   !adapter->secinfo.wep_enabled
+	    && !adapter->secinfo.WPAenabled
+	    && !adapter->secinfo.WPA2enabled) {
 		ext->alg = IW_ENCODE_ALG_NONE;
 		ext->key_len = 0;
 		dwrq->flags |= IW_ENCODE_DISABLED;
 	} else {
 		u8 *key = NULL;
 
-		if ((adapter->secinfo.WEPstatus == wlan802_11WEPenabled)
+		if (   adapter->secinfo.wep_enabled
 		    && !adapter->secinfo.WPAenabled
 		    && !adapter->secinfo.WPA2enabled) {
 			ext->alg = IW_ENCODE_ALG_WEP;
 			ext->key_len = adapter->wep_keys[index].len;
 			key = &adapter->wep_keys[index].key[0];
-		} else if ((adapter->secinfo.WEPstatus == wlan802_11WEPdisabled) &&
-		           (adapter->secinfo.WPAenabled ||
-		            adapter->secinfo.WPA2enabled)) {
+		} else if (   !adapter->secinfo.wep_enabled
+		           && (adapter->secinfo.WPAenabled ||
+		               adapter->secinfo.WPA2enabled)) {
 			/* WPA */
 			ext->alg = IW_ENCODE_ALG_TKIP;
 			ext->key_len = 0;
@@ -2149,7 +1823,7 @@ static int wlan_set_encodeext(struct net_device *dev,
 		/* If WEP isn't enabled, or if there is no key data but a valid
 		 * index, or if the set-TX-key flag was passed, set the TX key.
 		 */
-		if ((assoc_req->secinfo.WEPstatus != wlan802_11WEPenabled)
+		if (   !assoc_req->secinfo.wep_enabled
 		    || (dwrq->length == 0 && !is_default)
 		    || (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY))
 			set_tx_key = 1;
@@ -2161,11 +1835,9 @@ static int wlan_set_encodeext(struct net_device *dev,
 			goto out;
 
 		if (dwrq->flags & IW_ENCODE_RESTRICTED) {
-			assoc_req->secinfo.authmode =
-			    wlan802_11authmodeshared;
+			assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
 		} else if (dwrq->flags & IW_ENCODE_OPEN) {
-			assoc_req->secinfo.authmode =
-			    wlan802_11authmodeopen;
+			assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
 		}
 
 		/* Mark the various WEP bits as modified */
@@ -2350,15 +2022,13 @@ static int wlan_set_auth(struct net_device *dev,
 		}
 		if (dwrq->value & IW_AUTH_WPA_VERSION_WPA) {
 			assoc_req->secinfo.WPAenabled = 1;
-			assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
-			assoc_req->secinfo.authmode =
-			    wlan802_11authmodeopen;
+			assoc_req->secinfo.wep_enabled = 0;
+			assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
 		}
 		if (dwrq->value & IW_AUTH_WPA_VERSION_WPA2) {
 			assoc_req->secinfo.WPA2enabled = 1;
-			assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
-			assoc_req->secinfo.authmode =
-			    wlan802_11authmodeopen;
+			assoc_req->secinfo.wep_enabled = 0;
+			assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
 		}
 		updated = 1;
 		break;
@@ -2376,14 +2046,11 @@ static int wlan_set_auth(struct net_device *dev,
 
 	case IW_AUTH_80211_AUTH_ALG:
 		if (dwrq->value & IW_AUTH_ALG_SHARED_KEY) {
-			assoc_req->secinfo.authmode =
-			    wlan802_11authmodeshared;
+			assoc_req->secinfo.auth_mode = IW_AUTH_ALG_SHARED_KEY;
 		} else if (dwrq->value & IW_AUTH_ALG_OPEN_SYSTEM) {
-			assoc_req->secinfo.authmode =
-			    wlan802_11authmodeopen;
+			assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
 		} else if (dwrq->value & IW_AUTH_ALG_LEAP) {
-			assoc_req->secinfo.authmode =
-			    wlan802_11authmodenetworkEAP;
+			assoc_req->secinfo.auth_mode = IW_AUTH_ALG_LEAP;
 		} else {
 			ret = -EINVAL;
 		}
@@ -2396,9 +2063,8 @@ static int wlan_set_auth(struct net_device *dev,
 			    !assoc_req->secinfo.WPA2enabled) {
 				assoc_req->secinfo.WPAenabled = 1;
 				assoc_req->secinfo.WPA2enabled = 1;
-				assoc_req->secinfo.WEPstatus = wlan802_11WEPdisabled;
-				assoc_req->secinfo.authmode =
-				    wlan802_11authmodeopen;
+				assoc_req->secinfo.wep_enabled = 0;
+				assoc_req->secinfo.auth_mode = IW_AUTH_ALG_OPEN_SYSTEM;
 			}
 		} else {
 			assoc_req->secinfo.WPAenabled = 0;
@@ -2455,19 +2121,7 @@ static int wlan_get_auth(struct net_device *dev,
 		break;
 
 	case IW_AUTH_80211_AUTH_ALG:
-		switch (adapter->secinfo.authmode) {
-		case wlan802_11authmodeshared:
-			dwrq->value = IW_AUTH_ALG_SHARED_KEY;
-			break;
-		case wlan802_11authmodeopen:
-			dwrq->value = IW_AUTH_ALG_OPEN_SYSTEM;
-			break;
-		case wlan802_11authmodenetworkEAP:
-			dwrq->value = IW_AUTH_ALG_LEAP;
-			break;
-		default:
-			break;
-		}
+		dwrq->value = adapter->secinfo.auth_mode;
 		break;
 
 	case IW_AUTH_WPA_ENABLED:
diff --git a/drivers/net/wireless/libertas/wext.h b/drivers/net/wireless/libertas/wext.h
index 39f367c..15cfaaf 100644
--- a/drivers/net/wireless/libertas/wext.h
+++ b/drivers/net/wireless/libertas/wext.h
@@ -10,88 +10,22 @@
 /** PRIVATE CMD ID */
 #define	WLANIOCTL			SIOCIWFIRSTPRIV
 
-#define WLANSETWPAIE			(WLANIOCTL + 0)
-
-#define WLAN_SETINT_GETINT		(WLANIOCTL + 7)
-#define WLANNF					1
-#define WLANRSSI				2
-#define WLANENABLE11D				5
-#define WLANADHOCGRATE				6
-#define WLAN_SUBCMD_SET_PRESCAN			11
-
 #define WLAN_SETNONE_GETNONE	        (WLANIOCTL + 8)
-#define WLANDEAUTH                  		1
-#define WLANRADIOON                 		2
-#define WLANRADIOOFF                		3
-#define WLANREMOVEADHOCAES          		4
-#define WLANADHOCSTOP               		5
-#define WLANCIPHERTEST              		6
-#define WLANCRYPTOTEST				7
-
-#define WLANWLANIDLEON				10
-#define WLANWLANIDLEOFF				11
 #define WLAN_SUBCMD_BT_RESET			13
 #define WLAN_SUBCMD_FWT_RESET			14
 
-#define WLANGETLOG                  	(WLANIOCTL + 9)
-#define GETLOG_BUFSIZE  300
-
-#define WLANSCAN_TYPE			(WLANIOCTL + 11)
-
 #define WLAN_SETNONE_GETONEINT		(WLANIOCTL + 15)
 #define WLANGETREGION				1
-#define WLAN_GET_LISTEN_INTERVAL		2
-#define WLAN_GET_MULTIPLE_DTIM			3
-#define WLAN_GET_TX_RATE			4
-#define	WLANGETBCNAVG				5
 
-#define WLAN_GET_LINKMODE			6
-#define WLAN_GET_RADIOMODE			7
-#define WLAN_GET_DEBUGMODE			8
 #define WLAN_SUBCMD_FWT_CLEANUP			15
 #define WLAN_SUBCMD_FWT_TIME			16
 #define WLAN_SUBCMD_MESH_GET_TTL		17
 
-#define WLANREGCFRDWR			(WLANIOCTL + 18)
-
-#define WLAN_SETNONE_GETTWELVE_CHAR (WLANIOCTL + 19)
-#define WLAN_SUBCMD_GETRXANTENNA    1
-#define WLAN_SUBCMD_GETTXANTENNA    2
-#define WLAN_GET_TSF                3
-
-#define WLAN_SETNONE_GETWORDCHAR	(WLANIOCTL + 21)
-#define WLANGETADHOCAES				1
-
-#define WLAN_SETONEINT_GETONEINT	(WLANIOCTL + 23)
-#define WLAN_BEACON_INTERVAL			1
-#define	WLAN_LISTENINTRVL			4
-
-#define WLAN_TXCONTROL				6
-#define WLAN_NULLPKTINTERVAL			7
-
 #define WLAN_SETONEINT_GETNONE		(WLANIOCTL + 24)
-#define WLAN_SUBCMD_SETRXANTENNA		1
-#define WLAN_SUBCMD_SETTXANTENNA		2
-#define WLANSETAUTHALG				5
-#define WLANSET8021XAUTHALG			6
-#define WLANSETENCRYPTIONMODE			7
 #define WLANSETREGION				8
-#define WLAN_SET_LISTEN_INTERVAL		9
-
-#define WLAN_SET_MULTIPLE_DTIM			10
-#define WLAN_SET_ATIM_WINDOW			11
-#define WLANSETBCNAVG				13
-#define WLANSETDATAAVG				14
-#define WLAN_SET_LINKMODE			15
-#define WLAN_SET_RADIOMODE			16
-#define WLAN_SET_DEBUGMODE			17
 #define WLAN_SUBCMD_MESH_SET_TTL		18
 
 #define WLAN_SET128CHAR_GET128CHAR	(WLANIOCTL + 25)
-#define WLANSCAN_MODE				6
-
-#define WLAN_GET_ADHOC_STATUS			9
-
 #define WLAN_SUBCMD_BT_ADD			18
 #define WLAN_SUBCMD_BT_DEL   			19
 #define WLAN_SUBCMD_BT_LIST			20
@@ -103,27 +37,8 @@
 #define WLAN_SUBCMD_FWT_LIST_ROUTE			26
 
 #define WLAN_SET_GET_SIXTEEN_INT       (WLANIOCTL + 29)
-#define WLAN_TPCCFG                             1
-#define WLAN_POWERCFG                           2
-
-#define WLAN_AUTO_FREQ_SET			3
-#define WLAN_AUTO_FREQ_GET			4
 #define WLAN_LED_GPIO_CTRL			5
-#define WLAN_SCANPROBES 			6
-#define	WLAN_ADAPT_RATESET			8
-#define	WLAN_INACTIVITY_TIMEOUT			9
-#define WLANSNR					10
-#define WLAN_GET_RATE				11
-#define	WLAN_GET_RXINFO				12
-
-#define WLANCMD52RDWR			(WLANIOCTL + 30)
-#define WLANCMD53RDWR			(WLANIOCTL + 31)
-#define CMD53BUFLEN				32
 
-#define	REG_MAC					0x19
-#define	REG_BBP					0x1a
-#define	REG_RF					0x1b
-#define	REG_EEPROM				0x59
 #define WLAN_LINKMODE_802_3			0
 #define WLAN_LINKMODE_802_11			2
 #define WLAN_RADIOMODE_NONE    			0

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-05-08  6:33 Jeff Garzik
  2007-05-18 21:46 ` Mariusz Kozłowski
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2007-05-08  6:33 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML


Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 arch/mips/Kconfig                                  |    2 -
 arch/mips/configs/rbhma4500_defconfig              |   31 --
 .../toshiba_rbtx4927/toshiba_rbtx4927_setup.c      |   19 +
 arch/mips/tx4938/toshiba_rbtx4938/setup.c          |   20 +
 arch/powerpc/platforms/pasemi/pci.c                |   13 -
 arch/powerpc/platforms/pasemi/setup.c              |    1 -
 drivers/net/Kconfig                                |    3 +-
 drivers/net/arm/at91_ether.c                       |   49 +++-
 drivers/net/arm/at91_ether.h                       |   49 ++-
 drivers/net/atl1/atl1_ethtool.c                    |   19 +-
 drivers/net/atl1/atl1_hw.c                         |   44 +--
 drivers/net/atl1/atl1_main.c                       |   83 ++---
 drivers/net/atl1/atl1_param.c                      |   32 +-
 drivers/net/dm9000.c                               |   15 +-
 drivers/net/ehea/ehea_main.c                       |    6 +-
 drivers/net/myri10ge/myri10ge.c                    |  261 +++++++------
 drivers/net/myri10ge/myri10ge_mcp.h                |   20 +-
 drivers/net/natsemi.c                              |   70 ++++-
 drivers/net/ne.c                                   |  123 +++++-
 drivers/net/pasemi_mac.c                           |  404 +++++++++++++++-----
 drivers/net/pasemi_mac.h                           |   23 +-
 drivers/net/pcmcia/xirc2ps_cs.c                    |   14 +-
 drivers/net/skge.c                                 |    9 +-
 drivers/net/sky2.c                                 |   17 +-
 drivers/net/smc91x.h                               |   34 ++
 drivers/net/tc35815.c                              |    1 -
 drivers/net/wireless/Kconfig                       |    2 +-
 drivers/s390/cio/qdio.c                            |   37 ++-
 drivers/s390/cio/qdio.h                            |    4 +-
 drivers/s390/net/netiucv.c                         |    5 +-
 drivers/s390/net/qeth_eddp.c                       |    4 +-
 drivers/s390/net/qeth_eddp.h                       |    3 +-
 drivers/s390/net/qeth_main.c                       |   45 ++-
 drivers/s390/net/qeth_mpc.c                        |  101 +++++
 drivers/s390/net/qeth_mpc.h                        |  219 ++++++-----
 drivers/s390/net/qeth_sys.c                        |    2 -
 include/asm-s390/qdio.h                            |    1 +
 37 files changed, 1228 insertions(+), 557 deletions(-)

Andrew Victor (2):
      AT91RM9200 Ethernet: Support additional PHYs
      AT91RM9200 Ethernet: Fix multicast addressing

Atsushi Nemoto (6):
      ne: Add platform_driver
      ne: Misc fixes for platform driver.
      ne: Add NEEDS_PORTLIST to control ISA auto-probe
      ne: MIPS: Use platform_driver for ne on RBTX49XX
      MIPS: Drop unnecessary CONFIG_ISA from RBTX49XX
      tc35815: Remove unnecessary skb->dev assignment

Ben Dooks (1):
      DM9000: fix use of kfree() on net device

Brice Goglin (5):
      myri10ge: support new firmware counters
      myri10ge: update firmware headers
      myri10ge: fix restoring of multicast list after reset
      myri10ge: move the DMA test code into its own function
      myri10ge: replace the chipset whitelist with firmware autodetection

Jay Cliburn (2):
      atl1: use dev_printk macros
      atl1: fix whitespace damage

Jeff Garzik (1):
      [netdrvr] atl1: fix build

John W. Linville (1):
      libertas: fix for wireless Kconfig changes

Komuro (1):
      PCMCIA-NETDEV : xirc2ps_cs: bugfix of multicast code

Mark Brown (2):
      natsemi: Improve diagnostics for DspCfg workaround
      Subject: natsemi: Allow users to disable workaround for DspCfg reset

Nobuhiro Iwamatsu (1):
      smc91x SuperH support

Olof Johansson (10):
      pasemi_mac: A couple of minor bugfixes.
      pasemi_mac: Move the IRQ mapping from the PCI layer to the driver
      pasemi_mac: Abstract and fix up interrupt restart routines
      pasemi_mac: Timer and interrupt fixes
      pasemi_mac: Add SKB reuse / copy-break
      pasemi_mac: Minor cleanup / define fixes
      pasemi_mac: Logic cleanup / rx performance improvements
      pasemi_mac: Add msglevel support and "debug" module param
      pasemi_mac: PHY support
      pasemi_mac: Use local-mac-address instead of mac-address if available

Peter Tiedemann (1):
      s390: qeth driver hardware specs adaptions

Richard Knutsson (1):
      drivers/net/dm9000: Convert to generic boolean

Stephen Hemminger (2):
      skge: allow WOL except for known broken chips
      sky2: re-enable 88E8056 for most motherboards

Thomas Klein (1):
      ehea: Fix skb header access

Ursula Braun (3):
      s390: qeth driver connection hang
      s390: free skbs in finite amount of time in qeth
      s390: fix Oops when unloading module netiucv

diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 7441a2c..b7cb048 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -784,7 +784,6 @@ config TOSHIBA_RBTX4927
 	select HAS_TXX9_SERIAL
 	select HW_HAS_PCI
 	select I8259
-	select ISA
 	select SWAP_IO_SPACE
 	select SYS_HAS_CPU_TX49XX
 	select SYS_SUPPORTS_32BIT_KERNEL
@@ -806,7 +805,6 @@ config TOSHIBA_RBTX4938
 	select HAS_TXX9_SERIAL
 	select HW_HAS_PCI
 	select I8259
-	select ISA
 	select SWAP_IO_SPACE
 	select SYS_HAS_CPU_TX49XX
 	select SYS_SUPPORTS_32BIT_KERNEL
diff --git a/arch/mips/configs/rbhma4500_defconfig b/arch/mips/configs/rbhma4500_defconfig
index 29e0df9..7d0f217 100644
--- a/arch/mips/configs/rbhma4500_defconfig
+++ b/arch/mips/configs/rbhma4500_defconfig
@@ -245,7 +245,6 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 #
 CONFIG_HW_HAS_PCI=y
 CONFIG_PCI=y
-CONFIG_ISA=y
 CONFIG_MMU=y
 
 #
@@ -573,7 +572,6 @@ CONFIG_MTD_CFI_UTIL=y
 #
 # Plug and Play support
 #
-# CONFIG_PNP is not set
 # CONFIG_PNPACPI is not set
 
 #
@@ -658,7 +656,6 @@ CONFIG_BLK_DEV_IT8213=m
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 CONFIG_BLK_DEV_TC86C001=m
 # CONFIG_IDE_ARM is not set
-# CONFIG_IDE_CHIPSETS is not set
 CONFIG_BLK_DEV_IDEDMA=y
 # CONFIG_IDEDMA_IVB is not set
 # CONFIG_IDEDMA_AUTO is not set
@@ -677,11 +674,6 @@ CONFIG_RAID_ATTRS=m
 # CONFIG_ATA is not set
 
 #
-# Old CD-ROM drivers (not SCSI, not IDE)
-#
-# CONFIG_CD_NO_IDESCSI is not set
-
-#
 # Multi-device support (RAID and LVM)
 #
 # CONFIG_MD is not set
@@ -742,37 +734,20 @@ CONFIG_NET_ETHERNET=y
 # CONFIG_SUNGEM is not set
 # CONFIG_CASSINI is not set
 # CONFIG_NET_VENDOR_3COM is not set
-# CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_DM9000 is not set
-# CONFIG_NET_VENDOR_RACAL is not set
 
 #
 # Tulip family network device support
 #
 # CONFIG_NET_TULIP is not set
-# CONFIG_AT1700 is not set
-# CONFIG_DEPCA is not set
 # CONFIG_HP100 is not set
-CONFIG_NET_ISA=y
-# CONFIG_E2100 is not set
-# CONFIG_EWRK3 is not set
-# CONFIG_EEXPRESS is not set
-# CONFIG_EEXPRESS_PRO is not set
-# CONFIG_HPLAN_PLUS is not set
-# CONFIG_HPLAN is not set
-# CONFIG_LP486E is not set
-# CONFIG_ETH16I is not set
 CONFIG_NE2000=y
-# CONFIG_SEEQ8005 is not set
 CONFIG_NET_PCI=y
 # CONFIG_PCNET32 is not set
 # CONFIG_AMD8111_ETH is not set
 # CONFIG_ADAPTEC_STARFIRE is not set
-# CONFIG_AC3200 is not set
-# CONFIG_APRICOT is not set
 # CONFIG_B44 is not set
 # CONFIG_FORCEDETH is not set
-# CONFIG_CS89x0 is not set
 # CONFIG_DGRS is not set
 # CONFIG_EEPRO100 is not set
 # CONFIG_E100 is not set
@@ -833,8 +808,6 @@ CONFIG_NET_RADIO=y
 # Obsolete Wireless cards support (pre-802.11)
 #
 # CONFIG_STRIP is not set
-# CONFIG_ARLAN is not set
-# CONFIG_WAVELAN is not set
 
 #
 # Wireless 802.11b ISA/PCI cards support
@@ -920,9 +893,6 @@ CONFIG_KEYBOARD_ATKBD=y
 CONFIG_INPUT_MOUSE=y
 CONFIG_MOUSE_PS2=y
 # CONFIG_MOUSE_SERIAL is not set
-# CONFIG_MOUSE_INPORT is not set
-# CONFIG_MOUSE_LOGIBM is not set
-# CONFIG_MOUSE_PC110PAD is not set
 # CONFIG_MOUSE_VSXXXAA is not set
 # CONFIG_INPUT_JOYSTICK is not set
 # CONFIG_INPUT_TOUCHSCREEN is not set
@@ -1072,7 +1042,6 @@ CONFIG_FB_ATY_CT=y
 #
 CONFIG_VGA_CONSOLE=y
 # CONFIG_VGACON_SOFT_SCROLLBACK is not set
-# CONFIG_MDA_CONSOLE is not set
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FRAMEBUFFER_CONSOLE is not set
 
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index 0f7576d..a0c11ef 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -1049,3 +1049,22 @@ static int __init toshiba_rbtx4927_rtc_init(void)
 	return IS_ERR(dev) ? PTR_ERR(dev) : 0;
 }
 device_initcall(toshiba_rbtx4927_rtc_init);
+
+static int __init rbtx4927_ne_init(void)
+{
+	static struct resource __initdata res[] = {
+		{
+			.start	= RBTX4927_RTL_8019_BASE,
+			.end	= RBTX4927_RTL_8019_BASE + 0x20 - 1,
+			.flags	= IORESOURCE_IO,
+		}, {
+			.start	= RBTX4927_RTL_8019_IRQ,
+			.flags	= IORESOURCE_IRQ,
+		}
+	};
+	struct platform_device *dev =
+		platform_device_register_simple("ne", -1,
+						res, ARRAY_SIZE(res));
+	return IS_ERR(dev) ? PTR_ERR(dev) : 0;
+}
+device_initcall(rbtx4927_ne_init);
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 66163ba..f5d1ce7 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -20,6 +20,7 @@
 #include <linux/console.h>
 #include <linux/pci.h>
 #include <linux/pm.h>
+#include <linux/platform_device.h>
 
 #include <asm/wbflush.h>
 #include <asm/reboot.h>
@@ -1037,3 +1038,22 @@ static int __init tx4938_spi_proc_setup(void)
 
 __initcall(tx4938_spi_proc_setup);
 #endif
+
+static int __init rbtx4938_ne_init(void)
+{
+	struct resource res[] = {
+		{
+			.start	= RBTX4938_RTL_8019_BASE,
+			.end	= RBTX4938_RTL_8019_BASE + 0x20 - 1,
+			.flags	= IORESOURCE_IO,
+		}, {
+			.start	= RBTX4938_RTL_8019_IRQ,
+			.flags	= IORESOURCE_IRQ,
+		}
+	};
+	struct platform_device *dev =
+		platform_device_register_simple("ne", -1,
+						res, ARRAY_SIZE(res));
+	return IS_ERR(dev) ? PTR_ERR(dev) : 0;
+}
+device_initcall(rbtx4938_ne_init);
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
index 056243d..bbc6dfc 100644
--- a/arch/powerpc/platforms/pasemi/pci.c
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -173,19 +173,6 @@ static void __init pas_fixup_phb_resources(void)
 }
 
 
-void __devinit pas_pci_irq_fixup(struct pci_dev *dev)
-{
-	/* DMA is special, 84 interrupts (128 -> 211), all but 128
-	 * need to be mapped by hand here.
-	 */
-	if (dev->vendor == 0x1959 && dev->device == 0xa007) {
-		int i;
-		for (i = 129; i < 212; i++)
-			irq_create_mapping(NULL, i);
-	}
-}
-
-
 void __init pas_pci_init(void)
 {
 	struct device_node *np, *root;
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index f88f0ec..5bdd6ab 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -248,5 +248,4 @@ define_machine(pas) {
 	.calibrate_decr		= generic_calibrate_decr,
 	.progress		= pas_progress,
 	.machine_check_exception = pas_machine_check_handler,
-	.pci_irq_fixup		= pas_pci_irq_fixup,
 };
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 279ec62..b86ccd2 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1104,7 +1104,7 @@ config ETH16I
 
 config NE2000
 	tristate "NE2000/NE1000 support"
-	depends on NET_ISA || (Q40 && m) || M32R
+	depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938
 	select CRC32
 	---help---
 	  If you have a network (Ethernet) card of this type, say Y and read
@@ -2488,6 +2488,7 @@ config NETXEN_NIC
 config PASEMI_MAC
 	tristate "PA Semi 1/10Gbit MAC"
 	depends on PPC64 && PCI
+	select PHYLIB
 	help
 	  This driver supports the on-chip 1/10Gbit Ethernet controller on
 	  PA Semi's PWRficient line of chips.
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
index 152fa7a..ef2cc80 100644
--- a/drivers/net/arm/at91_ether.c
+++ b/drivers/net/arm/at91_ether.c
@@ -225,6 +225,16 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id)
 		if (!(phy & ((1 << 2) | 1)))
 			goto done;
 	}
+	else if (lp->phy_type == MII_T78Q21x3_ID) {			/* ack interrupt in Teridian PHY */
+		read_phy(lp->phy_address, MII_T78Q21INT_REG, &phy);
+		if (!(phy & ((1 << 2) | 1)))
+			goto done;
+	}
+	else if (lp->phy_type == MII_DP83848_ID) {
+		read_phy(lp->phy_address, MII_DPPHYSTS_REG, &phy);	/* ack interrupt in DP83848 PHY */
+		if (!(phy & (1 << 7)))
+			goto done;
+	}
 
 	update_linkspeed(dev, 0);
 
@@ -280,6 +290,19 @@ static void enable_phyirq(struct net_device *dev)
 		dsintr = (1 << 10) | ( 1 << 8);
 		write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
 	}
+	else if (lp->phy_type == MII_T78Q21x3_ID) {	/* for Teridian PHY */
+		read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr);
+		dsintr = dsintr | 0x500;		/* set bits 8, 10 */
+		write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr);
+	}
+	else if (lp->phy_type == MII_DP83848_ID) {	/* National Semiconductor DP83848 PHY */
+		read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr);
+		dsintr = dsintr | 0x3c;			/* set bits 2..5 */
+		write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
+		read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr);
+		dsintr = dsintr | 0x3;			/* set bits 0,1 */
+		write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
+	}
 
 	disable_mdi();
 	spin_unlock_irq(&lp->lock);
@@ -323,6 +346,19 @@ static void disable_phyirq(struct net_device *dev)
 		dsintr = ~((1 << 10) | (1 << 8));
 		write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
 	}
+	else if (lp->phy_type == MII_T78Q21x3_ID) {	/* for Teridian PHY */
+		read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr);
+		dsintr = dsintr & ~0x500;			/* clear bits 8, 10 */
+		write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr);
+	}
+	else if (lp->phy_type == MII_DP83848_ID) {	/* National Semiconductor DP83848 PHY */
+		read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr);
+		dsintr = dsintr & ~0x3;				/* clear bits 0, 1 */
+		write_phy(lp->phy_address, MII_DPMICR_REG, dsintr);
+		read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr);
+		dsintr = dsintr & ~0x3c;			/* clear bits 2..5 */
+		write_phy(lp->phy_address, MII_DPMISR_REG, dsintr);
+	}
 
 	disable_mdi();
 	spin_unlock_irq(&lp->lock);
@@ -535,8 +571,8 @@ static void at91ether_sethashtable(struct net_device *dev)
 		mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
 	}
 
-	at91_emac_write(AT91_EMAC_HSH, mc_filter[0]);
-	at91_emac_write(AT91_EMAC_HSL, mc_filter[1]);
+	at91_emac_write(AT91_EMAC_HSL, mc_filter[0]);
+	at91_emac_write(AT91_EMAC_HSH, mc_filter[1]);
 }
 
 /*
@@ -1062,10 +1098,16 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add
 		printk(KERN_INFO "%s: Broadcom BCM5221 PHY\n", dev->name);
 	else if (phy_type == MII_DP83847_ID)
 		printk(KERN_INFO "%s: National Semiconductor DP83847 PHY\n", dev->name);
+	else if (phy_type == MII_DP83848_ID)
+		printk(KERN_INFO "%s: National Semiconductor DP83848 PHY\n", dev->name);
 	else if (phy_type == MII_AC101L_ID)
 		printk(KERN_INFO "%s: Altima AC101L PHY\n", dev->name);
 	else if (phy_type == MII_KS8721_ID)
 		printk(KERN_INFO "%s: Micrel KS8721 PHY\n", dev->name);
+	else if (phy_type == MII_T78Q21x3_ID)
+		printk(KERN_INFO "%s: Teridian 78Q21x3 PHY\n", dev->name);
+	else if (phy_type == MII_LAN83C185_ID)
+		printk(KERN_INFO "%s: SMSC LAN83C185 PHY\n", dev->name);
 
 	return 0;
 }
@@ -1103,8 +1145,11 @@ static int __init at91ether_probe(struct platform_device *pdev)
 			case MII_RTL8201_ID:		/* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */
 			case MII_BCM5221_ID:		/* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */
 			case MII_DP83847_ID:		/* National Semiconductor DP83847:  */
+			case MII_DP83848_ID:		/* National Semiconductor DP83848:  */
 			case MII_AC101L_ID:		/* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */
 			case MII_KS8721_ID:		/* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */
+			case MII_T78Q21x3_ID:		/* Teridian 78Q21x3: PHY_ID1 = 0x0E, PHY_ID2 = 7237 */
+			case MII_LAN83C185_ID:		/* SMSC LAN83C185: PHY_ID1 = 0x0007, PHY_ID2 = 0xC0A1 */
 				detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk);
 				break;
 		}
diff --git a/drivers/net/arm/at91_ether.h b/drivers/net/arm/at91_ether.h
index b6b665d..a38fd2d 100644
--- a/drivers/net/arm/at91_ether.h
+++ b/drivers/net/arm/at91_ether.h
@@ -17,39 +17,46 @@
 
 
 /* Davicom 9161 PHY */
-#define MII_DM9161_ID	0x0181b880
-#define MII_DM9161A_ID	0x0181b8a0
-
-/* Davicom specific registers */
-#define MII_DSCR_REG	16
-#define MII_DSCSR_REG	17
-#define MII_DSINTR_REG	21
+#define MII_DM9161_ID		0x0181b880
+#define MII_DM9161A_ID		0x0181b8a0
+#define MII_DSCR_REG		16
+#define MII_DSCSR_REG		17
+#define MII_DSINTR_REG		21
 
 /* Intel LXT971A PHY */
-#define MII_LXT971A_ID	0x001378E0
-
-/* Intel specific registers */
-#define MII_ISINTE_REG	18
-#define MII_ISINTS_REG	19
-#define MII_LEDCTRL_REG	20
+#define MII_LXT971A_ID		0x001378E0
+#define MII_ISINTE_REG		18
+#define MII_ISINTS_REG		19
+#define MII_LEDCTRL_REG		20
 
 /* Realtek RTL8201 PHY */
-#define MII_RTL8201_ID	0x00008200
+#define MII_RTL8201_ID		0x00008200
 
 /* Broadcom BCM5221 PHY */
-#define MII_BCM5221_ID	0x004061e0
-
-/* Broadcom specific registers */
-#define MII_BCMINTR_REG	26
+#define MII_BCM5221_ID		0x004061e0
+#define MII_BCMINTR_REG		26
 
 /* National Semiconductor DP83847 */
-#define MII_DP83847_ID	0x20005c30
+#define MII_DP83847_ID		0x20005c30
+
+/* National Semiconductor DP83848 */
+#define MII_DP83848_ID		0x20005c90
+#define MII_DPPHYSTS_REG	16
+#define MII_DPMICR_REG		17
+#define MII_DPMISR_REG		18
 
 /* Altima AC101L PHY */
-#define MII_AC101L_ID	0x00225520
+#define MII_AC101L_ID		0x00225520
 
 /* Micrel KS8721 PHY */
-#define MII_KS8721_ID	0x00221610
+#define MII_KS8721_ID		0x00221610
+
+/* Teridian 78Q2123/78Q2133 */
+#define MII_T78Q21x3_ID		0x000e7230
+#define MII_T78Q21INT_REG	17
+
+/* SMSC LAN83C185 */
+#define MII_LAN83C185_ID	0x0007C0A0
 
 /* ........................................................................ */
 
diff --git a/drivers/net/atl1/atl1_ethtool.c b/drivers/net/atl1/atl1_ethtool.c
index c11c277..1f616c5 100644
--- a/drivers/net/atl1/atl1_ethtool.c
+++ b/drivers/net/atl1/atl1_ethtool.c
@@ -156,8 +156,7 @@ static int atl1_set_settings(struct net_device *netdev,
 	u16 old_media_type = hw->media_type;
 
 	if (netif_running(adapter->netdev)) {
-		printk(KERN_DEBUG "%s: ethtool shutting down adapter\n",
-			atl1_driver_name);
+		dev_dbg(&adapter->pdev->dev, "ethtool shutting down adapter\n");
 		atl1_down(adapter);
 	}
 
@@ -166,9 +165,8 @@ static int atl1_set_settings(struct net_device *netdev,
 	else {
 		if (ecmd->speed == SPEED_1000) {
 			if (ecmd->duplex != DUPLEX_FULL) {
-				printk(KERN_WARNING
-				       "%s: can't force to 1000M half duplex\n",
-					atl1_driver_name);
+				dev_warn(&adapter->pdev->dev,
+					"can't force to 1000M half duplex\n");
 				ret_val = -EINVAL;
 				goto exit_sset;
 			}
@@ -206,9 +204,8 @@ static int atl1_set_settings(struct net_device *netdev,
 	}
 	if (atl1_phy_setup_autoneg_adv(hw)) {
 		ret_val = -EINVAL;
-		printk(KERN_WARNING
-			"%s: invalid ethtool speed/duplex setting\n",
-			atl1_driver_name);
+		dev_warn(&adapter->pdev->dev,
+			"invalid ethtool speed/duplex setting\n");
 		goto exit_sset;
 	}
 	if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR ||
@@ -239,12 +236,10 @@ exit_sset:
 		hw->media_type = old_media_type;
 
 	if (netif_running(adapter->netdev)) {
-		printk(KERN_DEBUG "%s: ethtool starting adapter\n",
-			atl1_driver_name);
+		dev_dbg(&adapter->pdev->dev, "ethtool starting adapter\n");
 		atl1_up(adapter);
 	} else if (!ret_val) {
-		printk(KERN_DEBUG "%s: ethtool resetting adapter\n",
-			atl1_driver_name);
+		dev_dbg(&adapter->pdev->dev, "ethtool resetting adapter\n");
 		atl1_reset(adapter);
 	}
 	return ret_val;
diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c
index 69482e0..ef886bd 100644
--- a/drivers/net/atl1/atl1_hw.c
+++ b/drivers/net/atl1/atl1_hw.c
@@ -2,20 +2,20 @@
  * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved.
  * Copyright(c) 2006 Chris Snook <csnook@redhat.com>
  * Copyright(c) 2006 Jay Cliburn <jcliburn@gmail.com>
- * 
+ *
  * Derived from Intel e1000 driver
  * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved.
- * 
+ *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the Free
  * Software Foundation; either version 2 of the License, or (at your option)
  * any later version.
- * 
+ *
  * This program is distributed in the hope that 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., 59
  * Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -38,12 +38,13 @@
  */
 s32 atl1_reset_hw(struct atl1_hw *hw)
 {
+	struct pci_dev *pdev = hw->back->pdev;
 	u32 icr;
 	int i;
 
-	/* 
+	/*
 	 * Clear Interrupt mask to stop board from generating
-	 * interrupts & Clear any pending interrupt events 
+	 * interrupts & Clear any pending interrupt events
 	 */
 	/*
 	 * iowrite32(0, hw->hw_addr + REG_IMR);
@@ -74,7 +75,7 @@ s32 atl1_reset_hw(struct atl1_hw *hw)
 	}
 
 	if (icr) {
-		printk (KERN_DEBUG "icr = %x\n", icr); 
+		dev_dbg(&pdev->dev, "ICR = 0x%x\n", icr);
 		return icr;
 	}
 
@@ -136,8 +137,8 @@ s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data)
 	int i;
 
 	val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT |
-	    	MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
- 		MDIO_CLK_SEL_SHIFT;
+		MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 <<
+		MDIO_CLK_SEL_SHIFT;
 	iowrite32(val, hw->hw_addr + REG_MDIO_CTRL);
 	ioread32(hw->hw_addr + REG_MDIO_CTRL);
 
@@ -204,7 +205,7 @@ static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf)
 
 /*
  * get_permanent_address
- * return 0 if get valid mac address, 
+ * return 0 if get valid mac address,
  */
 static int atl1_get_permanent_address(struct atl1_hw *hw)
 {
@@ -301,7 +302,7 @@ static int atl1_get_permanent_address(struct atl1_hw *hw)
 }
 
 /*
- * Reads the adapter's MAC address from the EEPROM 
+ * Reads the adapter's MAC address from the EEPROM
  * hw - Struct containing variables accessed by shared code
  */
 s32 atl1_read_mac_addr(struct atl1_hw *hw)
@@ -437,6 +438,7 @@ s32 atl1_phy_enter_power_saving(struct atl1_hw *hw)
  */
 static s32 atl1_phy_reset(struct atl1_hw *hw)
 {
+	struct pci_dev *pdev = hw->back->pdev;
 	s32 ret_val;
 	u16 phy_data;
 
@@ -468,8 +470,7 @@ static s32 atl1_phy_reset(struct atl1_hw *hw)
 		u32 val;
 		int i;
 		/* pcie serdes link may be down! */
-		printk(KERN_DEBUG "%s: autoneg caused pcie phy link down\n", 
-			atl1_driver_name);
+		dev_dbg(&pdev->dev, "pcie phy link down\n");
 
 		for (i = 0; i < 25; i++) {
 			msleep(1);
@@ -479,9 +480,7 @@ static s32 atl1_phy_reset(struct atl1_hw *hw)
 		}
 
 		if ((val & (MDIO_START | MDIO_BUSY)) != 0) {
-			printk(KERN_WARNING 
-				"%s: pcie link down at least for 25ms\n", 
-				atl1_driver_name);
+			dev_warn(&pdev->dev, "pcie link down at least 25ms\n");
 			return ret_val;
 		}
 	}
@@ -571,6 +570,7 @@ s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw)
  */
 static s32 atl1_setup_link(struct atl1_hw *hw)
 {
+	struct pci_dev *pdev = hw->back->pdev;
 	s32 ret_val;
 
 	/*
@@ -581,15 +581,13 @@ static s32 atl1_setup_link(struct atl1_hw *hw)
 	 */
 	ret_val = atl1_phy_setup_autoneg_adv(hw);
 	if (ret_val) {
-		printk(KERN_DEBUG "%s: error setting up autonegotiation\n", 
-			atl1_driver_name);
+		dev_dbg(&pdev->dev, "error setting up autonegotiation\n");
 		return ret_val;
 	}
 	/* SW.Reset , En-Auto-Neg if needed */
 	ret_val = atl1_phy_reset(hw);
 	if (ret_val) {
-		printk(KERN_DEBUG "%s: error resetting the phy\n", 
-			atl1_driver_name);
+		dev_dbg(&pdev->dev, "error resetting phy\n");
 		return ret_val;
 	}
 	hw->phy_configured = true;
@@ -631,7 +629,7 @@ static void atl1_init_flash_opcode(struct atl1_hw *hw)
  * Performs basic configuration of the adapter.
  * hw - Struct containing variables accessed by shared code
  * Assumes that the controller has previously been reset and is in a
- * post-reset uninitialized state. Initializes multicast table, 
+ * post-reset uninitialized state. Initializes multicast table,
  * and  Calls routines to setup link
  * Leaves the transmit and receive units disabled and uninitialized.
  */
@@ -669,6 +667,7 @@ s32 atl1_init_hw(struct atl1_hw *hw)
  */
 s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
 {
+	struct pci_dev *pdev = hw->back->pdev;
 	s32 ret_val;
 	u16 phy_data;
 
@@ -691,8 +690,7 @@ s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex)
 		*speed = SPEED_10;
 		break;
 	default:
-		printk(KERN_DEBUG "%s: error getting speed\n", 
-			atl1_driver_name);
+		dev_dbg(&pdev->dev, "error getting speed\n");
 		return ATL1_ERR_PHY_SPEED;
 		break;
 	}
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 4b1d4d1..d28f88b 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -188,8 +188,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
 	size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count);
 	tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL);
 	if (unlikely(!tpd_ring->buffer_info)) {
-		printk(KERN_WARNING "%s: kzalloc failed , size = D%d\n",
-			atl1_driver_name, size);
+		dev_err(&pdev->dev, "kzalloc failed , size = D%d\n", size);
 		goto err_nomem;
 	}
 	rfd_ring->buffer_info =
@@ -207,9 +206,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter)
 	ring_header->desc = pci_alloc_consistent(pdev, ring_header->size,
 						&ring_header->dma);
 	if (unlikely(!ring_header->desc)) {
-		printk(KERN_WARNING
-			"%s: pci_alloc_consistent failed, size = D%d\n",
-			atl1_driver_name, size);
+		dev_err(&pdev->dev, "pci_alloc_consistent failed\n");
 		goto err_nomem;
 	}
 
@@ -373,8 +370,7 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
 		if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC |
 					ERR_FLAG_CODE | ERR_FLAG_OV)) {
 			adapter->hw_csum_err++;
-			printk(KERN_DEBUG "%s: rx checksum error\n",
-				atl1_driver_name);
+			dev_dbg(&adapter->pdev->dev, "rx checksum error\n");
 			return;
 		}
 	}
@@ -393,8 +389,9 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter,
 	}
 
 	/* IPv4, but hardware thinks its checksum is wrong */
-	printk(KERN_DEBUG "%s: hw csum wrong pkt_flag:%x, err_flag:%x\n",
-		atl1_driver_name, rrd->pkt_flg, rrd->err_flg);
+	dev_dbg(&adapter->pdev->dev,
+		"hw csum wrong, pkt_flag:%x, err_flag:%x\n",
+		rrd->pkt_flg, rrd->err_flg);
 	skb->ip_summed = CHECKSUM_COMPLETE;
 	skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum);
 	adapter->hw_csum_err++;
@@ -507,14 +504,13 @@ chk_rrd:
 			/* rrd seems to be bad */
 			if (unlikely(i-- > 0)) {
 				/* rrd may not be DMAed completely */
-				printk(KERN_DEBUG
-					"%s: RRD may not be DMAed completely\n",
-					atl1_driver_name);
+				dev_dbg(&adapter->pdev->dev,
+					"incomplete RRD DMA transfer\n");
 				udelay(1);
 				goto chk_rrd;
 			}
 			/* bad rrd */
-			printk(KERN_DEBUG "%s: bad RRD\n", atl1_driver_name);
+			dev_dbg(&adapter->pdev->dev, "bad RRD\n");
 			/* see if update RFD index */
 			if (rrd->num_buf > 1) {
 				u16 num_buf;
@@ -685,8 +681,8 @@ static void atl1_check_for_link(struct atl1_adapter *adapter)
 	/* notify upper layer link down ASAP */
 	if (!(phy_data & BMSR_LSTATUS)) {	/* Link Down */
 		if (netif_carrier_ok(netdev)) {	/* old link state: Up */
-			printk(KERN_INFO "%s: %s link is down\n",
-			       atl1_driver_name, netdev->name);
+			dev_info(&adapter->pdev->dev, "%s link is down\n",
+				netdev->name);
 			adapter->link_speed = SPEED_0;
 			netif_carrier_off(netdev);
 			netif_stop_queue(netdev);
@@ -731,8 +727,8 @@ static irqreturn_t atl1_intr(int irq, void *data)
 
 		/* check if PCIE PHY Link down */
 		if (status & ISR_PHY_LINKDOWN) {
-			printk(KERN_DEBUG "%s: pcie phy link down %x\n",
-				atl1_driver_name, status);
+			dev_dbg(&adapter->pdev->dev, "pcie phy link down %x\n",
+				status);
 			if (netif_running(adapter->netdev)) {	/* reset MAC */
 				iowrite32(0, adapter->hw.hw_addr + REG_IMR);
 				schedule_work(&adapter->pcie_dma_to_rst_task);
@@ -742,9 +738,9 @@ static irqreturn_t atl1_intr(int irq, void *data)
 
 		/* check if DMA read/write error ? */
 		if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) {
-			printk(KERN_DEBUG
-				"%s: pcie DMA r/w error (status = 0x%x)\n",
-				atl1_driver_name, status);
+			dev_dbg(&adapter->pdev->dev,
+				"pcie DMA r/w error (status = 0x%x)\n",
+				status);
 			iowrite32(0, adapter->hw.hw_addr + REG_IMR);
 			schedule_work(&adapter->pcie_dma_to_rst_task);
 			return IRQ_HANDLED;
@@ -762,14 +758,13 @@ static irqreturn_t atl1_intr(int irq, void *data)
 
 		/* rx exception */
 		if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
+			ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
+			ISR_HOST_RRD_OV | ISR_CMB_RX))) {
+			if (status & (ISR_RXF_OV | ISR_RFD_UNRUN |
 				ISR_RRD_OV | ISR_HOST_RFD_UNRUN |
-				ISR_HOST_RRD_OV | ISR_CMB_RX))) {
-			if (status &
-			    (ISR_RXF_OV | ISR_RFD_UNRUN | ISR_RRD_OV |
-			     ISR_HOST_RFD_UNRUN | ISR_HOST_RRD_OV))
-				printk(KERN_INFO
-					"%s: rx exception: status = 0x%x\n",
-					atl1_driver_name, status);
+				ISR_HOST_RRD_OV))
+				dev_dbg(&adapter->pdev->dev,
+					"rx exception, ISR = 0x%x\n", status);
 			atl1_intr_rx(adapter);
 		}
 
@@ -874,8 +869,7 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
 	atl1_read_phy_reg(hw, MII_BMSR, &phy_data);
 	if (!(phy_data & BMSR_LSTATUS)) {	/* link down */
 		if (netif_carrier_ok(netdev)) {	/* old link state: Up */
-			printk(KERN_INFO "%s: link is down\n",
-				atl1_driver_name);
+			dev_info(&adapter->pdev->dev, "link is down\n");
 			adapter->link_speed = SPEED_0;
 			netif_carrier_off(netdev);
 			netif_stop_queue(netdev);
@@ -918,11 +912,11 @@ static u32 atl1_check_link(struct atl1_adapter *adapter)
 			adapter->link_speed = speed;
 			adapter->link_duplex = duplex;
 			atl1_setup_mac_ctrl(adapter);
-			printk(KERN_INFO "%s: %s link is up %d Mbps %s\n",
-			       atl1_driver_name, netdev->name,
-			       adapter->link_speed,
-			       adapter->link_duplex ==
-			       FULL_DUPLEX ? "full duplex" : "half duplex");
+			dev_info(&adapter->pdev->dev,
+				"%s link is up %d Mbps %s\n",
+				netdev->name, adapter->link_speed,
+				adapter->link_duplex == FULL_DUPLEX ?
+				"full duplex" : "half duplex");
 		}
 		if (!netif_carrier_ok(netdev)) {	/* Link down -> Up */
 			netif_carrier_on(netdev);
@@ -1330,8 +1324,8 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
 		cso = skb_transport_offset(skb);
 		css = cso + skb->csum_offset;
 		if (unlikely(cso & 0x1)) {
-			printk(KERN_DEBUG "%s: payload offset != even number\n",
-				atl1_driver_name);
+			dev_dbg(&adapter->pdev->dev,
+				"payload offset not an even number\n");
 			return -1;
 		}
 		csum->csumpl |= (cso & CSUM_PARAM_PLOADOFFSET_MASK) <<
@@ -1579,7 +1573,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	if (!spin_trylock(&adapter->lock)) {
 		/* Can't get lock - tell upper layer to requeue */
 		local_irq_restore(flags);
-		printk(KERN_DEBUG "%s: TX locked\n", atl1_driver_name);
+		dev_dbg(&adapter->pdev->dev, "tx locked\n");
 		return NETDEV_TX_LOCKED;
 	}
 
@@ -1587,7 +1581,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 		/* not enough descriptors */
 		netif_stop_queue(netdev);
 		spin_unlock_irqrestore(&adapter->lock, flags);
-		printk(KERN_DEBUG "%s: TX busy\n", atl1_driver_name);
+		dev_dbg(&adapter->pdev->dev, "tx busy\n");
 		return NETDEV_TX_BUSY;
 	}
 
@@ -1841,8 +1835,7 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu)
 
 	if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) ||
 	    (max_frame > MAX_JUMBO_FRAME_SIZE)) {
-		printk(KERN_WARNING "%s: invalid MTU setting\n",
-			atl1_driver_name);
+		dev_warn(&adapter->pdev->dev, "invalid MTU setting\n");
 		return -EINVAL;
 	}
 
@@ -2136,9 +2129,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 	if (err) {
 		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (err) {
-			printk(KERN_DEBUG
-				"%s: no usable DMA configuration, aborting\n",
-				atl1_driver_name);
+			dev_err(&pdev->dev, "no usable DMA configuration\n");
 			goto err_dma;
 		}
 		pci_using_64 = false;
@@ -2175,7 +2166,9 @@ static int __devinit atl1_probe(struct pci_dev *pdev,
 		goto err_pci_iomap;
 	}
 	/* get device revision number */
-	adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr + (REG_MASTER_CTRL + 2));
+	adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr +
+					(REG_MASTER_CTRL + 2));
+	dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION);
 
 	/* set default ring resource counts */
 	adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD;
@@ -2466,8 +2459,6 @@ static void __exit atl1_exit_module(void)
  */
 static int __init atl1_init_module(void)
 {
-	printk(KERN_INFO "%s - version %s\n", atl1_driver_string, DRIVER_VERSION);
-	printk(KERN_INFO "%s\n", atl1_copyright);
 	return pci_register_driver(&atl1_driver);
 }
 
diff --git a/drivers/net/atl1/atl1_param.c b/drivers/net/atl1/atl1_param.c
index bcd0bd8..4246bb9 100644
--- a/drivers/net/atl1/atl1_param.c
+++ b/drivers/net/atl1/atl1_param.c
@@ -23,6 +23,7 @@
 
 #include <linux/types.h>
 #include <linux/moduleparam.h>
+#include <linux/pci.h>
 #include "atl1.h"
 
 /*
@@ -93,7 +94,7 @@ struct atl1_option {
 	} arg;
 };
 
-static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
+static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, struct pci_dev *pdev)
 {
 	if (*value == OPTION_UNSET) {
 		*value = opt->def;
@@ -104,19 +105,17 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
 	case enable_option:
 		switch (*value) {
 		case OPTION_ENABLED:
-			printk(KERN_INFO "%s: %s Enabled\n", atl1_driver_name,
-				opt->name);
+			dev_info(&pdev->dev, "%s enabled\n", opt->name);
 			return 0;
 		case OPTION_DISABLED:
-			printk(KERN_INFO "%s: %s Disabled\n", atl1_driver_name,
-				opt->name);
+			dev_info(&pdev->dev, "%s disabled\n", opt->name);
 			return 0;
 		}
 		break;
 	case range_option:
 		if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) {
-			printk(KERN_INFO "%s: %s set to %i\n",
-				atl1_driver_name, opt->name, *value);
+			dev_info(&pdev->dev, "%s set to %i\n", opt->name,
+				*value);
 			return 0;
 		}
 		break;
@@ -128,8 +127,8 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
 				ent = &opt->arg.l.p[i];
 				if (*value == ent->i) {
 					if (ent->str[0] != '\0')
-						printk(KERN_INFO "%s: %s\n",
-						       atl1_driver_name, ent->str);
+						dev_info(&pdev->dev, "%s\n",
+							ent->str);
 					return 0;
 				}
 			}
@@ -140,8 +139,8 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
 		break;
 	}
 
-	printk(KERN_INFO "%s: invalid %s specified (%i) %s\n",
-	       atl1_driver_name, opt->name, *value, opt->err);
+	dev_info(&pdev->dev, "invalid %s specified (%i) %s\n",
+		opt->name, *value, opt->err);
 	*value = opt->def;
 	return -1;
 }
@@ -157,12 +156,11 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt)
  */
 void __devinit atl1_check_options(struct atl1_adapter *adapter)
 {
+	struct pci_dev *pdev = adapter->pdev;
 	int bd = adapter->bd_number;
 	if (bd >= ATL1_MAX_NIC) {
-		printk(KERN_NOTICE "%s: warning: no configuration for board #%i\n",
-			atl1_driver_name, bd);
-		printk(KERN_NOTICE "%s: using defaults for all values\n",
-			atl1_driver_name);
+		dev_notice(&pdev->dev, "no configuration for board#%i\n", bd);
+		dev_notice(&pdev->dev, "using defaults for all values\n");
 	}
 	{			/* Interrupt Moderate Timer */
 		struct atl1_option opt = {
@@ -177,7 +175,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter)
 		int val;
 		if (num_int_mod_timer > bd) {
 			val = int_mod_timer[bd];
-			atl1_validate_option(&val, &opt);
+			atl1_validate_option(&val, &opt, pdev);
 			adapter->imt = (u16) val;
 		} else
 			adapter->imt = (u16) (opt.def);
@@ -197,7 +195,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter)
 		int val;
 		if (num_flash_vendor > bd) {
 			val = flash_vendor[bd];
-			atl1_validate_option(&val, &opt);
+			atl1_validate_option(&val, &opt, pdev);
 			adapter->hw.flash_vendor = (u8) val;
 		} else
 			adapter->hw.flash_vendor = (u8) (opt.def);
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 8cc1174..264fa0e 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -77,9 +77,6 @@
 
 #define DM9000_PHY		0x40	/* PHY address 0x01 */
 
-#define TRUE			1
-#define FALSE			0
-
 #define CARDNAME "dm9000"
 #define PFX CARDNAME ": "
 
@@ -601,7 +598,7 @@ dm9000_probe(struct platform_device *pdev)
 	printk("%s: not found (%d).\n", CARDNAME, ret);
 
 	dm9000_release_board(pdev, db);
-	kfree(ndev);
+	free_netdev(ndev);
 
 	return ret;
 }
@@ -896,7 +893,7 @@ dm9000_rx(struct net_device *dev)
 	struct dm9000_rxhdr rxhdr;
 	struct sk_buff *skb;
 	u8 rxbyte, *rdptr;
-	int GoodPacket;
+	bool GoodPacket;
 	int RxLen;
 
 	/* Check packet ready or not */
@@ -918,7 +915,7 @@ dm9000_rx(struct net_device *dev)
 			return;
 
 		/* A packet ready now  & Get status/length */
-		GoodPacket = TRUE;
+		GoodPacket = true;
 		writeb(DM9000_MRCMD, db->io_addr);
 
 		(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));
@@ -927,7 +924,7 @@ dm9000_rx(struct net_device *dev)
 
 		/* Packet Status check */
 		if (RxLen < 0x40) {
-			GoodPacket = FALSE;
+			GoodPacket = false;
 			PRINTK1("Bad Packet received (runt)\n");
 		}
 
@@ -936,7 +933,7 @@ dm9000_rx(struct net_device *dev)
 		}
 
 		if (rxhdr.RxStatus & 0xbf00) {
-			GoodPacket = FALSE;
+			GoodPacket = false;
 			if (rxhdr.RxStatus & 0x100) {
 				PRINTK1("fifo error\n");
 				db->stats.rx_fifo_errors++;
@@ -1193,7 +1190,7 @@ dm9000_drv_remove(struct platform_device *pdev)
 
 	unregister_netdev(ndev);
 	dm9000_release_board(pdev, (board_info_t *) ndev->priv);
-	kfree(ndev);		/* free device structure */
+	free_netdev(ndev);		/* free device structure */
 
 	PRINTK1("clean_module() exit\n");
 
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index c7a5614..7211648 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -1803,10 +1803,10 @@ static inline int ehea_hash_skb(struct sk_buff *skb, int num_qps)
 	u32 tmp;
 
 	if ((skb->protocol == htons(ETH_P_IP)) &&
-	    (skb->nh.iph->protocol == IPPROTO_TCP)) {
-		tcp = (struct tcphdr*)(skb->nh.raw + (skb->nh.iph->ihl * 4));
+	    (ip_hdr(skb)->protocol == IPPROTO_TCP)) {
+		tcp = (struct tcphdr*)(skb_network_header(skb) + (ip_hdr(skb)->ihl * 4));
 		tmp = (tcp->source + (tcp->dest << 16)) % 31;
-		tmp += skb->nh.iph->daddr % 31;
+		tmp += ip_hdr(skb)->daddr % 31;
 		return tmp % num_qps;
 	}
 	else
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 16e3c43..5d14be7 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -290,6 +290,8 @@ MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n");
 
 #define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
 
+static void myri10ge_set_multicast_list(struct net_device *dev);
+
 static inline void put_be32(__be32 val, __be32 __iomem * p)
 {
 	__raw_writel((__force __u32) val, (__force void __iomem *)p);
@@ -353,6 +355,8 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd,
 			return 0;
 		} else if (result == MXGEFW_CMD_UNKNOWN) {
 			return -ENOSYS;
+		} else if (result == MXGEFW_CMD_ERROR_UNALIGNED) {
+			return -E2BIG;
 		} else {
 			dev_err(&mgp->pdev->dev,
 				"command %d failed, result = %d\n",
@@ -712,14 +716,78 @@ myri10ge_change_promisc(struct myri10ge_priv *mgp, int promisc, int atomic)
 		       mgp->dev->name);
 }
 
-static int myri10ge_reset(struct myri10ge_priv *mgp)
+static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type)
 {
 	struct myri10ge_cmd cmd;
 	int status;
-	size_t bytes;
 	u32 len;
 	struct page *dmatest_page;
 	dma_addr_t dmatest_bus;
+	char *test = " ";
+
+	dmatest_page = alloc_page(GFP_KERNEL);
+	if (!dmatest_page)
+		return -ENOMEM;
+	dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
+				   DMA_BIDIRECTIONAL);
+
+	/* Run a small DMA test.
+	 * The magic multipliers to the length tell the firmware
+	 * to do DMA read, write, or read+write tests.  The
+	 * results are returned in cmd.data0.  The upper 16
+	 * bits or the return is the number of transfers completed.
+	 * The lower 16 bits is the time in 0.5us ticks that the
+	 * transfers took to complete.
+	 */
+
+	len = mgp->tx.boundary;
+
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
+	cmd.data2 = len * 0x10000;
+	status = myri10ge_send_cmd(mgp, test_type, &cmd, 0);
+	if (status != 0) {
+		test = "read";
+		goto abort;
+	}
+	mgp->read_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff);
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
+	cmd.data2 = len * 0x1;
+	status = myri10ge_send_cmd(mgp, test_type, &cmd, 0);
+	if (status != 0) {
+		test = "write";
+		goto abort;
+	}
+	mgp->write_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff);
+
+	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
+	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
+	cmd.data2 = len * 0x10001;
+	status = myri10ge_send_cmd(mgp, test_type, &cmd, 0);
+	if (status != 0) {
+		test = "read/write";
+		goto abort;
+	}
+	mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) /
+	    (cmd.data0 & 0xffff);
+
+abort:
+	pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
+	put_page(dmatest_page);
+
+	if (status != 0 && test_type != MXGEFW_CMD_UNALIGNED_TEST)
+		dev_warn(&mgp->pdev->dev, "DMA %s benchmark failed: %d\n",
+			 test, status);
+
+	return status;
+}
+
+static int myri10ge_reset(struct myri10ge_priv *mgp)
+{
+	struct myri10ge_cmd cmd;
+	int status;
+	size_t bytes;
 
 	/* try to send a reset command to the card to see if it
 	 * is alive */
@@ -729,11 +797,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
 		dev_err(&mgp->pdev->dev, "failed reset\n");
 		return -ENXIO;
 	}
-	dmatest_page = alloc_page(GFP_KERNEL);
-	if (!dmatest_page)
-		return -ENOMEM;
-	dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE,
-				   DMA_BIDIRECTIONAL);
+
+	(void)myri10ge_dma_test(mgp, MXGEFW_DMA_TEST);
 
 	/* Now exchange information about interrupts  */
 
@@ -761,52 +826,6 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
 	}
 	put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr);
 
-	/* Run a small DMA test.
-	 * The magic multipliers to the length tell the firmware
-	 * to do DMA read, write, or read+write tests.  The
-	 * results are returned in cmd.data0.  The upper 16
-	 * bits or the return is the number of transfers completed.
-	 * The lower 16 bits is the time in 0.5us ticks that the
-	 * transfers took to complete.
-	 */
-
-	len = mgp->tx.boundary;
-
-	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
-	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
-	cmd.data2 = len * 0x10000;
-	status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
-	if (status == 0)
-		mgp->read_dma = ((cmd.data0 >> 16) * len * 2) /
-		    (cmd.data0 & 0xffff);
-	else
-		dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n",
-			 status);
-	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
-	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
-	cmd.data2 = len * 0x1;
-	status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
-	if (status == 0)
-		mgp->write_dma = ((cmd.data0 >> 16) * len * 2) /
-		    (cmd.data0 & 0xffff);
-	else
-		dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n",
-			 status);
-
-	cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus);
-	cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus);
-	cmd.data2 = len * 0x10001;
-	status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0);
-	if (status == 0)
-		mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) /
-		    (cmd.data0 & 0xffff);
-	else
-		dev_warn(&mgp->pdev->dev,
-			 "DMA read/write benchmark failed: %d\n", status);
-
-	pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL);
-	put_page(dmatest_page);
-
 	memset(mgp->rx_done.entry, 0, bytes);
 
 	/* reset mcp/driver shared state back to 0 */
@@ -820,10 +839,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp)
 	mgp->rx_done.cnt = 0;
 	mgp->link_changes = 0;
 	status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr);
-	myri10ge_change_promisc(mgp, 0, 0);
 	myri10ge_change_pause(mgp, mgp->pause);
-	if (mgp->adopted_rx_filter_bug)
-		(void)myri10ge_send_cmd(mgp, MXGEFW_ENABLE_ALLMULTI, &cmd, 1);
+	myri10ge_set_multicast_list(mgp->dev);
 	return status;
 }
 
@@ -1355,7 +1372,9 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = {
 	"tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt",
 	"wake_queue", "stop_queue", "watchdog_resets", "tx_linearized",
 	"link_changes", "link_up", "dropped_link_overflow",
-	"dropped_link_error_or_filtered", "dropped_multicast_filtered",
+	"dropped_link_error_or_filtered",
+	"dropped_pause", "dropped_bad_phy", "dropped_bad_crc32",
+	"dropped_unicast_filtered", "dropped_multicast_filtered",
 	"dropped_runt", "dropped_overrun", "dropped_no_small_buffer",
 	"dropped_no_big_buffer"
 };
@@ -1412,6 +1431,11 @@ myri10ge_get_ethtool_stats(struct net_device *netdev,
 	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow);
 	data[i++] =
 	    (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered);
+	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_pause);
+	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_phy);
+	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_crc32);
+	data[i++] =
+	    (unsigned int)ntohl(mgp->fw_stats->dropped_unicast_filtered);
 	data[i++] =
 	    (unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered);
 	data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt);
@@ -2276,7 +2300,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
 	myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1);
 
 	/* This firmware is known to not support multicast */
-	if (!mgp->fw_multicast_support || mgp->adopted_rx_filter_bug)
+	if (!mgp->fw_multicast_support)
 		return;
 
 	/* Disable multicast filtering */
@@ -2288,7 +2312,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev)
 		goto abort;
 	}
 
-	if (dev->flags & IFF_ALLMULTI) {
+	if ((dev->flags & IFF_ALLMULTI) || mgp->adopted_rx_filter_bug) {
 		/* request to disable multicast filtering, so quit here */
 		return;
 	}
@@ -2461,8 +2485,6 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
 	err_cap |= PCI_ERR_CAP_ECRC_GENE;
 	pci_write_config_dword(bridge, cap + PCI_ERR_CAP, err_cap);
 	dev_info(dev, "Enabled ECRC on upstream bridge %s\n", pci_name(bridge));
-	mgp->tx.boundary = 4096;
-	mgp->fw_name = myri10ge_fw_aligned;
 }
 
 /*
@@ -2484,22 +2506,70 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp)
  * firmware image, and set tx.boundary to 4KB.
  */
 
-#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7
-#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa
-#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 0x3510
-#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4 0x351b
-#define PCI_DEVICE_ID_INTEL_E3000_PCIE	0x2779
-#define PCI_DEVICE_ID_INTEL_E3010_PCIE	0x277a
-#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140
-#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142
-
-static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
+static void myri10ge_firmware_probe(struct myri10ge_priv *mgp)
 {
-	struct pci_dev *bridge = mgp->pdev->bus->self;
+	struct pci_dev *pdev = mgp->pdev;
+	struct device *dev = &pdev->dev;
+	int cap, status;
+	u16 val;
+
+	mgp->tx.boundary = 4096;
+	/*
+	 * Verify the max read request size was set to 4KB
+	 * before trying the test with 4KB.
+	 */
+	cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
+	if (cap < 64) {
+		dev_err(dev, "Bad PCI_CAP_ID_EXP location %d\n", cap);
+		goto abort;
+	}
+	status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val);
+	if (status != 0) {
+		dev_err(dev, "Couldn't read max read req size: %d\n", status);
+		goto abort;
+	}
+	if ((val & (5 << 12)) != (5 << 12)) {
+		dev_warn(dev, "Max Read Request size != 4096 (0x%x)\n", val);
+		mgp->tx.boundary = 2048;
+	}
+	/*
+	 * load the optimized firmware (which assumes aligned PCIe
+	 * completions) in order to see if it works on this host.
+	 */
+	mgp->fw_name = myri10ge_fw_aligned;
+	status = myri10ge_load_firmware(mgp);
+	if (status != 0) {
+		goto abort;
+	}
+
+	/*
+	 * Enable ECRC if possible
+	 */
+	myri10ge_enable_ecrc(mgp);
+
+	/*
+	 * Run a DMA test which watches for unaligned completions and
+	 * aborts on the first one seen.
+	 */
 
+	status = myri10ge_dma_test(mgp, MXGEFW_CMD_UNALIGNED_TEST);
+	if (status == 0)
+		return;		/* keep the aligned firmware */
+
+	if (status != -E2BIG)
+		dev_warn(dev, "DMA test failed: %d\n", status);
+	if (status == -ENOSYS)
+		dev_warn(dev, "Falling back to ethp! "
+			 "Please install up to date fw\n");
+abort:
+	/* fall back to using the unaligned firmware */
 	mgp->tx.boundary = 2048;
 	mgp->fw_name = myri10ge_fw_unaligned;
 
+}
+
+static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
+{
 	if (myri10ge_force_firmware == 0) {
 		int link_width, exp_cap;
 		u16 lnk;
@@ -2508,8 +2578,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
 		pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk);
 		link_width = (lnk >> 4) & 0x3f;
 
-		myri10ge_enable_ecrc(mgp);
-
 		/* Check to see if Link is less than 8 or if the
 		 * upstream bridge is known to provide aligned
 		 * completions */
@@ -2518,46 +2586,8 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp)
 				 link_width);
 			mgp->tx.boundary = 4096;
 			mgp->fw_name = myri10ge_fw_aligned;
-		} else if (bridge &&
-			   /* ServerWorks HT2000/HT1000 */
-			   ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
-			     && bridge->device ==
-			     PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE)
-			    /* ServerWorks HT2100 */
-			    || (bridge->vendor == PCI_VENDOR_ID_SERVERWORKS
-				&& bridge->device >=
-				PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST
-				&& bridge->device <=
-				PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST)
-			    /* All Intel E3000/E3010 PCIE ports */
-			    || (bridge->vendor == PCI_VENDOR_ID_INTEL
-				&& (bridge->device ==
-				    PCI_DEVICE_ID_INTEL_E3000_PCIE
-				    || bridge->device ==
-				    PCI_DEVICE_ID_INTEL_E3010_PCIE))
-			    /* All Intel 6310/6311/6321ESB PCIE ports */
-			    || (bridge->vendor == PCI_VENDOR_ID_INTEL
-				&& bridge->device >=
-				PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1
-				&& bridge->device <=
-				PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4)
-			    /* All Intel E5000 PCIE ports */
-			    || (bridge->vendor == PCI_VENDOR_ID_INTEL
-				&& bridge->device >=
-				PCI_DEVICE_ID_INTEL_E5000_PCIE23
-				&& bridge->device <=
-				PCI_DEVICE_ID_INTEL_E5000_PCIE47))) {
-			dev_info(&mgp->pdev->dev,
-				 "Assuming aligned completions (0x%x:0x%x)\n",
-				 bridge->vendor, bridge->device);
-			mgp->tx.boundary = 4096;
-			mgp->fw_name = myri10ge_fw_aligned;
-		} else if (bridge &&
-			   bridge->vendor == PCI_VENDOR_ID_SGI &&
-			   bridge->device == 0x4002 /* TIOCE pcie-port */ ) {
-			/* this pcie bridge does not support 4K rdma request */
-			mgp->tx.boundary = 2048;
-			mgp->fw_name = myri10ge_fw_aligned;
+		} else {
+			myri10ge_firmware_probe(mgp);
 		}
 	} else {
 		if (myri10ge_force_firmware == 1) {
@@ -2825,7 +2855,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		status = -ENODEV;
 		goto abort_with_netdev;
 	}
-	myri10ge_select_firmware(mgp);
 
 	/* Find the vendor-specific cap so we can check
 	 * the reboot register later on */
@@ -2919,6 +2948,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto abort_with_ioremap;
 	memset(mgp->rx_done.entry, 0, bytes);
 
+	myri10ge_select_firmware(mgp);
+
 	status = myri10ge_load_firmware(mgp);
 	if (status != 0) {
 		dev_err(&pdev->dev, "failed to load firmware\n");
diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h
index 29463b3..a1d2a22 100644
--- a/drivers/net/myri10ge/myri10ge_mcp.h
+++ b/drivers/net/myri10ge/myri10ge_mcp.h
@@ -200,6 +200,13 @@ enum myri10ge_mcp_cmd_type {
 	/* data0, data1 = bus addr,
 	 * data2 = sizeof(struct mcp_irq_data) from driver point of view, allows
 	 * adding new stuff to mcp_irq_data without changing the ABI */
+
+	MXGEFW_CMD_UNALIGNED_TEST,
+	/* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned
+	 * chipset */
+
+	MXGEFW_CMD_UNALIGNED_STATUS
+	    /* return data = boolean, true if the chipset is known to be unaligned */
 };
 
 enum myri10ge_mcp_cmd_status {
@@ -212,18 +219,27 @@ enum myri10ge_mcp_cmd_status {
 	MXGEFW_CMD_ERROR_HASH_ERROR,
 	MXGEFW_CMD_ERROR_BAD_PORT,
 	MXGEFW_CMD_ERROR_RESOURCES,
-	MXGEFW_CMD_ERROR_MULTICAST
+	MXGEFW_CMD_ERROR_MULTICAST,
+	MXGEFW_CMD_ERROR_UNALIGNED
 };
 
 #define MXGEFW_OLD_IRQ_DATA_LEN 40
 
 struct mcp_irq_data {
 	/* add new counters at the beginning */
-	__be32 future_use[5];
+	__be32 future_use[1];
+	__be32 dropped_pause;
+	__be32 dropped_unicast_filtered;
+	__be32 dropped_bad_crc32;
+	__be32 dropped_bad_phy;
 	__be32 dropped_multicast_filtered;
 	/* 40 Bytes */
 	__be32 send_done_count;
 
+#define MXGEFW_LINK_DOWN 0
+#define MXGEFW_LINK_UP 1
+#define MXGEFW_LINK_MYRINET 2
+#define MXGEFW_LINK_UNKNOWN 3
 	__be32 link_up;
 	__be32 dropped_link_overflow;
 	__be32 dropped_link_error_or_filtered;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index a8d7ff2..223e0e6 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -81,6 +81,8 @@ static const int multicast_filter_limit = 100;
    Setting to > 1518 effectively disables this feature. */
 static int rx_copybreak;
 
+static int dspcfg_workaround = 1;
+
 /* Used to pass the media type, etc.
    Both 'options[]' and 'full_duplex[]' should exist for driver
    interoperability.
@@ -139,12 +141,14 @@ MODULE_LICENSE("GPL");
 module_param(mtu, int, 0);
 module_param(debug, int, 0);
 module_param(rx_copybreak, int, 0);
+module_param(dspcfg_workaround, int, 1);
 module_param_array(options, int, NULL, 0);
 module_param_array(full_duplex, int, NULL, 0);
 MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)");
 MODULE_PARM_DESC(debug, "DP8381x default debug level");
 MODULE_PARM_DESC(rx_copybreak,
 	"DP8381x copy breakpoint for copy-only-tiny-frames");
+MODULE_PARM_DESC(dspcfg_workaround, "DP8381x: control DspCfg workaround");
 MODULE_PARM_DESC(options,
 	"DP8381x: Bits 0-3: media type, bit 17: full duplex");
 MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)");
@@ -590,6 +594,7 @@ struct netdev_private {
 	u32 srr;
 	/* expected DSPCFG value */
 	u16 dspcfg;
+	int dspcfg_workaround;
 	/* parms saved in ethtool format */
 	u16	speed;		/* The forced speed, 10Mb, 100Mb, gigabit */
 	u8	duplex;		/* Duplex, half or full */
@@ -656,6 +661,56 @@ static int netdev_get_regs(struct net_device *dev, u8 *buf);
 static int netdev_get_eeprom(struct net_device *dev, u8 *buf);
 static const struct ethtool_ops ethtool_ops;
 
+#define NATSEMI_ATTR(_name) \
+static ssize_t natsemi_show_##_name(struct device *dev, \
+         struct device_attribute *attr, char *buf); \
+	 static ssize_t natsemi_set_##_name(struct device *dev, \
+		struct device_attribute *attr, \
+	        const char *buf, size_t count); \
+	 static DEVICE_ATTR(_name, 0644, natsemi_show_##_name, natsemi_set_##_name)
+
+#define NATSEMI_CREATE_FILE(_dev, _name) \
+         device_create_file(&_dev->dev, &dev_attr_##_name)
+#define NATSEMI_REMOVE_FILE(_dev, _name) \
+         device_create_file(&_dev->dev, &dev_attr_##_name)
+
+NATSEMI_ATTR(dspcfg_workaround);
+
+static ssize_t natsemi_show_dspcfg_workaround(struct device *dev,
+				  	      struct device_attribute *attr, 
+					      char *buf)
+{
+	struct netdev_private *np = netdev_priv(to_net_dev(dev));
+
+	return sprintf(buf, "%s\n", np->dspcfg_workaround ? "on" : "off");
+}
+
+static ssize_t natsemi_set_dspcfg_workaround(struct device *dev,
+					     struct device_attribute *attr,
+					     const char *buf, size_t count)
+{
+	struct netdev_private *np = netdev_priv(to_net_dev(dev));
+	int new_setting;
+	u32 flags;
+
+        /* Find out the new setting */
+        if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
+                new_setting = 1;
+        else if (!strncmp("off", buf, count - 1)
+                 || !strncmp("0", buf, count - 1))
+		new_setting = 0;
+	else
+                 return count; 
+
+	spin_lock_irqsave(&np->lock, flags);
+
+	np->dspcfg_workaround = new_setting;
+
+	spin_unlock_irqrestore(&np->lock, flags);
+
+	return count;
+}
+
 static inline void __iomem *ns_ioaddr(struct net_device *dev)
 {
 	return (void __iomem *) dev->base_addr;
@@ -820,6 +875,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 		np->ignore_phy = 1;
 	else
 		np->ignore_phy = 0;
+	np->dspcfg_workaround = dspcfg_workaround;
 
 	/* Initial port:
 	 * - If configured to ignore the PHY set up for external.
@@ -899,6 +955,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 	if (i)
 		goto err_register_netdev;
 
+	if (NATSEMI_CREATE_FILE(pdev, dspcfg_workaround))
+		goto err_create_file;
+
 	if (netif_msg_drv(np)) {
 		printk(KERN_INFO "natsemi %s: %s at %#08lx (%s), ",
 			dev->name, natsemi_pci_info[chip_idx].name, iostart,
@@ -915,6 +974,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 	}
 	return 0;
 
+ err_create_file:
+ 	unregister_netdev(dev);
+
  err_register_netdev:
 	iounmap(ioaddr);
 
@@ -1727,7 +1789,8 @@ static void init_registers(struct net_device *dev)
  *    It seems that a reference set for this chip went out with incorrect info,
  *    and there exist boards that aren't quite right.  An unexpected voltage
  *    drop can cause the PHY to get itself in a weird state (basically reset).
- *    NOTE: this only seems to affect revC chips.
+ *    NOTE: this only seems to affect revC chips.  The user can disable
+ *    this check via dspcfg_workaround sysfs option.
  * 3) check of death of the RX path due to OOM
  */
 static void netdev_timer(unsigned long data)
@@ -1753,10 +1816,10 @@ static void netdev_timer(unsigned long data)
 		writew(1, ioaddr+PGSEL);
 		dspcfg = readw(ioaddr+DSPCFG);
 		writew(0, ioaddr+PGSEL);
-		if (dspcfg != np->dspcfg) {
+		if (np->dspcfg_workaround && dspcfg != np->dspcfg) {
 			if (!netif_queue_stopped(dev)) {
 				spin_unlock_irq(&np->lock);
-				if (netif_msg_hw(np))
+				if (netif_msg_drv(np))
 					printk(KERN_NOTICE "%s: possible phy reset: "
 						"re-initializing\n", dev->name);
 				disable_irq(dev->irq);
@@ -3157,6 +3220,7 @@ static void __devexit natsemi_remove1 (struct pci_dev *pdev)
 	struct net_device *dev = pci_get_drvdata(pdev);
 	void __iomem * ioaddr = ns_ioaddr(dev);
 
+	NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround);
 	unregister_netdev (dev);
 	pci_release_regions (pdev);
 	iounmap(ioaddr);
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index a5c4199..c9f74bf 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -51,14 +51,11 @@ static const char version2[] =
 #include <linux/netdevice.h>
 #include <linux/etherdevice.h>
 #include <linux/jiffies.h>
+#include <linux/platform_device.h>
 
 #include <asm/system.h>
 #include <asm/io.h>
 
-#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
-#include <asm/tx4938/rbtx4938.h>
-#endif
-
 #include "8390.h"
 
 #define DRV_NAME "ne"
@@ -77,8 +74,13 @@ static const char version2[] =
 /* Do we have a non std. amount of memory? (in units of 256 byte pages) */
 /* #define PACKETBUF_MEMSIZE	0x40 */
 
+#if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R))
+/* Do we need a portlist for the ISA auto-probe ? */
+#define NEEDS_PORTLIST
+#endif
+
 /* A zero-terminated list of I/O addresses to be probed at boot. */
-#ifndef MODULE
+#ifdef NEEDS_PORTLIST
 static unsigned int netcard_portlist[] __initdata = {
 	0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0
 };
@@ -146,7 +148,7 @@ bad_clone_list[] __initdata = {
 #  define DCR_VAL 0x49
 #endif
 
-static int ne_probe1(struct net_device *dev, int ioaddr);
+static int ne_probe1(struct net_device *dev, unsigned long ioaddr);
 static int ne_probe_isapnp(struct net_device *dev);
 
 static int ne_open(struct net_device *dev);
@@ -184,8 +186,8 @@ static void ne_block_output(struct net_device *dev, const int count,
 
 static int __init do_ne_probe(struct net_device *dev)
 {
-	unsigned int base_addr = dev->base_addr;
-#ifndef MODULE
+	unsigned long base_addr = dev->base_addr;
+#ifdef NEEDS_PORTLIST
 	int orig_irq = dev->irq;
 #endif
 
@@ -201,7 +203,7 @@ static int __init do_ne_probe(struct net_device *dev)
 	if (isapnp_present() && (ne_probe_isapnp(dev) == 0))
 		return 0;
 
-#ifndef MODULE
+#ifdef NEEDS_PORTLIST
 	/* Last resort. The semi-risky ISA auto-probe. */
 	for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) {
 		int ioaddr = netcard_portlist[base_addr];
@@ -226,10 +228,6 @@ struct net_device * __init ne_probe(int unit)
 	sprintf(dev->name, "eth%d", unit);
 	netdev_boot_setup_check(dev);
 
-#ifdef CONFIG_TOSHIBA_RBTX4938
-	dev->base_addr = RBTX4938_RTL_8019_BASE;
-	dev->irq = RBTX4938_RTL_8019_IRQ;
-#endif
 	err = do_ne_probe(dev);
 	if (err)
 		goto out;
@@ -285,7 +283,7 @@ static int __init ne_probe_isapnp(struct net_device *dev)
 	return -ENODEV;
 }
 
-static int __init ne_probe1(struct net_device *dev, int ioaddr)
+static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr)
 {
 	int i;
 	unsigned char SA_prom[32];
@@ -324,7 +322,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
 	if (ei_debug  &&  version_printed++ == 0)
 		printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2);
 
-	printk(KERN_INFO "NE*000 ethercard probe at %#3x:", ioaddr);
+	printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr);
 
 	/* A user with a poor card that fails to ack the reset, or that
 	   does not have a valid 0x57,0x57 signature can still use this
@@ -516,8 +514,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
 	}
 #endif
 
-	printk("\n%s: %s found at %#x, using IRQ %d.\n",
-		dev->name, name, ioaddr, dev->irq);
+	printk("\n");
 
 	ei_status.name = name;
 	ei_status.tx_start_page = start_page;
@@ -547,6 +544,8 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr)
 	ret = register_netdev(dev);
 	if (ret)
 		goto out_irq;
+	printk(KERN_INFO "%s: %s found at %#lx, using IRQ %d.\n",
+	       dev->name, name, ioaddr, dev->irq);
 	return 0;
 
 out_irq:
@@ -807,6 +806,87 @@ retry:
 	return;
 }
 
+static int __init ne_drv_probe(struct platform_device *pdev)
+{
+	struct net_device *dev;
+	struct resource *res;
+	int err, irq;
+
+	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	irq = platform_get_irq(pdev, 0);
+	if (!res || irq < 0)
+		return -ENODEV;
+
+	dev = alloc_ei_netdev();
+	if (!dev)
+		return -ENOMEM;
+	dev->irq = irq;
+	dev->base_addr = res->start;
+	err = do_ne_probe(dev);
+	if (err) {
+		free_netdev(dev);
+		return err;
+	}
+	platform_set_drvdata(pdev, dev);
+	return 0;
+}
+
+static int __exit ne_drv_remove(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+
+	unregister_netdev(dev);
+	free_irq(dev->irq, dev);
+	release_region(dev->base_addr, NE_IO_EXTENT);
+	free_netdev(dev);
+	return 0;
+}
+
+#ifdef CONFIG_PM
+static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+
+	if (netif_running(dev))
+		netif_device_detach(dev);
+	return 0;
+}
+
+static int ne_drv_resume(struct platform_device *pdev)
+{
+	struct net_device *dev = platform_get_drvdata(pdev);
+
+	if (netif_running(dev)) {
+		ne_reset_8390(dev);
+		NS8390_init(dev, 1);
+		netif_device_attach(dev);
+	}
+	return 0;
+}
+#else
+#define ne_drv_suspend NULL
+#define ne_drv_resume NULL
+#endif
+
+static struct platform_driver ne_driver = {
+	.remove		= __exit_p(ne_drv_remove),
+	.suspend	= ne_drv_suspend,
+	.resume		= ne_drv_resume,
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init ne_init(void)
+{
+	return platform_driver_probe(&ne_driver, ne_drv_probe);
+}
+
+static void __exit ne_exit(void)
+{
+	platform_driver_unregister(&ne_driver);
+}
 
 #ifdef MODULE
 #define MAX_NE_CARDS	4	/* Max number of NE cards per module */
@@ -832,6 +912,7 @@ ISA device autoprobes on a running machine are not recommended anyway. */
 int __init init_module(void)
 {
 	int this_dev, found = 0;
+	int plat_found = !ne_init();
 
 	for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
 		struct net_device *dev = alloc_ei_netdev();
@@ -845,7 +926,7 @@ int __init init_module(void)
 			continue;
 		}
 		free_netdev(dev);
-		if (found)
+		if (found || plat_found)
 			break;
 		if (io[this_dev] != 0)
 			printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]);
@@ -853,7 +934,7 @@ int __init init_module(void)
 			printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n");
 		return -ENXIO;
 	}
-	if (found)
+	if (found || plat_found)
 		return 0;
 	return -ENODEV;
 }
@@ -871,6 +952,7 @@ void __exit cleanup_module(void)
 {
 	int this_dev;
 
+	ne_exit();
 	for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
 		struct net_device *dev = dev_ne[this_dev];
 		if (dev) {
@@ -880,4 +962,7 @@ void __exit cleanup_module(void)
 		}
 	}
 }
+#else /* MODULE */
+module_init(ne_init);
+module_exit(ne_exit);
 #endif /* MODULE */
diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c
index 76fe9dd..b8f976b 100644
--- a/drivers/net/pasemi_mac.c
+++ b/drivers/net/pasemi_mac.c
@@ -33,6 +33,8 @@
 #include <linux/tcp.h>
 #include <net/checksum.h>
 
+#include <asm/irq.h>
+
 #include "pasemi_mac.h"
 
 
@@ -51,6 +53,16 @@
 #define RX_RING_SIZE 512
 #define TX_RING_SIZE 512
 
+#define DEFAULT_MSG_ENABLE	  \
+	(NETIF_MSG_DRV		| \
+	 NETIF_MSG_PROBE	| \
+	 NETIF_MSG_LINK		| \
+	 NETIF_MSG_TIMER	| \
+	 NETIF_MSG_IFDOWN	| \
+	 NETIF_MSG_IFUP		| \
+	 NETIF_MSG_RX_ERR	| \
+	 NETIF_MSG_TX_ERR)
+
 #define TX_DESC(mac, num)	((mac)->tx->desc[(num) & (TX_RING_SIZE-1)])
 #define TX_DESC_INFO(mac, num)	((mac)->tx->desc_info[(num) & (TX_RING_SIZE-1)])
 #define RX_DESC(mac, num)	((mac)->rx->desc[(num) & (RX_RING_SIZE-1)])
@@ -59,11 +71,13 @@
 
 #define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */
 
-/* XXXOJN these should come out of the device tree some day */
-#define PAS_DMA_CAP_BASE   0xe00d0040
-#define PAS_DMA_CAP_SIZE   0x100
-#define PAS_DMA_COM_BASE   0xe00d0100
-#define PAS_DMA_COM_SIZE   0x100
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
+MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
+
+static int debug = -1;	/* -1 == use DEFAULT_MSG_ENABLE as value */
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value");
 
 static struct pasdma_status *dma_status;
 
@@ -80,7 +94,12 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac)
 		return -ENOENT;
 	}
 
-	maddr = get_property(dn, "mac-address", NULL);
+	maddr = get_property(dn, "local-mac-address", NULL);
+
+	/* Fall back to mac-address for older firmware */
+	if (maddr == NULL)
+		maddr = get_property(dn, "mac-address", NULL);
+
 	if (maddr == NULL) {
 		dev_warn(&pdev->dev,
 			 "no mac address in device tree, not configuring\n");
@@ -277,8 +296,8 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev)
 	for (i = 0; i < RX_RING_SIZE; i++) {
 		info = &RX_DESC_INFO(mac, i);
 		dp = &RX_DESC(mac, i);
-		if (info->dma) {
-			if (info->skb) {
+		if (info->skb) {
+			if (info->dma) {
 				pci_unmap_single(mac->dma_pdev,
 						 info->dma,
 						 info->skb->len,
@@ -309,82 +328,120 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev)
 	struct pasemi_mac *mac = netdev_priv(dev);
 	unsigned int i;
 	int start = mac->rx->next_to_fill;
-	unsigned int count;
+	unsigned int limit, count;
 
-	count = (mac->rx->next_to_clean + RX_RING_SIZE -
+	limit = (mac->rx->next_to_clean + RX_RING_SIZE -
 		 mac->rx->next_to_fill) & (RX_RING_SIZE - 1);
 
 	/* Check to see if we're doing first-time setup */
 	if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0))
-		count = RX_RING_SIZE;
+		limit = RX_RING_SIZE;
 
-	if (count <= 0)
+	if (limit <= 0)
 		return;
 
-	for (i = start; i < start + count; i++) {
+	i = start;
+	for (count = limit; count; count--) {
 		struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i);
 		u64 *buff = &RX_BUFF(mac, i);
 		struct sk_buff *skb;
 		dma_addr_t dma;
 
-		skb = dev_alloc_skb(BUF_SIZE);
+		/* skb might still be in there for recycle on short receives */
+		if (info->skb)
+			skb = info->skb;
+		else
+			skb = dev_alloc_skb(BUF_SIZE);
 
-		if (!skb) {
-			count = i - start;
+		if (unlikely(!skb))
 			break;
-		}
 
 		dma = pci_map_single(mac->dma_pdev, skb->data, skb->len,
 				     PCI_DMA_FROMDEVICE);
 
-		if (dma_mapping_error(dma)) {
+		if (unlikely(dma_mapping_error(dma))) {
 			dev_kfree_skb_irq(info->skb);
-			count = i - start;
 			break;
 		}
 
 		info->skb = skb;
 		info->dma = dma;
 		*buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma);
+		i++;
 	}
 
 	wmb();
 
 	pci_write_config_dword(mac->dma_pdev,
 			       PAS_DMA_RXCHAN_INCR(mac->dma_rxch),
-			       count);
+			       limit - count);
 	pci_write_config_dword(mac->dma_pdev,
 			       PAS_DMA_RXINT_INCR(mac->dma_if),
-			       count);
+			       limit - count);
 
-	mac->rx->next_to_fill += count;
+	mac->rx->next_to_fill += limit - count;
 }
 
+static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac)
+{
+	unsigned int reg, stat;
+	/* Re-enable packet count interrupts: finally
+	 * ack the packet count interrupt we got in rx_intr.
+	 */
+
+	pci_read_config_dword(mac->iob_pdev,
+			      PAS_IOB_DMA_RXCH_STAT(mac->dma_rxch),
+			      &stat);
+
+	reg = PAS_IOB_DMA_RXCH_RESET_PCNT(stat & PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
+		| PAS_IOB_DMA_RXCH_RESET_PINTC;
+
+	pci_write_config_dword(mac->iob_pdev,
+			       PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch),
+			       reg);
+}
+
+static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac)
+{
+	unsigned int reg, stat;
+
+	/* Re-enable packet count interrupts */
+	pci_read_config_dword(mac->iob_pdev,
+			      PAS_IOB_DMA_TXCH_STAT(mac->dma_txch), &stat);
+
+	reg = PAS_IOB_DMA_TXCH_RESET_PCNT(stat & PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
+		| PAS_IOB_DMA_TXCH_RESET_PINTC;
+
+	pci_write_config_dword(mac->iob_pdev,
+			       PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg);
+}
+
+
 static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 {
-	unsigned int i;
-	int start, count;
+	unsigned int n;
+	int count;
+	struct pas_dma_xct_descr *dp;
+	struct pasemi_mac_buffer *info;
+	struct sk_buff *skb;
+	unsigned int i, len;
+	u64 macrx;
+	dma_addr_t dma;
 
 	spin_lock(&mac->rx->lock);
 
-	start = mac->rx->next_to_clean;
-	count = 0;
+	n = mac->rx->next_to_clean;
 
-	for (i = start; i < (start + RX_RING_SIZE) && count < limit; i++) {
-		struct pas_dma_xct_descr *dp;
-		struct pasemi_mac_buffer *info;
-		struct sk_buff *skb;
-		unsigned int j, len;
-		dma_addr_t dma;
+	for (count = limit; count; count--) {
 
 		rmb();
 
-		dp = &RX_DESC(mac, i);
+		dp = &RX_DESC(mac, n);
+		macrx = dp->macrx;
 
-		if (!(dp->macrx & XCT_MACRX_O))
+		if (!(macrx & XCT_MACRX_O))
 			break;
 
-		count++;
 
 		info = NULL;
 
@@ -396,29 +453,42 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 		 */
 
 		dma = (dp->ptr & XCT_PTR_ADDR_M);
-		for (j = start; j < (start + RX_RING_SIZE); j++) {
-			info = &RX_DESC_INFO(mac, j);
+		for (i = n; i < (n + RX_RING_SIZE); i++) {
+			info = &RX_DESC_INFO(mac, i);
 			if (info->dma == dma)
 				break;
 		}
 
-		BUG_ON(!info);
-		BUG_ON(info->dma != dma);
+		skb = info->skb;
+		info->dma = 0;
 
-		pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len,
+		pci_unmap_single(mac->dma_pdev, dma, skb->len,
 				 PCI_DMA_FROMDEVICE);
 
-		skb = info->skb;
-
-		len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
+		len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S;
+
+		if (len < 256) {
+			struct sk_buff *new_skb =
+			    netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN);
+			if (new_skb) {
+				skb_reserve(new_skb, NET_IP_ALIGN);
+				memcpy(new_skb->data - NET_IP_ALIGN,
+					skb->data - NET_IP_ALIGN,
+					len + NET_IP_ALIGN);
+				/* save the skb in buffer_info as good */
+				skb = new_skb;
+			}
+			/* else just continue with the old one */
+		} else
+			info->skb = NULL;
 
 		skb_put(skb, len);
 
 		skb->protocol = eth_type_trans(skb, mac->netdev);
 
-		if ((dp->macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
+		if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) {
 			skb->ip_summed = CHECKSUM_COMPLETE;
-			skb->csum = (dp->macrx & XCT_MACRX_CSUM_M) >>
+			skb->csum = (macrx & XCT_MACRX_CSUM_M) >>
 					   XCT_MACRX_CSUM_S;
 		} else
 			skb->ip_summed = CHECKSUM_NONE;
@@ -428,13 +498,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit)
 
 		netif_receive_skb(skb);
 
-		info->dma = 0;
-		info->skb = NULL;
 		dp->ptr = 0;
 		dp->macrx = 0;
+
+		n++;
 	}
 
-	mac->rx->next_to_clean += count;
+	mac->rx->next_to_clean += limit - count;
 	pasemi_mac_replenish_rx_ring(mac->netdev);
 
 	spin_unlock(&mac->rx->lock);
@@ -476,6 +546,8 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac)
 	mac->tx->next_to_clean += count;
 	spin_unlock_irqrestore(&mac->tx->lock, flags);
 
+	netif_wake_queue(mac->netdev);
+
 	return count;
 }
 
@@ -486,18 +558,28 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data)
 	struct pasemi_mac *mac = netdev_priv(dev);
 	unsigned int reg;
 
-	if (!(*mac->rx_status & PAS_STATUS_INT))
+	if (!(*mac->rx_status & PAS_STATUS_CAUSE_M))
 		return IRQ_NONE;
 
-	netif_rx_schedule(dev);
-	pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
-			       PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0));
+	if (*mac->rx_status & PAS_STATUS_ERROR)
+		printk("rx_status reported error\n");
+
+	/* Don't reset packet count so it won't fire again but clear
+	 * all others.
+	 */
+
+	pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), &reg);
 
-	reg = PAS_IOB_DMA_RXCH_RESET_PINTC | PAS_IOB_DMA_RXCH_RESET_SINTC |
-	      PAS_IOB_DMA_RXCH_RESET_DINTC;
+	reg = 0;
+	if (*mac->rx_status & PAS_STATUS_SOFT)
+		reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
+	if (*mac->rx_status & PAS_STATUS_ERROR)
+		reg |= PAS_IOB_DMA_RXCH_RESET_DINTC;
 	if (*mac->rx_status & PAS_STATUS_TIMER)
 		reg |= PAS_IOB_DMA_RXCH_RESET_TINTC;
 
+	netif_rx_schedule(dev);
+
 	pci_write_config_dword(mac->iob_pdev,
 			       PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg);
 
@@ -510,31 +592,137 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data)
 	struct net_device *dev = data;
 	struct pasemi_mac *mac = netdev_priv(dev);
 	unsigned int reg;
-	int was_full;
 
-	was_full = mac->tx->next_to_clean - mac->tx->next_to_use == TX_RING_SIZE;
-
-	if (!(*mac->tx_status & PAS_STATUS_INT))
+	if (!(*mac->tx_status & PAS_STATUS_CAUSE_M))
 		return IRQ_NONE;
 
 	pasemi_mac_clean_tx(mac);
 
-	reg = PAS_IOB_DMA_TXCH_RESET_PINTC | PAS_IOB_DMA_TXCH_RESET_SINTC;
-	if (*mac->tx_status & PAS_STATUS_TIMER)
-		reg |= PAS_IOB_DMA_TXCH_RESET_TINTC;
+	reg = PAS_IOB_DMA_TXCH_RESET_PINTC;
+
+	if (*mac->tx_status & PAS_STATUS_SOFT)
+		reg |= PAS_IOB_DMA_TXCH_RESET_SINTC;
+	if (*mac->tx_status & PAS_STATUS_ERROR)
+		reg |= PAS_IOB_DMA_TXCH_RESET_DINTC;
 
 	pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch),
 			       reg);
 
-	if (was_full)
-		netif_wake_queue(dev);
-
 	return IRQ_HANDLED;
 }
 
+static void pasemi_adjust_link(struct net_device *dev)
+{
+	struct pasemi_mac *mac = netdev_priv(dev);
+	int msg;
+	unsigned int flags;
+	unsigned int new_flags;
+
+	if (!mac->phydev->link) {
+		/* If no link, MAC speed settings don't matter. Just report
+		 * link down and return.
+		 */
+		if (mac->link && netif_msg_link(mac))
+			printk(KERN_INFO "%s: Link is down.\n", dev->name);
+
+		netif_carrier_off(dev);
+		mac->link = 0;
+
+		return;
+	} else
+		netif_carrier_on(dev);
+
+	pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags);
+	new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M |
+			      PAS_MAC_CFG_PCFG_TSR_M);
+
+	if (!mac->phydev->duplex)
+		new_flags |= PAS_MAC_CFG_PCFG_HD;
+
+	switch (mac->phydev->speed) {
+	case 1000:
+		new_flags |= PAS_MAC_CFG_PCFG_SPD_1G |
+			     PAS_MAC_CFG_PCFG_TSR_1G;
+		break;
+	case 100:
+		new_flags |= PAS_MAC_CFG_PCFG_SPD_100M |
+			     PAS_MAC_CFG_PCFG_TSR_100M;
+		break;
+	case 10:
+		new_flags |= PAS_MAC_CFG_PCFG_SPD_10M |
+			     PAS_MAC_CFG_PCFG_TSR_10M;
+		break;
+	default:
+		printk("Unsupported speed %d\n", mac->phydev->speed);
+	}
+
+	/* Print on link or speed/duplex change */
+	msg = mac->link != mac->phydev->link || flags != new_flags;
+
+	mac->duplex = mac->phydev->duplex;
+	mac->speed = mac->phydev->speed;
+	mac->link = mac->phydev->link;
+
+	if (new_flags != flags)
+		pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, new_flags);
+
+	if (msg && netif_msg_link(mac))
+		printk(KERN_INFO "%s: Link is up at %d Mbps, %s duplex.\n",
+		       dev->name, mac->speed, mac->duplex ? "full" : "half");
+}
+
+static int pasemi_mac_phy_init(struct net_device *dev)
+{
+	struct pasemi_mac *mac = netdev_priv(dev);
+	struct device_node *dn, *phy_dn;
+	struct phy_device *phydev;
+	unsigned int phy_id;
+	const phandle *ph;
+	const unsigned int *prop;
+	struct resource r;
+	int ret;
+
+	dn = pci_device_to_OF_node(mac->pdev);
+	ph = get_property(dn, "phy-handle", NULL);
+	if (!ph)
+		return -ENODEV;
+	phy_dn = of_find_node_by_phandle(*ph);
+
+	prop = get_property(phy_dn, "reg", NULL);
+	ret = of_address_to_resource(phy_dn->parent, 0, &r);
+	if (ret)
+		goto err;
+
+	phy_id = *prop;
+	snprintf(mac->phy_id, BUS_ID_SIZE, PHY_ID_FMT, (int)r.start, phy_id);
+
+	of_node_put(phy_dn);
+
+	mac->link = 0;
+	mac->speed = 0;
+	mac->duplex = -1;
+
+	phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII);
+
+	if (IS_ERR(phydev)) {
+		printk(KERN_ERR "%s: Could not attach to phy\n", dev->name);
+		return PTR_ERR(phydev);
+	}
+
+	mac->phydev = phydev;
+
+	return 0;
+
+err:
+	of_node_put(phy_dn);
+	return -ENODEV;
+}
+
+
 static int pasemi_mac_open(struct net_device *dev)
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
+	int base_irq;
 	unsigned int flags;
 	int ret;
 
@@ -558,10 +746,18 @@ static int pasemi_mac_open(struct net_device *dev)
 	flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G;
 
 	pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch),
-			       PAS_IOB_DMA_RXCH_CFG_CNTTH(30));
+			       PAS_IOB_DMA_RXCH_CFG_CNTTH(1));
 
+	pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch),
+			       PAS_IOB_DMA_TXCH_CFG_CNTTH(32));
+
+	/* Clear out any residual packet count state from firmware */
+	pasemi_mac_restart_rx_intr(mac);
+	pasemi_mac_restart_tx_intr(mac);
+
+	/* 0xffffff is max value, about 16ms */
 	pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
-			       PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000));
+			       PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff));
 
 	pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags);
 
@@ -595,31 +791,50 @@ static int pasemi_mac_open(struct net_device *dev)
 
 	pasemi_mac_replenish_rx_ring(dev);
 
+	ret = pasemi_mac_phy_init(dev);
+	/* Some configs don't have PHYs (XAUI etc), so don't complain about
+	 * failed init due to -ENODEV.
+	 */
+	if (ret && ret != -ENODEV)
+		dev_warn(&mac->pdev->dev, "phy init failed: %d\n", ret);
+
 	netif_start_queue(dev);
 	netif_poll_enable(dev);
 
-	ret = request_irq(mac->dma_pdev->irq + mac->dma_txch,
-			  &pasemi_mac_tx_intr, IRQF_DISABLED,
+	/* Interrupts are a bit different for our DMA controller: While
+	 * it's got one a regular PCI device header, the interrupt there
+	 * is really the base of the range it's using. Each tx and rx
+	 * channel has it's own interrupt source.
+	 */
+
+	base_irq = virq_to_hw(mac->dma_pdev->irq);
+
+	mac->tx_irq = irq_create_mapping(NULL, base_irq + mac->dma_txch);
+	mac->rx_irq = irq_create_mapping(NULL, base_irq + 20 + mac->dma_txch);
+
+	ret = request_irq(mac->tx_irq, &pasemi_mac_tx_intr, IRQF_DISABLED,
 			  mac->tx->irq_name, dev);
 	if (ret) {
 		dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
-		       mac->dma_pdev->irq + mac->dma_txch, ret);
+			base_irq + mac->dma_txch, ret);
 		goto out_tx_int;
 	}
 
-	ret = request_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch,
-			  &pasemi_mac_rx_intr, IRQF_DISABLED,
+	ret = request_irq(mac->rx_irq, &pasemi_mac_rx_intr, IRQF_DISABLED,
 			  mac->rx->irq_name, dev);
 	if (ret) {
 		dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n",
-		       mac->dma_pdev->irq + 20 + mac->dma_rxch, ret);
+			base_irq + 20 + mac->dma_rxch, ret);
 		goto out_rx_int;
 	}
 
+	if (mac->phydev)
+		phy_start(mac->phydev);
+
 	return 0;
 
 out_rx_int:
-	free_irq(mac->dma_pdev->irq + mac->dma_txch, dev);
+	free_irq(mac->tx_irq, dev);
 out_tx_int:
 	netif_poll_disable(dev);
 	netif_stop_queue(dev);
@@ -639,6 +854,11 @@ static int pasemi_mac_close(struct net_device *dev)
 	unsigned int stat;
 	int retries;
 
+	if (mac->phydev) {
+		phy_stop(mac->phydev);
+		phy_disconnect(mac->phydev);
+	}
+
 	netif_stop_queue(dev);
 
 	/* Clean out any pending buffers */
@@ -660,40 +880,37 @@ static int pasemi_mac_close(struct net_device *dev)
 		pci_read_config_dword(mac->dma_pdev,
 				      PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch),
 				      &stat);
-		if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
+		if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
 			break;
 		cond_resched();
 	}
 
-	if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)) {
+	if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
 		dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n");
-	}
 
 	for (retries = 0; retries < MAX_RETRIES; retries++) {
 		pci_read_config_dword(mac->dma_pdev,
 				      PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch),
 				      &stat);
-		if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)
+		if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT))
 			break;
 		cond_resched();
 	}
 
-	if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)) {
+	if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)
 		dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n");
-	}
 
 	for (retries = 0; retries < MAX_RETRIES; retries++) {
 		pci_read_config_dword(mac->dma_pdev,
 				      PAS_DMA_RXINT_RCMDSTA(mac->dma_if),
 				      &stat);
-		if (stat & PAS_DMA_RXINT_RCMDSTA_ACT)
+		if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT))
 			break;
 		cond_resched();
 	}
 
-	if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT)) {
+	if (stat & PAS_DMA_RXINT_RCMDSTA_ACT)
 		dev_err(&mac->dma_pdev->dev, "Failed to stop rx interface\n");
-	}
 
 	/* Then, disable the channel. This must be done separately from
 	 * stopping, since you can't disable when active.
@@ -706,8 +923,8 @@ static int pasemi_mac_close(struct net_device *dev)
 	pci_write_config_dword(mac->dma_pdev,
 			       PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0);
 
-	free_irq(mac->dma_pdev->irq + mac->dma_txch, dev);
-	free_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch, dev);
+	free_irq(mac->tx_irq, dev);
+	free_irq(mac->rx_irq, dev);
 
 	/* Free resources */
 	pasemi_mac_free_rx_resources(dev);
@@ -802,6 +1019,7 @@ static struct net_device_stats *pasemi_mac_get_stats(struct net_device *dev)
 	return &mac->stats;
 }
 
+
 static void pasemi_mac_set_rx_mode(struct net_device *dev)
 {
 	struct pasemi_mac *mac = netdev_priv(dev);
@@ -826,18 +1044,17 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget)
 
 	pkts = pasemi_mac_clean_rx(mac, limit);
 
+	dev->quota -= pkts;
+	*budget -= pkts;
+
 	if (pkts < limit) {
 		/* all done, no more packets present */
 		netif_rx_complete(dev);
 
-		/* re-enable receive interrupts */
-		pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG,
-				       PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000));
+		pasemi_mac_restart_rx_intr(mac);
 		return 0;
 	} else {
 		/* used up our quantum, so reschedule */
-		dev->quota -= pkts;
-		*budget -= pkts;
 		return 1;
 	}
 }
@@ -937,6 +1154,11 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 	mac->rx_status = &dma_status->rx_sta[mac->dma_rxch];
 	mac->tx_status = &dma_status->tx_sta[mac->dma_txch];
 
+	mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
+
+	/* Enable most messages by default */
+	mac->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
+
 	err = register_netdev(dev);
 
 	if (err) {
@@ -1011,9 +1233,5 @@ int pasemi_mac_init_module(void)
 	return pci_register_driver(&pasemi_mac_driver);
 }
 
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
-MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver");
-
 module_init(pasemi_mac_init_module);
 module_exit(pasemi_mac_cleanup_module);
diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h
index c3e37e4..8bc0cea 100644
--- a/drivers/net/pasemi_mac.h
+++ b/drivers/net/pasemi_mac.h
@@ -24,6 +24,7 @@
 #include <linux/ethtool.h>
 #include <linux/netdevice.h>
 #include <linux/spinlock.h>
+#include <linux/phy.h>
 
 struct pasemi_mac_txring {
 	spinlock_t	 lock;
@@ -54,6 +55,7 @@ struct pasemi_mac {
 	struct pci_dev *pdev;
 	struct pci_dev *dma_pdev;
 	struct pci_dev *iob_pdev;
+	struct phy_device *phydev;
 	struct net_device_stats stats;
 
 	/* Pointer to the cacheable per-channel status registers */
@@ -73,6 +75,14 @@ struct pasemi_mac {
 
 	struct pasemi_mac_txring *tx;
 	struct pasemi_mac_rxring *rx;
+	unsigned long	tx_irq;
+	unsigned long	rx_irq;
+	int	link;
+	int	speed;
+	int	duplex;
+
+	unsigned int	msg_enable;
+	char	phy_id[BUS_ID_SIZE];
 };
 
 /* Software status descriptor (desc_info) */
@@ -193,11 +203,15 @@ enum {
 #define PAS_DMA_RXINT_RCMDSTA(i)	(0x200+(i)*_PAS_DMA_RXINT_STRIDE)
 #define    PAS_DMA_RXINT_RCMDSTA_EN	0x00000001
 #define    PAS_DMA_RXINT_RCMDSTA_ST	0x00000002
-#define    PAS_DMA_RXINT_RCMDSTA_OO	0x00000100
-#define    PAS_DMA_RXINT_RCMDSTA_BP	0x00000200
-#define    PAS_DMA_RXINT_RCMDSTA_DR	0x00000400
+#define    PAS_DMA_RXINT_RCMDSTA_MBT	0x00000008
+#define    PAS_DMA_RXINT_RCMDSTA_MDR	0x00000010
+#define    PAS_DMA_RXINT_RCMDSTA_MOO	0x00000020
+#define    PAS_DMA_RXINT_RCMDSTA_MBP	0x00000040
 #define    PAS_DMA_RXINT_RCMDSTA_BT	0x00000800
-#define    PAS_DMA_RXINT_RCMDSTA_TB	0x00001000
+#define    PAS_DMA_RXINT_RCMDSTA_DR	0x00001000
+#define    PAS_DMA_RXINT_RCMDSTA_OO	0x00002000
+#define    PAS_DMA_RXINT_RCMDSTA_BP	0x00004000
+#define    PAS_DMA_RXINT_RCMDSTA_TB	0x00008000
 #define    PAS_DMA_RXINT_RCMDSTA_ACT	0x00010000
 #define    PAS_DMA_RXINT_RCMDSTA_DROPS_M	0xfffe0000
 #define    PAS_DMA_RXINT_RCMDSTA_DROPS_S	17
@@ -297,6 +311,7 @@ enum {
 #define    PAS_STATUS_DCNT_S		16
 #define    PAS_STATUS_BPCNT_M		0x0000ffff00000000ull
 #define    PAS_STATUS_BPCNT_S		32
+#define    PAS_STATUS_CAUSE_M		0xf000000000000000ull
 #define    PAS_STATUS_TIMER		0x1000000000000000ull
 #define    PAS_STATUS_ERROR		0x2000000000000000ull
 #define    PAS_STATUS_SOFT		0x4000000000000000ull
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index 809ec44..258d6f3 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1420,7 +1420,7 @@ set_addresses(struct net_device *dev)
     kio_addr_t ioaddr = dev->base_addr;
     local_info_t *lp = netdev_priv(dev);
     struct dev_mc_list *dmi = dev->mc_list;
-    char *addr;
+    unsigned char *addr;
     int i,j,k,n;
 
     SelectPage(k=0x50);
@@ -1429,6 +1429,9 @@ set_addresses(struct net_device *dev)
 	    if (++n > 9)
 		break;
 	    i = 0;
+	    if (n > 1 && n <= dev->mc_count && dmi) {
+	   	 dmi = dmi->next;
+	    }
 	}
 	if (j > 15) {
 	    j = 8;
@@ -1436,10 +1439,9 @@ set_addresses(struct net_device *dev)
 	    SelectPage(k);
 	}
 
-	if (n && n <= dev->mc_count && dmi) {
+	if (n && n <= dev->mc_count && dmi)
 	    addr = dmi->dmi_addr;
-	    dmi = dmi->next;
-	} else
+	else
 	    addr = dev->dev_addr;
 
 	if (lp->mohawk)
@@ -1465,10 +1467,10 @@ set_multicast_list(struct net_device *dev)
     if (dev->flags & IFF_PROMISC) { /* snoop */
 	PutByte(XIRCREG42_SWC1, 0x06); /* set MPE and PME */
     } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) {
-	PutByte(XIRCREG42_SWC1, 0x06); /* set MPE */
+	PutByte(XIRCREG42_SWC1, 0x02); /* set MPE */
     } else if (dev->mc_count) {
 	/* the chip can filter 9 addresses perfectly */
-	PutByte(XIRCREG42_SWC1, 0x00);
+	PutByte(XIRCREG42_SWC1, 0x01);
 	SelectPage(0x40);
 	PutByte(XIRCREG40_CMD0, Offline);
 	set_addresses(dev);
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 21afe10..b07da10 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -135,10 +135,13 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs,
 /* Wake on Lan only supported on Yukon chips with rev 1 or above */
 static u32 wol_supported(const struct skge_hw *hw)
 {
-	if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev != 0)
-		return WAKE_MAGIC | WAKE_PHY;
-	else
+	if (hw->chip_id == CHIP_ID_GENESIS)
 		return 0;
+
+	if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0)
+		return 0;
+
+	return WAKE_MAGIC | WAKE_PHY;
 }
 
 static u32 pci_wake_enabled(struct pci_dev *dev)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 238c2ca..a307310 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -124,10 +124,7 @@ static const struct pci_device_id sky2_id_table[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */
-#ifdef broken
-	/* This device causes data corruption problems that are not resolved */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */
-#endif
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */
@@ -3581,10 +3578,21 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
 		goto err_out;
 	}
 
+	/* Some Gigabyte motherboards have 88e8056 but cause problems
+	 * There is some unresolved hardware related problem that causes
+	 * descriptor errors and receive data corruption.
+	 */
+	if (pdev->vendor == PCI_VENDOR_ID_MARVELL &&
+	    pdev->device == 0x4364 && pdev->subsystem_vendor == 0x1458) {
+		dev_err(&pdev->dev,
+			"88E8056 on Gigabyte motherboards not supported\n");
+		goto err_out_disable;
+	}
+
 	err = pci_request_regions(pdev, DRV_NAME);
 	if (err) {
 		dev_err(&pdev->dev, "cannot obtain PCI resources\n");
-		goto err_out;
+		goto err_out_disable;
 	}
 
 	pci_set_master(pdev);
@@ -3721,6 +3729,7 @@ err_out_free_hw:
 	kfree(hw);
 err_out_free_regions:
 	pci_release_regions(pdev);
+err_out_disable:
 	pci_disable_device(pdev);
 err_out:
 	return err;
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 7053026..111f23d 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -279,6 +279,40 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg)
 #define SMC_insw(a, r, p, l)	insw((a) + (r), p, l)
 #define SMC_outsw(a, r, p, l)	outsw((a) + (r), p, l)
 
+#elif   defined(CONFIG_SUPERH)
+
+#if defined(CONFIG_SH_7780_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE)
+#define SMC_CAN_USE_8BIT       0
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      0
+#define SMC_IO_SHIFT           0
+#define SMC_NOWAIT             1
+
+#define SMC_inb(a, r)          (inw((a) + ((r)&~1)) >> (8*(r%2)))&0xff
+#define SMC_inw(a, r)          inw((a) + (r))
+#define SMC_outb(v, a, r)      outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) + ((r)&~1))
+
+#define SMC_outw(v, a, r)      outw(v, (a) + (r))
+#define SMC_insw(a, r, p, l)   insw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)  outsw((a) + (r), p, l)
+
+#else /* BOARDS */
+
+#define SMC_CAN_USE_8BIT       1
+#define SMC_CAN_USE_16BIT      1
+#define SMC_CAN_USE_32BIT      1
+
+#define SMC_inb(a, r)          inb((a) + (r))
+#define SMC_inw(a, r)          inw((a) + (r))
+#define SMC_outb(v, a, r)      outb(v, (a) + (r))
+#define SMC_outw(v, a, r)      outw(v, (a) + (r))
+#define SMC_insw(a, r, p, l)   insw((a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)  outsw((a) + (r), p, l)
+
+#endif  /* BOARDS */
+
+#define set_irq_type(irq, type) do {} while (0)
+
 #elif   defined(CONFIG_M32R)
 
 #define SMC_CAN_USE_8BIT	0
diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c
index f1e2dfc..463d600 100644
--- a/drivers/net/tc35815.c
+++ b/drivers/net/tc35815.c
@@ -540,7 +540,6 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev,
 	skb = dev_alloc_skb(RX_BUF_SIZE);
 	if (!skb)
 		return NULL;
-	skb->dev = dev;
 	*dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE,
 				     PCI_DMA_FROMDEVICE);
 	if (pci_dma_mapping_error(*dma_handle)) {
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 0184614..e273347 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -267,7 +267,7 @@ config IPW2200_DEBUG
 
 config LIBERTAS_USB
 	tristate "Marvell Libertas 8388 802.11a/b/g cards"
-	depends on NET_RADIO && USB
+	depends on USB && WLAN_80211
 	select FW_LOADER
 	---help---
 	  A driver for Marvell Libertas 8388 USB devices.
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index cba64e4..f770018 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -996,18 +996,25 @@ __qdio_outbound_processing(struct qdio_q *q)
 	if (qdio_has_outbound_q_moved(q))
 		qdio_kick_outbound_handler(q);
 
-	if (q->is_iqdio_q) {
+	if (q->queue_type == QDIO_ZFCP_QFMT) {
+		if ((!q->hydra_gives_outbound_pcis) &&
+		    (!qdio_is_outbound_q_done(q)))
+			qdio_mark_q(q);
+	}
+	else if (((!q->is_iqdio_q) && (!q->is_pci_out)) ||
+		 (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) {
 		/* 
-		 * for asynchronous queues, we better check, if the sent
-		 * buffer is already switched from PRIMED to EMPTY.
+		 * make sure buffer switch from PRIMED to EMPTY is noticed
+		 * and outbound_handler is called
 		 */
-		if ((q->queue_type == QDIO_IQDIO_QFMT_ASYNCH) &&
-		    !qdio_is_outbound_q_done(q))
-			qdio_mark_q(q);
-
-	} else if (!q->hydra_gives_outbound_pcis)
-		if (!qdio_is_outbound_q_done(q))
-			qdio_mark_q(q);
+		if (qdio_is_outbound_q_done(q)) {
+			del_timer(&q->timer);
+		} else {
+			if (!timer_pending(&q->timer))
+				mod_timer(&q->timer, jiffies +
+					  QDIO_FORCE_CHECK_TIMEOUT);
+		}
+	}
 
 	qdio_release_q(q);
 }
@@ -1826,6 +1833,7 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
 			q->queue_type = QDIO_IQDIO_QFMT_ASYNCH;
 		q->int_parm=int_parm;
 		q->is_input_q=0;
+		q->is_pci_out = 0;
 		q->schid = irq_ptr->schid;
 		q->cdev = cdev;
 		q->irq_ptr = irq_ptr;
@@ -1838,6 +1846,10 @@ qdio_fill_qs(struct qdio_irq *irq_ptr, struct ccw_device *cdev,
 		q->tasklet.data=(unsigned long)q;
 		q->tasklet.func=(void(*)(unsigned long))
 			&qdio_outbound_processing;
+		q->timer.function=(void(*)(unsigned long))
+			&qdio_outbound_processing;
+		q->timer.data = (long)q;
+		init_timer(&q->timer);
 
 		atomic_set(&q->busy_siga_counter,0);
 		q->timing.busy_start=0;
@@ -2635,6 +2647,7 @@ qdio_shutdown(struct ccw_device *cdev, int how)
 
 	for (i=0;i<irq_ptr->no_output_qs;i++) {
 		tasklet_kill(&irq_ptr->output_qs[i]->tasklet);
+		del_timer(&irq_ptr->output_qs[i]->timer);
 		wait_event_interruptible_timeout(cdev->private->wait_q,
 						 !atomic_read(&irq_ptr->
 							      output_qs[i]->
@@ -3458,6 +3471,10 @@ do_qdio_handle_outbound(struct qdio_q *q, unsigned int callflags,
 		qdio_perf_stat_inc(&perf_stats.outbound_cnt);
 		return;
 	}
+	if (callflags & QDIO_FLAG_PCI_OUT)
+		q->is_pci_out = 1;
+	else
+		q->is_pci_out = 0;
 	if (q->is_iqdio_q) {
 		/* one siga for every sbal */
 		while (count--)
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 2895392..6d7aad1 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -60,6 +60,7 @@
 #define QDIO_ACTIVATE_TIMEOUT ((5*HZ)>>10)
 #define QDIO_CLEANUP_CLEAR_TIMEOUT (20*HZ)
 #define QDIO_CLEANUP_HALT_TIMEOUT (10*HZ)
+#define QDIO_FORCE_CHECK_TIMEOUT (10*HZ)
 
 enum qdio_irq_states {
 	QDIO_IRQ_STATE_INACTIVE,
@@ -511,8 +512,8 @@ struct qdio_q {
 
 	void *irq_ptr;
 
-#ifdef QDIO_USE_TIMERS_FOR_POLLING
 	struct timer_list timer;
+#ifdef QDIO_USE_TIMERS_FOR_POLLING
 	atomic_t timer_already_set;
 	spinlock_t timer_lock;
 #else /* QDIO_USE_TIMERS_FOR_POLLING */
@@ -558,6 +559,7 @@ struct qdio_q {
 	} timing;
 	atomic_t busy_siga_counter;
         unsigned int queue_type;
+	unsigned int is_pci_out;
 
 	/* leave this member at the end. won't be cleared in qdio_fill_qs */
 	struct slib *slib; /* a page is allocated under this pointer,
diff --git a/drivers/s390/net/netiucv.c b/drivers/s390/net/netiucv.c
index e10e85e..c358764 100644
--- a/drivers/s390/net/netiucv.c
+++ b/drivers/s390/net/netiucv.c
@@ -1862,12 +1862,14 @@ static void netiucv_remove_connection(struct iucv_connection *conn)
 	write_lock_bh(&iucv_connection_rwlock);
 	list_del_init(&conn->list);
 	write_unlock_bh(&iucv_connection_rwlock);
+	fsm_deltimer(&conn->timer);
+	netiucv_purge_skb_queue(&conn->collect_queue);
 	if (conn->path) {
 		iucv_path_sever(conn->path, iucvMagic);
 		kfree(conn->path);
 		conn->path = NULL;
 	}
-	fsm_deltimer(&conn->timer);
+	netiucv_purge_skb_queue(&conn->commit_queue);
 	kfree_fsm(conn->fsm);
 	kfree_skb(conn->rx_buff);
 	kfree_skb(conn->tx_buff);
@@ -2115,7 +2117,6 @@ static void __exit netiucv_exit(void)
 	while (!list_empty(&iucv_connection_list)) {
 		cp = list_entry(iucv_connection_list.next,
 				struct iucv_connection, list);
-		list_del(&cp->list);
 		ndev = cp->netdev;
 		priv = netdev_priv(ndev);
 		dev = priv->dev;
diff --git a/drivers/s390/net/qeth_eddp.c b/drivers/s390/net/qeth_eddp.c
index dd7034f..4640f32 100644
--- a/drivers/s390/net/qeth_eddp.c
+++ b/drivers/s390/net/qeth_eddp.c
@@ -620,10 +620,10 @@ qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
 
 struct qeth_eddp_context *
 qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb,
-			 struct qeth_hdr *qhdr)
+			 struct qeth_hdr *qhdr, unsigned char sk_protocol)
 {
 	QETH_DBF_TEXT(trace, 5, "creddpc");
-	switch (skb->sk->sk_protocol){
+	switch (sk_protocol) {
 	case IPPROTO_TCP:
 		return qeth_eddp_create_context_tcp(card, skb, qhdr);
 	default:
diff --git a/drivers/s390/net/qeth_eddp.h b/drivers/s390/net/qeth_eddp.h
index 103768d..52910c9 100644
--- a/drivers/s390/net/qeth_eddp.h
+++ b/drivers/s390/net/qeth_eddp.h
@@ -34,7 +34,8 @@ struct qeth_eddp_context_reference {
 };
 
 extern struct qeth_eddp_context *
-qeth_eddp_create_context(struct qeth_card *,struct sk_buff *,struct qeth_hdr *);
+qeth_eddp_create_context(struct qeth_card *,struct sk_buff *,
+			 struct qeth_hdr *, unsigned char);
 
 extern void
 qeth_eddp_put_context(struct qeth_eddp_context *);
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 6fd8870..29d1760 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1682,6 +1682,21 @@ qeth_put_reply(struct qeth_reply *reply)
 		kfree(reply);
 }
 
+static void
+qeth_issue_ipa_msg(struct qeth_ipa_cmd *cmd, struct qeth_card *card)
+{
+	int rc;
+	int com;
+	char * ipa_name;
+
+	com = cmd->hdr.command;
+	rc  = cmd->hdr.return_code;
+	ipa_name = qeth_get_ipa_cmd_name(com);
+
+	PRINT_ERR("%s(x%X) for %s returned x%X \"%s\"\n", ipa_name, com,
+		   QETH_CARD_IFNAME(card), rc, qeth_get_ipa_msg(rc));
+}
+
 static struct qeth_ipa_cmd *
 qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
 {
@@ -1690,8 +1705,11 @@ qeth_check_ipa_data(struct qeth_card *card, struct qeth_cmd_buffer *iob)
 	QETH_DBF_TEXT(trace,5,"chkipad");
 	if (IS_IPA(iob->data)){
 		cmd = (struct qeth_ipa_cmd *) PDU_ENCAPSULATION(iob->data);
-		if (IS_IPA_REPLY(cmd))
+		if (IS_IPA_REPLY(cmd)) {
+			if (cmd->hdr.return_code)
+				qeth_issue_ipa_msg(cmd, card);
 			return cmd;
+		}
 		else {
 			switch (cmd->hdr.command) {
 			case IPA_CMD_STOPLAN:
@@ -2816,6 +2834,7 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
 	struct qeth_qdio_out_buffer *buf;
 	int rc;
 	int i;
+	unsigned int qdio_flags;
 
 	QETH_DBF_TEXT(trace, 6, "flushbuf");
 
@@ -2859,13 +2878,13 @@ qeth_flush_buffers(struct qeth_qdio_out_q *queue, int under_int,
 		queue->card->perf_stats.outbound_do_qdio_start_time =
 			qeth_get_micros();
 	}
+	qdio_flags = QDIO_FLAG_SYNC_OUTPUT;
 	if (under_int)
-		rc = do_QDIO(CARD_DDEV(queue->card),
-			     QDIO_FLAG_SYNC_OUTPUT | QDIO_FLAG_UNDER_INTERRUPT,
-			     queue->queue_no, index, count, NULL);
-	else
-		rc = do_QDIO(CARD_DDEV(queue->card), QDIO_FLAG_SYNC_OUTPUT,
-			     queue->queue_no, index, count, NULL);
+		qdio_flags |= QDIO_FLAG_UNDER_INTERRUPT;
+	if (atomic_read(&queue->set_pci_flags_count))
+		qdio_flags |= QDIO_FLAG_PCI_OUT;
+	rc = do_QDIO(CARD_DDEV(queue->card), qdio_flags,
+		     queue->queue_no, index, count, NULL);
 	if (queue->card->options.performance_stats)
 		queue->card->perf_stats.outbound_do_qdio_time +=
 			qeth_get_micros() -
@@ -4490,7 +4509,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
 		qeth_fill_header(card, hdr, new_skb, ipv, cast_type);
 	}
 	if (large_send == QETH_LARGE_SEND_EDDP) {
-		ctx = qeth_eddp_create_context(card, new_skb, hdr);
+		ctx = qeth_eddp_create_context(card, new_skb, hdr,
+					       skb->sk->sk_protocol);
 		if (ctx == NULL) {
 			__qeth_free_new_skb(skb, new_skb);
 			PRINT_WARN("could not create eddp context\n");
@@ -5948,9 +5968,6 @@ qeth_layer2_send_setmac_cb(struct qeth_card *card,
 	cmd = (struct qeth_ipa_cmd *) data;
 	if (cmd->hdr.return_code) {
 		QETH_DBF_TEXT_(trace, 2, "L2er%x", cmd->hdr.return_code);
-		PRINT_WARN("Error in registering MAC address on " \
-			   "device %s: x%x\n", CARD_BUS_ID(card),
-			   cmd->hdr.return_code);
 		card->info.mac_bits &= ~QETH_LAYER2_MAC_REGISTERED;
 		cmd->hdr.return_code = -EIO;
 	} else {
@@ -5985,9 +6002,6 @@ qeth_layer2_send_delmac_cb(struct qeth_card *card,
 	QETH_DBF_TEXT(trace, 2, "L2Dmaccb");
 	cmd = (struct qeth_ipa_cmd *) data;
 	if (cmd->hdr.return_code) {
-		PRINT_WARN("Error in deregistering MAC address on " \
-			   "device %s: x%x\n", CARD_BUS_ID(card),
-			   cmd->hdr.return_code);
 		QETH_DBF_TEXT_(trace, 2, "err%d", cmd->hdr.return_code);
 		cmd->hdr.return_code = -EIO;
 		return 0;
@@ -6651,7 +6665,7 @@ qeth_setadpparms_change_macaddr_cb(struct qeth_card *card,
 	QETH_DBF_TEXT(trace,4,"chgmaccb");
 
 	cmd = (struct qeth_ipa_cmd *) data;
-	if (!card->options.layer2 || card->info.guestlan ||
+	if (!card->options.layer2 ||
 	    !(card->info.mac_bits & QETH_LAYER2_MAC_READ)) {
 		memcpy(card->dev->dev_addr,
 		       &cmd->data.setadapterparms.data.change_addr.addr,
@@ -8497,6 +8511,7 @@ __qeth_reboot_event_card(struct device *dev, void *data)
 	card = (struct qeth_card *) dev->driver_data;
 	qeth_clear_ip_list(card, 0, 0);
 	qeth_qdio_clear_card(card, 0);
+	qeth_clear_qdio_buffers(card);
 	return 0;
 }
 
diff --git a/drivers/s390/net/qeth_mpc.c b/drivers/s390/net/qeth_mpc.c
index 77c8320..f54fdfd 100644
--- a/drivers/s390/net/qeth_mpc.c
+++ b/drivers/s390/net/qeth_mpc.c
@@ -157,12 +157,113 @@ unsigned char READ_CCW[]={
 };
 
 
+struct ipa_rc_msg {
+	enum qeth_ipa_return_codes rc;
+	char *msg;
+};
 
+struct ipa_rc_msg qeth_ipa_rc_msg[] = {
+	{IPA_RC_SUCCESS,		"success"},
+	{IPA_RC_NOTSUPP,		"Command not supported"},
+	{IPA_RC_IP_TABLE_FULL,		"Add Addr IP Table Full - ipv6"},
+	{IPA_RC_UNKNOWN_ERROR,		"IPA command failed - reason unknown"},
+	{IPA_RC_UNSUPPORTED_COMMAND,	"Command not supported"},
+	{IPA_RC_DUP_IPV6_REMOTE,"ipv6 address already registered remote"},
+	{IPA_RC_DUP_IPV6_HOME,		"ipv6 address already registered"},
+	{IPA_RC_UNREGISTERED_ADDR,	"Address not registered"},
+	{IPA_RC_NO_ID_AVAILABLE,	"No identifiers available"},
+	{IPA_RC_ID_NOT_FOUND,		"Identifier not found"},
+	{IPA_RC_INVALID_IP_VERSION,	"IP version incorrect"},
+	{IPA_RC_LAN_FRAME_MISMATCH,	"LAN and frame mismatch"},
+	{IPA_RC_L2_UNSUPPORTED_CMD,	"Unsupported layer 2 command"},
+	{IPA_RC_L2_DUP_MAC,		"Duplicate MAC address"},
+	{IPA_RC_L2_ADDR_TABLE_FULL,	"Layer2 address table full"},
+	{IPA_RC_L2_DUP_LAYER3_MAC,	"Duplicate with layer 3 MAC"},
+	{IPA_RC_L2_GMAC_NOT_FOUND,	"GMAC not found"},
+	{IPA_RC_L2_MAC_NOT_FOUND,	"L2 mac address not found"},
+	{IPA_RC_L2_INVALID_VLAN_ID,	"L2 invalid vlan id"},
+	{IPA_RC_L2_DUP_VLAN_ID,		"L2 duplicate vlan id"},
+	{IPA_RC_L2_VLAN_ID_NOT_FOUND,	"L2 vlan id not found"},
+	{IPA_RC_DATA_MISMATCH,		"Data field mismatch (v4/v6 mixed)"},
+	{IPA_RC_INVALID_MTU_SIZE,	"Invalid MTU size"},
+	{IPA_RC_INVALID_LANTYPE,	"Invalid LAN type"},
+	{IPA_RC_INVALID_LANNUM,		"Invalid LAN num"},
+	{IPA_RC_DUPLICATE_IP_ADDRESS,	"Address already registered"},
+	{IPA_RC_IP_ADDR_TABLE_FULL,	"IP address table full"},
+	{IPA_RC_LAN_PORT_STATE_ERROR,	"LAN port state error"},
+	{IPA_RC_SETIP_NO_STARTLAN,	"Setip no startlan received"},
+	{IPA_RC_SETIP_ALREADY_RECEIVED,	"Setip already received"},
+	{IPA_RC_IP_ADDR_ALREADY_USED,	"IP address already in use on LAN"},
+	{IPA_RC_MULTICAST_FULL,		"No task available, multicast full"},
+	{IPA_RC_SETIP_INVALID_VERSION,	"SETIP invalid IP version"},
+	{IPA_RC_UNSUPPORTED_SUBCMD,	"Unsupported assist subcommand"},
+	{IPA_RC_ARP_ASSIST_NO_ENABLE,	"Only partial success, no enable"},
+	{IPA_RC_PRIMARY_ALREADY_DEFINED,"Primary already defined"},
+	{IPA_RC_SECOND_ALREADY_DEFINED,	"Secondary already defined"},
+	{IPA_RC_INVALID_SETRTG_INDICATOR,"Invalid SETRTG indicator"},
+	{IPA_RC_MC_ADDR_ALREADY_DEFINED,"Multicast address already defined"},
+	{IPA_RC_LAN_OFFLINE,		"STRTLAN_LAN_DISABLED - LAN offline"},
+	{IPA_RC_INVALID_IP_VERSION2,	"Invalid IP version"},
+	{IPA_RC_FFFF,			"Unknown Error"}
+};
 
 
 
+char *
+qeth_get_ipa_msg(enum qeth_ipa_return_codes rc)
+{
+	int x = 0;
+	qeth_ipa_rc_msg[sizeof(qeth_ipa_rc_msg) /
+			sizeof(struct ipa_rc_msg) - 1].rc = rc;
+	while(qeth_ipa_rc_msg[x].rc != rc)
+		x++;
+	return qeth_ipa_rc_msg[x].msg;
+}
 
 
+struct ipa_cmd_names {
+	enum qeth_ipa_cmds cmd;
+	char *name;
+};
+
+struct ipa_cmd_names qeth_ipa_cmd_names[] = {
+	{IPA_CMD_STARTLAN,	"startlan"},
+	{IPA_CMD_STOPLAN,	"stoplan"},
+	{IPA_CMD_SETVMAC,	"setvmac"},
+	{IPA_CMD_DELVMAC,	"delvmca"},
+	{IPA_CMD_SETGMAC,	"setgmac"},
+	{IPA_CMD_DELGMAC,	"delgmac"},
+	{IPA_CMD_SETVLAN,	"setvlan"},
+	{IPA_CMD_DELVLAN,	"delvlan"},
+	{IPA_CMD_SETCCID,	"setccid"},
+	{IPA_CMD_DELCCID,	"delccid"},
+	{IPA_CMD_MODCCID,	"setip"},
+	{IPA_CMD_SETIP,		"setip"},
+	{IPA_CMD_QIPASSIST,	"qipassist"},
+	{IPA_CMD_SETASSPARMS,	"setassparms"},
+	{IPA_CMD_SETIPM,	"setipm"},
+	{IPA_CMD_DELIPM,	"delipm"},
+	{IPA_CMD_SETRTG,	"setrtg"},
+	{IPA_CMD_DELIP,		"delip"},
+	{IPA_CMD_SETADAPTERPARMS, "setadapterparms"},
+	{IPA_CMD_SET_DIAG_ASS,	"set_diag_ass"},
+	{IPA_CMD_CREATE_ADDR,	"create_addr"},
+	{IPA_CMD_DESTROY_ADDR,	"destroy_addr"},
+	{IPA_CMD_REGISTER_LOCAL_ADDR,	"register_local_addr"},
+	{IPA_CMD_UNREGISTER_LOCAL_ADDR,	"unregister_local_addr"},
+	{IPA_CMD_UNKNOWN,	"unknown"},
+};
 
+char *
+qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd)
+{
+	int x = 0;
+	qeth_ipa_cmd_names[
+		sizeof(qeth_ipa_cmd_names)/
+			sizeof(struct ipa_cmd_names)-1].cmd = cmd;
+	while(qeth_ipa_cmd_names[x].cmd != cmd)
+		x++;
+	return qeth_ipa_cmd_names[x].name;
+}
 
 
diff --git a/drivers/s390/net/qeth_mpc.h b/drivers/s390/net/qeth_mpc.h
index d74bc43..1d8083c 100644
--- a/drivers/s390/net/qeth_mpc.h
+++ b/drivers/s390/net/qeth_mpc.h
@@ -25,14 +25,14 @@ extern unsigned char IPA_PDU_HEADER[];
 
 #define IPA_CMD_LENGTH	(IPA_PDU_HEADER_SIZE + sizeof(struct qeth_ipa_cmd))
 
-#define QETH_SEQ_NO_LENGTH 	4
-#define QETH_MPC_TOKEN_LENGTH 	4
+#define QETH_SEQ_NO_LENGTH	4
+#define QETH_MPC_TOKEN_LENGTH	4
 #define QETH_MCL_LENGTH		4
 #define OSA_ADDR_LEN		6
 
-#define QETH_TIMEOUT 		(10 * HZ)
-#define QETH_IPA_TIMEOUT 	(45 * HZ)
-#define QETH_IDX_COMMAND_SEQNO 	0xffff0000
+#define QETH_TIMEOUT		(10 * HZ)
+#define QETH_IPA_TIMEOUT	(45 * HZ)
+#define QETH_IDX_COMMAND_SEQNO	0xffff0000
 #define SR_INFO_LEN		16
 
 #define QETH_CLEAR_CHANNEL_PARM	-10
@@ -93,79 +93,107 @@ enum qeth_checksum_types {
  */
 #define RESET_ROUTING_FLAG 0x10 /* indicate that routing type shall be set */
 enum qeth_routing_types {
-	NO_ROUTER           = 0, /* TODO: set to bit flag used in IPA Command */
-	PRIMARY_ROUTER      = 1,
-	SECONDARY_ROUTER    = 2,
-	MULTICAST_ROUTER    = 3,
-	PRIMARY_CONNECTOR   = 4,
-	SECONDARY_CONNECTOR = 5,
+	NO_ROUTER		= 0, /* TODO: set to bit flag used in IPA Command */
+	PRIMARY_ROUTER		= 1,
+	SECONDARY_ROUTER	= 2,
+	MULTICAST_ROUTER	= 3,
+	PRIMARY_CONNECTOR	= 4,
+	SECONDARY_CONNECTOR	= 5,
 };
 
-
 /* IPA Commands */
 enum qeth_ipa_cmds {
-	IPA_CMD_STARTLAN              = 0x01,
-	IPA_CMD_STOPLAN               = 0x02,
-	IPA_CMD_SETVMAC 	      = 0x21,
-	IPA_CMD_DELVMAC 	      =	0x22,
-	IPA_CMD_SETGMAC  	      = 0x23,
-	IPA_CMD_DELGMAC 	      = 0x24,
-	IPA_CMD_SETVLAN 	      = 0x25,
-	IPA_CMD_DELVLAN 	      = 0x26,
-	IPA_CMD_SETCCID               = 0x41,
-	IPA_CMD_DELCCID               = 0x42,
-	IPA_CMD_MODCCID               = 0x43,
-	IPA_CMD_SETIP                 = 0xb1,
-	IPA_CMD_DELIP                 = 0xb7,
-	IPA_CMD_QIPASSIST             = 0xb2,
-	IPA_CMD_SETASSPARMS           = 0xb3,
-	IPA_CMD_SETIPM                = 0xb4,
-	IPA_CMD_DELIPM                = 0xb5,
-	IPA_CMD_SETRTG                = 0xb6,
-	IPA_CMD_SETADAPTERPARMS       = 0xb8,
-	IPA_CMD_IPFRAME               = 0xb9,
-	IPA_CMD_ADD_ADDR_ENTRY        = 0xc1,
-	IPA_CMD_DELETE_ADDR_ENTRY     = 0xc2,
-	IPA_CMD_CREATE_ADDR           = 0xc3,
-	IPA_CMD_DESTROY_ADDR          = 0xc4,
-	IPA_CMD_REGISTER_LOCAL_ADDR   = 0xd1,
-	IPA_CMD_UNREGISTER_LOCAL_ADDR = 0xd2,
+	IPA_CMD_STARTLAN		= 0x01,
+	IPA_CMD_STOPLAN			= 0x02,
+	IPA_CMD_SETVMAC			= 0x21,
+	IPA_CMD_DELVMAC			= 0x22,
+	IPA_CMD_SETGMAC			= 0x23,
+	IPA_CMD_DELGMAC			= 0x24,
+	IPA_CMD_SETVLAN			= 0x25,
+	IPA_CMD_DELVLAN			= 0x26,
+	IPA_CMD_SETCCID			= 0x41,
+	IPA_CMD_DELCCID			= 0x42,
+	IPA_CMD_MODCCID			= 0x43,
+	IPA_CMD_SETIP			= 0xb1,
+	IPA_CMD_QIPASSIST		= 0xb2,
+	IPA_CMD_SETASSPARMS		= 0xb3,
+	IPA_CMD_SETIPM			= 0xb4,
+	IPA_CMD_DELIPM			= 0xb5,
+	IPA_CMD_SETRTG			= 0xb6,
+	IPA_CMD_DELIP			= 0xb7,
+	IPA_CMD_SETADAPTERPARMS		= 0xb8,
+	IPA_CMD_SET_DIAG_ASS		= 0xb9,
+	IPA_CMD_CREATE_ADDR		= 0xc3,
+	IPA_CMD_DESTROY_ADDR		= 0xc4,
+	IPA_CMD_REGISTER_LOCAL_ADDR	= 0xd1,
+	IPA_CMD_UNREGISTER_LOCAL_ADDR	= 0xd2,
+	IPA_CMD_UNKNOWN			= 0x00
 };
 
 enum qeth_ip_ass_cmds {
 	IPA_CMD_ASS_START	= 0x0001,
 	IPA_CMD_ASS_STOP	= 0x0002,
-	IPA_CMD_ASS_CONFIGURE 	= 0x0003,
-	IPA_CMD_ASS_ENABLE 	= 0x0004,
+	IPA_CMD_ASS_CONFIGURE	= 0x0003,
+	IPA_CMD_ASS_ENABLE	= 0x0004,
 };
 
 enum qeth_arp_process_subcmds {
-	IPA_CMD_ASS_ARP_SET_NO_ENTRIES 	= 0x0003,
-	IPA_CMD_ASS_ARP_QUERY_CACHE 	= 0x0004,
-	IPA_CMD_ASS_ARP_ADD_ENTRY 	= 0x0005,
-	IPA_CMD_ASS_ARP_REMOVE_ENTRY 	= 0x0006,
-	IPA_CMD_ASS_ARP_FLUSH_CACHE 	= 0x0007,
-	IPA_CMD_ASS_ARP_QUERY_INFO 	= 0x0104,
-	IPA_CMD_ASS_ARP_QUERY_STATS 	= 0x0204,
+	IPA_CMD_ASS_ARP_SET_NO_ENTRIES	= 0x0003,
+	IPA_CMD_ASS_ARP_QUERY_CACHE	= 0x0004,
+	IPA_CMD_ASS_ARP_ADD_ENTRY	= 0x0005,
+	IPA_CMD_ASS_ARP_REMOVE_ENTRY	= 0x0006,
+	IPA_CMD_ASS_ARP_FLUSH_CACHE	= 0x0007,
+	IPA_CMD_ASS_ARP_QUERY_INFO	= 0x0104,
+	IPA_CMD_ASS_ARP_QUERY_STATS	= 0x0204,
 };
 
-/* Return Codes for IPA Commands */
+
+/* Return Codes for IPA Commands
+ * according to OSA card Specs */
+
 enum qeth_ipa_return_codes {
-	IPA_RC_SUCCESS             = 0x0000,
-	IPA_RC_NOTSUPP             = 0x0001,
-	IPA_RC_NO_ACCESS           = 0x0002,
-	IPA_RC_FAILED              = 0x0003,
-	IPA_RC_DATA_MISMATCH       = 0xe001,
-	IPA_RC_INVALID_LAN_TYPE    = 0xe003,
-	IPA_RC_INVALID_LAN_NO      = 0xe004,
-	IPA_RC_IPADDR_ALREADY_REG  = 0xe005,
-	IPA_RC_IPADDR_TABLE_FULL   = 0xe006,
-	IPA_RC_IPADDR_ALREADY_USED = 0xe00a,
-	IPA_RC_ASSNO_NOT_SUPP      = 0xe00d,
-	IPA_RC_ASSCMD_START_FAILED = 0xe00e,
-	IPA_RC_ASSCMD_PART_SUCCESS = 0xe00f,
-	IPA_RC_IPADDR_NOT_DEFINED  = 0xe010,
-	IPA_RC_LAN_OFFLINE         = 0xe080,
+	IPA_RC_SUCCESS			= 0x0000,
+	IPA_RC_NOTSUPP			= 0x0001,
+	IPA_RC_IP_TABLE_FULL		= 0x0002,
+	IPA_RC_UNKNOWN_ERROR		= 0x0003,
+	IPA_RC_UNSUPPORTED_COMMAND	= 0x0004,
+	IPA_RC_DUP_IPV6_REMOTE		= 0x0008,
+	IPA_RC_DUP_IPV6_HOME		= 0x0010,
+	IPA_RC_UNREGISTERED_ADDR	= 0x0011,
+	IPA_RC_NO_ID_AVAILABLE		= 0x0012,
+	IPA_RC_ID_NOT_FOUND		= 0x0013,
+	IPA_RC_INVALID_IP_VERSION	= 0x0020,
+	IPA_RC_LAN_FRAME_MISMATCH	= 0x0040,
+	IPA_RC_L2_UNSUPPORTED_CMD	= 0x2003,
+	IPA_RC_L2_DUP_MAC		= 0x2005,
+	IPA_RC_L2_ADDR_TABLE_FULL	= 0x2006,
+	IPA_RC_L2_DUP_LAYER3_MAC	= 0x200a,
+	IPA_RC_L2_GMAC_NOT_FOUND	= 0x200b,
+	IPA_RC_L2_MAC_NOT_FOUND		= 0x2010,
+	IPA_RC_L2_INVALID_VLAN_ID	= 0x2015,
+	IPA_RC_L2_DUP_VLAN_ID		= 0x2016,
+	IPA_RC_L2_VLAN_ID_NOT_FOUND	= 0x2017,
+	IPA_RC_DATA_MISMATCH		= 0xe001,
+	IPA_RC_INVALID_MTU_SIZE		= 0xe002,
+	IPA_RC_INVALID_LANTYPE		= 0xe003,
+	IPA_RC_INVALID_LANNUM		= 0xe004,
+	IPA_RC_DUPLICATE_IP_ADDRESS	= 0xe005,
+	IPA_RC_IP_ADDR_TABLE_FULL	= 0xe006,
+	IPA_RC_LAN_PORT_STATE_ERROR	= 0xe007,
+	IPA_RC_SETIP_NO_STARTLAN	= 0xe008,
+	IPA_RC_SETIP_ALREADY_RECEIVED	= 0xe009,
+	IPA_RC_IP_ADDR_ALREADY_USED	= 0xe00a,
+	IPA_RC_MULTICAST_FULL		= 0xe00b,
+	IPA_RC_SETIP_INVALID_VERSION	= 0xe00d,
+	IPA_RC_UNSUPPORTED_SUBCMD	= 0xe00e,
+	IPA_RC_ARP_ASSIST_NO_ENABLE	= 0xe00f,
+	IPA_RC_PRIMARY_ALREADY_DEFINED	= 0xe010,
+	IPA_RC_SECOND_ALREADY_DEFINED	= 0xe011,
+	IPA_RC_INVALID_SETRTG_INDICATOR	= 0xe012,
+	IPA_RC_MC_ADDR_ALREADY_DEFINED	= 0xe013,
+	IPA_RC_LAN_OFFLINE		= 0xe080,
+	IPA_RC_INVALID_IP_VERSION2	= 0xf001,
+	IPA_RC_FFFF			= 0xffff
 };
 
 /* IPA function flags; each flag marks availability of respective function */
@@ -183,7 +211,9 @@ enum qeth_ipa_funcs {
 	IPA_SETADAPTERPARMS     = 0x00000400L,
 	IPA_VLAN_PRIO           = 0x00000800L,
 	IPA_PASSTHRU            = 0x00001000L,
+	IPA_FLUSH_ARP_SUPPORT   = 0x00002000L,
 	IPA_FULL_VLAN           = 0x00004000L,
+	IPA_INBOUND_PASSTHRU    = 0x00008000L,
 	IPA_SOURCE_MAC          = 0x00010000L,
 	IPA_OSA_MC_ROUTER       = 0x00020000L,
 	IPA_QUERY_ARP_ASSIST	= 0x00040000L,
@@ -204,31 +234,30 @@ enum qeth_ipa_setdelip_flags {
 /* SETADAPTER IPA Command: ****************************************************/
 enum qeth_ipa_setadp_cmd {
 	IPA_SETADP_QUERY_COMMANDS_SUPPORTED	= 0x01,
-	IPA_SETADP_ALTER_MAC_ADDRESS 		= 0x02,
-	IPA_SETADP_ADD_DELETE_GROUP_ADDRESS 	= 0x04,
-	IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR 	= 0x08,
-	IPA_SETADP_SET_ADDRESSING_MODE 		= 0x10,
-	IPA_SETADP_SET_CONFIG_PARMS 		= 0x20,
-	IPA_SETADP_SET_CONFIG_PARMS_EXTENDED 	= 0x40,
-	IPA_SETADP_SET_BROADCAST_MODE 		= 0x80,
-	IPA_SETADP_SEND_OSA_MESSAGE 		= 0x0100,
-	IPA_SETADP_SET_SNMP_CONTROL 		= 0x0200,
-	IPA_SETADP_READ_SNMP_PARMS 		= 0x0400,
+	IPA_SETADP_ALTER_MAC_ADDRESS		= 0x02,
+	IPA_SETADP_ADD_DELETE_GROUP_ADDRESS	= 0x04,
+	IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR	= 0x08,
+	IPA_SETADP_SET_ADDRESSING_MODE		= 0x10,
+	IPA_SETADP_SET_CONFIG_PARMS		= 0x20,
+	IPA_SETADP_SET_CONFIG_PARMS_EXTENDED	= 0x40,
+	IPA_SETADP_SET_BROADCAST_MODE		= 0x80,
+	IPA_SETADP_SEND_OSA_MESSAGE		= 0x0100,
+	IPA_SETADP_SET_SNMP_CONTROL		= 0x0200,
+	IPA_SETADP_QUERY_CARD_INFO		= 0x0400,
 	IPA_SETADP_SET_PROMISC_MODE		= 0x0800,
-	IPA_SETADP_QUERY_CARD_INFO 		= 0x1000,
 };
 enum qeth_ipa_mac_ops {
-	CHANGE_ADDR_READ_MAC 		= 0,
-	CHANGE_ADDR_REPLACE_MAC 	= 1,
-	CHANGE_ADDR_ADD_MAC 		= 2,
-	CHANGE_ADDR_DEL_MAC 		= 4,
-	CHANGE_ADDR_RESET_MAC 		= 8,
+	CHANGE_ADDR_READ_MAC		= 0,
+	CHANGE_ADDR_REPLACE_MAC		= 1,
+	CHANGE_ADDR_ADD_MAC		= 2,
+	CHANGE_ADDR_DEL_MAC		= 4,
+	CHANGE_ADDR_RESET_MAC		= 8,
 };
 enum qeth_ipa_addr_ops {
-	CHANGE_ADDR_READ_ADDR 		= 0,
-	CHANGE_ADDR_ADD_ADDR 		= 1,
-	CHANGE_ADDR_DEL_ADDR 		= 2,
-	CHANGE_ADDR_FLUSH_ADDR_TABLE 	= 4,
+	CHANGE_ADDR_READ_ADDR		= 0,
+	CHANGE_ADDR_ADD_ADDR		= 1,
+	CHANGE_ADDR_DEL_ADDR		= 2,
+	CHANGE_ADDR_FLUSH_ADDR_TABLE	= 4,
 };
 enum qeth_ipa_promisc_modes {
 	SET_PROMISC_MODE_OFF		= 0,
@@ -407,15 +436,15 @@ struct qeth_ipacmd_hdr {
 struct qeth_ipa_cmd {
 	struct qeth_ipacmd_hdr hdr;
 	union {
-		struct qeth_ipacmd_setdelip4   		setdelip4;
-		struct qeth_ipacmd_setdelip6   		setdelip6;
+		struct qeth_ipacmd_setdelip4		setdelip4;
+		struct qeth_ipacmd_setdelip6		setdelip6;
 		struct qeth_ipacmd_setdelipm		setdelipm;
-		struct qeth_ipacmd_setassparms 		setassparms;
-		struct qeth_ipacmd_layer2setdelmac  	setdelmac;
-		struct qeth_ipacmd_layer2setdelvlan 	setdelvlan;
-		struct qeth_create_destroy_address 	create_destroy_addr;
-		struct qeth_ipacmd_setadpparms 		setadapterparms;
-		struct qeth_set_routing 		setrtg;
+		struct qeth_ipacmd_setassparms		setassparms;
+		struct qeth_ipacmd_layer2setdelmac	setdelmac;
+		struct qeth_ipacmd_layer2setdelvlan	setdelvlan;
+		struct qeth_create_destroy_address	create_destroy_addr;
+		struct qeth_ipacmd_setadpparms		setadapterparms;
+		struct qeth_set_routing			setrtg;
 	} data;
 } __attribute__ ((packed));
 
@@ -433,6 +462,12 @@ enum qeth_ipa_arp_return_codes {
 	QETH_IPA_ARP_RC_Q_NO_DATA    = 0x0008,
 };
 
+
+extern char *
+qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
+extern char *
+qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
+
 #define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
 			       sizeof(struct qeth_ipacmd_setassparms_hdr))
 #define QETH_IPA_ARP_DATA_POS(buffer) (buffer + IPA_PDU_HEADER_SIZE + \
@@ -521,7 +556,7 @@ extern unsigned char DM_ACT[];
 extern unsigned char IDX_ACTIVATE_READ[];
 extern unsigned char IDX_ACTIVATE_WRITE[];
 
-#define IDX_ACTIVATE_SIZE 	0x22
+#define IDX_ACTIVATE_SIZE	0x22
 #define QETH_IDX_ACT_ISSUER_RM_TOKEN(buffer) (buffer+0x0c)
 #define QETH_IDX_NO_PORTNAME_REQUIRED(buffer) ((buffer)[0x0b]&0x80)
 #define QETH_IDX_ACT_FUNC_LEVEL(buffer) (buffer+0x10)
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index d518419..65ffc21 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -384,8 +384,6 @@ qeth_dev_route_store(struct qeth_card *card, struct qeth_routing_info *route,
 		route->type = PRIMARY_CONNECTOR;
 	} else if (!strcmp(tmp, "secondary_connector")) {
 		route->type = SECONDARY_CONNECTOR;
-	} else if (!strcmp(tmp, "multicast_router")) {
-		route->type = MULTICAST_ROUTER;
 	} else if (!strcmp(tmp, "primary_router")) {
 		route->type = PRIMARY_ROUTER;
 	} else if (!strcmp(tmp, "secondary_router")) {
diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h
index 127f72e..74db1dc 100644
--- a/include/asm-s390/qdio.h
+++ b/include/asm-s390/qdio.h
@@ -120,6 +120,7 @@ extern unsigned long qdio_get_status(int irq);
 #define QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT 0x08 /* no effect on
 						     adapter interrupts */
 #define QDIO_FLAG_DONT_SIGA 0x10
+#define QDIO_FLAG_PCI_OUT   0x20
 
 extern int do_QDIO(struct ccw_device*, unsigned int flags, 
 		   unsigned int queue_number,

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-04-29 16:19 Jeff Garzik
@ 2007-04-29 16:21 ` Christoph Hellwig
  0 siblings, 0 replies; 101+ messages in thread
From: Christoph Hellwig @ 2007-04-29 16:21 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev, LKML, akpm, torvalds

On Sun, Apr 29, 2007 at 12:19:01PM -0400, Jeff Garzik wrote:
> 
> (just sent this upstream to Linus and Andrew)
> 
> The only really notable thing is the merging of the wireless driver for
> the OLPC, libertas.

I don't think it's quite ready yet, at least I've got no feedback about
completion of the todo list of obvious items I sent out a while ago.
Nor has an updated patchset been posted to lkml.


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-04-29 16:19 Jeff Garzik
  2007-04-29 16:21 ` Christoph Hellwig
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2007-04-29 16:19 UTC (permalink / raw)
  To: netdev; +Cc: LKML


(just sent this upstream to Linus and Andrew)

The only really notable thing is the merging of the wireless driver for
the OLPC, libertas.
 
Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 Documentation/DocBook/kernel-api.tmpl          |    6 +
 Documentation/networking/bcm43xx.txt           |   97 +-
 MAINTAINERS                                    |   20 +-
 arch/mips/mips-boards/sim/Makefile             |    3 +-
 arch/mips/mips-boards/sim/sim_platform.c       |   35 +
 arch/powerpc/sysdev/qe_lib/ucc_fast.c          |    3 +
 crypto/michael_mic.c                           |    4 +-
 drivers/net/3c509.c                            |    1 -
 drivers/net/Kconfig                            |   15 +-
 drivers/net/Makefile                           |    2 +-
 drivers/net/chelsio/Makefile                   |    4 +-
 drivers/net/chelsio/common.h                   |    6 +-
 drivers/net/chelsio/cphy.h                     |   16 +-
 drivers/net/chelsio/gmac.h                     |   10 +-
 drivers/net/chelsio/ixf1010.c                  |  505 -----
 drivers/net/chelsio/mac.c                      |    2 +-
 drivers/net/chelsio/mv88e1xxx.c                |    8 +-
 drivers/net/chelsio/mv88x201x.c                |    8 +-
 drivers/net/chelsio/my3126.c                   |    8 +-
 drivers/net/chelsio/pm3393.c                   |    8 +-
 drivers/net/chelsio/subr.c                     |  199 ++-
 drivers/net/chelsio/vsc7326.c                  |    2 +-
 drivers/net/chelsio/vsc8244.c                  |  367 ----
 drivers/net/chelsio/vsc8244_reg.h              |  172 --
 drivers/net/e100.c                             |  159 +-
 drivers/net/e1000/e1000.h                      |    3 -
 drivers/net/e1000/e1000_ethtool.c              |   34 +-
 drivers/net/e1000/e1000_main.c                 |   45 +-
 drivers/net/e1000/e1000_param.c                |    4 +-
 drivers/net/eexpress.c                         |    9 +-
 drivers/net/ehea/ehea.h                        |   42 +-
 drivers/net/ehea/ehea_ethtool.c                |  115 +-
 drivers/net/ehea/ehea_main.c                   |  940 +++++---
 drivers/net/ehea/ehea_phyp.c                   |    6 +-
 drivers/net/ehea/ehea_phyp.h                   |    6 +-
 drivers/net/ehea/ehea_qmr.c                    |  184 ++-
 drivers/net/ehea/ehea_qmr.h                    |   16 +-
 drivers/net/hamradio/baycom_ser_fdx.c          |   13 +-
 drivers/net/ibmveth.c                          |   10 +-
 drivers/net/ixgb/ixgb.h                        |    3 -
 drivers/net/ixgb/ixgb_ethtool.c                |    4 +-
 drivers/net/ixgb/ixgb_main.c                   |    4 +-
 drivers/net/ixgb/ixgb_param.c                  |    8 +-
 drivers/net/mii.c                              |   57 +
 drivers/net/mipsnet.c                          |   53 +-
 drivers/net/mv643xx_eth.c                      |   59 +-
 drivers/net/mv643xx_eth.h                      |    4 -
 drivers/net/netxen/netxen_nic.h                |  189 +-
 drivers/net/netxen/netxen_nic_ethtool.c        |  212 ++-
 drivers/net/netxen/netxen_nic_hdr.h            |   12 +
 drivers/net/netxen/netxen_nic_hw.c             |  401 +++-
 drivers/net/netxen/netxen_nic_hw.h             |   85 +-
 drivers/net/netxen/netxen_nic_init.c           |  130 +-
 drivers/net/netxen/netxen_nic_isr.c            |  101 +-
 drivers/net/netxen/netxen_nic_main.c           |  769 ++++---
 drivers/net/netxen/netxen_nic_niu.c            |  168 +-
 drivers/net/netxen/netxen_nic_phan_reg.h       |  134 +-
 drivers/net/pcnet32.c                          |  159 +-
 drivers/net/phy/mdio_bus.c                     |   19 +-
 drivers/net/phy/phy.c                          |  194 ++-
 drivers/net/phy/phy_device.c                   |  114 +-
 drivers/net/qla3xxx.c                          |  371 +++-
 drivers/net/qla3xxx.h                          |   33 +-
 drivers/net/s2io-regs.h                        |    2 +-
 drivers/net/s2io.c                             |   78 +-
 drivers/net/s2io.h                             |    8 +-
 drivers/net/sb1250-mac.c                       |  294 ++-
 drivers/net/sgiseeq.c                          |   28 +-
 drivers/net/sk98lin/skge.c                     |   20 +-
 drivers/net/skfp/h/lnkstat.h                   |   84 -
 drivers/net/skge.c                             |   30 +-
 drivers/net/skge.h                             |   10 +-
 drivers/net/smc911x.c                          |    2 +-
 drivers/net/tc35815.c                          | 2554 ++++++++++++++++------
 drivers/net/tulip/dmfe.c                       |  118 +-
 drivers/net/tulip/interrupt.c                  |    4 +-
 drivers/net/tulip/media.c                      |   40 +-
 drivers/net/tulip/tulip.h                      |    9 +-
 drivers/net/tulip/tulip_core.c                 |    6 +-
 drivers/net/tulip/winbond-840.c                |    2 +-
 drivers/net/ucc_geth.c                         |  946 +++-----
 drivers/net/ucc_geth.h                         |  114 +-
 drivers/net/ucc_geth_mii.c                     |  279 +++
 drivers/net/ucc_geth_mii.h                     |  100 +
 drivers/net/ucc_geth_phy.c                     |  785 -------
 drivers/net/ucc_geth_phy.h                     |  217 --
 drivers/net/wan/hdlc_cisco.c                   |   29 +-
 drivers/net/wan/hdlc_fr.c                      |   18 +-
 drivers/net/wireless/Kconfig                   |   13 +
 drivers/net/wireless/Makefile                  |    1 +
 drivers/net/wireless/README                    |   25 -
 drivers/net/wireless/airo.c                    |   70 +-
 drivers/net/wireless/bcm43xx/bcm43xx.h         |    3 +
 drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c |    4 +-
 drivers/net/wireless/bcm43xx/bcm43xx_main.c    |    4 +-
 drivers/net/wireless/bcm43xx/bcm43xx_phy.c     |   23 +-
 drivers/net/wireless/bcm43xx/bcm43xx_phy.h     |    4 +
 drivers/net/wireless/bcm43xx/bcm43xx_radio.c   |  196 ++-
 drivers/net/wireless/hostap/hostap_ap.c        |    4 +-
 drivers/net/wireless/hostap/hostap_common.h    |    4 +-
 drivers/net/wireless/hostap/hostap_cs.c        |    9 +-
 drivers/net/wireless/hostap/hostap_hw.c        |    4 +-
 drivers/net/wireless/hostap/hostap_main.c      |    4 +-
 drivers/net/wireless/hostap/hostap_pci.c       |    2 +-
 drivers/net/wireless/hostap/hostap_plx.c       |    2 +-
 drivers/net/wireless/ipw2100.c                 |    4 +-
 drivers/net/wireless/ipw2200.c                 |   47 +
 drivers/net/wireless/libertas/11d.c            |  754 +++++++
 drivers/net/wireless/libertas/11d.h            |  105 +
 drivers/net/wireless/libertas/LICENSE          |   16 +
 drivers/net/wireless/libertas/Makefile         |   21 +
 drivers/net/wireless/libertas/README           | 1044 +++++++++
 drivers/net/wireless/libertas/assoc.c          |  588 +++++
 drivers/net/wireless/libertas/assoc.h          |   30 +
 drivers/net/wireless/libertas/cmd.c            | 1958 +++++++++++++++++
 drivers/net/wireless/libertas/cmdresp.c        | 1031 +++++++++
 drivers/net/wireless/libertas/debugfs.c        | 1935 +++++++++++++++++
 drivers/net/wireless/libertas/debugfs.h        |    6 +
 drivers/net/wireless/libertas/decl.h           |   83 +
 drivers/net/wireless/libertas/defs.h           |  369 ++++
 drivers/net/wireless/libertas/dev.h            |  403 ++++
 drivers/net/wireless/libertas/ethtool.c        |  184 ++
 drivers/net/wireless/libertas/fw.c             |  361 +++
 drivers/net/wireless/libertas/fw.h             |   13 +
 drivers/net/wireless/libertas/host.h           |  338 +++
 drivers/net/wireless/libertas/hostcmd.h        |  693 ++++++
 drivers/net/wireless/libertas/if_bootcmd.c     |   38 +
 drivers/net/wireless/libertas/if_usb.c         |  952 ++++++++
 drivers/net/wireless/libertas/if_usb.h         |  109 +
 drivers/net/wireless/libertas/ioctl.c          | 2500 +++++++++++++++++++++
 drivers/net/wireless/libertas/join.c           | 1055 +++++++++
 drivers/net/wireless/libertas/join.h           |   64 +
 drivers/net/wireless/libertas/main.c           | 1258 +++++++++++
 drivers/net/wireless/libertas/radiotap.h       |   57 +
 drivers/net/wireless/libertas/rx.c             |  459 ++++
 drivers/net/wireless/libertas/sbi.h            |   40 +
 drivers/net/wireless/libertas/scan.c           | 2044 +++++++++++++++++
 drivers/net/wireless/libertas/scan.h           |  216 ++
 drivers/net/wireless/libertas/thread.h         |   52 +
 drivers/net/wireless/libertas/tx.c             |  285 +++
 drivers/net/wireless/libertas/types.h          |  289 +++
 drivers/net/wireless/libertas/version.h        |    8 +
 drivers/net/wireless/libertas/wext.c           | 2769 ++++++++++++++++++++++++
 drivers/net/wireless/libertas/wext.h           |  147 ++
 drivers/net/wireless/todo.txt                  |   15 -
 drivers/net/wireless/zd1211rw/zd_chip.c        |   47 +-
 drivers/net/wireless/zd1211rw/zd_chip.h        |    1 +
 drivers/net/wireless/zd1211rw/zd_mac.c         |   23 +-
 drivers/net/wireless/zd1211rw/zd_rf.c          |   18 +-
 drivers/net/wireless/zd1211rw/zd_rf.h          |   11 +-
 drivers/net/wireless/zd1211rw/zd_rf_al2230.c   |   91 +-
 drivers/net/wireless/zd1211rw/zd_rf_al7230b.c  |  317 +++-
 drivers/net/wireless/zd1211rw/zd_rf_rf2959.c   |    4 +-
 drivers/net/wireless/zd1211rw/zd_usb.c         |   24 +-
 include/asm-powerpc/ucc_fast.h                 |    3 +
 include/linux/fsl_devices.h                    |   39 -
 include/linux/hdlc.h                           |    3 +-
 include/linux/pci_ids.h                        |    2 +
 include/linux/phy.h                            |    1 +
 include/linux/wireless.h                       |    2 +-
 include/net/ieee80211.h                        |    4 +-
 include/net/ieee80211_crypt.h                  |    4 +-
 include/net/ieee80211_radiotap.h               |   77 +-
 net/ieee80211/ieee80211_crypt.c                |    2 +-
 net/ieee80211/ieee80211_crypt_ccmp.c           |    4 +-
 net/ieee80211/ieee80211_crypt_tkip.c           |    6 +-
 net/ieee80211/ieee80211_crypt_wep.c            |    2 +-
 net/ieee80211/ieee80211_module.c               |    5 +-
 net/ieee80211/ieee80211_rx.c                   |    4 +-
 net/ieee80211/ieee80211_wx.c                   |    4 +-
 170 files changed, 29413 insertions(+), 6144 deletions(-)
 create mode 100644 arch/mips/mips-boards/sim/sim_platform.c
 delete mode 100644 drivers/net/chelsio/ixf1010.c
 delete mode 100644 drivers/net/chelsio/vsc8244.c
 delete mode 100644 drivers/net/chelsio/vsc8244_reg.h
 delete mode 100644 drivers/net/skfp/h/lnkstat.h
 create mode 100644 drivers/net/ucc_geth_mii.c
 create mode 100644 drivers/net/ucc_geth_mii.h
 delete mode 100644 drivers/net/ucc_geth_phy.c
 delete mode 100644 drivers/net/ucc_geth_phy.h
 delete mode 100644 drivers/net/wireless/README
 create mode 100644 drivers/net/wireless/libertas/11d.c
 create mode 100644 drivers/net/wireless/libertas/11d.h
 create mode 100644 drivers/net/wireless/libertas/LICENSE
 create mode 100644 drivers/net/wireless/libertas/Makefile
 create mode 100644 drivers/net/wireless/libertas/README
 create mode 100644 drivers/net/wireless/libertas/assoc.c
 create mode 100644 drivers/net/wireless/libertas/assoc.h
 create mode 100644 drivers/net/wireless/libertas/cmd.c
 create mode 100644 drivers/net/wireless/libertas/cmdresp.c
 create mode 100644 drivers/net/wireless/libertas/debugfs.c
 create mode 100644 drivers/net/wireless/libertas/debugfs.h
 create mode 100644 drivers/net/wireless/libertas/decl.h
 create mode 100644 drivers/net/wireless/libertas/defs.h
 create mode 100644 drivers/net/wireless/libertas/dev.h
 create mode 100644 drivers/net/wireless/libertas/ethtool.c
 create mode 100644 drivers/net/wireless/libertas/fw.c
 create mode 100644 drivers/net/wireless/libertas/fw.h
 create mode 100644 drivers/net/wireless/libertas/host.h
 create mode 100644 drivers/net/wireless/libertas/hostcmd.h
 create mode 100644 drivers/net/wireless/libertas/if_bootcmd.c
 create mode 100644 drivers/net/wireless/libertas/if_usb.c
 create mode 100644 drivers/net/wireless/libertas/if_usb.h
 create mode 100644 drivers/net/wireless/libertas/ioctl.c
 create mode 100644 drivers/net/wireless/libertas/join.c
 create mode 100644 drivers/net/wireless/libertas/join.h
 create mode 100644 drivers/net/wireless/libertas/main.c
 create mode 100644 drivers/net/wireless/libertas/radiotap.h
 create mode 100644 drivers/net/wireless/libertas/rx.c
 create mode 100644 drivers/net/wireless/libertas/sbi.h
 create mode 100644 drivers/net/wireless/libertas/scan.c
 create mode 100644 drivers/net/wireless/libertas/scan.h
 create mode 100644 drivers/net/wireless/libertas/thread.h
 create mode 100644 drivers/net/wireless/libertas/tx.c
 create mode 100644 drivers/net/wireless/libertas/types.h
 create mode 100644 drivers/net/wireless/libertas/version.h
 create mode 100644 drivers/net/wireless/libertas/wext.c
 create mode 100644 drivers/net/wireless/libertas/wext.h
 delete mode 100644 drivers/net/wireless/todo.txt

Adrian Bunk (3):
      make drivers/net/s2io.c:vlan_strip_flag static
      drivers/net/qla3xxx.c: make 2 functions static
      make drivers/net/qla3xxx.c:PHY_DEVICES[] static

Ahmed S. Darwish (2):
      e1000: Use ARRAY_SIZE macro when appropriate
      ixgb: Use ARRAY_SIZE macro when appropriate.

Andrew Morton (1):
      ipw2200: fix ieee80211_get_geo typo

Arjan van de Ven (1):
      user of the jiffies rounding code: e1000

Atsushi Nemoto (3):
      tc35815 driver update (take 2)
      tc35815: Fix an usage of streaming DMA API.
      tc35815: Zap changelog from source code

Auke Kok (1):
      e1000: list e1000-devel mailing list in MAINTAINERS

Daniel Drake (10):
      zd1211rw: Use compare_ether_addr()
      zd1211rw: Add AL2230S RF support
      zd1211rw: More device IDs
      zd1211rw: Mark some data const
      zd1211rw: Don't handle broken frames in monitor mode
      zd1211rw: Add another ID for Linksys WUSBF54G
      zd1211rw: Remove invalid CR write during ZD1211 phy reset
      zd1211rw: rework band edge patching
      zd1211rw: Add AL7230B RF support for ZD1211B
      zd1211rw: Add ID for ZyXEL AG-220

Deepak Saxena (1):
      Netpoll support for Sibyte MAC

Dmitriy Monakhov (1):
      sk98lin: handle pci_enable_device() return value in skge_resume()

Don Fry (2):
      pcnet32: only allocate init_block dma consistent
      pcnet32: change to use netdev_priv

Folkert van Heusden (1):
      baycom_ser_fdx: also allow i/o ports >= 0x1000 and enhanced failure logging

Gabriel Paubert (1):
      mv643xx_eth: make eth_port_uc_addr_{get,set}() calls symmetric

Jan-Bernd Themann (5):
      ehea: dynamic add / remove port
      ehea: NAPI multi queue TX/RX path for SMP
      ehea: fix for dynamic lpar support
      ehea: code cleanup
      ehea: removing unused functionality

Jean Delvare (1):
      strlcpy is smart enough

Jesse Brandeburg (2):
      e100: allow bad MAC address when running with invalid eeprom csum
      e100: Optionally use I/O mode only to access register space

John W. Linville (2):
      wireless: remove obsolete text files
      libertas: fix build breakage from netdev class_device -> device

Jouni Malinen (2):
      hostap: Add D-Link DWL-650 Rev. P1 product id
      Update my email address from jkmaline@cc.hut.fi to j@w1.fi

Kim Phillips (3):
      phylib: add RGMII-ID interface mode definition
      ucc_geth: migrate ucc_geth to phylib
      ucc_geth: version 1.1

Krzysztof Halasa (1):
      Generic HDLC sparse annotations

Ladislav Michl (1):
      Add support for Seeq 8003 on Challenge S Mezz board.

Larry Finger (5):
      bcm43xx: Update Documentation/bcm43xx.txt
      bcm43xx:Eliminate some 'G Mode Enable' magic numbers
      bcm43xx: Change initialization for 2050 radios
      ieee80211-crypt: Make some TKIP and CCMP error logging conditional
      ieee80211: add missing global needed by IEEE80211_DEBUG_XXXX

Marcelo Tosatti (1):
      Marvell Libertas 8388 802.11b/g USB driver

Marcin Juszkiewicz (1):
      hostap_cs: support ADLINK 345 CF

Mark Mason (1):
      add NAPI support to sb1250-mac.c

Maxim Levitsky (2):
      dmfe: add support for suspend/resume
      dmfe: add support for Wake on lan

Michael Barkowski (1):
      ucc_geth: Fix interrupt coalescing size and alignment

Michael Ellerman (1):
      Fix sparse errors in drivers/net/ibmveth.c

Michael Reiss (2):
      ucc_geth: NAPI-related bug fixes
      ucc_geth: Implement Transmit on Demand support

Michal Schmidt (2):
      airo: Don't check for NULL before kfree()
      airo: Make /sys/bus/pci/drivers/airo/{,un}bind work

Milind Arun Choudhary (2):
      e1000: ROUND_UP macro cleanup in drivers/net/e1000
      ixgb: ROUND_UP macro cleanup in drivers/net/ixgb

Mithlesh Thukral (7):
      NetXen: Use multiple PCI functions
      NetXen: Removal of redundant argument passing
      NetXen: Multi PCI support for Quad cards
      NetXen: Removal of redundant macros
      NetXen: Port swap feature for multi port cards
      NetXen: Fixes for Power PC architecture
      NetXen: Fix for vmalloc issues

Nicu Ioan Petru (1):
      ucc_geth: fixes for ucc_geth_memclean

Pavel Roskin (3):
      hostap: use offsetof() instead of own equivalent
      sparse-annotate radiotap header
      Remove comment about IEEE80211_RADIOTAP_FCS

Ralf Baechle (1):
      MIPSnet: Modernize use platform_device API.

Ramkrishna Vepa (3):
      S2IO: Save/Restore unused buffer mappings in 2/3 buffer mode
      S2io: Remove unused variables
      S2io: Change of driver maintainers

Randy Dunlap (2):
      phy layer: add kernel-doc + DocBook
      mii: add kernel-doc notation

Robert P. J. Day (2):
      remove unused header file: drivers/net/skfp/h/lnkstat.h
      3C509: Remove unnecessary include of <linux/pm_legacy.h>

Ron Mercer (3):
      qla3xxx: Add ethtool get_pauseparam for improved bonding support.
      qla3xxx: Adding support for the Agere PHY (ET1011C)
      qla3xxx: Bumping driver version number to v2.03.00-k4

Sam Ravnborg (1):
      bcm43xx: do not rebuild when kernel version changes

Scott Feldman (1):
      [netdrvr e100] experiment with doing RX in a similar manner to eepro100

Shan Lu (1):
      network: add the missing phy_device speed information to phy_mii_ioctl

Shani (1):
      Patch:replace with time_after in drivers/net/eexpress.c

Shani Moideen (1):
      [netdrvr] eexpress: minor corrections

Stephen Hemminger (7):
      chelsio: remove unused code for 1G boards
      chelsio: use C99 style initialization
      chelsio: use const for virtual functions
      skge: ignore unused error interrupts
      skge: transmit locking improvements
      skge: rearrange fields
      skge: version 1.11

Thibaut VARENE (1):
      TULIP: Natsemi dp83840a PHY fix

Thomas Klein (2):
      ehea: fix for sysfs entries
      ehea: fix for dlpar support

Tony Breeds (1):
      libertas: use standard kernel macros

Ulrich Kunitz (1):
      zd1211rw: changed GFP_NOFS to GFP_KERNEL

Valerie Henson (3):
      TULIP: Fix for 64-bit MIPS
      Fix tulip SytemError typo
      Rev tulip version

Vitaly Wool (1):
      smc911x: fix compilation breakage wjen debug is on

Yan Burman (1):
      e1000: Use kcalloc()

Zhu Yi (1):
      ipw2200: add channels sysfs entry

[patch snipped due to size; it's in git]


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-02-21 13:27   ` John W. Linville
  (?)
@ 2007-02-22 15:48   ` Dan Williams
  -1 siblings, 0 replies; 101+ messages in thread
From: Dan Williams @ 2007-02-22 15:48 UTC (permalink / raw)
  To: jeff; +Cc: Roger While, netdev, linux-wireless

On Wed, 2007-02-21 at 08:27 -0500, John W. Linville wrote:
> On Wed, Feb 21, 2007 at 12:46:46PM +0100, Roger While wrote:
> > 
> > >
> > >Dan Williams (1):
> > >      prism54: correct assignment of DOT1XENABLE in WE-19 codepaths
> > 
> > Where did this spring from ?
> > I see no posting of this patch let alone
> > an ACK.
> > The patch is also doing rather more than the description -
> > It is inserting extra breaks into a switch statement with
> > no comment as to why.
> 
> Dan posted it to linux-wireless@vger.kernel.org on 13 Feb 2007.
> The description in the body is quoted below:

It was also posted to stable@kernel.org and accepted for 2.6.19 and
2.6.20.

Dan

> 	Correct assignment of DOT1XENABLE in WE-19 codepaths.
> 	RX_UNENCRYPTED_EAPOL = 1 really means setting DOT1XENABLE _off_, and
> 	vice versa.  The original WE-19 patch erroneously reversed that.  This
> 	patch fixes association with unencrypted and WEP networks when using
> 	wpa_supplicant.
> 	
> 	It also adds two missing break statements that, left out, could result
> 	in incorrect card configuration.
> 	
> 	Please commit to both development and stable branches.
> 
> Hth...
> 
> John


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
@ 2007-02-21 13:27   ` John W. Linville
  0 siblings, 0 replies; 101+ messages in thread
From: John W. Linville @ 2007-02-21 13:27 UTC (permalink / raw)
  To: Roger While; +Cc: netdev, jeff, dcbw, linux-wireless

On Wed, Feb 21, 2007 at 12:46:46PM +0100, Roger While wrote:
> 
> >
> >Dan Williams (1):
> >      prism54: correct assignment of DOT1XENABLE in WE-19 codepaths
> 
> Where did this spring from ?
> I see no posting of this patch let alone
> an ACK.
> The patch is also doing rather more than the description -
> It is inserting extra breaks into a switch statement with
> no comment as to why.

Dan posted it to linux-wireless@vger.kernel.org on 13 Feb 2007.
The description in the body is quoted below:

	Correct assignment of DOT1XENABLE in WE-19 codepaths.
	RX_UNENCRYPTED_EAPOL = 1 really means setting DOT1XENABLE _off_, and
	vice versa.  The original WE-19 patch erroneously reversed that.  This
	patch fixes association with unencrypted and WEP networks when using
	wpa_supplicant.
	
	It also adds two missing break statements that, left out, could result
	in incorrect card configuration.
	
	Please commit to both development and stable branches.

Hth...

John
-- 
John W. Linville
linville@tuxdriver.com

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
@ 2007-02-21 13:27   ` John W. Linville
  0 siblings, 0 replies; 101+ messages in thread
From: John W. Linville @ 2007-02-21 13:27 UTC (permalink / raw)
  To: Roger While
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, jeff-o2qLIJkoznsdnm+yROfE0A,
	dcbw-H+wXaHxf7aLQT0dZR+AlfA,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA

On Wed, Feb 21, 2007 at 12:46:46PM +0100, Roger While wrote:
> 
> >
> >Dan Williams (1):
> >      prism54: correct assignment of DOT1XENABLE in WE-19 codepaths
> 
> Where did this spring from ?
> I see no posting of this patch let alone
> an ACK.
> The patch is also doing rather more than the description -
> It is inserting extra breaks into a switch statement with
> no comment as to why.

Dan posted it to linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org on 13 Feb 2007.
The description in the body is quoted below:

	Correct assignment of DOT1XENABLE in WE-19 codepaths.
	RX_UNENCRYPTED_EAPOL = 1 really means setting DOT1XENABLE _off_, and
	vice versa.  The original WE-19 patch erroneously reversed that.  This
	patch fixes association with unencrypted and WEP networks when using
	wpa_supplicant.
	
	It also adds two missing break statements that, left out, could result
	in incorrect card configuration.
	
	Please commit to both development and stable branches.

Hth...

John
-- 
John W. Linville
linville-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2007-02-21 11:46 Roger While
@ 2007-02-21 12:01 ` Johannes Berg
  2007-02-21 13:27   ` John W. Linville
  1 sibling, 0 replies; 101+ messages in thread
From: Johannes Berg @ 2007-02-21 12:01 UTC (permalink / raw)
  To: Roger While; +Cc: netdev, jeff

[-- Attachment #1: Type: text/plain, Size: 647 bytes --]

On Wed, 2007-02-21 at 12:46 +0100, Roger While wrote:
> >
> >Dan Williams (1):
> >       prism54: correct assignment of DOT1XENABLE in WE-19 codepaths
> 
> Where did this spring from ?

wireless

> I see no posting of this patch let alone
> an ACK.
> The patch is also doing rather more than the description -
> It is inserting extra breaks into a switch statement with
> no comment as to why.

The patch description clearly indicates those break statements, and
they're also clearly necessary.

http://kernel.org/git/?p=linux/kernel/git/linville/wireless-2.6.git;a=commit;h=b5c41651645f7604dda7abc3445e1622f9b1b9ab

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 190 bytes --]

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-02-21 11:46 Roger While
  2007-02-21 12:01 ` Johannes Berg
  2007-02-21 13:27   ` John W. Linville
  0 siblings, 2 replies; 101+ messages in thread
From: Roger While @ 2007-02-21 11:46 UTC (permalink / raw)
  To: netdev; +Cc: jeff


>
>Dan Williams (1):
>       prism54: correct assignment of DOT1XENABLE in WE-19 codepaths

Where did this spring from ?
I see no posting of this patch let alone
an ACK.
The patch is also doing rather more than the description -
It is inserting extra breaks into a switch statement with
no comment as to why.

Roger While



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-02-20 18:16 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2007-02-20 18:16 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML


Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 drivers/net/8139too.c                           |   40 ++---
 drivers/net/hamradio/baycom_epp.c               |   13 +--
 drivers/net/hamradio/hdlcdrv.c                  |   13 +--
 drivers/net/hamradio/yam.c                      |   11 +-
 drivers/net/natsemi.c                           |   43 +++++-
 drivers/net/r8169.c                             |   25 ++-
 drivers/net/s2io.c                              |   21 ++-
 drivers/net/sis190.c                            |    7 +-
 drivers/net/skge.c                              |    9 +-
 drivers/net/wireless/airo.c                     |    4 +-
 drivers/net/wireless/bcm43xx/bcm43xx.h          |    8 +-
 drivers/net/wireless/bcm43xx/bcm43xx_ilt.c      |   15 ++
 drivers/net/wireless/bcm43xx/bcm43xx_ilt.h      |    1 +
 drivers/net/wireless/bcm43xx/bcm43xx_main.c     |   20 +--
 drivers/net/wireless/bcm43xx/bcm43xx_phy.c      |  195 ++++++++++-------------
 drivers/net/wireless/bcm43xx/bcm43xx_radio.c    |   13 +-
 drivers/net/wireless/bcm43xx/bcm43xx_xmit.h     |   10 +-
 drivers/net/wireless/hostap/hostap.h            |    3 +-
 drivers/net/wireless/ipw2100.c                  |   14 +-
 drivers/net/wireless/prism54/isl_ioctl.c        |    8 +-
 drivers/net/wireless/prism54/oid_mgt.c          |    4 +-
 drivers/net/wireless/wavelan.c                  |   14 +-
 drivers/net/wireless/wavelan.p.h                |    3 -
 drivers/net/wireless/zd1211rw/zd_chip.c         |    2 +-
 include/linux/wireless.h                        |    4 +-
 net/ieee80211/softmac/ieee80211softmac_module.c |   13 +--
 net/ieee80211/softmac/ieee80211softmac_wx.c     |   11 +-
 27 files changed, 264 insertions(+), 260 deletions(-)

Ahmed S. Darwish (4):
      ipw2100: Use ARRAY_SIZE macro when appropriate
      misc-wireless: Use ARRAY_SIZE macro when appropriate
      hostap: Use ARRAY_SIZE macro when appropriate
      wavelan: Use ARRAY_SIZE macro when appropriate

Dan Williams (1):
      prism54: correct assignment of DOT1XENABLE in WE-19 codepaths

Daniel Drake (1):
      zd1211rw: Readd zd_addr_t cast

Francois Romieu (4):
      r8169: RTNL and flush_scheduled_work deadlock
      sis190: RTNL and flush_scheduled_work deadlock
      8139too: RTNL and flush_scheduled_work deadlock
      s2io: RTNL and flush_scheduled_work deadlock

Ingo van Lil (1):
      wireless: fix IW_IS_{GET,SET} comment in wireless.h

Larry Finger (5):
      bcm43xx: Janitorial change - remove two unused variables
      bcm43xx: Fix for oops on resume
      bcm43xx: Fix for 4311 and 02/07/07 specification changes
      bcm43xx: OFDM fix for rev 1 cards
      ieee80211softmac: Fix setting of initial transmit rates

Mark Brown (2):
      natsemi: Add support for using MII port with no PHY
      natsemi: Support Aculab E1/T1 PMXc cPCI carrier cards

Michael Buesch (1):
      bcm43xx: Ignore ampdu status reports

Ralf Baechle (1):
      Replace local random function with random32()

Stephen Hemminger (1):
      skge: race with workq and RTNL

diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 35ad5cf..99304b2 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -1109,6 +1109,8 @@ static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
 
 	assert (dev != NULL);
 
+	flush_scheduled_work();
+
 	unregister_netdev (dev);
 
 	__rtl8139_cleanup_dev (dev);
@@ -1603,18 +1605,21 @@ static void rtl8139_thread (struct work_struct *work)
 	struct net_device *dev = tp->mii.dev;
 	unsigned long thr_delay = next_tick;
 
+	rtnl_lock();
+
+	if (!netif_running(dev))
+		goto out_unlock;
+
 	if (tp->watchdog_fired) {
 		tp->watchdog_fired = 0;
 		rtl8139_tx_timeout_task(work);
-	} else if (rtnl_trylock()) {
-		rtl8139_thread_iter (dev, tp, tp->mmio_addr);
-		rtnl_unlock ();
-	} else {
-		/* unlikely race.  mitigate with fast poll. */
-		thr_delay = HZ / 2;
-	}
+	} else
+		rtl8139_thread_iter(dev, tp, tp->mmio_addr);
 
-	schedule_delayed_work(&tp->thread, thr_delay);
+	if (tp->have_thread)
+		schedule_delayed_work(&tp->thread, thr_delay);
+out_unlock:
+	rtnl_unlock ();
 }
 
 static void rtl8139_start_thread(struct rtl8139_private *tp)
@@ -1626,19 +1631,11 @@ static void rtl8139_start_thread(struct rtl8139_private *tp)
 		return;
 
 	tp->have_thread = 1;
+	tp->watchdog_fired = 0;
 
 	schedule_delayed_work(&tp->thread, next_tick);
 }
 
-static void rtl8139_stop_thread(struct rtl8139_private *tp)
-{
-	if (tp->have_thread) {
-		cancel_rearming_delayed_work(&tp->thread);
-		tp->have_thread = 0;
-	} else
-		flush_scheduled_work();
-}
-
 static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
 {
 	tp->cur_tx = 0;
@@ -1696,12 +1693,11 @@ static void rtl8139_tx_timeout (struct net_device *dev)
 {
 	struct rtl8139_private *tp = netdev_priv(dev);
 
+	tp->watchdog_fired = 1;
 	if (!tp->have_thread) {
-		INIT_DELAYED_WORK(&tp->thread, rtl8139_tx_timeout_task);
+		INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
 		schedule_delayed_work(&tp->thread, next_tick);
-	} else
-		tp->watchdog_fired = 1;
-
+	}
 }
 
 static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
@@ -2233,8 +2229,6 @@ static int rtl8139_close (struct net_device *dev)
 
 	netif_stop_queue (dev);
 
-	rtl8139_stop_thread(tp);
-
 	if (netif_msg_ifdown(tp))
 		printk(KERN_DEBUG "%s: Shutting down ethercard, status was 0x%4.4x.\n",
 			dev->name, RTL_R16 (IntrStatus));
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 153b6dc..84aa211 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -52,6 +52,7 @@
 #include <linux/hdlcdrv.h>
 #include <linux/baycom.h>
 #include <linux/jiffies.h>
+#include <linux/random.h>
 #include <net/ax25.h> 
 #include <asm/uaccess.h>
 
@@ -433,16 +434,6 @@ static void encode_hdlc(struct baycom_state *bc)
 
 /* ---------------------------------------------------------------------- */
 
-static unsigned short random_seed;
-
-static inline unsigned short random_num(void)
-{
-	random_seed = 28629 * random_seed + 157;
-	return random_seed;
-}
-
-/* ---------------------------------------------------------------------- */
-
 static int transmit(struct baycom_state *bc, int cnt, unsigned char stat)
 {
 	struct parport *pp = bc->pdev->port;
@@ -464,7 +455,7 @@ static int transmit(struct baycom_state *bc, int cnt, unsigned char stat)
 			if ((--bc->hdlctx.slotcnt) > 0)
 				return 0;
 			bc->hdlctx.slotcnt = bc->ch_params.slottime;
-			if ((random_num() % 256) > bc->ch_params.ppersist)
+			if ((random32() % 256) > bc->ch_params.ppersist)
 				return 0;
 		}
 	}
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 452873e..f5a17ad 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -56,6 +56,7 @@
 #include <linux/if_arp.h>
 #include <linux/skbuff.h>
 #include <linux/hdlcdrv.h>
+#include <linux/random.h>
 #include <net/ax25.h> 
 #include <asm/uaccess.h>
 
@@ -371,16 +372,6 @@ static void start_tx(struct net_device *dev, struct hdlcdrv_state *s)
 
 /* ---------------------------------------------------------------------- */
 
-static unsigned short random_seed;
-
-static inline unsigned short random_num(void)
-{
-	random_seed = 28629 * random_seed + 157;
-	return random_seed;
-}
-
-/* ---------------------------------------------------------------------- */
-
 void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
 {
 	if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt || !s->skb) 
@@ -396,7 +387,7 @@ void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
 	if ((--s->hdlctx.slotcnt) > 0)
 		return;
 	s->hdlctx.slotcnt = s->ch_params.slottime;
-	if ((random_num() % 256) > s->ch_params.ppersist)
+	if ((random32() % 256) > s->ch_params.ppersist)
 		return;
 	start_tx(dev, s);
 }
diff --git a/drivers/net/hamradio/yam.c b/drivers/net/hamradio/yam.c
index 08f2711..ee3ea4f 100644
--- a/drivers/net/hamradio/yam.c
+++ b/drivers/net/hamradio/yam.c
@@ -50,6 +50,7 @@
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/bitops.h>
+#include <linux/random.h>
 #include <asm/io.h>
 #include <asm/system.h>
 #include <linux/interrupt.h>
@@ -566,14 +567,6 @@ static void yam_start_tx(struct net_device *dev, struct yam_port *yp)
 	ptt_on(dev);
 }
 
-static unsigned short random_seed;
-
-static inline unsigned short random_num(void)
-{
-	random_seed = 28629 * random_seed + 157;
-	return random_seed;
-}
-
 static void yam_arbitrate(struct net_device *dev)
 {
 	struct yam_port *yp = netdev_priv(dev);
@@ -600,7 +593,7 @@ static void yam_arbitrate(struct net_device *dev)
 	yp->slotcnt = yp->slot / 10;
 
 	/* is random > persist ? */
-	if ((random_num() % 256) > yp->pers)
+	if ((random32() % 256) > yp->pers)
 		return;
 
 	yam_start_tx(dev, yp);
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index ffa0afd..adf29dd 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -244,6 +244,9 @@ enum {
 	MII_EN_SCRM	= 0x0004,	/* enable scrambler (tp) */
 };
 
+enum {
+	NATSEMI_FLAG_IGNORE_PHY		= 0x1,
+};
 
 /* array of board data directly indexed by pci_tbl[x].driver_data */
 static const struct {
@@ -251,10 +254,12 @@ static const struct {
 	unsigned long flags;
 	unsigned int eeprom_size;
 } natsemi_pci_info[] __devinitdata = {
+	{ "Aculab E1/T1 PMXc cPCI carrier card", NATSEMI_FLAG_IGNORE_PHY, 128 },
 	{ "NatSemi DP8381[56]", 0, 24 },
 };
 
 static const struct pci_device_id natsemi_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_NS, 0x0020, 0x12d9,     0x000c,     0, 0, 0 },
 	{ PCI_VENDOR_ID_NS, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ }	/* terminate list */
 };
@@ -568,6 +573,8 @@ struct netdev_private {
 	u32 intr_status;
 	/* Do not touch the nic registers */
 	int hands_off;
+	/* Don't pay attention to the reported link state. */
+	int ignore_phy;
 	/* external phy that is used: only valid if dev->if_port != PORT_TP */
 	int mii;
 	int phy_addr_external;
@@ -696,7 +703,10 @@ static void __devinit natsemi_init_media (struct net_device *dev)
 	struct netdev_private *np = netdev_priv(dev);
 	u32 tmp;
 
-	netif_carrier_off(dev);
+	if (np->ignore_phy)
+		netif_carrier_on(dev);
+	else
+		netif_carrier_off(dev);
 
 	/* get the initial settings from hardware */
 	tmp            = mdio_read(dev, MII_BMCR);
@@ -806,8 +816,13 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 	np->hands_off = 0;
 	np->intr_status = 0;
 	np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size;
+	if (natsemi_pci_info[chip_idx].flags & NATSEMI_FLAG_IGNORE_PHY)
+		np->ignore_phy = 1;
+	else
+		np->ignore_phy = 0;
 
 	/* Initial port:
+	 * - If configured to ignore the PHY set up for external.
 	 * - If the nic was configured to use an external phy and if find_mii
 	 *   finds a phy: use external port, first phy that replies.
 	 * - Otherwise: internal port.
@@ -815,7 +830,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 	 * The address would be used to access a phy over the mii bus, but
 	 * the internal phy is accessed through mapped registers.
 	 */
-	if (readl(ioaddr + ChipConfig) & CfgExtPhy)
+	if (np->ignore_phy || readl(ioaddr + ChipConfig) & CfgExtPhy)
 		dev->if_port = PORT_MII;
 	else
 		dev->if_port = PORT_TP;
@@ -825,7 +840,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 
 	if (dev->if_port != PORT_TP) {
 		np->phy_addr_external = find_mii(dev);
-		if (np->phy_addr_external == PHY_ADDR_NONE) {
+		/* If we're ignoring the PHY it doesn't matter if we can't
+		 * find one. */
+		if (!np->ignore_phy && np->phy_addr_external == PHY_ADDR_NONE) {
 			dev->if_port = PORT_TP;
 			np->phy_addr_external = PHY_ADDR_INTERNAL;
 		}
@@ -891,6 +908,8 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 		printk("%02x, IRQ %d", dev->dev_addr[i], irq);
 		if (dev->if_port == PORT_TP)
 			printk(", port TP.\n");
+		else if (np->ignore_phy)
+			printk(", port MII, ignoring PHY\n");
 		else
 			printk(", port MII, phy ad %d.\n", np->phy_addr_external);
 	}
@@ -1571,9 +1590,13 @@ static void check_link(struct net_device *dev)
 {
 	struct netdev_private *np = netdev_priv(dev);
 	void __iomem * ioaddr = ns_ioaddr(dev);
-	int duplex;
+	int duplex = np->duplex;
 	u16 bmsr;
 
+	/* If we are ignoring the PHY then don't try reading it. */
+	if (np->ignore_phy)
+		goto propagate_state;
+
 	/* The link status field is latched: it remains low after a temporary
 	 * link failure until it's read. We need the current link status,
 	 * thus read twice.
@@ -1585,7 +1608,7 @@ static void check_link(struct net_device *dev)
 		if (netif_carrier_ok(dev)) {
 			if (netif_msg_link(np))
 				printk(KERN_NOTICE "%s: link down.\n",
-					dev->name);
+				       dev->name);
 			netif_carrier_off(dev);
 			undo_cable_magic(dev);
 		}
@@ -1609,6 +1632,7 @@ static void check_link(struct net_device *dev)
 			duplex = 1;
 	}
 
+propagate_state:
 	/* if duplex is set then bit 28 must be set, too */
 	if (duplex ^ !!(np->rx_config & RxAcceptTx)) {
 		if (netif_msg_link(np))
@@ -2819,6 +2843,15 @@ static int netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
 	}
 
 	/*
+	 * If we're ignoring the PHY then autoneg and the internal
+	 * transciever are really not going to work so don't let the
+	 * user select them.
+	 */
+	if (np->ignore_phy && (ecmd->autoneg == AUTONEG_ENABLE ||
+			       ecmd->port == PORT_TP))
+		return -EINVAL;
+
+	/*
 	 * maxtxpkt, maxrxpkt: ignored for now.
 	 *
 	 * transceiver:
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 5598d86..13cf06e 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1733,6 +1733,8 @@ rtl8169_remove_one(struct pci_dev *pdev)
 	assert(dev != NULL);
 	assert(tp != NULL);
 
+	flush_scheduled_work();
+
 	unregister_netdev(dev);
 	rtl8169_release_board(pdev, dev, tp->mmio_addr);
 	pci_set_drvdata(pdev, NULL);
@@ -2161,10 +2163,13 @@ static void rtl8169_reinit_task(struct work_struct *work)
 	struct net_device *dev = tp->dev;
 	int ret;
 
-	if (netif_running(dev)) {
-		rtl8169_wait_for_quiescence(dev);
-		rtl8169_close(dev);
-	}
+	rtnl_lock();
+
+	if (!netif_running(dev))
+		goto out_unlock;
+
+	rtl8169_wait_for_quiescence(dev);
+	rtl8169_close(dev);
 
 	ret = rtl8169_open(dev);
 	if (unlikely(ret < 0)) {
@@ -2179,6 +2184,9 @@ static void rtl8169_reinit_task(struct work_struct *work)
 		}
 		rtl8169_schedule_work(dev, rtl8169_reinit_task);
 	}
+
+out_unlock:
+	rtnl_unlock();
 }
 
 static void rtl8169_reset_task(struct work_struct *work)
@@ -2187,8 +2195,10 @@ static void rtl8169_reset_task(struct work_struct *work)
 		container_of(work, struct rtl8169_private, task.work);
 	struct net_device *dev = tp->dev;
 
+	rtnl_lock();
+
 	if (!netif_running(dev))
-		return;
+		goto out_unlock;
 
 	rtl8169_wait_for_quiescence(dev);
 
@@ -2210,6 +2220,9 @@ static void rtl8169_reset_task(struct work_struct *work)
 		}
 		rtl8169_schedule_work(dev, rtl8169_reset_task);
 	}
+
+out_unlock:
+	rtnl_unlock();
 }
 
 static void rtl8169_tx_timeout(struct net_device *dev)
@@ -2722,8 +2735,6 @@ static void rtl8169_down(struct net_device *dev)
 
 	netif_stop_queue(dev);
 
-	flush_scheduled_work();
-
 core_down:
 	spin_lock_irq(&tp->lock);
 
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index e8e0d94..fd85648 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3758,7 +3758,6 @@ static int s2io_close(struct net_device *dev)
 {
 	struct s2io_nic *sp = dev->priv;
 
-	flush_scheduled_work();
 	netif_stop_queue(dev);
 	/* Reset card, kill tasklet and free Tx and Rx buffers. */
 	s2io_card_down(sp);
@@ -5847,9 +5846,14 @@ static void s2io_set_link(struct work_struct *work)
 	register u64 val64;
 	u16 subid;
 
+	rtnl_lock();
+
+	if (!netif_running(dev))
+		goto out_unlock;
+
 	if (test_and_set_bit(0, &(nic->link_state))) {
 		/* The card is being reset, no point doing anything */
-		return;
+		goto out_unlock;
 	}
 
 	subid = nic->pdev->subsystem_device;
@@ -5903,6 +5907,9 @@ static void s2io_set_link(struct work_struct *work)
 		s2io_link(nic, LINK_DOWN);
 	}
 	clear_bit(0, &(nic->link_state));
+
+out_unlock:
+	rtnl_lock();
 }
 
 static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp,
@@ -6356,6 +6363,11 @@ static void s2io_restart_nic(struct work_struct *work)
 	struct s2io_nic *sp = container_of(work, struct s2io_nic, rst_timer_task);
 	struct net_device *dev = sp->dev;
 
+	rtnl_lock();
+
+	if (!netif_running(dev))
+		goto out_unlock;
+
 	s2io_card_down(sp);
 	if (s2io_card_up(sp)) {
 		DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
@@ -6364,7 +6376,8 @@ static void s2io_restart_nic(struct work_struct *work)
 	netif_wake_queue(dev);
 	DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n",
 		  dev->name);
-
+out_unlock:
+	rtnl_unlock();
 }
 
 /**
@@ -7173,6 +7186,8 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev)
 		return;
 	}
 
+	flush_scheduled_work();
+
 	sp = dev->priv;
 	unregister_netdev(dev);
 
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 45d91b1..b08508b 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -909,6 +909,9 @@ static void sis190_phy_task(struct work_struct *work)
 
 	rtnl_lock();
 
+	if (!netif_running(dev))
+		goto out_unlock;
+
 	val = mdio_read(ioaddr, phy_id, MII_BMCR);
 	if (val & BMCR_RESET) {
 		// FIXME: needlessly high ?  -- FR 02/07/2005
@@ -981,6 +984,7 @@ static void sis190_phy_task(struct work_struct *work)
 		netif_carrier_on(dev);
 	}
 
+out_unlock:
 	rtnl_unlock();
 }
 
@@ -1102,8 +1106,6 @@ static void sis190_down(struct net_device *dev)
 
 	netif_stop_queue(dev);
 
-	flush_scheduled_work();
-
 	do {
 		spin_lock_irq(&tp->lock);
 
@@ -1857,6 +1859,7 @@ static void __devexit sis190_remove_one(struct pci_dev *pdev)
 	struct net_device *dev = pci_get_drvdata(pdev);
 
 	sis190_mii_remove(dev);
+	flush_scheduled_work();
 	unregister_netdev(dev);
 	sis190_release_board(pdev);
 	pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index e482e7f..c3d2e0a 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -1419,7 +1419,8 @@ static void xm_link_timer(struct work_struct *work)
 	mutex_unlock(&hw->phy_mutex);
 
 nochange:
-	schedule_delayed_work(&skge->link_thread, LINK_HZ);
+	if (netif_running(dev))
+		schedule_delayed_work(&skge->link_thread, LINK_HZ);
 }
 
 static void genesis_mac_init(struct skge_hw *hw, int port)
@@ -2530,7 +2531,7 @@ static int skge_down(struct net_device *dev)
 
 	netif_stop_queue(dev);
 	if (hw->chip_id == CHIP_ID_GENESIS && hw->phy_type == SK_PHY_XMAC)
-		cancel_rearming_delayed_work(&skge->link_thread);
+		cancel_delayed_work(&skge->link_thread);
 
 	skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF);
 	if (hw->chip_id == CHIP_ID_GENESIS)
@@ -3690,6 +3691,8 @@ static void __devexit skge_remove(struct pci_dev *pdev)
 	if (!hw)
 		return;
 
+	flush_scheduled_work();
+
 	if ((dev1 = hw->dev[1]))
 		unregister_netdev(dev1);
 	dev0 = hw->dev[0];
@@ -3704,8 +3707,6 @@ static void __devexit skge_remove(struct pci_dev *pdev)
 	skge_write16(hw, B0_LED, LED_STAT_OFF);
 	skge_write8(hw, B0_CTST, CS_RST_SET);
 
-	flush_scheduled_work();
-
 	free_irq(pdev->irq, hw);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index b08055a..a8c2bfe 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -1623,7 +1623,7 @@ static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
 
 	crypto_cipher_setkey(tfm, pkey, 16);
 	counter = 0;
-	for (i = 0; i < (sizeof(context->coeff)/sizeof(context->coeff[0])); ) {
+	for (i = 0; i < ARRAY_SIZE(context->coeff); ) {
 		aes_counter[15] = (u8)(counter >> 0);
 		aes_counter[14] = (u8)(counter >> 8);
 		aes_counter[13] = (u8)(counter >> 16);
@@ -1632,7 +1632,7 @@ static void emmh32_setseed(emmh32_context *context, u8 *pkey, int keylen,
 		memcpy (plain, aes_counter, 16);
 		crypto_cipher_encrypt_one(tfm, plain, plain);
 		cipher = plain;
-		for (j=0; (j<16) && (i< (sizeof(context->coeff)/sizeof(context->coeff[0]))); ) {
+		for (j = 0; (j < 16) && (i < ARRAY_SIZE(context->coeff)); ) {
 			context->coeff[i++] = ntohl(*(u32 *)&cipher[j]);
 			j += 4;
 		}
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 0e790ef..95ff175 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -21,7 +21,7 @@
 #define PFX				KBUILD_MODNAME ": "
 
 #define BCM43xx_SWITCH_CORE_MAX_RETRIES	50
-#define BCM43xx_IRQWAIT_MAX_RETRIES	50
+#define BCM43xx_IRQWAIT_MAX_RETRIES	100
 
 #define BCM43xx_IO_SIZE			8192
 
@@ -333,7 +333,7 @@
 #define BCM43xx_SBF_PS2			0x04000000
 #define BCM43xx_SBF_NO_SSID_BCAST	0x08000000
 #define BCM43xx_SBF_TIME_UPDATE		0x10000000
-#define BCM43xx_SBF_80000000		0x80000000 /*FIXME: fix name*/
+#define BCM43xx_SBF_MODE_G		0x80000000
 
 /* Microcode */
 #define BCM43xx_UCODE_REVISION		0x0000
@@ -507,8 +507,6 @@ struct bcm43xx_sprominfo {
 	u8 et1macaddr[6];
 	u8 et0phyaddr:5;
 	u8 et1phyaddr:5;
-	u8 et0mdcport:1;
-	u8 et1mdcport:1;
 	u8 boardrev;
 	u8 locale:4;
 	u8 antennas_aphy:2;
@@ -542,7 +540,7 @@ struct bcm43xx_lopair {
 
 struct bcm43xx_phyinfo {
 	/* Hardware Data */
-	u8 version;
+	u8 analog;
 	u8 type;
 	u8 rev;
 	u16 antenna_diversity;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
index ad8e569..f2b8dba 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.c
@@ -325,6 +325,21 @@ void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val)
 	}
 }
 
+void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val)
+{
+	if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
+		bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_CTRL, offset);
+		mmiowb();
+		bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA2, (val & 0xFFFF0000) >> 16);
+		bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_A_DATA1, val & 0x0000FFFF);
+	} else {
+		bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_CTRL, offset);
+		mmiowb();
+		bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA2, (val & 0xFFFF0000) >> 16);
+		bcm43xx_phy_write(bcm, BCM43xx_PHY_ILT_G_DATA1, val & 0x0000FFFF);
+	}
+}
+
 u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset)
 {
 	if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_A) {
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
index 464521a..d7eaf5f 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_ilt.h
@@ -27,6 +27,7 @@ extern const u16 bcm43xx_ilt_sigmasqr2[BCM43xx_ILT_SIGMASQR_SIZE];
 
 
 void bcm43xx_ilt_write(struct bcm43xx_private *bcm, u16 offset, u16 val);
+void bcm43xx_ilt_write32(struct bcm43xx_private *bcm, u16 offset, u32 val);
 u16 bcm43xx_ilt_read(struct bcm43xx_private *bcm, u16 offset);
 
 #endif /* BCM43xx_ILT_H_ */
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 2e400aa..73c831a 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -851,8 +851,6 @@ static int bcm43xx_sprom_extract(struct bcm43xx_private *bcm)
 	value = sprom[BCM43xx_SPROM_ETHPHY];
 	bcm->sprom.et0phyaddr = (value & 0x001F);
 	bcm->sprom.et1phyaddr = (value & 0x03E0) >> 5;
-	bcm->sprom.et0mdcport = (value & (1 << 14)) >> 14;
-	bcm->sprom.et1mdcport = (value & (1 << 15)) >> 15;
 
 	/* boardrev, antennas, locale */
 	value = sprom[BCM43xx_SPROM_BOARDREV];
@@ -1449,12 +1447,10 @@ static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
 
 		bcm43xx_debugfs_log_txstat(bcm, &stat);
 
-		if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE)
+		if (stat.flags & BCM43xx_TXSTAT_FLAG_AMPDU)
+			continue;
+		if (stat.flags & BCM43xx_TXSTAT_FLAG_INTER)
 			continue;
-		if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
-			//TODO: packet was not acked (was lost)
-		}
-		//TODO: There are more (unknown) flags to test. see bcm43xx_main.h
 
 		if (bcm43xx_using_pio(bcm))
 			bcm43xx_pio_handle_xmitstatus(bcm, &stat);
@@ -3696,7 +3692,7 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
 {
 	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
 	u16 value;
-	u8 phy_version;
+	u8 phy_analog;
 	u8 phy_type;
 	u8 phy_rev;
 	int phy_rev_ok = 1;
@@ -3704,12 +3700,12 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
 
 	value = bcm43xx_read16(bcm, BCM43xx_MMIO_PHY_VER);
 
-	phy_version = (value & 0xF000) >> 12;
+	phy_analog = (value & 0xF000) >> 12;
 	phy_type = (value & 0x0F00) >> 8;
 	phy_rev = (value & 0x000F);
 
-	dprintk(KERN_INFO PFX "Detected PHY: Version: %x, Type %x, Revision %x\n",
-		phy_version, phy_type, phy_rev);
+	dprintk(KERN_INFO PFX "Detected PHY: Analog: %x, Type %x, Revision %x\n",
+		phy_analog, phy_type, phy_rev);
 
 	switch (phy_type) {
 	case BCM43xx_PHYTYPE_A:
@@ -3752,7 +3748,7 @@ static int bcm43xx_read_phyinfo(struct bcm43xx_private *bcm)
 		       phy_rev);
 	}
 
-	phy->version = phy_version;
+	phy->analog = phy_analog;
 	phy->type = phy_type;
 	phy->rev = phy_rev;
 	if ((phy_type == BCM43xx_PHYTYPE_B) || (phy_type == BCM43xx_PHYTYPE_G)) {
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
index 52ce2a9..3a5c9c2 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c
@@ -205,8 +205,8 @@ static void bcm43xx_phy_init_pctl(struct bcm43xx_private *bcm)
 	    (bcm->board_type == 0x0416))
 		return;
 
-	bcm43xx_write16(bcm, 0x03E6, bcm43xx_read16(bcm, 0x03E6) & 0xFFDF);
 	bcm43xx_phy_write(bcm, 0x0028, 0x8018);
+	bcm43xx_write16(bcm, 0x03E6, bcm43xx_read16(bcm, 0x03E6) & 0xFFDF);
 
 	if (phy->type == BCM43xx_PHYTYPE_G) {
 		if (!phy->connected)
@@ -317,6 +317,13 @@ static void bcm43xx_phy_agcsetup(struct bcm43xx_private *bcm)
 	bcm43xx_ilt_write(bcm, offset + 0x0801, 7);
 	bcm43xx_ilt_write(bcm, offset + 0x0802, 16);
 	bcm43xx_ilt_write(bcm, offset + 0x0803, 28);
+
+	if (phy->rev >= 6) {
+		bcm43xx_phy_write(bcm, 0x0426, (bcm43xx_phy_read(bcm, 0x0426)
+				  & 0xFFFC));
+		bcm43xx_phy_write(bcm, 0x0426, (bcm43xx_phy_read(bcm, 0x0426)
+				  & 0xEFFF));
+	}
 }
 
 static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
@@ -337,7 +344,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
 		for (i = 0; i < BCM43xx_ILT_NOISEG1_SIZE; i++)
 			bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noiseg1[i]);
 		for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++)
-			bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
+			bcm43xx_ilt_write32(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
 	} else {
 		/* nrssi values are signed 6-bit values. Not sure why we write 0x7654 here... */
 		bcm43xx_nrssi_hw_write(bcm, 0xBA98, (s16)0x7654);
@@ -377,7 +384,7 @@ static void bcm43xx_phy_setupg(struct bcm43xx_private *bcm)
 	
 	if (phy->rev == 1) {
 		for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++)
-			bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
+			bcm43xx_ilt_write32(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
 		for (i = 0; i < 4; i++) {
 			bcm43xx_ilt_write(bcm, 0x5404 + i, 0x0020);
 			bcm43xx_ilt_write(bcm, 0x5408 + i, 0x0020);
@@ -500,10 +507,10 @@ static void bcm43xx_phy_setupa(struct bcm43xx_private *bcm)
 		for (i = 0; i < BCM43xx_ILT_NOISEA2_SIZE; i++)
 			bcm43xx_ilt_write(bcm, 0x1800 + i, bcm43xx_ilt_noisea2[i]);
 		for (i = 0; i < BCM43xx_ILT_ROTOR_SIZE; i++)
-			bcm43xx_ilt_write(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
+			bcm43xx_ilt_write32(bcm, 0x2000 + i, bcm43xx_ilt_rotor[i]);
 		bcm43xx_phy_init_noisescaletbl(bcm);
 		for (i = 0; i < BCM43xx_ILT_RETARD_SIZE; i++)
-			bcm43xx_ilt_write(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
+			bcm43xx_ilt_write32(bcm, 0x2400 + i, bcm43xx_ilt_retard[i]);
 		break;
 	case 3:
 		for (i = 0; i < 64; i++)
@@ -729,19 +736,19 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
 	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
 	struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
 	u16 offset;
+	u16 value;
+	u8 old_channel;
 
-	if (phy->version == 1 &&
-	    radio->version == 0x2050) {
+	if (phy->analog == 1)
 		bcm43xx_radio_write16(bcm, 0x007A,
 				      bcm43xx_radio_read16(bcm, 0x007A)
 				      | 0x0050);
-	}
 	if ((bcm->board_vendor != PCI_VENDOR_ID_BROADCOM) &&
 	    (bcm->board_type != 0x0416)) {
+		value = 0x2120;
 		for (offset = 0x00A8 ; offset < 0x00C7; offset++) {
-			bcm43xx_phy_write(bcm, offset,
-					  (bcm43xx_phy_read(bcm, offset) + 0x2020)
-					  & 0x3F3F);
+			bcm43xx_phy_write(bcm, offset, value);
+			value += 0x0202;
 		}
 	}
 	bcm43xx_phy_write(bcm, 0x0035,
@@ -750,7 +757,7 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
 	if (radio->version == 0x2050)
 		bcm43xx_phy_write(bcm, 0x0038, 0x0667);
 
-	if (phy->connected) {
+	if (phy->type == BCM43xx_PHYTYPE_G) {
 		if (radio->version == 0x2050) {
 			bcm43xx_radio_write16(bcm, 0x007A,
 					      bcm43xx_radio_read16(bcm, 0x007A)
@@ -776,7 +783,7 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
 				  bcm43xx_phy_read(bcm, BCM43xx_PHY_RADIO_BITFIELD) | (1 << 11));
 	}
 
-	if (phy->version == 1 && radio->version == 0x2050) {
+	if (phy->analog == 1) {
 		bcm43xx_phy_write(bcm, 0x0026, 0xCE00);
 		bcm43xx_phy_write(bcm, 0x0021, 0x3763);
 		bcm43xx_phy_write(bcm, 0x0022, 0x1BC3);
@@ -787,14 +794,15 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
 	bcm43xx_phy_write(bcm, 0x0030, 0x00C6);
 	bcm43xx_write16(bcm, 0x03EC, 0x3F22);
 
-	if (phy->version == 1 && radio->version == 0x2050)
+	if (phy->analog == 1)
 		bcm43xx_phy_write(bcm, 0x0020, 0x3E1C);
 	else
 		bcm43xx_phy_write(bcm, 0x0020, 0x301C);
 
-	if (phy->version == 0)
+	if (phy->analog == 0)
 		bcm43xx_write16(bcm, 0x03E4, 0x3000);
 
+	old_channel = radio->channel;
 	/* Force to channel 7, even if not supported. */
 	bcm43xx_radio_selectchannel(bcm, 7, 0);
 
@@ -816,11 +824,11 @@ static void bcm43xx_phy_initb5(struct bcm43xx_private *bcm)
 
 	bcm43xx_radio_write16(bcm, 0x007A, bcm43xx_radio_read16(bcm, 0x007A) | 0x0007);
 
-	bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0);
+	bcm43xx_radio_selectchannel(bcm, old_channel, 0);
 
 	bcm43xx_phy_write(bcm, 0x0014, 0x0080);
 	bcm43xx_phy_write(bcm, 0x0032, 0x00CA);
-	bcm43xx_phy_write(bcm, 0x88A3, 0x002A);
+	bcm43xx_phy_write(bcm, 0x002A, 0x88A3);
 
 	bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
 
@@ -835,61 +843,24 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
 	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
 	struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
 	u16 offset, val;
+	u8 old_channel;
 
 	bcm43xx_phy_write(bcm, 0x003E, 0x817A);
 	bcm43xx_radio_write16(bcm, 0x007A,
 	                      (bcm43xx_radio_read16(bcm, 0x007A) | 0x0058));
-	if ((radio->manufact == 0x17F) &&
-	    (radio->version == 0x2050) &&
-	    (radio->revision == 3 ||
-	     radio->revision == 4 ||
-	     radio->revision == 5)) {
-		bcm43xx_radio_write16(bcm, 0x0051, 0x001F);
-		bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
-		bcm43xx_radio_write16(bcm, 0x0053, 0x005B);
-		bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
+	if (radio->revision == 4 ||
+	     radio->revision == 5) {
+		bcm43xx_radio_write16(bcm, 0x0051, 0x0037);
+		bcm43xx_radio_write16(bcm, 0x0052, 0x0070);
+		bcm43xx_radio_write16(bcm, 0x0053, 0x00B3);
+		bcm43xx_radio_write16(bcm, 0x0054, 0x009B);
 		bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
 		bcm43xx_radio_write16(bcm, 0x005B, 0x0088);
 		bcm43xx_radio_write16(bcm, 0x005D, 0x0088);
 		bcm43xx_radio_write16(bcm, 0x005E, 0x0088);
 		bcm43xx_radio_write16(bcm, 0x007D, 0x0088);
 	}
-	if ((radio->manufact == 0x17F) &&
-	    (radio->version == 0x2050) &&
-	    (radio->revision == 6)) {
-		bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
-		bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
-		bcm43xx_radio_write16(bcm, 0x0053, 0x00B7);
-		bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
-		bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
-		bcm43xx_radio_write16(bcm, 0x005B, 0x008B);
-		bcm43xx_radio_write16(bcm, 0x005C, 0x00B5);
-		bcm43xx_radio_write16(bcm, 0x005D, 0x0088);
-		bcm43xx_radio_write16(bcm, 0x005E, 0x0088);
-		bcm43xx_radio_write16(bcm, 0x007D, 0x0088);
-		bcm43xx_radio_write16(bcm, 0x007C, 0x0001);
-		bcm43xx_radio_write16(bcm, 0x007E, 0x0008);
-	}
-	if ((radio->manufact == 0x17F) &&
-	    (radio->version == 0x2050) &&
-	    (radio->revision == 7)) {
-		bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
-		bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
-		bcm43xx_radio_write16(bcm, 0x0053, 0x00B7);
-		bcm43xx_radio_write16(bcm, 0x0054, 0x0098);
-		bcm43xx_radio_write16(bcm, 0x005A, 0x0088);
-		bcm43xx_radio_write16(bcm, 0x005B, 0x00A8);
-		bcm43xx_radio_write16(bcm, 0x005C, 0x0075);
-		bcm43xx_radio_write16(bcm, 0x005D, 0x00F5);
-		bcm43xx_radio_write16(bcm, 0x005E, 0x00B8);
-		bcm43xx_radio_write16(bcm, 0x007D, 0x00E8);
-		bcm43xx_radio_write16(bcm, 0x007C, 0x0001);
-		bcm43xx_radio_write16(bcm, 0x007E, 0x0008);
-		bcm43xx_radio_write16(bcm, 0x007B, 0x0000);
-	}
-	if ((radio->manufact == 0x17F) &&
-	    (radio->version == 0x2050) &&
-	    (radio->revision == 8)) {
+	if (radio->revision == 8) {
 		bcm43xx_radio_write16(bcm, 0x0051, 0x0000);
 		bcm43xx_radio_write16(bcm, 0x0052, 0x0040);
 		bcm43xx_radio_write16(bcm, 0x0053, 0x00B7);
@@ -933,20 +904,26 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
 		                  bcm43xx_phy_read(bcm, 0x0802) | 0x0100);
 		bcm43xx_phy_write(bcm, 0x042B,
 		                  bcm43xx_phy_read(bcm, 0x042B) | 0x2000);
+		bcm43xx_phy_write(bcm, 0x5B, 0x0000);
+		bcm43xx_phy_write(bcm, 0x5C, 0x0000);
 	}
 
-	/* Force to channel 7, even if not supported. */
-	bcm43xx_radio_selectchannel(bcm, 7, 0);
+	old_channel = radio->channel;
+	if (old_channel >= 8)
+		bcm43xx_radio_selectchannel(bcm, 1, 0);
+	else
+		bcm43xx_radio_selectchannel(bcm, 13, 0);
 
 	bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
 	bcm43xx_radio_write16(bcm, 0x0050, 0x0023);
 	udelay(40);
-	bcm43xx_radio_write16(bcm, 0x007C, (bcm43xx_radio_read16(bcm, 0x007C) | 0x0002));
-	bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
-	if (radio->manufact == 0x17F &&
-	    radio->version == 0x2050 &&
-	    radio->revision <= 2) {
+	if (radio->revision < 6 || radio-> revision == 8) {
+		bcm43xx_radio_write16(bcm, 0x007C, (bcm43xx_radio_read16(bcm, 0x007C)
+				      | 0x0002));
 		bcm43xx_radio_write16(bcm, 0x0050, 0x0020);
+	}
+	if (radio->revision <= 2) {
+		bcm43xx_radio_write16(bcm, 0x007C, 0x0020);
 		bcm43xx_radio_write16(bcm, 0x005A, 0x0070);
 		bcm43xx_radio_write16(bcm, 0x005B, 0x007B);
 		bcm43xx_radio_write16(bcm, 0x005C, 0x00B0);
@@ -954,46 +931,41 @@ static void bcm43xx_phy_initb6(struct bcm43xx_private *bcm)
 	bcm43xx_radio_write16(bcm, 0x007A,
 	                      (bcm43xx_radio_read16(bcm, 0x007A) & 0x00F8) | 0x0007);
 
-	bcm43xx_radio_selectchannel(bcm, BCM43xx_RADIO_DEFAULT_CHANNEL_BG, 0);
+	bcm43xx_radio_selectchannel(bcm, old_channel, 0);
 
 	bcm43xx_phy_write(bcm, 0x0014, 0x0200);
-	if (radio->version == 0x2050){
-		if (radio->revision == 3 ||
-		    radio->revision == 4 ||
-		    radio->revision == 5)
-			bcm43xx_phy_write(bcm, 0x002A, 0x8AC0);
-		else
-			bcm43xx_phy_write(bcm, 0x002A, 0x88C2);
-	}
+	if (radio->revision >= 6)
+		bcm43xx_phy_write(bcm, 0x002A, 0x88C2);
+	else
+		bcm43xx_phy_write(bcm, 0x002A, 0x8AC0);
 	bcm43xx_phy_write(bcm, 0x0038, 0x0668);
 	bcm43xx_radio_set_txpower_bg(bcm, 0xFFFF, 0xFFFF, 0xFFFF);
-	if (radio->version == 0x2050) {
-		if (radio->revision == 3 ||
-		    radio->revision == 4 ||
-		    radio->revision == 5)
-			bcm43xx_phy_write(bcm, 0x005D, bcm43xx_phy_read(bcm, 0x005D) | 0x0003);
-		else if (radio->revision <= 2)
-			bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
-	}
+	if (radio->revision <= 5)
+		bcm43xx_phy_write(bcm, 0x005D, bcm43xx_phy_read(bcm, 0x005D) | 0x0003);
+	if (radio->revision <= 2)
+		bcm43xx_radio_write16(bcm, 0x005D, 0x000D);
 	
-	if (phy->rev == 4)
-		bcm43xx_phy_write(bcm, 0x0002, (bcm43xx_phy_read(bcm, 0x0002) & 0xFFC0) | 0x0004);
-	else
+	if (phy->analog == 4){
 		bcm43xx_write16(bcm, 0x03E4, 0x0009);
+		bcm43xx_phy_write(bcm, 0x61, bcm43xx_phy_read(bcm, 0x61) & 0xFFF);
+	} else {
+		bcm43xx_phy_write(bcm, 0x0002, (bcm43xx_phy_read(bcm, 0x0002) & 0xFFC0) | 0x0004);
+	}
+	if (phy->type == BCM43xx_PHYTYPE_G)
+		bcm43xx_write16(bcm, 0x03E6, 0x0);
 	if (phy->type == BCM43xx_PHYTYPE_B) {
 		bcm43xx_write16(bcm, 0x03E6, 0x8140);
 		bcm43xx_phy_write(bcm, 0x0016, 0x0410);
 		bcm43xx_phy_write(bcm, 0x0017, 0x0820);
 		bcm43xx_phy_write(bcm, 0x0062, 0x0007);
 		(void) bcm43xx_radio_calibrationvalue(bcm);
-		bcm43xx_phy_lo_b_measure(bcm);
+		bcm43xx_phy_lo_g_measure(bcm);
 		if (bcm->sprom.boardflags & BCM43xx_BFL_RSSI) {
 			bcm43xx_calc_nrssi_slope(bcm);
 			bcm43xx_calc_nrssi_threshold(bcm);
 		}
 		bcm43xx_phy_init_pctl(bcm);
-	} else
-		bcm43xx_write16(bcm, 0x03E6, 0x0);
+	}
 }
 
 static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
@@ -1063,7 +1035,7 @@ static void bcm43xx_calc_loopback_gain(struct bcm43xx_private *bcm)
 	bcm43xx_phy_write(bcm, 0x005A, 0x0780);
 	bcm43xx_phy_write(bcm, 0x0059, 0xC810);
 	bcm43xx_phy_write(bcm, 0x0058, 0x000D);
-	if (phy->version == 0) {
+	if (phy->analog == 0) {
 		bcm43xx_phy_write(bcm, 0x0003, 0x0122);
 	} else {
 		bcm43xx_phy_write(bcm, 0x000A,
@@ -1205,27 +1177,30 @@ static void bcm43xx_phy_initg(struct bcm43xx_private *bcm)
 	if (phy->rev >= 2) {
 		bcm43xx_phy_write(bcm, 0x0814, 0x0000);
 		bcm43xx_phy_write(bcm, 0x0815, 0x0000);
-		if (phy->rev == 2)
-			bcm43xx_phy_write(bcm, 0x0811, 0x0000);
-		else if (phy->rev >= 3)
-			bcm43xx_phy_write(bcm, 0x0811, 0x0400);
+	}
+	if (phy->rev == 2) {
+		bcm43xx_phy_write(bcm, 0x0811, 0x0000);
 		bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
-		if (phy->connected) {
-			tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF;
-			if (tmp < 6) {
-				bcm43xx_phy_write(bcm, 0x04C2, 0x1816);
-				bcm43xx_phy_write(bcm, 0x04C3, 0x8006);
-				if (tmp != 3) {
-					bcm43xx_phy_write(bcm, 0x04CC,
-							  (bcm43xx_phy_read(bcm, 0x04CC)
-							   & 0x00FF) | 0x1F00);
-				}
+	}
+	if (phy->rev >= 3) {
+		bcm43xx_phy_write(bcm, 0x0811, 0x0400);
+		bcm43xx_phy_write(bcm, 0x0015, 0x00C0);
+	}
+	if (phy->connected) {
+		tmp = bcm43xx_phy_read(bcm, 0x0400) & 0xFF;
+		if (tmp < 6) {
+			bcm43xx_phy_write(bcm, 0x04C2, 0x1816);
+			bcm43xx_phy_write(bcm, 0x04C3, 0x8006);
+			if (tmp != 3) {
+				bcm43xx_phy_write(bcm, 0x04CC,
+						  (bcm43xx_phy_read(bcm, 0x04CC)
+						   & 0x00FF) | 0x1F00);
 			}
 		}
 	}
 	if (phy->rev < 3 && phy->connected)
 		bcm43xx_phy_write(bcm, 0x047E, 0x0078);
-	if (phy->rev >= 6 && phy->rev <= 8) {
+	if (radio->revision == 8) {
 		bcm43xx_phy_write(bcm, 0x0801, bcm43xx_phy_read(bcm, 0x0801) | 0x0080);
 		bcm43xx_phy_write(bcm, 0x043E, bcm43xx_phy_read(bcm, 0x043E) | 0x0004);
 	}
@@ -1638,14 +1613,14 @@ void bcm43xx_phy_set_baseband_attenuation(struct bcm43xx_private *bcm,
 	struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
 	u16 value;
 
-	if (phy->version == 0) {
+	if (phy->analog == 0) {
 		value = (bcm43xx_read16(bcm, 0x03E6) & 0xFFF0);
 		value |= (baseband_attenuation & 0x000F);
 		bcm43xx_write16(bcm, 0x03E6, value);
 		return;
 	}
 
-	if (phy->version > 1) {
+	if (phy->analog > 1) {
 		value = bcm43xx_phy_read(bcm, 0x0060) & ~0x003C;
 		value |= (baseband_attenuation << 2) & 0x003C;
 	} else {
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
index af19a07..32beb91 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_radio.c
@@ -1393,11 +1393,12 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
 	backup[12] = bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT);
 
 	// Initialization
-	if (phy->version == 0) {
+	if (phy->analog == 0) {
 		bcm43xx_write16(bcm, 0x03E6, 0x0122);
 	} else {
-		if (phy->version >= 2)
-			bcm43xx_write16(bcm, 0x03E6, 0x0040);
+		if (phy->analog >= 2)
+			bcm43xx_phy_write(bcm, 0x0003, (bcm43xx_phy_read(bcm, 0x0003)
+					& 0xFFBF) | 0x0040);
 		bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT,
 		                (bcm43xx_read16(bcm, BCM43xx_MMIO_CHANNEL_EXT) | 0x2000));
 	}
@@ -1405,7 +1406,7 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
 	ret = bcm43xx_radio_calibrationvalue(bcm);
 
 	if (phy->type == BCM43xx_PHYTYPE_B)
-		bcm43xx_radio_write16(bcm, 0x0078, 0x0003);
+		bcm43xx_radio_write16(bcm, 0x0078, 0x0026);
 
 	bcm43xx_phy_write(bcm, 0x0015, 0xBFAF);
 	bcm43xx_phy_write(bcm, 0x002B, 0x1403);
@@ -1416,7 +1417,7 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
 	                      (bcm43xx_radio_read16(bcm, 0x0051) | 0x0004));
 	bcm43xx_radio_write16(bcm, 0x0052, 0x0000);
 	bcm43xx_radio_write16(bcm, 0x0043,
-			      bcm43xx_radio_read16(bcm, 0x0043) | 0x0009);
+			      (bcm43xx_radio_read16(bcm, 0x0043) & 0xFFF0) | 0x0009);
 	bcm43xx_phy_write(bcm, 0x0058, 0x0000);
 
 	for (i = 0; i < 16; i++) {
@@ -1488,7 +1489,7 @@ u16 bcm43xx_radio_init2050(struct bcm43xx_private *bcm)
 	bcm43xx_phy_write(bcm, 0x0059, backup[17]);
 	bcm43xx_phy_write(bcm, 0x0058, backup[18]);
 	bcm43xx_write16(bcm, 0x03E6, backup[11]);
-	if (phy->version != 0)
+	if (phy->analog != 0)
 		bcm43xx_write16(bcm, BCM43xx_MMIO_CHANNEL_EXT, backup[12]);
 	bcm43xx_phy_write(bcm, 0x0035, backup[10]);
 	bcm43xx_radio_selectchannel(bcm, radio->channel, 1);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
index 2aed19e..9ecf2bf 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
@@ -137,14 +137,8 @@ struct bcm43xx_xmitstatus {
 	u16 unknown; //FIXME
 };
 
-#define BCM43xx_TXSTAT_FLAG_ACK		0x01
-//TODO #define BCM43xx_TXSTAT_FLAG_???	0x02
-//TODO #define BCM43xx_TXSTAT_FLAG_???	0x04
-//TODO #define BCM43xx_TXSTAT_FLAG_???	0x08
-//TODO #define BCM43xx_TXSTAT_FLAG_???	0x10
-#define BCM43xx_TXSTAT_FLAG_IGNORE	0x20
-//TODO #define BCM43xx_TXSTAT_FLAG_???	0x40
-//TODO #define BCM43xx_TXSTAT_FLAG_???	0x80
+#define BCM43xx_TXSTAT_FLAG_AMPDU	0x10
+#define BCM43xx_TXSTAT_FLAG_INTER	0x20
 
 u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate);
 u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate);
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index e89c890..ef37a75 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -2,13 +2,14 @@
 #define HOSTAP_H
 
 #include <linux/ethtool.h>
+#include <linux/kernel.h>
 
 #include "hostap_wlan.h"
 #include "hostap_ap.h"
 
 static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
 				  2447, 2452, 2457, 2462, 2467, 2472, 2484 };
-#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0]))
+#define FREQ_COUNT ARRAY_SIZE(freq_list)
 
 /* hostap.c */
 
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index d0639a4..ad6e4a4 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -2888,7 +2888,7 @@ static int __ipw2100_tx_process(struct ipw2100_priv *priv)
 
 #ifdef CONFIG_IPW2100_DEBUG
 		if (packet->info.c_struct.cmd->host_command_reg <
-		    sizeof(command_types) / sizeof(*command_types))
+		    ARRAY_SIZE(command_types))
 			IPW_DEBUG_TX("Command '%s (%d)' processed: %d.\n",
 				     command_types[packet->info.c_struct.cmd->
 						   host_command_reg],
@@ -3736,7 +3736,7 @@ static ssize_t show_registers(struct device *d, struct device_attribute *attr,
 
 	out += sprintf(out, "%30s [Address ] : Hex\n", "Register");
 
-	for (i = 0; i < (sizeof(hw_data) / sizeof(*hw_data)); i++) {
+	for (i = 0; i < ARRAY_SIZE(hw_data); i++) {
 		read_register(dev, hw_data[i].addr, &val);
 		out += sprintf(out, "%30s [%08X] : %08X\n",
 			       hw_data[i].name, hw_data[i].addr, val);
@@ -3757,7 +3757,7 @@ static ssize_t show_hardware(struct device *d, struct device_attribute *attr,
 
 	out += sprintf(out, "%30s [Address ] : Hex\n", "NIC entry");
 
-	for (i = 0; i < (sizeof(nic_data) / sizeof(*nic_data)); i++) {
+	for (i = 0; i < ARRAY_SIZE(nic_data); i++) {
 		u8 tmp8;
 		u16 tmp16;
 		u32 tmp32;
@@ -3894,13 +3894,11 @@ static ssize_t show_ordinals(struct device *d, struct device_attribute *attr,
 	if (priv->status & STATUS_RF_KILL_MASK)
 		return 0;
 
-	if (loop >= sizeof(ord_data) / sizeof(*ord_data))
+	if (loop >= ARRAY_SIZE(ord_data))
 		loop = 0;
 
 	/* sysfs provides us PAGE_SIZE buffer */
-	while (len < PAGE_SIZE - 128 &&
-	       loop < (sizeof(ord_data) / sizeof(*ord_data))) {
-
+	while (len < PAGE_SIZE - 128 && loop < ARRAY_SIZE(ord_data)) {
 		val_len = sizeof(u32);
 
 		if (ipw2100_get_ordinal(priv, ord_data[loop].index, &val,
@@ -6589,7 +6587,7 @@ static const long ipw2100_rates_11b[] = {
 	11000000
 };
 
-#define RATE_COUNT (sizeof(ipw2100_rates_11b) / sizeof(ipw2100_rates_11b[0]))
+#define RATE_COUNT ARRAY_SIZE(ipw2100_rates_11b)
 
 static int ipw2100_wx_get_name(struct net_device *dev,
 			       struct iw_request_info *info,
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 838d510..841b3c1 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -1395,11 +1395,16 @@ static int prism54_set_auth(struct net_device *ndev,
 		break;
 
 	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
-		dot1x = param->value ? 1 : 0;
+		/* dot1x should be the opposite of RX_UNENCRYPTED_EAPOL;
+		 * turn off dot1x when allowing receipt of unencrypted EAPOL
+		 * frames, turn on dot1x when receipt should be disallowed
+		 */
+		dot1x = param->value ? 0 : 0x01;
 		break;
 
 	case IW_AUTH_PRIVACY_INVOKED:
 		privinvoked = param->value ? 1 : 0;
+		break;
 
 	case IW_AUTH_DROP_UNENCRYPTED:
 		exunencrypt = param->value ? 1 : 0;
@@ -1589,6 +1594,7 @@ static int prism54_set_encodeext(struct net_device *ndev,
 			}
 			key.type = DOT11_PRIV_TKIP;
 			key.length = KEY_SIZE_TKIP;
+			break;
 		default:
 			return -EINVAL;
 		}
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index e6cf9df..4278032 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -16,6 +16,8 @@
  *
  */
 
+#include <linux/kernel.h>
+
 #include "prismcompat.h"
 #include "islpci_dev.h"
 #include "islpci_mgt.h"
@@ -692,7 +694,7 @@ mgt_update_addr(islpci_private *priv)
 	return ret;
 }
 
-#define VEC_SIZE(a) (sizeof(a)/sizeof(a[0]))
+#define VEC_SIZE(a) ARRAY_SIZE(a)
 
 int
 mgt_commit(islpci_private *priv)
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 24221e4..2aa3c76 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -28,7 +28,7 @@
  */
 static u8 wv_irq_to_psa(int irq)
 {
-	if (irq < 0 || irq >= NELS(irqvals))
+	if (irq < 0 || irq >= ARRAY_SIZE(irqvals))
 		return 0;
 
 	return irqvals[irq];
@@ -42,7 +42,7 @@ static int __init wv_psa_to_irq(u8 irqval)
 {
 	int irq;
 
-	for (irq = 0; irq < NELS(irqvals); irq++)
+	for (irq = 0; irq < ARRAY_SIZE(irqvals); irq++)
 		if (irqvals[irq] == irqval)
 			return irq;
 
@@ -1695,7 +1695,7 @@ static int wv_frequency_list(unsigned long ioaddr,	/* I/O port of the card */
 		/* Look in the table if the frequency is allowed */
 		if (table[9 - (freq / 16)] & (1 << (freq % 16))) {
 			/* Compute approximate channel number */
-			while ((c < NELS(channel_bands)) &&
+			while ((c < ARRAY_SIZE(channel_bands)) &&
 				(((channel_bands[c] >> 1) - 24) < freq)) 
 				c++;
 			list[i].i = c;	/* Set the list index */
@@ -4269,7 +4269,7 @@ struct net_device * __init wavelan_probe(int unit)
 		printk(KERN_DEBUG "%s: <-wavelan_probe()\n", dev->name);
 #endif
 	} else { /* Scan all possible addresses of the WaveLAN hardware. */
-		for (i = 0; i < NELS(iobase); i++) {
+		for (i = 0; i < ARRAY_SIZE(iobase); i++) {
 			dev->irq = def_irq;
 			if (wavelan_config(dev, iobase[i]) == 0) {
 #ifdef DEBUG_CALLBACK_TRACE
@@ -4280,7 +4280,7 @@ struct net_device * __init wavelan_probe(int unit)
 				break;
 			}
 		}
-		if (i == NELS(iobase))
+		if (i == ARRAY_SIZE(iobase))
 			r = -ENODEV;
 	}
 	if (r) 
@@ -4327,14 +4327,14 @@ int __init init_module(void)
 #endif
 
 		/* Copy the basic set of address to be probed. */
-		for (i = 0; i < NELS(iobase); i++)
+		for (i = 0; i < ARRAY_SIZE(iobase); i++)
 			io[i] = iobase[i];
 	}
 
 
 	/* Loop on all possible base addresses. */
 	i = -1;
-	while ((io[++i] != 0) && (i < NELS(io))) {
+	while ((io[++i] != 0) && (i < ARRAY_SIZE(io))) {
 		struct net_device *dev = alloc_etherdev(sizeof(net_local));
 		if (!dev)
 			break;
diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
index 72b646c..fe24281 100644
--- a/drivers/net/wireless/wavelan.p.h
+++ b/drivers/net/wireless/wavelan.p.h
@@ -449,9 +449,6 @@ static const char	*version	= "wavelan.c : v24 (SMP + wireless extensions) 11/12/
 /* Watchdog temporisation */
 #define	WATCHDOG_JIFFIES	(512*HZ/100)
 
-/* Macro to get the number of elements in an array */
-#define	NELS(a)				(sizeof(a) / sizeof(a[0]))
-
 /* ------------------------ PRIVATE IOCTL ------------------------ */
 
 #define SIOCSIPQTHR	SIOCIWFIRSTPRIV		/* Set quality threshold */
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c
index 12dfc0b..9c64f89 100644
--- a/drivers/net/wireless/zd1211rw/zd_chip.c
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c
@@ -113,7 +113,7 @@ int zd_ioread32v_locked(struct zd_chip *chip, u32 *values, const zd_addr_t *addr
 
 	/* Allocate a single memory block for values and addresses. */
 	count16 = 2*count;
-	a16 = kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
+	a16 = (zd_addr_t *) kmalloc(count16 * (sizeof(zd_addr_t) + sizeof(u16)),
 		                   GFP_NOFS);
 	if (!a16) {
 		dev_dbg_f(zd_chip_dev(chip),
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 7c269f4..447c52b 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -334,7 +334,7 @@
  * separate range because of collisions with other tools such as
  * 'mii-tool'.
  * We now have 32 commands, so a bit more space ;-).
- * Also, all 'odd' commands are only usable by root and don't return the
+ * Also, all 'even' commands are only usable by root and don't return the
  * content of ifr/iwr to user (but you are not obliged to use the set/get
  * convention, just use every other two command). More details in iwpriv.c.
  * And I repeat : you are not forced to use them with iwpriv, but you
@@ -348,7 +348,7 @@
 #define SIOCIWLAST	SIOCIWLASTPRIV		/* 0x8BFF */
 #define IW_IOCTL_IDX(cmd)	((cmd) - SIOCIWFIRST)
 
-/* Even : get (world access), odd : set (root access) */
+/* Odd : get (world access), even : set (root access) */
 #define IW_IS_SET(cmd)	(!((cmd) & 0x1))
 #define IW_IS_GET(cmd)	((cmd) & 0x1)
 
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
index 4f8c3ef..e9cdc66 100644
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ b/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -265,17 +265,10 @@ void ieee80211softmac_init_bss(struct ieee80211softmac_device *mac)
 	/* Change the default txrate to the highest possible value.
 	 * The txrate machine will lower it, if it is too high.
 	 */
-	/* FIXME: We don't correctly handle backing down to lower
-	   rates, so 801.11g devices start off at 11M for now. People
-	   can manually change it if they really need to, but 11M is
-	   more reliable. Note similar logic in
-	   ieee80211softmac_wx_set_rate() */
-	if (ieee->modulation & IEEE80211_CCK_MODULATION) {
+	if (ieee->modulation & IEEE80211_OFDM_MODULATION)
+		txrates->user_rate = IEEE80211_OFDM_RATE_24MB;
+	else
 		txrates->user_rate = IEEE80211_CCK_RATE_11MB;
-	} else if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
-		txrates->user_rate = IEEE80211_OFDM_RATE_54MB;
-	} else
-		assert(0);
 
 	txrates->default_rate = IEEE80211_CCK_RATE_1MB;
 	change |= IEEE80211SOFTMAC_TXRATECHG_DEFAULT;
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index c306d52..f13937b 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -177,15 +177,10 @@ ieee80211softmac_wx_set_rate(struct net_device *net_dev,
 	int err = -EINVAL;
 
 	if (in_rate == -1) {
-		/* FIXME: We don't correctly handle backing down to lower
-		   rates, so 801.11g devices start off at 11M for now. People
-		   can manually change it if they really need to, but 11M is
-		   more reliable. Note similar logic in
-		   ieee80211softmac_wx_set_rate() */
-		if (ieee->modulation & IEEE80211_CCK_MODULATION)
-			in_rate = 11000000;
+		if (ieee->modulation & IEEE80211_OFDM_MODULATION)
+			in_rate = 24000000;
 		else
-			in_rate = 54000000;
+			in_rate = 11000000;
 	}
 
 	switch (in_rate) {

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2007-02-17 22:17 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2007-02-17 22:17 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML

Mostly fixes, a few cleanups. nothing really notable.

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 MAINTAINERS                                 |    4 +-
 drivers/atm/he.c                            |    2 +-
 drivers/atm/idt77252.c                      |    8 +-
 drivers/atm/nicstarmac.c                    |    4 +-
 drivers/net/Kconfig                         |   14 ++-
 drivers/net/arcnet/arc-rawmode.c            |    4 +-
 drivers/net/arcnet/arcnet.c                 |    2 +-
 drivers/net/arcnet/com20020-pci.c           |    3 +
 drivers/net/arcnet/com20020.c               |    2 +-
 drivers/net/atl1/atl1_hw.c                  |   37 ++++---
 drivers/net/atl1/atl1_main.c                |    5 +-
 drivers/net/b44.c                           |   19 ++--
 drivers/net/cxgb3/cxgb3_defs.h              |    1 -
 drivers/net/cxgb3/cxgb3_offload.c           |    1 -
 drivers/net/cxgb3/cxgb3_offload.h           |    1 -
 drivers/net/cxgb3/l2t.c                     |    1 -
 drivers/net/cxgb3/l2t.h                     |    1 -
 drivers/net/cxgb3/t3cdev.h                  |    1 -
 drivers/net/e1000/e1000.h                   |    1 -
 drivers/net/e1000/e1000_ethtool.c           |    2 +-
 drivers/net/e1000/e1000_main.c              |   70 ++----------
 drivers/net/ehea/ehea.h                     |    2 +-
 drivers/net/ehea/ehea_main.c                |    8 +-
 drivers/net/ehea/ehea_phyp.c                |   10 ++
 drivers/net/ehea/ehea_phyp.h                |    3 +
 drivers/net/ehea/ehea_qmr.c                 |   42 +++++++
 drivers/net/ehea/ehea_qmr.h                 |    5 +
 drivers/net/gianfar.c                       |   85 +++-----------
 drivers/net/gianfar_sysfs.c                 |  108 +++++++++--------
 drivers/net/ioc3-eth.c                      |   16 ++-
 drivers/net/macb.c                          |   24 +----
 drivers/net/meth.c                          |   26 ++--
 drivers/net/netxen/netxen_nic.h             |    9 +-
 drivers/net/netxen/netxen_nic_ethtool.c     |    9 +-
 drivers/net/netxen/netxen_nic_hw.c          |    2 +
 drivers/net/netxen/netxen_nic_init.c        |   12 ++-
 drivers/net/netxen/netxen_nic_main.c        |    3 +-
 drivers/net/netxen/netxen_nic_niu.c         |    2 +-
 drivers/net/pcmcia/3c574_cs.c               |    2 +-
 drivers/net/pcmcia/smc91c92_cs.c            |    2 +-
 drivers/net/phy/marvell.c                   |  156 ++++++++++++++++++++++--
 drivers/net/phy/phy_device.c                |    4 +-
 drivers/net/sk98lin/skge.c                  |    3 +
 drivers/net/sky2.c                          |  125 +++++++++++++-------
 drivers/net/sky2.h                          |    3 +-
 drivers/net/wan/Kconfig                     |    2 +-
 drivers/net/wan/pc300too.c                  |    2 +-
 drivers/net/wireless/bcm43xx/bcm43xx.h      |    1 +
 drivers/net/wireless/bcm43xx/bcm43xx_dma.c  |  171 +++++++++++++++++++--------
 drivers/net/wireless/bcm43xx/bcm43xx_main.c |   25 +++--
 drivers/net/wireless/bcm43xx/bcm43xx_wx.c   |   28 ++--
 drivers/net/wireless/ipw2100.c              |   16 ++--
 drivers/net/wireless/zd1211rw/zd_mac.c      |   44 ++++++--
 drivers/net/wireless/zd1211rw/zd_usb.c      |   12 ++
 include/linux/pci_ids.h                     |    1 +
 net/core/net-sysfs.c                        |    4 +-
 net/ieee80211/ieee80211_tx.c                |    3 -
 57 files changed, 706 insertions(+), 447 deletions(-)

Ahmed S. Darwish (1):
      atm: Use ARRAY_SIZE macro when appropriate

Al Viro (1):
      atl1: fix bad ioread address

Amit S. Kale (3):
      NetXen: Fixes for ppc architecture.
      NetXen: Updates for ethtool support
      NetXen: Fix to get the driver working after sparse changes

Andy Fleming (1):
      phylib: Add support for Marvell 88e1111S and 88e1145

Baruch Even (1):
      Hostess SV-11 depends on INET

Chris Snook (2):
      atl1: remove unused define
      atl1: add L1 device id to pci_ids, then use it

Daniel Drake (2):
      zd1211rw: Remove noisy debug message
      sk98lin: mark deprecated in Kconfig

Gary Zambrano (2):
      b44: replace define
      B44: increase wait loop

Haavard Skinnemoen (1):
      macb: Remove inappropriate spinlocks around mii calls

Jan-Bernd Themann (1):
      ehea: Fixed error recovery

Jay Cliburn (3):
      atl1: drop NET_PCI from Kconfig
      atl1: read MAC address from register
      atl1: bump version number

Jeff Morrow (1):
      bugfixes and new hardware support for arcnet driver

Kok, Auke (3):
      e1000: fix shared interrupt warning message
      e1000: remove obsolete custom pci_save_state code
      e1000: allow ethtool to see link status when down

Komuro (1):
      PCMCIA-NETDEV : the 2nd argument of el3_interrrupt and smc_interrupt is struct net_device*

Kumar Gala (1):
      Convert network devices to use struct device instead of class_device

Larry Finger (5):
      bcm43xx: Fix problem with >1 GB RAM
      bcm43xx: Fix scaling error for 'iwlist rate' information
      bcm43xx: Fix scaling error for 'iwlist freq' information
      bcm43xx: Check error returns in initialization routines
      ieee80211: Fix sparse warning

Maxime Austruy (1):
      zd1211rw: fix potential leak in usb_init

Michael Buesch (1):
      bcm43xx: Enable fwpostfix in nondebug bcm43xx

pcnet32@verizon.net (2):
      MAINTAINER
      pcnet32 NAPI no longer experimental

Ralf Baechle (2):
      Convert meth to netdev_priv
      Fix link autonegotiation timer.

Randy Dunlap (1):
      phy devices: use same arg types

Richard Knutsson (1):
      net/wan/pc300too.c: pci_module_init to pci_register_driver

Robert P. J. Day (2):
      Rename IPW2100 debugging macros to not look like config options.
      Replace incorrect macro name "WIRELESS_EXT" with "CONFIG_WIRELESS_EXT"

Sergei Shtylyov (1):
      gianfar: don't duplicate gfar_error()

Stephen Hemminger (7):
      sky2: dont flush good pause frames
      sky2: no need to reset pause bits on shutdown
      sky2: flow control negotiation for Yukon-FE
      sky2: transmit timeout
      sky2: receive error handling improvements
      sky2: v1.13
      sk98lin: planned removal

Steve Wise (1):
      cxgb3 Fix copyrights in the cxgb3 driver.

Ulrich Kunitz (3):
      zd1211rw: Reset device in the probe call
      zd1211rw: Fixed array size issue in reset_mode
      zd1211rw: Added error stats update

diff --git a/MAINTAINERS b/MAINTAINERS
index b0fd71b..c0f9a1a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2623,8 +2623,8 @@ T:	git kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
 S:	Maintained
 
 PCNET32 NETWORK DRIVER
-P:	Thomas Bogendörfer
-M:	tsbogend@alpha.franken.de
+P:	Don Fry
+M:	pcnet32@verizon.net
 L:	netdev@vger.kernel.org
 S:	Maintained
 
diff --git a/drivers/atm/he.c b/drivers/atm/he.c
index db33f6f..8510026 100644
--- a/drivers/atm/he.c
+++ b/drivers/atm/he.c
@@ -3017,7 +3017,7 @@ read_prom_byte(struct he_dev *he_dev, int addr)
 	he_writel(he_dev, val, HOST_CNTL);
        
 	/* Send READ instruction */
-	for (i = 0; i < sizeof(readtab)/sizeof(readtab[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(readtab); i++) {
 		he_writel(he_dev, val | readtab[i], HOST_CNTL);
 		udelay(EEPROM_DELAY);
 	}
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c
index f407861..b4b8014 100644
--- a/drivers/atm/idt77252.c
+++ b/drivers/atm/idt77252.c
@@ -388,7 +388,7 @@ idt77252_eeprom_read_status(struct idt77252_dev *card)
 
 	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
 
-	for (i = 0; i < sizeof(rdsrtab)/sizeof(rdsrtab[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(rdsrtab); i++) {
 		idt77252_write_gp(card, gp | rdsrtab[i]);
 		udelay(5);
 	}
@@ -422,7 +422,7 @@ idt77252_eeprom_read_byte(struct idt77252_dev *card, u8 offset)
 
 	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
 
-	for (i = 0; i < sizeof(rdtab)/sizeof(rdtab[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(rdtab); i++) {
 		idt77252_write_gp(card, gp | rdtab[i]);
 		udelay(5);
 	}
@@ -469,14 +469,14 @@ idt77252_eeprom_write_byte(struct idt77252_dev *card, u8 offset, u8 data)
 
 	gp = idt77252_read_gp(card) & ~(SAR_GP_EESCLK|SAR_GP_EECS|SAR_GP_EEDO);
 
-	for (i = 0; i < sizeof(wrentab)/sizeof(wrentab[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(wrentab); i++) {
 		idt77252_write_gp(card, gp | wrentab[i]);
 		udelay(5);
 	}
 	idt77252_write_gp(card, gp | SAR_GP_EECS);
 	udelay(5);
 
-	for (i = 0; i < sizeof(wrtab)/sizeof(wrtab[0]); i++) {
+	for (i = 0; i < ARRAY_SIZE(wrtab); i++) {
 		idt77252_write_gp(card, gp | wrtab[i]);
 		udelay(5);
 	}
diff --git a/drivers/atm/nicstarmac.c b/drivers/atm/nicstarmac.c
index 2c5e3ae..480947f 100644
--- a/drivers/atm/nicstarmac.c
+++ b/drivers/atm/nicstarmac.c
@@ -7,6 +7,8 @@
  * Read this ForeRunner's MAC address from eprom/eeprom
  */
 
+#include <linux/kernel.h>
+
 typedef void __iomem *virt_addr_t;
 
 #define CYCLE_DELAY 5
@@ -176,7 +178,7 @@ read_eprom_byte(virt_addr_t base, u_int8_t offset)
    val = NICSTAR_REG_READ( base, NICSTAR_REG_GENERAL_PURPOSE ) & 0xFFFFFFF0;
 
    /* Send READ instruction */
-   for (i=0; i<sizeof readtab/sizeof readtab[0]; i++)
+   for (i=0; i<ARRAY_SIZE(readtab); i++)
    {
 	NICSTAR_REG_WRITE( base, NICSTAR_REG_GENERAL_PURPOSE,
 		(val | readtab[i]) );
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 38f41a5..d9400ef 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1284,8 +1284,8 @@ config PCNET32
 	  will be called pcnet32.
 
 config PCNET32_NAPI
-	bool "Use RX polling (NAPI) (EXPERIMENTAL)"
-	depends on PCNET32 && EXPERIMENTAL
+	bool "Use RX polling (NAPI)"
+	depends on PCNET32
 	help
 	  NAPI is a new driver API designed to reduce CPU and interrupt load
 	  when the driver is receiving lots of packets from the card. It is
@@ -2125,14 +2125,16 @@ config SKY2
 	  will be called sky2.  This is recommended.
 
 config SK98LIN
-	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support"
+	tristate "Marvell Yukon Chipset / SysKonnect SK-98xx Support (DEPRECATED)"
 	depends on PCI
 	---help---
 	  Say Y here if you have a Marvell Yukon or SysKonnect SK-98xx/SK-95xx
 	  compliant Gigabit Ethernet Adapter.
 
-	  This driver supports the original Yukon chipset. A cleaner driver is 
-	  also available (skge) which seems to work better than this one.
+	  This driver supports the original Yukon chipset. This driver is
+	  deprecated and will be removed from the kernel in the near future,
+	  it has been replaced by the skge driver. skge is cleaner and
+	  seems to work better.
 
 	  This driver does not support the newer Yukon2 chipset. A separate
 	  driver, sky2, is provided to support Yukon2-based adapters.
@@ -2337,7 +2339,7 @@ config QLA3XXX
 
 config ATL1
 	tristate "Attansic L1 Gigabit Ethernet support (EXPERIMENTAL)"
-	depends on NET_PCI && PCI && EXPERIMENTAL
+	depends on PCI && EXPERIMENTAL
 	select CRC32
 	select MII
 	help
diff --git a/drivers/net/arcnet/arc-rawmode.c b/drivers/net/arcnet/arc-rawmode.c
index e7555d4..6318814 100644
--- a/drivers/net/arcnet/arc-rawmode.c
+++ b/drivers/net/arcnet/arc-rawmode.c
@@ -94,7 +94,7 @@ static void rx(struct net_device *dev, int bufnum,
 
 	BUGMSG(D_DURING, "it's a raw packet (length=%d)\n", length);
 
-	if (length >= MinTU)
+	if (length > MTU)
 		ofs = 512 - length;
 	else
 		ofs = 256 - length;
@@ -183,7 +183,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length,
 		       length, XMTU);
 		length = XMTU;
 	}
-	if (length > MinTU) {
+	if (length >= MinTU) {
 		hard->offset[0] = 0;
 		hard->offset[1] = ofs = 512 - length;
 	} else if (length > MTU) {
diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c
index 4e91dab..83004fd 100644
--- a/drivers/net/arcnet/arcnet.c
+++ b/drivers/net/arcnet/arcnet.c
@@ -41,7 +41,7 @@
  *     <jojo@repas.de>
  */
 
-#define VERSION "arcnet: v3.93 BETA 2000/04/29 - by Avery Pennarun et al.\n"
+#define VERSION "arcnet: v3.94 BETA 2007/02/08 - by Avery Pennarun et al.\n"
 
 #include <linux/module.h>
 #include <linux/types.h>
diff --git a/drivers/net/arcnet/com20020-pci.c b/drivers/net/arcnet/com20020-pci.c
index 98d326b..b8c0fa6 100644
--- a/drivers/net/arcnet/com20020-pci.c
+++ b/drivers/net/arcnet/com20020-pci.c
@@ -155,6 +155,7 @@ static struct pci_device_id com20020pci_id_table[] = {
 	{ 0x1571, 0xa00b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
 	{ 0x1571, 0xa00c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
 	{ 0x1571, 0xa00d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
+	{ 0x1571, 0xa00e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_IS_5MBIT },
 	{ 0x1571, 0xa201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 	{ 0x1571, 0xa202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 	{ 0x1571, 0xa203, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
@@ -163,6 +164,8 @@ static struct pci_device_id com20020pci_id_table[] = {
 	{ 0x1571, 0xa206, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 	{ 0x10B5, 0x9030, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 	{ 0x10B5, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+	{ 0x14BA, 0x6000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
+	{ 0x10B5, 0x2200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ARC_CAN_10MBIT },
 	{0,}
 };
 
diff --git a/drivers/net/arcnet/com20020.c b/drivers/net/arcnet/com20020.c
index 4218075..7cf0a25 100644
--- a/drivers/net/arcnet/com20020.c
+++ b/drivers/net/arcnet/com20020.c
@@ -104,7 +104,7 @@ int com20020_check(struct net_device *dev)
 	SET_SUBADR(SUB_SETUP1);
 	outb(lp->setup, _XREG);
 
-	if (lp->card_flags & ARC_CAN_10MBIT)
+	if (lp->clockm != 0)
 	{
 		SET_SUBADR(SUB_SETUP2);
 		outb(lp->setup2, _XREG);
diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c
index 08b2d78..314dbaa 100644
--- a/drivers/net/atl1/atl1_hw.c
+++ b/drivers/net/atl1/atl1_hw.c
@@ -243,14 +243,8 @@ static int atl1_get_permanent_address(struct atl1_hw *hw)
 			i += 4;
 		}
 
-/*
- * The following 2 lines are the Attansic originals.  Saving for posterity.
- *		*(u32 *) & eth_addr[2] = LONGSWAP(addr[0]);
- *		*(u16 *) & eth_addr[0] = SHORTSWAP(*(u16 *) & addr[1]);
- */
-		*(u32 *) & eth_addr[2] = swab32(addr[0]);
-		*(u16 *) & eth_addr[0] = swab16(*(u16 *) & addr[1]);
-
+		*(u32 *) &eth_addr[2] = swab32(addr[0]);
+		*(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
 		if (is_valid_ether_addr(eth_addr)) {
 			memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
 			return 0;
@@ -281,17 +275,28 @@ static int atl1_get_permanent_address(struct atl1_hw *hw)
 		i += 4;
 	}
 
-/*
- * The following 2 lines are the Attansic originals.  Saving for posterity.
- *	*(u32 *) & eth_addr[2] = LONGSWAP(addr[0]);
- *	*(u16 *) & eth_addr[0] = SHORTSWAP(*(u16 *) & addr[1]);
- */
-	*(u32 *) & eth_addr[2] = swab32(addr[0]);
-	*(u16 *) & eth_addr[0] = swab16(*(u16 *) & addr[1]);
+	*(u32 *) &eth_addr[2] = swab32(addr[0]);
+	*(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
 	if (is_valid_ether_addr(eth_addr)) {
 		memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
 		return 0;
 	}
+
+	/*
+	 * On some motherboards, the MAC address is written by the
+	 * BIOS directly to the MAC register during POST, and is
+	 * not stored in eeprom.  If all else thus far has failed
+	 * to fetch the permanent MAC address, try reading it directly.
+	 */
+	addr[0] = ioread32(hw->hw_addr + REG_MAC_STA_ADDR);
+	addr[1] = ioread16(hw->hw_addr + (REG_MAC_STA_ADDR + 4));
+	*(u32 *) &eth_addr[2] = swab32(addr[0]);
+	*(u16 *) &eth_addr[0] = swab16(*(u16 *) &addr[1]);
+	if (is_valid_ether_addr(eth_addr)) {
+		memcpy(hw->perm_mac_addr, eth_addr, ETH_ALEN);
+		return 0;
+	}
+
 	return 1;
 }
 
@@ -357,7 +362,7 @@ void atl1_hash_set(struct atl1_hw *hw, u32 hash_value)
 	 */
 	hash_reg = (hash_value >> 31) & 0x1;
 	hash_bit = (hash_value >> 26) & 0x1F;
-	mta = ioread32((hw + REG_RX_HASH_TABLE) + (hash_reg << 2));
+	mta = ioread32((hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
 	mta |= (1 << hash_bit);
 	iowrite32(mta, (hw->hw_addr + REG_RX_HASH_TABLE) + (hash_reg << 2));
 }
diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c
index 6655640..6567348 100644
--- a/drivers/net/atl1/atl1_main.c
+++ b/drivers/net/atl1/atl1_main.c
@@ -82,8 +82,7 @@
 
 #include "atl1.h"
 
-#define RUN_REALTIME 0
-#define DRIVER_VERSION "2.0.6"
+#define DRIVER_VERSION "2.0.7"
 
 char atl1_driver_name[] = "atl1";
 static const char atl1_driver_string[] = "Attansic L1 Ethernet Network Driver";
@@ -100,7 +99,7 @@ MODULE_VERSION(DRIVER_VERSION);
  * atl1_pci_tbl - PCI Device ID Table
  */
 static const struct pci_device_id atl1_pci_tbl[] = {
-	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1048)},
+	{PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1)},
 	/* required last entry */
 	{0,}
 };
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 5ff7882..aaada57 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -59,7 +59,6 @@
 #define B44_DEF_TX_RING_PENDING		(B44_TX_RING_SIZE - 1)
 #define B44_TX_RING_BYTES	(sizeof(struct dma_desc) * \
 				 B44_TX_RING_SIZE)
-#define B44_DMA_MASK 0x3fffffff
 
 #define TX_RING_GAP(BP)	\
 	(B44_TX_RING_SIZE - (BP)->tx_pending)
@@ -665,7 +664,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
 	/* Hardware bug work-around, the chip is unable to do PCI DMA
 	   to/from anything above 1GB :-( */
 	if (dma_mapping_error(mapping) ||
-		mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
+		mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
 		/* Sigh... */
 		if (!dma_mapping_error(mapping))
 			pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
@@ -677,7 +676,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
 					 RX_PKT_BUF_SZ,
 					 PCI_DMA_FROMDEVICE);
 		if (dma_mapping_error(mapping) ||
-			mapping + RX_PKT_BUF_SZ > B44_DMA_MASK) {
+			mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
 			if (!dma_mapping_error(mapping))
 				pci_unmap_single(bp->pdev, mapping, RX_PKT_BUF_SZ,PCI_DMA_FROMDEVICE);
 			dev_kfree_skb_any(skb);
@@ -988,7 +987,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	}
 
 	mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
-	if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) {
+	if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
 		/* Chip can't handle DMA to/from >1GB, use bounce buffer */
 		if (!dma_mapping_error(mapping))
 			pci_unmap_single(bp->pdev, mapping, len, PCI_DMA_TODEVICE);
@@ -1000,7 +999,7 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 		mapping = pci_map_single(bp->pdev, bounce_skb->data,
 					 len, PCI_DMA_TODEVICE);
-		if (dma_mapping_error(mapping) || mapping + len > B44_DMA_MASK) {
+		if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
 			if (!dma_mapping_error(mapping))
 				pci_unmap_single(bp->pdev, mapping,
 					 len, PCI_DMA_TODEVICE);
@@ -1227,7 +1226,7 @@ static int b44_alloc_consistent(struct b44 *bp)
 		                             DMA_BIDIRECTIONAL);
 
 		if (dma_mapping_error(rx_ring_dma) ||
-			rx_ring_dma + size > B44_DMA_MASK) {
+			rx_ring_dma + size > DMA_30BIT_MASK) {
 			kfree(rx_ring);
 			goto out_err;
 		}
@@ -1254,7 +1253,7 @@ static int b44_alloc_consistent(struct b44 *bp)
 		                             DMA_TO_DEVICE);
 
 		if (dma_mapping_error(tx_ring_dma) ||
-			tx_ring_dma + size > B44_DMA_MASK) {
+			tx_ring_dma + size > DMA_30BIT_MASK) {
 			kfree(tx_ring);
 			goto out_err;
 		}
@@ -1289,7 +1288,7 @@ static void b44_chip_reset(struct b44 *bp)
 	if (ssb_is_core_up(bp)) {
 		bw32(bp, B44_RCV_LAZY, 0);
 		bw32(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE);
-		b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 100, 1);
+		b44_wait_bit(bp, B44_ENET_CTRL, ENET_CTRL_DISABLE, 200, 1);
 		bw32(bp, B44_DMATX_CTRL, 0);
 		bp->tx_prod = bp->tx_cons = 0;
 		if (br32(bp, B44_DMARX_STAT) & DMARX_STAT_EMASK) {
@@ -2151,13 +2150,13 @@ static int __devinit b44_init_one(struct pci_dev *pdev,
 
 	pci_set_master(pdev);
 
-	err = pci_set_dma_mask(pdev, (u64) B44_DMA_MASK);
+	err = pci_set_dma_mask(pdev, (u64) DMA_30BIT_MASK);
 	if (err) {
 		dev_err(&pdev->dev, "No usable DMA configuration, aborting.\n");
 		goto err_out_free_res;
 	}
 
-	err = pci_set_consistent_dma_mask(pdev, (u64) B44_DMA_MASK);
+	err = pci_set_consistent_dma_mask(pdev, (u64) DMA_30BIT_MASK);
 	if (err) {
 		dev_err(&pdev->dev, "No usable DMA configuration, aborting.\n");
 		goto err_out_free_res;
diff --git a/drivers/net/cxgb3/cxgb3_defs.h b/drivers/net/cxgb3/cxgb3_defs.h
index 16e0049..e14862b 100644
--- a/drivers/net/cxgb3/cxgb3_defs.h
+++ b/drivers/net/cxgb3/cxgb3_defs.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006-2007 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/cxgb3_offload.c b/drivers/net/cxgb3/cxgb3_offload.c
index c6b7266..b2cf5f6 100644
--- a/drivers/net/cxgb3/cxgb3_offload.c
+++ b/drivers/net/cxgb3/cxgb3_offload.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006-2007 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/cxgb3_offload.h b/drivers/net/cxgb3/cxgb3_offload.h
index 0e6beb6..f15446a 100644
--- a/drivers/net/cxgb3/cxgb3_offload.h
+++ b/drivers/net/cxgb3/cxgb3_offload.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2006-2007 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006-2007 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/l2t.c b/drivers/net/cxgb3/l2t.c
index 3c0cb85..d660af7 100644
--- a/drivers/net/cxgb3/l2t.c
+++ b/drivers/net/cxgb3/l2t.c
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006-2007 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/l2t.h b/drivers/net/cxgb3/l2t.h
index ba5d2cb..d790013 100644
--- a/drivers/net/cxgb3/l2t.h
+++ b/drivers/net/cxgb3/l2t.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (c) 2003-2007 Chelsio, Inc. All rights reserved.
- * Copyright (c) 2006-2007 Open Grid Computing, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/cxgb3/t3cdev.h b/drivers/net/cxgb3/t3cdev.h
index 9af3bcd..fa4099b 100644
--- a/drivers/net/cxgb3/t3cdev.h
+++ b/drivers/net/cxgb3/t3cdev.h
@@ -1,6 +1,5 @@
 /*
  * Copyright (C) 2006-2007 Chelsio Communications.  All rights reserved.
- * Copyright (C) 2006-2007 Open Grid Computing, Inc.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 689f158..dd4b728 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -337,7 +337,6 @@ struct e1000_adapter {
 	struct e1000_rx_ring test_rx_ring;
 
 
-	uint32_t *config_space;
 	int msg_enable;
 #ifdef CONFIG_PCI_MSI
 	boolean_t have_msi;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 44ebc72..6777887 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -166,7 +166,7 @@ e1000_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
 			ecmd->transceiver = XCVR_EXTERNAL;
 	}
 
-	if (netif_carrier_ok(adapter->netdev)) {
+	if (E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_LU) {
 
 		e1000_get_speed_and_duplex(hw, &adapter->link_speed,
 		                                   &adapter->link_duplex);
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 619c892..a710237 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1417,10 +1417,6 @@ e1000_open(struct net_device *netdev)
 	if ((err = e1000_setup_all_rx_resources(adapter)))
 		goto err_setup_rx;
 
-	err = e1000_request_irq(adapter);
-	if (err)
-		goto err_req_irq;
-
 	e1000_power_up_phy(adapter);
 
 	if ((err = e1000_up(adapter)))
@@ -1431,6 +1427,10 @@ e1000_open(struct net_device *netdev)
 		e1000_update_mng_vlan(adapter);
 	}
 
+	err = e1000_request_irq(adapter);
+	if (err)
+		goto err_req_irq;
+
 	/* If AMT is enabled, let the firmware know that the network
 	 * interface is now open */
 	if (adapter->hw.mac_type == e1000_82573 &&
@@ -1439,10 +1439,10 @@ e1000_open(struct net_device *netdev)
 
 	return E1000_SUCCESS;
 
+err_req_irq:
+	e1000_down(adapter);
 err_up:
 	e1000_power_down_phy(adapter);
-	e1000_free_irq(adapter);
-err_req_irq:
 	e1000_free_all_rx_resources(adapter);
 err_setup_rx:
 	e1000_free_all_tx_resources(adapter);
@@ -5071,58 +5071,6 @@ e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx)
 	return 0;
 }
 
-#ifdef CONFIG_PM
-/* Save/restore 16 or 64 dwords of PCI config space depending on which
- * bus we're on (PCI(X) vs. PCI-E)
- */
-#define PCIE_CONFIG_SPACE_LEN 256
-#define PCI_CONFIG_SPACE_LEN 64
-static int
-e1000_pci_save_state(struct e1000_adapter *adapter)
-{
-	struct pci_dev *dev = adapter->pdev;
-	int size;
-	int i;
-
-	if (adapter->hw.mac_type >= e1000_82571)
-		size = PCIE_CONFIG_SPACE_LEN;
-	else
-		size = PCI_CONFIG_SPACE_LEN;
-
-	WARN_ON(adapter->config_space != NULL);
-
-	adapter->config_space = kmalloc(size, GFP_KERNEL);
-	if (!adapter->config_space) {
-		DPRINTK(PROBE, ERR, "unable to allocate %d bytes\n", size);
-		return -ENOMEM;
-	}
-	for (i = 0; i < (size / 4); i++)
-		pci_read_config_dword(dev, i * 4, &adapter->config_space[i]);
-	return 0;
-}
-
-static void
-e1000_pci_restore_state(struct e1000_adapter *adapter)
-{
-	struct pci_dev *dev = adapter->pdev;
-	int size;
-	int i;
-
-	if (adapter->config_space == NULL)
-		return;
-
-	if (adapter->hw.mac_type >= e1000_82571)
-		size = PCIE_CONFIG_SPACE_LEN;
-	else
-		size = PCI_CONFIG_SPACE_LEN;
-	for (i = 0; i < (size / 4); i++)
-		pci_write_config_dword(dev, i * 4, adapter->config_space[i]);
-	kfree(adapter->config_space);
-	adapter->config_space = NULL;
-	return;
-}
-#endif /* CONFIG_PM */
-
 static int
 e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 {
@@ -5142,9 +5090,7 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 	}
 
 #ifdef CONFIG_PM
-	/* Implement our own version of pci_save_state(pdev) because pci-
-	 * express adapters have 256-byte config spaces. */
-	retval = e1000_pci_save_state(adapter);
+	retval = pci_save_state(pdev);
 	if (retval)
 		return retval;
 #endif
@@ -5231,7 +5177,7 @@ e1000_resume(struct pci_dev *pdev)
 	uint32_t err;
 
 	pci_set_power_state(pdev, PCI_D0);
-	e1000_pci_restore_state(adapter);
+	pci_restore_state(pdev);
 	if ((err = pci_enable_device(pdev))) {
 		printk(KERN_ERR "e1000: Cannot enable PCI device from suspend\n");
 		return err;
diff --git a/drivers/net/ehea/ehea.h b/drivers/net/ehea/ehea.h
index 272e1ec..42295d6 100644
--- a/drivers/net/ehea/ehea.h
+++ b/drivers/net/ehea/ehea.h
@@ -39,7 +39,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME	"ehea"
-#define DRV_VERSION	"EHEA_0045"
+#define DRV_VERSION	"EHEA_0046"
 
 #define EHEA_MSG_DEFAULT (NETIF_MSG_LINK | NETIF_MSG_TIMER \
 	| NETIF_MSG_RX_ERR | NETIF_MSG_TX_ERR)
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index 38b2fa4..88ad1c8 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -76,7 +76,7 @@ void ehea_dump(void *adr, int len, char *msg) {
 	int x;
 	unsigned char *deb = adr;
 	for (x = 0; x < len; x += 16) {
-		printk(DRV_NAME "%s adr=%p ofs=%04x %016lx %016lx\n", msg,
+		printk(DRV_NAME " %s adr=%p ofs=%04x %016lx %016lx\n", msg,
 			  deb, x, *((u64*)&deb[0]), *((u64*)&deb[8]));
 		deb += 16;
 	}
@@ -555,6 +555,7 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
 {
 	struct ehea_port *port = param;
 	struct ehea_eqe *eqe;
+	struct ehea_qp *qp;
 	u32 qp_token;
 
 	eqe = ehea_poll_eq(port->qp_eq);
@@ -563,9 +564,14 @@ static irqreturn_t ehea_qp_aff_irq_handler(int irq, void *param)
 		qp_token = EHEA_BMASK_GET(EHEA_EQE_QP_TOKEN, eqe->entry);
 		ehea_error("QP aff_err: entry=0x%lx, token=0x%x",
 			   eqe->entry, qp_token);
+
+		qp = port->port_res[qp_token].qp;
+		ehea_error_data(port->adapter, qp->fw_handle);
 		eqe = ehea_poll_eq(port->qp_eq);
 	}
 
+	queue_work(port->adapter->ehea_wq, &port->reset_task);
+
 	return IRQ_HANDLED;
 }
 
diff --git a/drivers/net/ehea/ehea_phyp.c b/drivers/net/ehea/ehea_phyp.c
index 37716e0..bc3c005 100644
--- a/drivers/net/ehea/ehea_phyp.c
+++ b/drivers/net/ehea/ehea_phyp.c
@@ -612,3 +612,13 @@ u64 ehea_h_reset_events(const u64 adapter_handle, const u64 neq_handle,
 				       event_mask,		/* R6 */
 				       0, 0, 0, 0);		/* R7-R12 */
 }
+
+u64 ehea_h_error_data(const u64 adapter_handle, const u64 ressource_handle,
+		      void *rblock)
+{
+	return ehea_plpar_hcall_norets(H_ERROR_DATA,
+				       adapter_handle,          /* R4 */
+				       ressource_handle,        /* R5 */
+				       virt_to_abs(rblock),     /* R6 */
+				       0, 0, 0, 0);             /* R7-R12 */
+}
diff --git a/drivers/net/ehea/ehea_phyp.h b/drivers/net/ehea/ehea_phyp.h
index 919f94b..90acddb 100644
--- a/drivers/net/ehea/ehea_phyp.h
+++ b/drivers/net/ehea/ehea_phyp.h
@@ -454,4 +454,7 @@ u64 ehea_h_reg_dereg_bcmc(const u64 adapter_handle, const u16 port_num,
 u64 ehea_h_reset_events(const u64 adapter_handle, const u64 neq_handle,
 			const u64 event_mask);
 
+u64 ehea_h_error_data(const u64 adapter_handle, const u64 ressource_handle,
+		      void *rblock);
+
 #endif	/* __EHEA_PHYP_H__ */
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index f143e13..96ff3b6 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -486,6 +486,7 @@ int ehea_destroy_qp(struct ehea_qp *qp)
 	if (!qp)
 		return 0;
 
+	ehea_h_disable_and_get_hea(qp->adapter->handle, qp->fw_handle);
 	hret = ehea_h_free_resource(qp->adapter->handle, qp->fw_handle);
 	if (hret != H_SUCCESS) {
 		ehea_error("destroy_qp failed");
@@ -581,4 +582,45 @@ out:
 	return ret;
 }
 
+void print_error_data(u64 *data)
+{
+	int length;
+	u64 type = EHEA_BMASK_GET(ERROR_DATA_TYPE, data[2]);
+	u64 resource = data[1];
+
+	length = EHEA_BMASK_GET(ERROR_DATA_LENGTH, data[0]);
+
+	if (length > EHEA_PAGESIZE)
+		length = EHEA_PAGESIZE;
+
+	if (type == 0x8) /* Queue Pair */
+		ehea_error("QP (resource=%lX) state: AER=0x%lX, AERR=0x%lX, "
+			   "port=%lX", resource, data[6], data[12], data[22]);
+
+	ehea_dump(data, length, "error data");
+}
+
+void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle)
+{
+	unsigned long ret;
+	u64 *rblock;
+
+	rblock = kzalloc(PAGE_SIZE, GFP_KERNEL);
+	if (!rblock) {
+		ehea_error("Cannot allocate rblock memory.");
+		return;
+	}
 
+	ret = ehea_h_error_data(adapter->handle,
+				res_handle,
+				rblock);
+
+	if (ret == H_R_STATE)
+		ehea_error("No error data is available: %lX.", res_handle);
+	else if (ret == H_SUCCESS)
+		print_error_data(rblock);
+	else
+		ehea_error("Error data could not be fetched: %lX", res_handle);
+
+	kfree(rblock);
+}
diff --git a/drivers/net/ehea/ehea_qmr.h b/drivers/net/ehea/ehea_qmr.h
index 7efdc96..1ff6098 100644
--- a/drivers/net/ehea/ehea_qmr.h
+++ b/drivers/net/ehea/ehea_qmr.h
@@ -180,6 +180,9 @@ struct ehea_eqe {
 	u64 entry;
 };
 
+#define ERROR_DATA_LENGTH  EHEA_BMASK_IBM(52,63)
+#define ERROR_DATA_TYPE    EHEA_BMASK_IBM(0,7)
+
 static inline void *hw_qeit_calc(struct hw_queue *queue, u64 q_offset)
 {
 	struct ehea_page *current_page;
@@ -355,4 +358,6 @@ int ehea_destroy_qp(struct ehea_qp *qp);
 
 int ehea_reg_mr_adapter(struct ehea_adapter *adapter);
 
+void ehea_error_data(struct ehea_adapter *adapter, u64 res_handle);
+
 #endif	/* __EHEA_QMR_H__ */
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 1be4a84..1f83988 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -10,6 +10,7 @@
  * Maintainer: Kumar Gala
  *
  * Copyright (c) 2002-2006 Freescale Semiconductor, Inc.
+ * Copyright (c) 2007 MontaVista Software, Inc.
  *
  * This program is free software; you can redistribute  it and/or modify it
  * under  the terms of  the GNU General  Public License as published by the
@@ -1612,71 +1613,17 @@ static irqreturn_t gfar_interrupt(int irq, void *dev_id)
 	/* Save ievent for future reference */
 	u32 events = gfar_read(&priv->regs->ievent);
 
-	/* Clear IEVENT */
-	gfar_write(&priv->regs->ievent, events);
-
 	/* Check for reception */
-	if ((events & IEVENT_RXF0) || (events & IEVENT_RXB0))
+	if (events & IEVENT_RX_MASK)
 		gfar_receive(irq, dev_id);
 
 	/* Check for transmit completion */
-	if ((events & IEVENT_TXF) || (events & IEVENT_TXB))
+	if (events & IEVENT_TX_MASK)
 		gfar_transmit(irq, dev_id);
 
-	/* Update error statistics */
-	if (events & IEVENT_TXE) {
-		priv->stats.tx_errors++;
-
-		if (events & IEVENT_LC)
-			priv->stats.tx_window_errors++;
-		if (events & IEVENT_CRL)
-			priv->stats.tx_aborted_errors++;
-		if (events & IEVENT_XFUN) {
-			if (netif_msg_tx_err(priv))
-				printk(KERN_WARNING "%s: tx underrun. dropped packet\n", dev->name);
-			priv->stats.tx_dropped++;
-			priv->extra_stats.tx_underrun++;
-
-			/* Reactivate the Tx Queues */
-			gfar_write(&priv->regs->tstat, TSTAT_CLEAR_THALT);
-		}
-	}
-	if (events & IEVENT_BSY) {
-		priv->stats.rx_errors++;
-		priv->extra_stats.rx_bsy++;
-
-		gfar_receive(irq, dev_id);
-
-#ifndef CONFIG_GFAR_NAPI
-		/* Clear the halt bit in RSTAT */
-		gfar_write(&priv->regs->rstat, RSTAT_CLEAR_RHALT);
-#endif
-
-		if (netif_msg_rx_err(priv))
-			printk(KERN_DEBUG "%s: busy error (rhalt: %x)\n",
-					dev->name,
-					gfar_read(&priv->regs->rstat));
-	}
-	if (events & IEVENT_BABR) {
-		priv->stats.rx_errors++;
-		priv->extra_stats.rx_babr++;
-
-		if (netif_msg_rx_err(priv))
-			printk(KERN_DEBUG "%s: babbling error\n", dev->name);
-	}
-	if (events & IEVENT_EBERR) {
-		priv->extra_stats.eberr++;
-		if (netif_msg_rx_err(priv))
-			printk(KERN_DEBUG "%s: EBERR\n", dev->name);
-	}
-	if ((events & IEVENT_RXC) && (netif_msg_rx_err(priv)))
-			printk(KERN_DEBUG "%s: control frame\n", dev->name);
-
-	if (events & IEVENT_BABT) {
-		priv->extra_stats.tx_babt++;
-		if (netif_msg_rx_err(priv))
-			printk(KERN_DEBUG "%s: babt error\n", dev->name);
-	}
+	/* Check for errors */
+	if (events & IEVENT_ERR_MASK)
+		gfar_error(irq, dev_id);
 
 	return IRQ_HANDLED;
 }
@@ -1938,7 +1885,7 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
 	/* Hmm... */
 	if (netif_msg_rx_err(priv) || netif_msg_tx_err(priv))
 		printk(KERN_DEBUG "%s: error interrupt (ievent=0x%08x imask=0x%08x)\n",
-				dev->name, events, gfar_read(&priv->regs->imask));
+		       dev->name, events, gfar_read(&priv->regs->imask));
 
 	/* Update the error counters */
 	if (events & IEVENT_TXE) {
@@ -1950,8 +1897,8 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
 			priv->stats.tx_aborted_errors++;
 		if (events & IEVENT_XFUN) {
 			if (netif_msg_tx_err(priv))
-				printk(KERN_DEBUG "%s: underrun.  packet dropped.\n",
-						dev->name);
+				printk(KERN_DEBUG "%s: TX FIFO underrun, "
+				       "packet dropped.\n", dev->name);
 			priv->stats.tx_dropped++;
 			priv->extra_stats.tx_underrun++;
 
@@ -1973,30 +1920,28 @@ static irqreturn_t gfar_error(int irq, void *dev_id)
 #endif
 
 		if (netif_msg_rx_err(priv))
-			printk(KERN_DEBUG "%s: busy error (rhalt: %x)\n",
-					dev->name,
-					gfar_read(&priv->regs->rstat));
+			printk(KERN_DEBUG "%s: busy error (rstat: %x)\n",
+			       dev->name, gfar_read(&priv->regs->rstat));
 	}
 	if (events & IEVENT_BABR) {
 		priv->stats.rx_errors++;
 		priv->extra_stats.rx_babr++;
 
 		if (netif_msg_rx_err(priv))
-			printk(KERN_DEBUG "%s: babbling error\n", dev->name);
+			printk(KERN_DEBUG "%s: babbling RX error\n", dev->name);
 	}
 	if (events & IEVENT_EBERR) {
 		priv->extra_stats.eberr++;
 		if (netif_msg_rx_err(priv))
-			printk(KERN_DEBUG "%s: EBERR\n", dev->name);
+			printk(KERN_DEBUG "%s: bus error\n", dev->name);
 	}
 	if ((events & IEVENT_RXC) && netif_msg_rx_status(priv))
-		if (netif_msg_rx_status(priv))
-			printk(KERN_DEBUG "%s: control frame\n", dev->name);
+		printk(KERN_DEBUG "%s: control frame\n", dev->name);
 
 	if (events & IEVENT_BABT) {
 		priv->extra_stats.tx_babt++;
 		if (netif_msg_tx_err(priv))
-			printk(KERN_DEBUG "%s: babt error\n", dev->name);
+			printk(KERN_DEBUG "%s: babbling TX error\n", dev->name);
 	}
 	return IRQ_HANDLED;
 }
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c
index 45ffb5d..aec9ab1 100644
--- a/drivers/net/gianfar_sysfs.c
+++ b/drivers/net/gianfar_sysfs.c
@@ -38,13 +38,15 @@
 #include "gianfar.h"
 
 #define GFAR_ATTR(_name) \
-static ssize_t gfar_show_##_name(struct class_device *cdev, char *buf); \
-static ssize_t gfar_set_##_name(struct class_device *cdev, \
+static ssize_t gfar_show_##_name(struct device *dev, \
+	 struct device_attribute *attr, char *buf); \
+static ssize_t gfar_set_##_name(struct device *dev, \
+		struct device_attribute *attr, \
 		const char *buf, size_t count); \
-static CLASS_DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
+static DEVICE_ATTR(_name, 0644, gfar_show_##_name, gfar_set_##_name)
 
 #define GFAR_CREATE_FILE(_dev, _name) \
-	class_device_create_file(&_dev->class_dev, &class_device_attr_##_name)
+	device_create_file(&_dev->dev, &dev_attr_##_name)
 
 GFAR_ATTR(bd_stash);
 GFAR_ATTR(rx_stash_size);
@@ -53,29 +55,28 @@ GFAR_ATTR(fifo_threshold);
 GFAR_ATTR(fifo_starve);
 GFAR_ATTR(fifo_starve_off);
 
-#define to_net_dev(cd) container_of(cd, struct net_device, class_dev)
-
-static ssize_t gfar_show_bd_stash(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_bd_stash(struct device *dev,
+				  struct device_attribute *attr, char *buf)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 
-	return sprintf(buf, "%s\n", priv->bd_stash_en? "on" : "off");
+	return sprintf(buf, "%s\n", priv->bd_stash_en ? "on" : "off");
 }
 
-static ssize_t gfar_set_bd_stash(struct class_device *cdev,
-		const char *buf, size_t count)
+static ssize_t gfar_set_bd_stash(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 	int new_setting = 0;
 	u32 temp;
 	unsigned long flags;
 
 	/* Find out the new setting */
-	if (!strncmp("on", buf, count-1) || !strncmp("1", buf, count-1))
+	if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1))
 		new_setting = 1;
-	else if (!strncmp("off", buf, count-1) || !strncmp("0", buf, count-1))
+	else if (!strncmp("off", buf, count - 1)
+		 || !strncmp("0", buf, count - 1))
 		new_setting = 0;
 	else
 		return count;
@@ -99,19 +100,19 @@ static ssize_t gfar_set_bd_stash(struct class_device *cdev,
 	return count;
 }
 
-static ssize_t gfar_show_rx_stash_size(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_rx_stash_size(struct device *dev,
+				       struct device_attribute *attr, char *buf)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 
 	return sprintf(buf, "%d\n", priv->rx_stash_size);
 }
 
-static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
-		const char *buf, size_t count)
+static ssize_t gfar_set_rx_stash_size(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 	unsigned int length = simple_strtoul(buf, NULL, 0);
 	u32 temp;
 	unsigned long flags;
@@ -145,21 +146,21 @@ static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
 	return count;
 }
 
-
 /* Stashing will only be enabled when rx_stash_size != 0 */
-static ssize_t gfar_show_rx_stash_index(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_rx_stash_index(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 
 	return sprintf(buf, "%d\n", priv->rx_stash_index);
 }
 
-static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
-		const char *buf, size_t count)
+static ssize_t gfar_set_rx_stash_index(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t count)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 	unsigned short index = simple_strtoul(buf, NULL, 0);
 	u32 temp;
 	unsigned long flags;
@@ -183,19 +184,20 @@ static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
 	return count;
 }
 
-static ssize_t gfar_show_fifo_threshold(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_fifo_threshold(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 
 	return sprintf(buf, "%d\n", priv->fifo_threshold);
 }
 
-static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
-		const char *buf, size_t count)
+static ssize_t gfar_set_fifo_threshold(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t count)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 	unsigned int length = simple_strtoul(buf, NULL, 0);
 	u32 temp;
 	unsigned long flags;
@@ -217,20 +219,19 @@ static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
 	return count;
 }
 
-static ssize_t gfar_show_fifo_starve(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_fifo_starve(struct device *dev,
+				     struct device_attribute *attr, char *buf)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 
 	return sprintf(buf, "%d\n", priv->fifo_starve);
 }
 
-
-static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
-		const char *buf, size_t count)
+static ssize_t gfar_set_fifo_starve(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 	unsigned int num = simple_strtoul(buf, NULL, 0);
 	u32 temp;
 	unsigned long flags;
@@ -252,19 +253,20 @@ static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
 	return count;
 }
 
-static ssize_t gfar_show_fifo_starve_off(struct class_device *cdev, char *buf)
+static ssize_t gfar_show_fifo_starve_off(struct device *dev,
+					 struct device_attribute *attr,
+					 char *buf)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 
 	return sprintf(buf, "%d\n", priv->fifo_starve_off);
 }
 
-static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
-		const char *buf, size_t count)
+static ssize_t gfar_set_fifo_starve_off(struct device *dev,
+					struct device_attribute *attr,
+					const char *buf, size_t count)
 {
-	struct net_device *dev = to_net_dev(cdev);
-	struct gfar_private *priv = netdev_priv(dev);
+	struct gfar_private *priv = netdev_priv(to_net_dev(dev));
 	unsigned int num = simple_strtoul(buf, NULL, 0);
 	u32 temp;
 	unsigned long flags;
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index f0d30cf..4ad7807 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -836,13 +836,17 @@ static int ioc3_mii_init(struct ioc3_private *ip)
 	}
 
 	ip->mii.phy_id = i;
+
+out:
+	return res;
+}
+
+static void ioc3_mii_start(struct ioc3_private *ip)
+{
 	ip->ioc3_timer.expires = jiffies + (12 * HZ)/10;  /* 1.2 sec. */
 	ip->ioc3_timer.data = (unsigned long) ip;
 	ip->ioc3_timer.function = &ioc3_timer;
 	add_timer(&ip->ioc3_timer);
-
-out:
-	return res;
 }
 
 static inline void ioc3_clean_rx_ring(struct ioc3_private *ip)
@@ -1071,6 +1075,7 @@ static int ioc3_open(struct net_device *dev)
 	ip->ehar_h = 0;
 	ip->ehar_l = 0;
 	ioc3_init(dev);
+	ioc3_mii_start(ip);
 
 	netif_start_queue(dev);
 	return 0;
@@ -1274,6 +1279,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		goto out_stop;
 	}
 
+	ioc3_mii_start(ip);
 	ioc3_ssram_disc(ip);
 	ioc3_get_eaddr(ip);
 
@@ -1314,6 +1320,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
 out_stop:
 	ioc3_stop(ip);
+	del_timer_sync(&ip->ioc3_timer);
 	ioc3_free_rings(ip);
 out_res:
 	pci_release_regions(pdev);
@@ -1335,6 +1342,8 @@ static void __devexit ioc3_remove_one (struct pci_dev *pdev)
 	struct ioc3 *ioc3 = ip->regs;
 
 	unregister_netdev(dev);
+	del_timer_sync(&ip->ioc3_timer);
+
 	iounmap(ioc3);
 	pci_release_regions(pdev);
 	free_netdev(dev);
@@ -1492,6 +1501,7 @@ static void ioc3_timeout(struct net_device *dev)
 	ioc3_stop(ip);
 	ioc3_init(dev);
 	ioc3_mii_init(ip);
+	ioc3_mii_start(ip);
 
 	spin_unlock_irq(&ip->ioc3_lock);
 
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index a41418b..2e9571b 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -881,27 +881,15 @@ static struct net_device_stats *macb_get_stats(struct net_device *dev)
 static int macb_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct macb *bp = netdev_priv(dev);
-	int ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&bp->lock, flags);
-	ret = mii_ethtool_gset(&bp->mii, cmd);
-	spin_unlock_irqrestore(&bp->lock, flags);
 
-	return ret;
+	return mii_ethtool_gset(&bp->mii, cmd);
 }
 
 static int macb_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct macb *bp = netdev_priv(dev);
-	int ret;
-	unsigned long flags;
-
-	spin_lock_irqsave(&bp->lock, flags);
-	ret = mii_ethtool_sset(&bp->mii, cmd);
-	spin_unlock_irqrestore(&bp->lock, flags);
 
-	return ret;
+	return mii_ethtool_sset(&bp->mii, cmd);
 }
 
 static void macb_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
@@ -930,17 +918,11 @@ static struct ethtool_ops macb_ethtool_ops = {
 static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct macb *bp = netdev_priv(dev);
-	int ret;
-	unsigned long flags;
 
 	if (!netif_running(dev))
 		return -EINVAL;
 
-	spin_lock_irqsave(&bp->lock, flags);
-	ret = generic_mii_ioctl(&bp->mii, if_mii(rq), cmd, NULL);
-	spin_unlock_irqrestore(&bp->lock, flags);
-
-	return ret;
+	return generic_mii_ioctl(&bp->mii, if_mii(rq), cmd, NULL);
 }
 
 static ssize_t macb_mii_show(const struct device *_dev, char *buf,
diff --git a/drivers/net/meth.c b/drivers/net/meth.c
index d38b7c7..7e69ca6 100644
--- a/drivers/net/meth.c
+++ b/drivers/net/meth.c
@@ -170,7 +170,7 @@ static int mdio_probe(struct meth_private *priv)
 
 static void meth_check_link(struct net_device *dev)
 {
-	struct meth_private *priv = (struct meth_private *) dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 	unsigned long mii_advertising = mdio_read(priv, 4);
 	unsigned long mii_partner = mdio_read(priv, 5);
 	unsigned long negotiated = mii_advertising & mii_partner;
@@ -268,7 +268,7 @@ static void meth_free_rx_ring(struct meth_private *priv)
 
 int meth_reset(struct net_device *dev)
 {
-	struct meth_private *priv = (struct meth_private *) dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 
 	/* Reset card */
 	mace->eth.mac_ctrl = SGI_MAC_RESET;
@@ -310,7 +310,7 @@ int meth_reset(struct net_device *dev)
  */
 static int meth_open(struct net_device *dev)
 {
-	struct meth_private *priv = dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 	int ret;
 
 	priv->phy_addr = -1;    /* No PHY is known yet... */
@@ -354,7 +354,7 @@ out_free_tx_ring:
 
 static int meth_release(struct net_device *dev)
 {
-	struct meth_private *priv = dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 
 	DPRINTK("Stopping queue\n");
 	netif_stop_queue(dev); /* can't transmit any more */
@@ -376,7 +376,7 @@ static void meth_rx(struct net_device* dev, unsigned long int_status)
 {
 	struct sk_buff *skb;
 	unsigned long status;
-	struct meth_private *priv = (struct meth_private *) dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 	unsigned long fifo_rptr = (int_status & METH_INT_RX_RPTR_MASK) >> 8;
 
 	spin_lock(&priv->meth_lock);
@@ -466,14 +466,14 @@ static void meth_rx(struct net_device* dev, unsigned long int_status)
 
 static int meth_tx_full(struct net_device *dev)
 {
-	struct meth_private *priv = (struct meth_private *) dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 
 	return (priv->tx_count >= TX_RING_ENTRIES - 1);
 }
 
 static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status)
 {
-	struct meth_private *priv = dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 	unsigned long status;
 	struct sk_buff *skb;
 	unsigned long rptr = (int_status&TX_INFO_RPTR) >> 16;
@@ -536,7 +536,7 @@ static void meth_tx_cleanup(struct net_device* dev, unsigned long int_status)
 
 static void meth_error(struct net_device* dev, unsigned status)
 {
-	struct meth_private *priv = (struct meth_private *) dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 
 	printk(KERN_WARNING "meth: error status: 0x%08x\n",status);
 	/* check for errors too... */
@@ -570,7 +570,7 @@ static void meth_error(struct net_device* dev, unsigned status)
 static irqreturn_t meth_interrupt(int irq, void *dev_id)
 {
 	struct net_device *dev = (struct net_device *)dev_id;
-	struct meth_private *priv = (struct meth_private *) dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 	unsigned long status;
 
 	status = mace->eth.int_stat;
@@ -695,7 +695,7 @@ static void meth_add_to_tx_ring(struct meth_private *priv, struct sk_buff *skb)
  */
 static int meth_tx(struct sk_buff *skb, struct net_device *dev)
 {
-	struct meth_private *priv = (struct meth_private *) dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 	unsigned long flags;
 
 	spin_lock_irqsave(&priv->meth_lock, flags);
@@ -726,7 +726,7 @@ static int meth_tx(struct sk_buff *skb, struct net_device *dev)
  */
 static void meth_tx_timeout(struct net_device *dev)
 {
-	struct meth_private *priv = (struct meth_private *) dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 	unsigned long flags;
 
 	printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
@@ -778,7 +778,7 @@ static int meth_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
  */
 static struct net_device_stats *meth_stats(struct net_device *dev)
 {
-	struct meth_private *priv = (struct meth_private *) dev->priv;
+	struct meth_private *priv = netdev_priv(dev);
 	return &priv->stats;
 }
 
@@ -807,7 +807,7 @@ static struct net_device *meth_init(void)
 	dev->irq	     = MACE_ETHERNET_IRQ;
 	dev->base_addr	     = (unsigned long)&mace->eth;
 
-	priv = (struct meth_private *) dev->priv;
+	priv = netdev_priv(dev);
 	spin_lock_init(&priv->meth_lock);
 
 	ret = register_netdev(dev);
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 3f3896e..2807ef4 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -252,7 +252,7 @@ typedef u32 netxen_ctx_msg;
 #define netxen_set_msg_ctxid(config_word, val)	\
 	((config_word) &= ~(0x3ff<<18), (config_word) |= (val & 0x3ff) << 18)
 #define netxen_set_msg_opcode(config_word, val)	\
-	((config_word) &= ~(0xf<<24), (config_word) |= (val & 0xf) << 24)
+	((config_word) &= ~(0xf<<28), (config_word) |= (val & 0xf) << 28)
 
 struct netxen_rcv_context {
 	__le64 rcv_ring_addr;
@@ -303,14 +303,14 @@ struct netxen_ring_ctx {
 	(cmd_desc)->flags_opcode |= cpu_to_le16((val) & 0x7f))
 #define netxen_set_cmd_desc_opcode(cmd_desc, val)	\
 	((cmd_desc)->flags_opcode &= ~cpu_to_le16(0x3f<<7), \
-	(cmd_desc)->flags_opcode |= cpu_to_le16((val) & (0x3f<<7)))
+	(cmd_desc)->flags_opcode |= cpu_to_le16(((val & 0x3f)<<7)))
 
 #define netxen_set_cmd_desc_num_of_buff(cmd_desc, val)	\
 	((cmd_desc)->num_of_buffers_total_length &= ~cpu_to_le32(0xff), \
 	(cmd_desc)->num_of_buffers_total_length |= cpu_to_le32((val) & 0xff))
 #define netxen_set_cmd_desc_totallength(cmd_desc, val)	\
-	((cmd_desc)->num_of_buffers_total_length &= cpu_to_le32(0xff), \
-	(cmd_desc)->num_of_buffers_total_length |= cpu_to_le32(val << 24))
+	((cmd_desc)->num_of_buffers_total_length &= ~cpu_to_le32(0xffffff00), \
+	(cmd_desc)->num_of_buffers_total_length |= cpu_to_le32(val << 8))
 
 #define netxen_get_cmd_desc_opcode(cmd_desc)	\
 	((le16_to_cpu((cmd_desc)->flags_opcode) >> 7) & 0x003F)
@@ -1040,6 +1040,7 @@ int netxen_flash_unlock(struct netxen_adapter *adapter);
 int netxen_backup_crbinit(struct netxen_adapter *adapter);
 int netxen_flash_erase_secondary(struct netxen_adapter *adapter);
 int netxen_flash_erase_primary(struct netxen_adapter *adapter);
+void netxen_halt_pegs(struct netxen_adapter *adapter);
 
 int netxen_rom_fast_write(struct netxen_adapter *adapter, int addr, int data);
 int netxen_rom_se(struct netxen_adapter *adapter, int addr);
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index cc0efe2..6252e9a 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -402,7 +402,7 @@ netxen_nic_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 	wol->wolopts = 0;
 }
 
-static u32 netxen_nic_get_link(struct net_device *dev)
+static u32 netxen_nic_test_link(struct net_device *dev)
 {
 	struct netxen_port *port = netdev_priv(dev);
 	struct netxen_adapter *adapter = port->adapter;
@@ -459,6 +459,7 @@ netxen_nic_set_eeprom(struct net_device *dev, struct ethtool_eeprom *eeprom,
 	int ret;
 
 	if (flash_start == 0) {
+		netxen_halt_pegs(adapter);
 		ret = netxen_flash_unlock(adapter);
 		if (ret < 0) {
 			printk(KERN_ERR "%s: Flash unlock failed.\n",
@@ -712,7 +713,7 @@ netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
 {
 	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {	/* offline tests */
 		/* link test */
-		if (!(data[4] = (u64) netxen_nic_get_link(dev)))
+		if (!(data[4] = (u64) netxen_nic_test_link(dev)))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		if (netif_running(dev))
@@ -727,7 +728,7 @@ netxen_nic_diag_test(struct net_device *dev, struct ethtool_test *eth_test,
 			dev->open(dev);
 	} else {		/* online tests */
 		/* link test */
-		if (!(data[4] = (u64) netxen_nic_get_link(dev)))
+		if (!(data[4] = (u64) netxen_nic_test_link(dev)))
 			eth_test->flags |= ETH_TEST_FL_FAILED;
 
 		/* other tests pass by default */
@@ -783,7 +784,7 @@ struct ethtool_ops netxen_nic_ethtool_ops = {
 	.get_regs_len = netxen_nic_get_regs_len,
 	.get_regs = netxen_nic_get_regs,
 	.get_wol = netxen_nic_get_wol,
-	.get_link = netxen_nic_get_link,
+	.get_link = ethtool_op_get_link,
 	.get_eeprom_len = netxen_nic_get_eeprom_len,
 	.get_eeprom = netxen_nic_get_eeprom,
 	.set_eeprom = netxen_nic_set_eeprom,
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index f263232..7195af3 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -420,6 +420,7 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
 	for (i = 0; i < size / sizeof(u32); i++) {
 		if (netxen_rom_fast_read(adapter, addr, ptr32) == -1)
 			return -1;
+		*ptr32 = cpu_to_le32(*ptr32);
 		ptr32++;
 		addr += sizeof(u32);
 	}
@@ -428,6 +429,7 @@ static int netxen_get_flash_block(struct netxen_adapter *adapter, int base,
 
 		if (netxen_rom_fast_read(adapter, addr, &local) == -1)
 			return -1;
+		local = cpu_to_le32(local);
 		memcpy(ptr32, &local, (char *)buf + size - (char *)ptr32);
 	}
 
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index f7bb8c9..2f32436 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -717,6 +717,14 @@ netxen_flash_erase_primary(struct netxen_adapter *adapter)
 	return ret;
 }
 
+void netxen_halt_pegs(struct netxen_adapter *adapter)
+{
+	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_0 + 0x3c, 1);
+	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_1 + 0x3c, 1);
+	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_2 + 0x3c, 1);
+	 netxen_crb_writelit_adapter(adapter, NETXEN_CRB_PEG_NET_3 + 0x3c, 1);
+}
+
 int netxen_flash_unlock(struct netxen_adapter *adapter)
 {
 	int ret = 0;
@@ -1246,7 +1254,7 @@ int netxen_process_cmd_ring(unsigned long data)
 	 * the netdev which is associated with that device.
 	 */
 
-	consumer = *(adapter->cmd_consumer);
+	consumer = le32_to_cpu(*(adapter->cmd_consumer));
 	if (last_consumer == consumer) {	/* Ring is empty    */
 		DPRINTK(INFO, "last_consumer %d == consumer %d\n",
 			last_consumer, consumer);
@@ -1340,7 +1348,7 @@ int netxen_process_cmd_ring(unsigned long data)
 	if (adapter->last_cmd_consumer == consumer &&
 	    (((adapter->cmd_producer + 1) %
 	      adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) {
-		consumer = *(adapter->cmd_consumer);
+		consumer = le32_to_cpu(*(adapter->cmd_consumer));
 	}
 	done = (adapter->last_cmd_consumer == consumer);
 
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 36ba6a1..225ff55 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -434,12 +434,13 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 		adapter->port_count++;
 		adapter->port[i] = port;
 	}
-
+#ifndef CONFIG_PPC64
 	writel(0, NETXEN_CRB_NORMALIZE(adapter, CRB_CMDPEG_STATE));
 	netxen_pinit_from_rom(adapter, 0);
 	udelay(500);
 	netxen_load_firmware(adapter);
 	netxen_phantom_init(adapter, NETXEN_NIC_PEG_TUNE);
+#endif
 	/*
 	 * delay a while to ensure that the Pegs are up & running.
 	 * Otherwise, we might see some flaky behaviour.
diff --git a/drivers/net/netxen/netxen_nic_niu.c b/drivers/net/netxen/netxen_nic_niu.c
index 40d7003..d5d9507 100644
--- a/drivers/net/netxen/netxen_nic_niu.c
+++ b/drivers/net/netxen/netxen_nic_niu.c
@@ -458,7 +458,7 @@ int netxen_niu_gbe_init_port(struct netxen_adapter *adapter, int port)
 
 int netxen_niu_xg_init_port(struct netxen_adapter *adapter, int port)
 {
-	long reg = 0, ret = 0;
+	u32 reg = 0, ret = 0;
 
 	if (adapter->ahw.boardcfg.board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) {
 		netxen_crb_writelit_adapter(adapter,
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 448bf4a..c7bd9c1 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -915,7 +915,7 @@ static void media_check(unsigned long arg)
 	if ((inw(ioaddr + EL3_STATUS) & IntLatch) && (inb(ioaddr + Timer) == 0xff)) {
 		if (!lp->fast_poll)
 			printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
-		el3_interrupt(dev->irq, lp);
+		el3_interrupt(dev->irq, dev);
 		lp->fast_poll = HZ;
 	}
 	if (lp->fast_poll) {
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index 530df88..2561f76 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -1927,7 +1927,7 @@ static void media_check(u_long arg)
     if (smc->watchdog++ && ((i>>8) & i)) {
 	if (!smc->fast_poll)
 	    printk(KERN_INFO "%s: interrupt(s) dropped!\n", dev->name);
-	smc_interrupt(dev->irq, smc);
+	smc_interrupt(dev->irq, dev);
 	smc->fast_poll = HZ;
     }
     if (smc->fast_poll) {
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index f4d4eb6..22aec5c 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -42,6 +42,19 @@
 #define MII_M1011_IMASK_INIT		0x6400
 #define MII_M1011_IMASK_CLEAR		0x0000
 
+#define MII_M1011_PHY_SCR		0x10
+#define MII_M1011_PHY_SCR_AUTO_CROSS	0x0060
+
+#define MII_M1145_PHY_EXT_CR		0x14
+#define MII_M1145_RGMII_RX_DELAY	0x0080
+#define MII_M1145_RGMII_TX_DELAY	0x0002
+
+#define M1145_DEV_FLAGS_RESISTANCE	0x00000001
+
+#define MII_M1111_PHY_LED_CONTROL	0x18
+#define MII_M1111_PHY_LED_DIRECT	0x4100
+#define MII_M1111_PHY_LED_COMBINE	0x411c
+
 MODULE_DESCRIPTION("Marvell PHY driver");
 MODULE_AUTHOR("Andy Fleming");
 MODULE_LICENSE("GPL");
@@ -63,7 +76,7 @@ static int marvell_config_intr(struct phy_device *phydev)
 {
 	int err;
 
-	if(phydev->interrupts == PHY_INTERRUPT_ENABLED)
+	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
 		err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
 	else
 		err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
@@ -103,34 +116,153 @@ static int marvell_config_aneg(struct phy_device *phydev)
 	if (err < 0)
 		return err;
 
+	err = phy_write(phydev, MII_M1011_PHY_SCR,
+			MII_M1011_PHY_SCR_AUTO_CROSS);
+	if (err < 0)
+		return err;
+
+	err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL,
+			MII_M1111_PHY_LED_DIRECT);
+	if (err < 0)
+		return err;
 
 	err = genphy_config_aneg(phydev);
 
 	return err;
 }
 
+static int m88e1145_config_init(struct phy_device *phydev)
+{
+	int err;
+
+	/* Take care of errata E0 & E1 */
+	err = phy_write(phydev, 0x1d, 0x001b);
+	if (err < 0)
+		return err;
+
+	err = phy_write(phydev, 0x1e, 0x418f);
+	if (err < 0)
+		return err;
+
+	err = phy_write(phydev, 0x1d, 0x0016);
+	if (err < 0)
+		return err;
+
+	err = phy_write(phydev, 0x1e, 0xa2da);
+	if (err < 0)
+		return err;
+
+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
+		int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR);
+		if (temp < 0)
+			return temp;
+
+		temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY);
+
+		err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp);
+		if (err < 0)
+			return err;
+
+		if (phydev->dev_flags & M1145_DEV_FLAGS_RESISTANCE) {
+			err = phy_write(phydev, 0x1d, 0x0012);
+			if (err < 0)
+				return err;
+
+			temp = phy_read(phydev, 0x1e);
+			if (temp < 0)
+				return temp;
+
+			temp &= 0xf03f;
+			temp |= 2 << 9;	/* 36 ohm */
+			temp |= 2 << 6;	/* 39 ohm */
+
+			err = phy_write(phydev, 0x1e, temp);
+			if (err < 0)
+				return err;
+
+			err = phy_write(phydev, 0x1d, 0x3);
+			if (err < 0)
+				return err;
+
+			err = phy_write(phydev, 0x1e, 0x8000);
+			if (err < 0)
+				return err;
+		}
+	}
+
+	return 0;
+}
 
 static struct phy_driver m88e1101_driver = {
-	.phy_id		= 0x01410c00,
-	.phy_id_mask	= 0xffffff00,
-	.name		= "Marvell 88E1101",
-	.features	= PHY_GBIT_FEATURES,
-	.flags		= PHY_HAS_INTERRUPT,
-	.config_aneg	= &marvell_config_aneg,
-	.read_status	= &genphy_read_status,
-	.ack_interrupt	= &marvell_ack_interrupt,
-	.config_intr	= &marvell_config_intr,
-	.driver 	= { .owner = THIS_MODULE,},
+	.phy_id = 0x01410c60,
+	.phy_id_mask = 0xfffffff0,
+	.name = "Marvell 88E1101",
+	.features = PHY_GBIT_FEATURES,
+	.flags = PHY_HAS_INTERRUPT,
+	.config_aneg = &marvell_config_aneg,
+	.read_status = &genphy_read_status,
+	.ack_interrupt = &marvell_ack_interrupt,
+	.config_intr = &marvell_config_intr,
+	.driver = {.owner = THIS_MODULE,},
+};
+
+static struct phy_driver m88e1111s_driver = {
+	.phy_id = 0x01410cc0,
+	.phy_id_mask = 0xfffffff0,
+	.name = "Marvell 88E1111",
+	.features = PHY_GBIT_FEATURES,
+	.flags = PHY_HAS_INTERRUPT,
+	.config_aneg = &marvell_config_aneg,
+	.read_status = &genphy_read_status,
+	.ack_interrupt = &marvell_ack_interrupt,
+	.config_intr = &marvell_config_intr,
+	.driver = {.owner = THIS_MODULE,},
+};
+
+static struct phy_driver m88e1145_driver = {
+	.phy_id = 0x01410cd0,
+	.phy_id_mask = 0xfffffff0,
+	.name = "Marvell 88E1145",
+	.features = PHY_GBIT_FEATURES,
+	.flags = PHY_HAS_INTERRUPT,
+	.config_init = &m88e1145_config_init,
+	.config_aneg = &marvell_config_aneg,
+	.read_status = &genphy_read_status,
+	.ack_interrupt = &marvell_ack_interrupt,
+	.config_intr = &marvell_config_intr,
+	.driver = {.owner = THIS_MODULE,},
 };
 
 static int __init marvell_init(void)
 {
-	return phy_driver_register(&m88e1101_driver);
+	int ret;
+
+	ret = phy_driver_register(&m88e1101_driver);
+	if (ret)
+		return ret;
+
+	ret = phy_driver_register(&m88e1111s_driver);
+	if (ret)
+		goto err1111s;
+
+	ret = phy_driver_register(&m88e1145_driver);
+	if (ret)
+		goto err1145;
+
+	return 0;
+
+      err1145:
+	phy_driver_unregister(&m88e1111s_driver);
+      err1111s:
+	phy_driver_unregister(&m88e1101_driver);
+	return ret;
 }
 
 static void __exit marvell_exit(void)
 {
 	phy_driver_unregister(&m88e1101_driver);
+	phy_driver_unregister(&m88e1111s_driver);
+	phy_driver_unregister(&m88e1145_driver);
 }
 
 module_init(marvell_init);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index fdf45fd..7d5b6d1 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -138,7 +138,7 @@ void phy_prepare_link(struct phy_device *phydev,
  */
 struct phy_device * phy_connect(struct net_device *dev, const char *phy_id,
 		void (*handler)(struct net_device *), u32 flags,
-		u32 interface)
+		phy_interface_t interface)
 {
 	struct phy_device *phydev;
 
@@ -187,7 +187,7 @@ static int phy_compare_id(struct device *dev, void *data)
 }
 
 struct phy_device *phy_attach(struct net_device *dev,
-		const char *phy_id, u32 flags, u32 interface)
+		const char *phy_id, u32 flags, phy_interface_t interface)
 {
 	struct bus_type *bus = &mdio_bus_type;
 	struct phy_device *phydev;
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 92d11b9..e94ab25 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -5188,6 +5188,9 @@ static struct pci_driver skge_driver = {
 
 static int __init skge_init(void)
 {
+	printk(KERN_NOTICE "sk98lin: driver has been replaced by the skge driver"
+	       " and is scheduled for removal\n");
+
 	return pci_register_driver(&skge_driver);
 }
 
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index f2ab3d5..52edbd7 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -49,7 +49,7 @@
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"1.12"
+#define DRV_VERSION		"1.13"
 #define PFX			DRV_NAME " "
 
 /*
@@ -1742,13 +1742,6 @@ static void sky2_link_down(struct sky2_port *sky2)
 	reg &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA);
 	gma_write16(hw, port, GM_GP_CTRL, reg);
 
-	if (sky2->flow_status == FC_RX) {
-		/* restore Asymmetric Pause bit */
-		gm_phy_write(hw, port, PHY_MARV_AUNE_ADV,
-			     gm_phy_read(hw, port, PHY_MARV_AUNE_ADV)
-			     | PHY_M_AN_ASP);
-	}
-
 	netif_carrier_off(sky2->netdev);
 	netif_stop_queue(sky2->netdev);
 
@@ -1773,10 +1766,10 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
 {
 	struct sky2_hw *hw = sky2->hw;
 	unsigned port = sky2->port;
-	u16 lpa;
+	u16 advert, lpa;
 
+	advert = gm_phy_read(hw, port, PHY_MARV_AUNE_ADV);
 	lpa = gm_phy_read(hw, port, PHY_MARV_AUNE_LP);
-
 	if (lpa & PHY_M_AN_RF) {
 		printk(KERN_ERR PFX "%s: remote fault", sky2->netdev->name);
 		return -1;
@@ -1791,20 +1784,40 @@ static int sky2_autoneg_done(struct sky2_port *sky2, u16 aux)
 	sky2->speed = sky2_phy_speed(hw, aux);
 	sky2->duplex = (aux & PHY_M_PS_FULL_DUP) ? DUPLEX_FULL : DUPLEX_HALF;
 
-	/* Pause bits are offset (9..8) */
-	if (hw->chip_id == CHIP_ID_YUKON_XL
-	    || hw->chip_id == CHIP_ID_YUKON_EC_U
-	    || hw->chip_id == CHIP_ID_YUKON_EX)
-		aux >>= 6;
-
-	sky2->flow_status = sky2_flow(aux & PHY_M_PS_RX_P_EN,
-				      aux & PHY_M_PS_TX_P_EN);
+	/* Since the pause result bits seem to in different positions on
+	 * different chips. look at registers.
+	 */
+	if (!sky2_is_copper(hw)) {
+		/* Shift for bits in fiber PHY */
+		advert &= ~(ADVERTISE_PAUSE_CAP|ADVERTISE_PAUSE_ASYM);
+		lpa &= ~(LPA_PAUSE_CAP|LPA_PAUSE_ASYM);
+
+		if (advert & ADVERTISE_1000XPAUSE)
+			advert |= ADVERTISE_PAUSE_CAP;
+		if (advert & ADVERTISE_1000XPSE_ASYM)
+			advert |= ADVERTISE_PAUSE_ASYM;
+		if (lpa & LPA_1000XPAUSE)
+			lpa |= LPA_PAUSE_CAP;
+		if (lpa & LPA_1000XPAUSE_ASYM)
+			lpa |= LPA_PAUSE_ASYM;
+	}
+
+	sky2->flow_status = FC_NONE;
+	if (advert & ADVERTISE_PAUSE_CAP) {
+		if (lpa & LPA_PAUSE_CAP)
+			sky2->flow_status = FC_BOTH;
+		else if (advert & ADVERTISE_PAUSE_ASYM)
+			sky2->flow_status = FC_RX;
+	} else if (advert & ADVERTISE_PAUSE_ASYM) {
+		if ((lpa & LPA_PAUSE_CAP) && (lpa & LPA_PAUSE_ASYM))
+			sky2->flow_status = FC_TX;
+	}
 
 	if (sky2->duplex == DUPLEX_HALF && sky2->speed < SPEED_1000
 	    && !(hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX))
 		sky2->flow_status = FC_NONE;
 
-	if (aux & PHY_M_PS_RX_P_EN)
+	if (sky2->flow_status & FC_TX)
 		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_ON);
 	else
 		sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_PAUSE_OFF);
@@ -1853,16 +1866,13 @@ out:
 	spin_unlock(&sky2->phy_lock);
 }
 
-
 /* Transmit timeout is only called if we are running, carrier is up
  * and tx queue is full (stopped).
- * Called with netif_tx_lock held.
  */
 static void sky2_tx_timeout(struct net_device *dev)
 {
 	struct sky2_port *sky2 = netdev_priv(dev);
 	struct sky2_hw *hw = sky2->hw;
-	u32 imask;
 
 	if (netif_msg_timer(sky2))
 		printk(KERN_ERR PFX "%s: tx timeout\n", dev->name);
@@ -1872,19 +1882,8 @@ static void sky2_tx_timeout(struct net_device *dev)
 	       sky2_read16(hw, sky2->port == 0 ? STAT_TXA1_RIDX : STAT_TXA2_RIDX),
 	       sky2_read16(hw, Q_ADDR(txqaddr[sky2->port], Q_DONE)));
 
-	imask = sky2_read32(hw, B0_IMSK);	/* block IRQ in hw */
-	sky2_write32(hw, B0_IMSK, 0);
-	sky2_read32(hw, B0_IMSK);
-
-	netif_poll_disable(hw->dev[0]);		/* stop NAPI poll */
-	synchronize_irq(hw->pdev->irq);
-
-	netif_start_queue(dev);			/* don't wakeup during flush */
-	sky2_tx_complete(sky2, sky2->tx_prod);	/* Flush transmit queue */
-
-	sky2_write32(hw, B0_IMSK, imask);
-
-	sky2_phy_reinit(sky2);			/* this clears flow control etc */
+	/* can't restart safely under softirq */
+	schedule_work(&hw->restart_work);
 }
 
 static int sky2_change_mtu(struct net_device *dev, int new_mtu)
@@ -2057,9 +2056,6 @@ static struct sk_buff *sky2_receive(struct net_device *dev,
 	if (!(status & GMR_FS_RX_OK))
 		goto resubmit;
 
-	if (length > dev->mtu + ETH_HLEN)
-		goto oversize;
-
 	if (length < copybreak)
 		skb = receive_copy(sky2, re, length);
 	else
@@ -2069,14 +2065,10 @@ resubmit:
 
 	return skb;
 
-oversize:
-	++sky2->net_stats.rx_over_errors;
-	goto resubmit;
-
 error:
 	++sky2->net_stats.rx_errors;
 	if (status & GMR_FS_RX_FF_OV) {
-		sky2->net_stats.rx_fifo_errors++;
+		sky2->net_stats.rx_over_errors++;
 		goto resubmit;
 	}
 
@@ -2638,6 +2630,49 @@ static void sky2_reset(struct sky2_hw *hw)
 	sky2_write8(hw, STAT_ISR_TIMER_CTRL, TIM_START);
 }
 
+static void sky2_restart(struct work_struct *work)
+{
+	struct sky2_hw *hw = container_of(work, struct sky2_hw, restart_work);
+	struct net_device *dev;
+	int i, err;
+
+	dev_dbg(&hw->pdev->dev, "restarting\n");
+
+	del_timer_sync(&hw->idle_timer);
+
+	rtnl_lock();
+	sky2_write32(hw, B0_IMSK, 0);
+	sky2_read32(hw, B0_IMSK);
+
+	netif_poll_disable(hw->dev[0]);
+
+	for (i = 0; i < hw->ports; i++) {
+		dev = hw->dev[i];
+		if (netif_running(dev))
+			sky2_down(dev);
+	}
+
+	sky2_reset(hw);
+	sky2_write32(hw, B0_IMSK, Y2_IS_BASE);
+	netif_poll_enable(hw->dev[0]);
+
+	for (i = 0; i < hw->ports; i++) {
+		dev = hw->dev[i];
+		if (netif_running(dev)) {
+			err = sky2_up(dev);
+			if (err) {
+				printk(KERN_INFO PFX "%s: could not restart %d\n",
+				       dev->name, err);
+				dev_close(dev);
+			}
+		}
+	}
+
+	sky2_idle_start(hw);
+
+	rtnl_unlock();
+}
+
 static inline u8 sky2_wol_supported(const struct sky2_hw *hw)
 {
 	return sky2_is_copper(hw) ? (WAKE_PHY | WAKE_MAGIC) : 0;
@@ -3600,6 +3635,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev,
 	}
 
 	setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw);
+	INIT_WORK(&hw->restart_work, sky2_restart);
+
 	sky2_idle_start(hw);
 
 	pci_set_drvdata(pdev, hw);
@@ -3636,6 +3673,8 @@ static void __devexit sky2_remove(struct pci_dev *pdev)
 
 	del_timer_sync(&hw->idle_timer);
 
+	flush_scheduled_work();
+
 	sky2_write32(hw, B0_IMSK, 0);
 	synchronize_irq(hw->pdev->irq);
 
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 3b01895..ac24bdc 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1589,7 +1589,7 @@ enum {
 
 	GMR_FS_ANY_ERR	= GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
 			  GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
-		  	  GMR_FS_MII_ERR | GMR_FS_GOOD_FC | GMR_FS_BAD_FC |
+		  	  GMR_FS_MII_ERR | GMR_FS_BAD_FC |
 			  GMR_FS_UN_SIZE | GMR_FS_JABBER,
 };
 
@@ -1933,6 +1933,7 @@ struct sky2_hw {
 	dma_addr_t   	     st_dma;
 
 	struct timer_list    idle_timer;
+	struct work_struct   restart_work;
 	int		     msi;
 	wait_queue_head_t    msi_wait;
 };
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 61708cf..8897f53 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -26,7 +26,7 @@ config WAN
 # There is no way to detect a comtrol sv11 - force it modular for now.
 config HOSTESS_SV11
 	tristate "Comtrol Hostess SV-11 support"
-	depends on WAN && ISA && m && ISA_DMA_API
+	depends on WAN && ISA && m && ISA_DMA_API && INET
 	help
 	  Driver for Comtrol Hostess SV-11 network card which
 	  operates on low speed synchronous serial links at up to
diff --git a/drivers/net/wan/pc300too.c b/drivers/net/wan/pc300too.c
index bc156b5..aff05db 100644
--- a/drivers/net/wan/pc300too.c
+++ b/drivers/net/wan/pc300too.c
@@ -542,7 +542,7 @@ static int __init pc300_init_module(void)
 
 	CLOCK_BASE = use_crystal_clock ? 24576000 : pci_clock_freq;
 
-	return pci_module_init(&pc300_pci_driver);
+	return pci_register_driver(&pc300_pci_driver);
 }
 
 
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 3a064de..0e790ef 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -771,6 +771,7 @@ struct bcm43xx_private {
 	 * This is currently always BCM43xx_BUSTYPE_PCI
 	 */
 	u8 bustype;
+	u64 dma_mask;
 
 	u16 board_vendor;
 	u16 board_type;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
index 978ed09..6e0dc76 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
@@ -145,16 +145,14 @@ dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
 			  int tx)
 {
 	dma_addr_t dmaaddr;
+	int direction = PCI_DMA_FROMDEVICE;
 
-	if (tx) {
-		dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
-					 buf, len,
-					 DMA_TO_DEVICE);
-	} else {
-		dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
+	if (tx)
+		direction = PCI_DMA_TODEVICE;
+
+	dmaaddr = pci_map_single(ring->bcm->pci_dev,
 					 buf, len,
-					 DMA_FROM_DEVICE);
-	}
+					 direction);
 
 	return dmaaddr;
 }
@@ -166,13 +164,13 @@ void unmap_descbuffer(struct bcm43xx_dmaring *ring,
 		      int tx)
 {
 	if (tx) {
-		dma_unmap_single(&ring->bcm->pci_dev->dev,
+		pci_unmap_single(ring->bcm->pci_dev,
 				 addr, len,
-				 DMA_TO_DEVICE);
+				 PCI_DMA_TODEVICE);
 	} else {
-		dma_unmap_single(&ring->bcm->pci_dev->dev,
+		pci_unmap_single(ring->bcm->pci_dev,
 				 addr, len,
-				 DMA_FROM_DEVICE);
+				 PCI_DMA_FROMDEVICE);
 	}
 }
 
@@ -183,8 +181,8 @@ void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,
 {
 	assert(!ring->tx);
 
-	dma_sync_single_for_cpu(&ring->bcm->pci_dev->dev,
-				addr, len, DMA_FROM_DEVICE);
+	pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
+				    addr, len, PCI_DMA_FROMDEVICE);
 }
 
 static inline
@@ -194,8 +192,8 @@ void sync_descbuffer_for_device(struct bcm43xx_dmaring *ring,
 {
 	assert(!ring->tx);
 
-	dma_sync_single_for_device(&ring->bcm->pci_dev->dev,
-				   addr, len, DMA_FROM_DEVICE);
+	pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
+				    addr, len, PCI_DMA_TODEVICE);
 }
 
 /* Unmap and free a descriptor buffer. */
@@ -214,17 +212,53 @@ void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
 
 static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
 {
-	struct device *dev = &(ring->bcm->pci_dev->dev);
-
-	ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
-					    &(ring->dmabase), GFP_KERNEL);
+	ring->descbase = pci_alloc_consistent(ring->bcm->pci_dev, BCM43xx_DMA_RINGMEMSIZE,
+					    &(ring->dmabase));
 	if (!ring->descbase) {
-		printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
-		return -ENOMEM;
+		/* Allocation may have failed due to pci_alloc_consistent
+		   insisting on use of GFP_DMA, which is more restrictive
+		   than necessary...  */
+		struct dma_desc *rx_ring;
+		dma_addr_t rx_ring_dma;
+
+		rx_ring = kzalloc(BCM43xx_DMA_RINGMEMSIZE, GFP_KERNEL);
+		if (!rx_ring)
+			goto out_err;
+
+		rx_ring_dma = pci_map_single(ring->bcm->pci_dev, rx_ring,
+					     BCM43xx_DMA_RINGMEMSIZE,
+					     PCI_DMA_BIDIRECTIONAL);
+
+		if (pci_dma_mapping_error(rx_ring_dma) ||
+		    rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {
+			/* Sigh... */
+			if (!pci_dma_mapping_error(rx_ring_dma))
+				pci_unmap_single(ring->bcm->pci_dev,
+						 rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,
+						 PCI_DMA_BIDIRECTIONAL);
+			rx_ring_dma = pci_map_single(ring->bcm->pci_dev,
+						 rx_ring, BCM43xx_DMA_RINGMEMSIZE,
+						 PCI_DMA_BIDIRECTIONAL);
+			if (pci_dma_mapping_error(rx_ring_dma) ||
+			    rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > ring->bcm->dma_mask) {
+				assert(0);
+				if (!pci_dma_mapping_error(rx_ring_dma))
+					pci_unmap_single(ring->bcm->pci_dev,
+							 rx_ring_dma, BCM43xx_DMA_RINGMEMSIZE,
+							 PCI_DMA_BIDIRECTIONAL);
+				goto out_err;
+			}
+                }
+
+                ring->descbase = rx_ring;
+                ring->dmabase = rx_ring_dma;
 	}
 	memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
 
 	return 0;
+out_err:
+	printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
+	return -ENOMEM;
 }
 
 static void free_ringmemory(struct bcm43xx_dmaring *ring)
@@ -407,6 +441,29 @@ static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
 	if (unlikely(!skb))
 		return -ENOMEM;
 	dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
+	/* This hardware bug work-around adapted from the b44 driver.
+	   The chip may be unable to do PCI DMA to/from anything above 1GB */
+	if (pci_dma_mapping_error(dmaaddr) ||
+	    dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
+		/* This one has 30-bit addressing... */
+		if (!pci_dma_mapping_error(dmaaddr))
+			pci_unmap_single(ring->bcm->pci_dev,
+					 dmaaddr, ring->rx_buffersize,
+					 PCI_DMA_FROMDEVICE);
+		dev_kfree_skb_any(skb);
+		skb = __dev_alloc_skb(ring->rx_buffersize,GFP_DMA);
+		if (skb == NULL)
+			return -ENOMEM;
+		dmaaddr = pci_map_single(ring->bcm->pci_dev,
+					 skb->data, ring->rx_buffersize,
+					 PCI_DMA_FROMDEVICE);
+		if (pci_dma_mapping_error(dmaaddr) ||
+		    dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
+			assert(0);
+			dev_kfree_skb_any(skb);
+			return -ENOMEM;
+		}
+	}
 	meta->skb = skb;
 	meta->dmaaddr = dmaaddr;
 	skb->dev = ring->bcm->net_dev;
@@ -636,8 +693,10 @@ struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
 	err = dmacontroller_setup(ring);
 	if (err)
 		goto err_free_ringmemory;
+	return ring;
 
 out:
+	printk(KERN_ERR PFX "Error in bcm43xx_setup_dmaring\n");
 	return ring;
 
 err_free_ringmemory:
@@ -705,30 +764,16 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
 	struct bcm43xx_dmaring *ring;
 	int err = -ENOMEM;
 	int dma64 = 0;
-	u64 mask = bcm43xx_get_supported_dma_mask(bcm);
-	int nobits;
 
-	if (mask == DMA_64BIT_MASK) {
+	bcm->dma_mask = bcm43xx_get_supported_dma_mask(bcm);
+	if (bcm->dma_mask == DMA_64BIT_MASK)
 		dma64 = 1;
-		nobits = 64;
-	} else if (mask == DMA_32BIT_MASK)
-		nobits = 32;
-	else
-		nobits = 30;
-	err = pci_set_dma_mask(bcm->pci_dev, mask);
-	err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask);
-	if (err) {
-#ifdef CONFIG_BCM43XX_PIO
-		printk(KERN_WARNING PFX "DMA not supported on this device."
-					" Falling back to PIO.\n");
-		bcm->__using_pio = 1;
-		return -ENOSYS;
-#else
-		printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
-				    "Please recompile the driver with PIO support.\n");
-		return -ENODEV;
-#endif /* CONFIG_BCM43XX_PIO */
-	}
+	err = pci_set_dma_mask(bcm->pci_dev, bcm->dma_mask);
+	if (err)
+		goto no_dma;
+	err = pci_set_consistent_dma_mask(bcm->pci_dev, bcm->dma_mask);
+	if (err)
+		goto no_dma;
 
 	/* setup TX DMA channels. */
 	ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
@@ -774,7 +819,9 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
 		dma->rx_ring3 = ring;
 	}
 
-	dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits);
+	dprintk(KERN_INFO PFX "%d-bit DMA initialized\n",
+		(bcm->dma_mask == DMA_64BIT_MASK) ? 64 :
+		(bcm->dma_mask == DMA_32BIT_MASK) ? 32 : 30);
 	err = 0;
 out:
 	return err;
@@ -800,7 +847,17 @@ err_destroy_tx1:
 err_destroy_tx0:
 	bcm43xx_destroy_dmaring(dma->tx_ring0);
 	dma->tx_ring0 = NULL;
-	goto out;
+no_dma:
+#ifdef CONFIG_BCM43XX_PIO
+	printk(KERN_WARNING PFX "DMA not supported on this device."
+				" Falling back to PIO.\n");
+	bcm->__using_pio = 1;
+	return -ENOSYS;
+#else
+	printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
+			    "Please recompile the driver with PIO support.\n");
+	return -ENODEV;
+#endif /* CONFIG_BCM43XX_PIO */
 }
 
 /* Generate a cookie for the TX header. */
@@ -905,6 +962,7 @@ static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
 	struct bcm43xx_dmadesc_generic *desc;
 	struct bcm43xx_dmadesc_meta *meta;
 	dma_addr_t dmaaddr;
+	struct sk_buff *bounce_skb;
 
 	assert(skb_shinfo(skb)->nr_frags == 0);
 
@@ -924,9 +982,28 @@ static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
 			       skb->len - sizeof(struct bcm43xx_txhdr),
 			       (cur_frag == 0),
 			       generate_cookie(ring, slot));
+	dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
+	if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > ring->bcm->dma_mask) {
+		/* chip cannot handle DMA to/from > 1GB, use bounce buffer (copied from b44 driver) */
+		if (!dma_mapping_error(dmaaddr))
+			unmap_descbuffer(ring, dmaaddr, skb->len, 1);
+		bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC|GFP_DMA);
+		if (!bounce_skb)
+			return;
+		dmaaddr = map_descbuffer(ring, bounce_skb->data, bounce_skb->len, 1);
+		if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > ring->bcm->dma_mask) {
+			if (!dma_mapping_error(dmaaddr))
+				unmap_descbuffer(ring, dmaaddr, skb->len, 1);
+			dev_kfree_skb_any(bounce_skb);
+			assert(0);
+			return;
+		}
+		memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len);
+		dev_kfree_skb_any(skb);
+		skb = bounce_skb;
+	}
 
 	meta->skb = skb;
-	dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
 	meta->dmaaddr = dmaaddr;
 
 	fill_descriptor(ring, desc, dmaaddr,
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index 23aaf1e..2e400aa 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -95,13 +95,9 @@ static int modparam_noleds;
 module_param_named(noleds, modparam_noleds, int, 0444);
 MODULE_PARM_DESC(noleds, "Turn off all LED activity");
 
-#ifdef CONFIG_BCM43XX_DEBUG
 static char modparam_fwpostfix[64];
 module_param_string(fwpostfix, modparam_fwpostfix, 64, 0444);
-MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for debugging.");
-#else
-# define modparam_fwpostfix  ""
-#endif /* CONFIG_BCM43XX_DEBUG*/
+MODULE_PARM_DESC(fwpostfix, "Postfix for .fw files. Useful for using multiple firmware image versions.");
 
 
 /* If you want to debug with just a single device, enable this,
@@ -2983,8 +2979,10 @@ static int bcm43xx_chipset_attach(struct bcm43xx_private *bcm)
 	err = bcm43xx_pctl_set_crystal(bcm, 1);
 	if (err)
 		goto out;
-	bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status);
-	bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT);
+	err = bcm43xx_pci_read_config16(bcm, PCI_STATUS, &pci_status);
+	if (err)
+		goto out;
+	err = bcm43xx_pci_write_config16(bcm, PCI_STATUS, pci_status & ~PCI_STATUS_SIG_TARGET_ABORT);
 
 out:
 	return err;
@@ -3796,12 +3794,18 @@ static int bcm43xx_attach_board(struct bcm43xx_private *bcm)
 	}
 	net_dev->base_addr = (unsigned long)bcm->mmio_addr;
 
-	bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
+	err = bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_VENDOR_ID,
 	                          &bcm->board_vendor);
-	bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
+	if (err)
+		goto err_iounmap;
+	err = bcm43xx_pci_read_config16(bcm, PCI_SUBSYSTEM_ID,
 	                          &bcm->board_type);
-	bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
+	if (err)
+		goto err_iounmap;
+	err = bcm43xx_pci_read_config16(bcm, PCI_REVISION_ID,
 	                          &bcm->board_revision);
+	if (err)
+		goto err_iounmap;
 
 	err = bcm43xx_chipset_attach(bcm);
 	if (err)
@@ -3892,6 +3896,7 @@ err_pci_release:
 	pci_release_regions(pci_dev);
 err_pci_disable:
 	pci_disable_device(pci_dev);
+	printk(KERN_ERR PFX "Unable to attach board\n");
 	goto out;
 }
 
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
index d2ca949..7b665e2 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c
@@ -260,22 +260,22 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
 	if (phy->type == BCM43xx_PHYTYPE_A ||
 	    phy->type == BCM43xx_PHYTYPE_G) {
 		range->num_bitrates = 8;
-		range->bitrate[i++] = IEEE80211_OFDM_RATE_6MB;
-		range->bitrate[i++] = IEEE80211_OFDM_RATE_9MB;
-		range->bitrate[i++] = IEEE80211_OFDM_RATE_12MB;
-		range->bitrate[i++] = IEEE80211_OFDM_RATE_18MB;
-		range->bitrate[i++] = IEEE80211_OFDM_RATE_24MB;
-		range->bitrate[i++] = IEEE80211_OFDM_RATE_36MB;
-		range->bitrate[i++] = IEEE80211_OFDM_RATE_48MB;
-		range->bitrate[i++] = IEEE80211_OFDM_RATE_54MB;
+		range->bitrate[i++] = IEEE80211_OFDM_RATE_6MB * 500000;
+		range->bitrate[i++] = IEEE80211_OFDM_RATE_9MB * 500000;
+		range->bitrate[i++] = IEEE80211_OFDM_RATE_12MB * 500000;
+		range->bitrate[i++] = IEEE80211_OFDM_RATE_18MB * 500000;
+		range->bitrate[i++] = IEEE80211_OFDM_RATE_24MB * 500000;
+		range->bitrate[i++] = IEEE80211_OFDM_RATE_36MB * 500000;
+		range->bitrate[i++] = IEEE80211_OFDM_RATE_48MB * 500000;
+		range->bitrate[i++] = IEEE80211_OFDM_RATE_54MB * 500000;
 	}
 	if (phy->type == BCM43xx_PHYTYPE_B ||
 	    phy->type == BCM43xx_PHYTYPE_G) {
 		range->num_bitrates += 4;
-		range->bitrate[i++] = IEEE80211_CCK_RATE_1MB;
-		range->bitrate[i++] = IEEE80211_CCK_RATE_2MB;
-		range->bitrate[i++] = IEEE80211_CCK_RATE_5MB;
-		range->bitrate[i++] = IEEE80211_CCK_RATE_11MB;
+		range->bitrate[i++] = IEEE80211_CCK_RATE_1MB * 500000;
+		range->bitrate[i++] = IEEE80211_CCK_RATE_2MB * 500000;
+		range->bitrate[i++] = IEEE80211_CCK_RATE_5MB * 500000;
+		range->bitrate[i++] = IEEE80211_CCK_RATE_11MB * 500000;
 	}
 
 	geo = ieee80211_get_geo(bcm->ieee);
@@ -285,7 +285,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
 		if (j == IW_MAX_FREQUENCIES)
 			break;
 		range->freq[j].i = j + 1;
-		range->freq[j].m = geo->a[i].freq;//FIXME?
+		range->freq[j].m = geo->a[i].freq * 100000;
 		range->freq[j].e = 1;
 		j++;
 	}
@@ -293,7 +293,7 @@ static int bcm43xx_wx_get_rangeparams(struct net_device *net_dev,
 		if (j == IW_MAX_FREQUENCIES)
 			break;
 		range->freq[j].i = j + 1;
-		range->freq[j].m = geo->bg[i].freq;//FIXME?
+		range->freq[j].m = geo->bg[i].freq * 100000;
 		range->freq[j].e = 1;
 		j++;
 	}
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index b85857a..d0639a4 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -175,7 +175,7 @@ that only one external action is invoked at a time.
 
 /* Debugging stuff */
 #ifdef CONFIG_IPW2100_DEBUG
-#define CONFIG_IPW2100_RX_DEBUG	/* Reception debugging */
+#define IPW2100_RX_DEBUG	/* Reception debugging */
 #endif
 
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -2239,7 +2239,7 @@ static void ipw2100_snapshot_free(struct ipw2100_priv *priv)
 	priv->snapshot[0] = NULL;
 }
 
-#ifdef CONFIG_IPW2100_DEBUG_C3
+#ifdef IPW2100_DEBUG_C3
 static int ipw2100_snapshot_alloc(struct ipw2100_priv *priv)
 {
 	int i;
@@ -2314,13 +2314,13 @@ static u32 ipw2100_match_buf(struct ipw2100_priv *priv, u8 * in_buf,
  * The size of the constructed ethernet
  *
  */
-#ifdef CONFIG_IPW2100_RX_DEBUG
+#ifdef IPW2100_RX_DEBUG
 static u8 packet_data[IPW_RX_NIC_BUFFER_LENGTH];
 #endif
 
 static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
 {
-#ifdef CONFIG_IPW2100_DEBUG_C3
+#ifdef IPW2100_DEBUG_C3
 	struct ipw2100_status *status = &priv->status_queue.drv[i];
 	u32 match, reg;
 	int j;
@@ -2342,7 +2342,7 @@ static void ipw2100_corruption_detected(struct ipw2100_priv *priv, int i)
 	}
 #endif
 
-#ifdef CONFIG_IPW2100_DEBUG_C3
+#ifdef IPW2100_DEBUG_C3
 	/* Halt the fimrware so we can get a good image */
 	write_register(priv->net_dev, IPW_REG_RESET_REG,
 		       IPW_AUX_HOST_RESET_REG_STOP_MASTER);
@@ -2413,7 +2413,7 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
 
 	skb_put(packet->skb, status->frame_size);
 
-#ifdef CONFIG_IPW2100_RX_DEBUG
+#ifdef IPW2100_RX_DEBUG
 	/* Make a copy of the frame so we can dump it to the logs if
 	 * ieee80211_rx fails */
 	memcpy(packet_data, packet->skb->data,
@@ -2421,7 +2421,7 @@ static void isr_rx(struct ipw2100_priv *priv, int i,
 #endif
 
 	if (!ieee80211_rx(priv->ieee, packet->skb, stats)) {
-#ifdef CONFIG_IPW2100_RX_DEBUG
+#ifdef IPW2100_RX_DEBUG
 		IPW_DEBUG_DROP("%s: Non consumed packet:\n",
 			       priv->net_dev->name);
 		printk_buf(IPW_DL_DROP, packet_data, status->frame_size);
@@ -4912,7 +4912,7 @@ static int ipw2100_set_power_mode(struct ipw2100_priv *priv, int power_level)
 	else
 		priv->power_mode = IPW_POWER_ENABLED | power_level;
 
-#ifdef CONFIG_IPW2100_TX_POWER
+#ifdef IPW2100_TX_POWER
 	if (priv->port_type == IBSS && priv->adhoc_power != DFTL_IBSS_TX_POWER) {
 		/* Set beacon interval */
 		cmd.host_command = TX_POWER_INDEX;
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index a085241..4c5f78e 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -156,7 +156,7 @@ void zd_mac_clear(struct zd_mac *mac)
 static int reset_mode(struct zd_mac *mac)
 {
 	struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
-	struct zd_ioreq32 ioreqs[3] = {
+	struct zd_ioreq32 ioreqs[] = {
 		{ CR_RX_FILTER, STA_RX_FILTER },
 		{ CR_SNIFFER_ON, 0U },
 	};
@@ -164,10 +164,9 @@ static int reset_mode(struct zd_mac *mac)
 	if (ieee->iw_mode == IW_MODE_MONITOR) {
 		ioreqs[0].value = 0xffffffff;
 		ioreqs[1].value = 0x1;
-		ioreqs[2].value = ENC_SNIFFER;
 	}
 
-	return zd_iowrite32a(&mac->chip, ioreqs, 3);
+	return zd_iowrite32a(&mac->chip, ioreqs, ARRAY_SIZE(ioreqs));
 }
 
 int zd_mac_open(struct net_device *netdev)
@@ -904,16 +903,21 @@ static int fill_ctrlset(struct zd_mac *mac,
 static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri)
 {
 	int i, r;
+	struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
 
 	for (i = 0; i < txb->nr_frags; i++) {
 		struct sk_buff *skb = txb->fragments[i];
 
 		r = fill_ctrlset(mac, txb, i);
-		if (r)
+		if (r) {
+			ieee->stats.tx_dropped++;
 			return r;
+		}
 		r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len);
-		if (r)
+		if (r) {
+			ieee->stats.tx_dropped++;
 			return r;
+		}
 	}
 
 	/* FIXME: shouldn't this be handled by the upper layers? */
@@ -1063,9 +1067,23 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats,
 
 	*pstatus = status = zd_tail(buffer, length, sizeof(struct rx_status));
 	if (status->frame_status & ZD_RX_ERROR) {
-		/* FIXME: update? */
+		struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
+		ieee->stats.rx_errors++;
+		if (status->frame_status & ZD_RX_TIMEOUT_ERROR)
+			ieee->stats.rx_missed_errors++;
+		else if (status->frame_status & ZD_RX_FIFO_OVERRUN_ERROR)
+			ieee->stats.rx_fifo_errors++;
+		else if (status->frame_status & ZD_RX_DECRYPTION_ERROR)
+			ieee->ieee_stats.rx_discards_undecryptable++;
+		else if (status->frame_status & ZD_RX_CRC32_ERROR) {
+			ieee->stats.rx_crc_errors++;
+			ieee->ieee_stats.rx_fcs_errors++;
+		}
+		else if (status->frame_status & ZD_RX_CRC16_ERROR)
+			ieee->stats.rx_crc_errors++;
 		return -EINVAL;
 	}
+
 	memset(stats, 0, sizeof(struct ieee80211_rx_stats));
 	stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN +
 		               + sizeof(struct rx_status));
@@ -1094,14 +1112,16 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb)
 	if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN +
 	               IEEE80211_FCS_LEN + sizeof(struct rx_status))
 	{
-		dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n",
-			 skb->len);
+		ieee->stats.rx_errors++;
+		ieee->stats.rx_length_errors++;
 		goto free_skb;
 	}
 
 	r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len);
 	if (r) {
-		/* Only packets with rx errors are included here. */
+		/* Only packets with rx errors are included here.
+		 * The error stats have already been set in fill_rx_stats.
+		 */
 		goto free_skb;
 	}
 
@@ -1114,8 +1134,10 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb)
 
 	r = filter_rx(ieee, skb->data, skb->len, &stats);
 	if (r <= 0) {
-		if (r < 0)
+		if (r < 0) {
+			ieee->stats.rx_errors++;
 			dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n");
+		}
 		goto free_skb;
 	}
 
@@ -1146,7 +1168,9 @@ int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length)
 
 	skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length);
 	if (!skb) {
+		struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
 		dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n");
+		ieee->stats.rx_dropped++;
 		return -ENOMEM;
 	}
 	skb_reserve(skb, sizeof(struct zd_rt_hdr));
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 75ef556..aac8a1c 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -313,6 +313,12 @@ out:
 
 static inline void handle_retry_failed_int(struct urb *urb)
 {
+	struct zd_usb *usb = urb->context;
+	struct zd_mac *mac = zd_usb_to_mac(usb);
+	struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
+
+	ieee->stats.tx_errors++;
+	ieee->ieee_stats.tx_retry_limit_exceeded++;
 	dev_dbg_f(urb_dev(urb), "retry failed interrupt\n");
 }
 
@@ -487,6 +493,9 @@ static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer,
 
 	if (length < sizeof(struct rx_length_info)) {
 		/* It's not a complete packet anyhow. */
+		struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac);
+		ieee->stats.rx_errors++;
+		ieee->stats.rx_length_errors++;
 		return;
 	}
 	length_info = (struct rx_length_info *)
@@ -923,6 +932,8 @@ static int probe(struct usb_interface *intf, const struct usb_device_id *id)
 		goto error;
 	}
 
+	usb_reset_device(interface_to_usbdev(intf));
+
 	netdev = zd_netdev_alloc(intf);
 	if (netdev == NULL) {
 		r = -ENOMEM;
@@ -1024,6 +1035,7 @@ static int __init usb_init(void)
 
 	r = usb_register(&driver);
 	if (r) {
+		destroy_workqueue(zd_workqueue);
 		printk(KERN_ERR "%s usb_register() failed. Error number %d\n",
 		       driver.name, r);
 		return r;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 182a96f..600308f 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2089,6 +2089,7 @@
 #define PCI_VENDOR_ID_PASEMI		0x1959
 
 #define PCI_VENDOR_ID_ATTANSIC		0x1969
+#define PCI_DEVICE_ID_ATTANSIC_L1	0x1048
 
 #define PCI_VENDOR_ID_JMICRON		0x197B
 #define PCI_DEVICE_ID_JMICRON_JMB360	0x2360
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 6189dc0..4cbb129 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -340,7 +340,7 @@ static struct attribute_group netstat_group = {
 	.attrs  = netstat_attrs,
 };
 
-#ifdef WIRELESS_EXT
+#ifdef CONFIG_WIRELESS_EXT
 /* helper function that does all the locking etc for wireless stats */
 static ssize_t wireless_show(struct device *d, char *buf,
 			     ssize_t (*format)(const struct iw_statistics *,
@@ -473,7 +473,7 @@ int netdev_register_sysfs(struct net_device *net)
 	if (net->get_stats)
 		*groups++ = &netstat_group;
 
-#ifdef WIRELESS_EXT
+#ifdef CONFIG_WIRELESS_EXT
 	if (net->wireless_handlers && net->wireless_handlers->get_wireless_stats)
 		*groups++ = &wireless_group;
 #endif
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index c55949e..0292d63 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -502,9 +502,6 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev)
 		if (host_encrypt)
 			ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
 		else if (host_build_iv) {
-			struct ieee80211_crypt_data *crypt;
-
-			crypt = ieee->crypt[ieee->tx_keyidx];
 			atomic_inc(&crypt->refcnt);
 			if (crypt->ops->build_iv)
 				crypt->ops->build_iv(skb_frag, hdr_len,

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-12-11 15:45 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2006-12-11 15:45 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, LKML


Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 drivers/net/Kconfig             |    8 +
 drivers/net/chelsio/cxgb2.c     |   23 +-
 drivers/net/chelsio/sge.c       |  115 ++++-----
 drivers/net/chelsio/sge.h       |    4 
 drivers/net/macb.c              |    8 -
 drivers/net/macb.h              |    6 
 drivers/net/myri10ge/myri10ge.c |  498 ++++++++++++++++++++-------------------
 drivers/net/smc91x.h            |   90 -------
 drivers/net/ucc_geth.c          |   12 +
 9 files changed, 334 insertions(+), 430 deletions(-)

Brice Goglin:
      myri10ge: indentation cleanups
      myri10ge: add page-based skb routines
      myri10ge: switch to page-based skb
      myri10ge: drop contiguous skb routines
      myri10ge: Full vlan frame in small_bytes
      myri10ge: fix big_bytes in case of vlan frames
      myri10ge: update driver version to 1.1.0

Haavard Skinnemoen:
      MACB: Use struct delayed_work instead of struct work_struct
      MACB: Use __raw register access

Paul Mundt:
      smc91x: Kill off excessive versatile hooks.

Scott Wood:
      ucc_geth: compilation error fixes
      ucc_geth: Initialize mdio_lock.

Stephen Hemminger:
      chelsio: working NAPI

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 9de0eed..8aa8dd0 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2384,6 +2384,14 @@ config CHELSIO_T1_1G
           Enables support for Chelsio's gigabit Ethernet PCI cards.  If you
           are using only 10G cards say 'N' here.
 
+config CHELSIO_T1_NAPI
+	bool "Use Rx Polling (NAPI)"
+	depends on CHELSIO_T1
+	default y
+	help
+	  NAPI is a driver API designed to reduce CPU and interrupt load
+	  when the driver is receiving lots of packets from the card.
+
 config EHEA
 	tristate "eHEA Ethernet support"
 	depends on IBMEBUS
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
index de48ead..fd5d821 100644
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -220,9 +220,8 @@ static int cxgb_up(struct adapter *adapt
 
 	t1_interrupts_clear(adapter);
 
-	adapter->params.has_msi = !disable_msi && pci_enable_msi(adapter->pdev) == 0;
-	err = request_irq(adapter->pdev->irq,
-			  t1_select_intr_handler(adapter),
+	adapter->params.has_msi = !disable_msi && !pci_enable_msi(adapter->pdev);
+	err = request_irq(adapter->pdev->irq, t1_interrupt,
 			  adapter->params.has_msi ? 0 : IRQF_SHARED,
 			  adapter->name, adapter);
 	if (err) {
@@ -764,18 +763,7 @@ static int set_coalesce(struct net_devic
 {
 	struct adapter *adapter = dev->priv;
 
-	/*
-	 * If RX coalescing is requested we use NAPI, otherwise interrupts.
-	 * This choice can be made only when all ports and the TOE are off.
-	 */
-	if (adapter->open_device_map == 0)
-		adapter->params.sge.polling = c->use_adaptive_rx_coalesce;
-
-	if (adapter->params.sge.polling) {
-		adapter->params.sge.rx_coalesce_usecs = 0;
-	} else {
-		adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
-	}
+	adapter->params.sge.rx_coalesce_usecs = c->rx_coalesce_usecs;
  	adapter->params.sge.coalesce_enable = c->use_adaptive_rx_coalesce;
 	adapter->params.sge.sample_interval_usecs = c->rate_sample_interval;
 	t1_sge_set_coalesce_params(adapter->sge, &adapter->params.sge);
@@ -944,7 +932,7 @@ static void t1_netpoll(struct net_device
 	struct adapter *adapter = dev->priv;
 
 	local_irq_save(flags);
-	t1_select_intr_handler(adapter)(adapter->pdev->irq, adapter);
+	t1_interrupt(adapter->pdev->irq, adapter);
 	local_irq_restore(flags);
 }
 #endif
@@ -1165,7 +1153,10 @@ #endif
 #ifdef CONFIG_NET_POLL_CONTROLLER
 		netdev->poll_controller = t1_netpoll;
 #endif
+#ifdef CONFIG_CHELSIO_T1_NAPI
 		netdev->weight = 64;
+		netdev->poll = t1_poll;
+#endif
 
 		SET_ETHTOOL_OPS(netdev, &t1_ethtool_ops);
 	}
diff --git a/drivers/net/chelsio/sge.c b/drivers/net/chelsio/sge.c
index 0ca8d87..659cb22 100644
--- a/drivers/net/chelsio/sge.c
+++ b/drivers/net/chelsio/sge.c
@@ -1413,16 +1413,20 @@ static int sge_rx(struct sge *sge, struc
 
 	if (unlikely(adapter->vlan_grp && p->vlan_valid)) {
 		st->vlan_xtract++;
-		if (adapter->params.sge.polling)
+#ifdef CONFIG_CHELSIO_T1_NAPI
 			vlan_hwaccel_receive_skb(skb, adapter->vlan_grp,
 						 ntohs(p->vlan));
-		else
+#else
 			vlan_hwaccel_rx(skb, adapter->vlan_grp,
 					ntohs(p->vlan));
-	} else if (adapter->params.sge.polling)
+#endif
+	} else {
+#ifdef CONFIG_CHELSIO_T1_NAPI
 		netif_receive_skb(skb);
-	else
+#else
 		netif_rx(skb);
+#endif
+	}
 	return 0;
 }
 
@@ -1572,6 +1576,7 @@ static int process_responses(struct adap
 	return budget;
 }
 
+#ifdef CONFIG_CHELSIO_T1_NAPI
 /*
  * A simpler version of process_responses() that handles only pure (i.e.,
  * non data-carrying) responses.  Such respones are too light-weight to justify
@@ -1619,92 +1624,76 @@ static int process_pure_responses(struct
  * or protection from interrupts as data interrupts are off at this point and
  * other adapter interrupts do not interfere.
  */
-static int t1_poll(struct net_device *dev, int *budget)
+int t1_poll(struct net_device *dev, int *budget)
 {
 	struct adapter *adapter = dev->priv;
 	int effective_budget = min(*budget, dev->quota);
-
 	int work_done = process_responses(adapter, effective_budget);
+
 	*budget -= work_done;
 	dev->quota -= work_done;
 
 	if (work_done >= effective_budget)
 		return 1;
 
+ 	spin_lock_irq(&adapter->async_lock);
 	__netif_rx_complete(dev);
-
-	/*
-	 * Because we don't atomically flush the following write it is
-	 * possible that in very rare cases it can reach the device in a way
-	 * that races with a new response being written plus an error interrupt
-	 * causing the NAPI interrupt handler below to return unhandled status
-	 * to the OS.  To protect against this would require flushing the write
-	 * and doing both the write and the flush with interrupts off.  Way too
-	 * expensive and unjustifiable given the rarity of the race.
-	 */
 	writel(adapter->sge->respQ.cidx, adapter->regs + A_SG_SLEEPING);
-	return 0;
-}
+	writel(adapter->slow_intr_mask | F_PL_INTR_SGE_DATA,
+	       adapter->regs + A_PL_ENABLE);
+ 	spin_unlock_irq(&adapter->async_lock);
 
-/*
- * Returns true if the device is already scheduled for polling.
- */
-static inline int napi_is_scheduled(struct net_device *dev)
-{
-	return test_bit(__LINK_STATE_RX_SCHED, &dev->state);
+	return 0;
 }
 
 /*
  * NAPI version of the main interrupt handler.
  */
-static irqreturn_t t1_interrupt_napi(int irq, void *data)
+irqreturn_t t1_interrupt(int irq, void *data)
 {
-	int handled;
 	struct adapter *adapter = data;
+ 	struct net_device *dev = adapter->sge->netdev;
 	struct sge *sge = adapter->sge;
-	struct respQ *q = &adapter->sge->respQ;
+ 	u32 cause;
+	int handled = 0;
 
-	/*
-	 * Clear the SGE_DATA interrupt first thing.  Normally the NAPI
-	 * handler has control of the response queue and the interrupt handler
-	 * can look at the queue reliably only once it knows NAPI is off.
-	 * We can't wait that long to clear the SGE_DATA interrupt because we
-	 * could race with t1_poll rearming the SGE interrupt, so we need to
-	 * clear the interrupt speculatively and really early on.
-	 */
-	writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE);
+	cause = readl(adapter->regs + A_PL_CAUSE);
+	if (cause == 0 || cause == ~0)
+		return IRQ_NONE;
 
 	spin_lock(&adapter->async_lock);
-	if (!napi_is_scheduled(sge->netdev)) {
+ 	if (cause & F_PL_INTR_SGE_DATA) {
+		struct respQ *q = &adapter->sge->respQ;
 		struct respQ_e *e = &q->entries[q->cidx];
 
-		if (e->GenerationBit == q->genbit) {
-			if (e->DataValid ||
-			    process_pure_responses(adapter, e)) {
-				if (likely(__netif_rx_schedule_prep(sge->netdev)))
-					__netif_rx_schedule(sge->netdev);
-				else if (net_ratelimit())
-					printk(KERN_INFO
-					       "NAPI schedule failure!\n");
-			} else
-				writel(q->cidx, adapter->regs + A_SG_SLEEPING);
-
-			handled = 1;
-			goto unlock;
-		} else
-			writel(q->cidx, adapter->regs + A_SG_SLEEPING);
-	}  else if (readl(adapter->regs + A_PL_CAUSE) & F_PL_INTR_SGE_DATA) {
-	        printk(KERN_ERR "data interrupt while NAPI running\n");
-	}
-	
-	handled = t1_slow_intr_handler(adapter);
+ 		handled = 1;
+ 		writel(F_PL_INTR_SGE_DATA, adapter->regs + A_PL_CAUSE);
+
+		if (e->GenerationBit == q->genbit &&
+		    __netif_rx_schedule_prep(dev)) {
+			if (e->DataValid || process_pure_responses(adapter, e)) {
+				/* mask off data IRQ */
+				writel(adapter->slow_intr_mask,
+				       adapter->regs + A_PL_ENABLE);
+				__netif_rx_schedule(sge->netdev);
+				goto unlock;
+			}
+			/* no data, no NAPI needed */
+			netif_poll_enable(dev);
+
+		}
+		writel(q->cidx, adapter->regs + A_SG_SLEEPING);
+	} else
+		handled = t1_slow_intr_handler(adapter);
+
 	if (!handled)
 		sge->stats.unhandled_irqs++;
- unlock:
+unlock:
 	spin_unlock(&adapter->async_lock);
 	return IRQ_RETVAL(handled != 0);
 }
 
+#else
 /*
  * Main interrupt handler, optimized assuming that we took a 'DATA'
  * interrupt.
@@ -1720,7 +1709,7 @@ static irqreturn_t t1_interrupt_napi(int
  * 5. If we took an interrupt, but no valid respQ descriptors was found we
  *      let the slow_intr_handler run and do error handling.
  */
-static irqreturn_t t1_interrupt(int irq, void *cookie)
+irqreturn_t t1_interrupt(int irq, void *cookie)
 {
 	int work_done;
 	struct respQ_e *e;
@@ -1752,11 +1741,7 @@ static irqreturn_t t1_interrupt(int irq,
 	spin_unlock(&adapter->async_lock);
 	return IRQ_RETVAL(work_done != 0);
 }
-
-irq_handler_t t1_select_intr_handler(adapter_t *adapter)
-{
-	return adapter->params.sge.polling ? t1_interrupt_napi : t1_interrupt;
-}
+#endif
 
 /*
  * Enqueues the sk_buff onto the cmdQ[qid] and has hardware fetch it.
@@ -2033,7 +2018,6 @@ static void sge_tx_reclaim_cb(unsigned l
  */
 int t1_sge_set_coalesce_params(struct sge *sge, struct sge_params *p)
 {
-	sge->netdev->poll = t1_poll;
 	sge->fixed_intrtimer = p->rx_coalesce_usecs *
 		core_ticks_per_usec(sge->adapter);
 	writel(sge->fixed_intrtimer, sge->adapter->regs + A_SG_INTRTIMER);
@@ -2234,7 +2218,6 @@ struct sge * __devinit t1_sge_create(str
 
 	p->coalesce_enable = 0;
 	p->sample_interval_usecs = 0;
-	p->polling = 0;
 
 	return sge;
 nomem_port:
diff --git a/drivers/net/chelsio/sge.h b/drivers/net/chelsio/sge.h
index 7ceb011..d132a0e 100644
--- a/drivers/net/chelsio/sge.h
+++ b/drivers/net/chelsio/sge.h
@@ -76,7 +76,9 @@ struct sge *t1_sge_create(struct adapter
 int t1_sge_configure(struct sge *, struct sge_params *);
 int t1_sge_set_coalesce_params(struct sge *, struct sge_params *);
 void t1_sge_destroy(struct sge *);
-irq_handler_t t1_select_intr_handler(adapter_t *adapter);
+irqreturn_t t1_interrupt(int irq, void *cookie);
+int t1_poll(struct net_device *, int *);
+
 int t1_start_xmit(struct sk_buff *skb, struct net_device *dev);
 void t1_set_vlan_accel(struct adapter *adapter, int on_off);
 void t1_sge_start(struct sge *);
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index bd0ce98..25b559b 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -264,12 +264,12 @@ static void macb_update_stats(struct mac
 	WARN_ON((unsigned long)(end - p - 1) != (MACB_TPF - MACB_PFR) / 4);
 
 	for(; p < end; p++, reg++)
-		*p += readl(reg);
+		*p += __raw_readl(reg);
 }
 
-static void macb_periodic_task(void *arg)
+static void macb_periodic_task(struct work_struct *work)
 {
-	struct macb *bp = arg;
+	struct macb *bp = container_of(work, struct macb, periodic_task.work);
 
 	macb_update_stats(bp);
 	macb_check_media(bp, 1, 0);
@@ -1088,7 +1088,7 @@ static int __devinit macb_probe(struct p
 
 	dev->base_addr = regs->start;
 
-	INIT_WORK(&bp->periodic_task, macb_periodic_task, bp);
+	INIT_DELAYED_WORK(&bp->periodic_task, macb_periodic_task);
 	mutex_init(&bp->mdio_mutex);
 	init_completion(&bp->mdio_complete);
 
diff --git a/drivers/net/macb.h b/drivers/net/macb.h
index 8c253db..27bf0ae 100644
--- a/drivers/net/macb.h
+++ b/drivers/net/macb.h
@@ -250,9 +250,9 @@ #define MACB_BFINS(name,value,old)			\
 
 /* Register access macros */
 #define macb_readl(port,reg)				\
-	readl((port)->regs + MACB_##reg)
+	__raw_readl((port)->regs + MACB_##reg)
 #define macb_writel(port,reg,value)			\
-	writel((value), (port)->regs + MACB_##reg)
+	__raw_writel((value), (port)->regs + MACB_##reg)
 
 struct dma_desc {
 	u32	addr;
@@ -377,7 +377,7 @@ struct macb {
 
 	unsigned int		rx_pending, tx_pending;
 
-	struct work_struct	periodic_task;
+	struct delayed_work	periodic_task;
 
 	struct mutex		mdio_mutex;
 	struct completion	mdio_complete;
diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c
index 81f127a..94ac168 100644
--- a/drivers/net/myri10ge/myri10ge.c
+++ b/drivers/net/myri10ge/myri10ge.c
@@ -71,7 +71,7 @@ #endif
 #include "myri10ge_mcp.h"
 #include "myri10ge_mcp_gen_header.h"
 
-#define MYRI10GE_VERSION_STR "1.0.0"
+#define MYRI10GE_VERSION_STR "1.1.0"
 
 MODULE_DESCRIPTION("Myricom 10G driver (10GbE)");
 MODULE_AUTHOR("Maintainer: help@myri.com");
@@ -92,8 +92,13 @@ #define MYRI10GE_MAX_SEND_DESC_TSO ((655
 #define MYRI10GE_NO_CONFIRM_DATA htonl(0xffffffff)
 #define MYRI10GE_NO_RESPONSE_RESULT 0xffffffff
 
+#define MYRI10GE_ALLOC_ORDER 0
+#define MYRI10GE_ALLOC_SIZE ((1 << MYRI10GE_ALLOC_ORDER) * PAGE_SIZE)
+#define MYRI10GE_MAX_FRAGS_PER_FRAME (MYRI10GE_MAX_ETHER_MTU/MYRI10GE_ALLOC_SIZE + 1)
+
 struct myri10ge_rx_buffer_state {
-	struct sk_buff *skb;
+	struct page *page;
+	int page_offset;
 	 DECLARE_PCI_UNMAP_ADDR(bus)
 	 DECLARE_PCI_UNMAP_LEN(len)
 };
@@ -116,9 +121,14 @@ struct myri10ge_rx_buf {
 	u8 __iomem *wc_fifo;	/* w/c rx dma addr fifo address */
 	struct mcp_kreq_ether_recv *shadow;	/* host shadow of recv ring */
 	struct myri10ge_rx_buffer_state *info;
+	struct page *page;
+	dma_addr_t bus;
+	int page_offset;
 	int cnt;
+	int fill_cnt;
 	int alloc_fail;
 	int mask;		/* number of rx slots -1 */
+	int watchdog_needed;
 };
 
 struct myri10ge_tx_buf {
@@ -150,6 +160,7 @@ struct myri10ge_priv {
 	struct myri10ge_rx_buf rx_big;
 	struct myri10ge_rx_done rx_done;
 	int small_bytes;
+	int big_bytes;
 	struct net_device *dev;
 	struct net_device_stats stats;
 	u8 __iomem *sram;
@@ -238,11 +249,6 @@ module_param(myri10ge_force_firmware, in
 MODULE_PARM_DESC(myri10ge_force_firmware,
 		 "Force firmware to assume aligned completions\n");
 
-static int myri10ge_skb_cross_4k = 0;
-module_param(myri10ge_skb_cross_4k, int, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(myri10ge_skb_cross_4k,
-		 "Can a small skb cross a 4KB boundary?\n");
-
 static int myri10ge_initial_mtu = MYRI10GE_MAX_ETHER_MTU - ETH_HLEN;
 module_param(myri10ge_initial_mtu, int, S_IRUGO);
 MODULE_PARM_DESC(myri10ge_initial_mtu, "Initial MTU\n");
@@ -266,6 +272,10 @@ static int myri10ge_debug = -1;	/* defau
 module_param(myri10ge_debug, int, 0);
 MODULE_PARM_DESC(myri10ge_debug, "Debug level (0=none,...,16=all)");
 
+static int myri10ge_fill_thresh = 256;
+module_param(myri10ge_fill_thresh, int, S_IRUGO | S_IWUSR);
+MODULE_PARM_DESC(myri10ge_fill_thresh, "Number of empty rx slots allowed\n");
+
 #define MYRI10GE_FW_OFFSET 1024*1024
 #define MYRI10GE_HIGHPART_TO_U32(X) \
 (sizeof (X) == 8) ? ((u32)((u64)(X) >> 32)) : (0)
@@ -273,9 +283,9 @@ #define MYRI10GE_LOWPART_TO_U32(X) ((u32
 
 #define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8)
 
-static inline void put_be32(__be32 val, __be32 __iomem *p)
+static inline void put_be32(__be32 val, __be32 __iomem * p)
 {
-	__raw_writel((__force __u32)val, (__force void __iomem *)p);
+	__raw_writel((__force __u32) val, (__force void __iomem *)p);
 }
 
 static int
@@ -804,194 +814,179 @@ myri10ge_submit_8rx(struct mcp_kreq_ethe
 	mb();
 }
 
-/*
- * Set of routines to get a new receive buffer.  Any buffer which
- * crosses a 4KB boundary must start on a 4KB boundary due to PCIe
- * wdma restrictions. We also try to align any smaller allocation to
- * at least a 16 byte boundary for efficiency.  We assume the linux
- * memory allocator works by powers of 2, and will not return memory
- * smaller than 2KB which crosses a 4KB boundary.  If it does, we fall
- * back to allocating 2x as much space as required.
- *
- * We intend to replace large (>4KB) skb allocations by using
- * pages directly and building a fraglist in the near future.
- */
-
-static inline struct sk_buff *myri10ge_alloc_big(struct net_device *dev,
-						 int bytes)
-{
-	struct sk_buff *skb;
-	unsigned long data, roundup;
-
-	skb = netdev_alloc_skb(dev, bytes + 4096 + MXGEFW_PAD);
-	if (skb == NULL)
-		return NULL;
-
-	/* Correct skb->truesize so that socket buffer
-	 * accounting is not confused the rounding we must
-	 * do to satisfy alignment constraints.
-	 */
-	skb->truesize -= 4096;
-
-	data = (unsigned long)(skb->data);
-	roundup = (-data) & (4095);
-	skb_reserve(skb, roundup);
-	return skb;
-}
-
-/* Allocate 2x as much space as required and use whichever portion
- * does not cross a 4KB boundary */
-static inline struct sk_buff *myri10ge_alloc_small_safe(struct net_device *dev,
-							unsigned int bytes)
+static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum)
 {
-	struct sk_buff *skb;
-	unsigned long data, boundary;
-
-	skb = netdev_alloc_skb(dev, 2 * (bytes + MXGEFW_PAD) - 1);
-	if (unlikely(skb == NULL))
-		return NULL;
-
-	/* Correct skb->truesize so that socket buffer
-	 * accounting is not confused the rounding we must
-	 * do to satisfy alignment constraints.
-	 */
-	skb->truesize -= bytes + MXGEFW_PAD;
-
-	data = (unsigned long)(skb->data);
-	boundary = (data + 4095UL) & ~4095UL;
-	if ((boundary - data) >= (bytes + MXGEFW_PAD))
-		return skb;
+	struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data);
 
-	skb_reserve(skb, boundary - data);
-	return skb;
+	if ((skb->protocol == htons(ETH_P_8021Q)) &&
+	    (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) ||
+	     vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) {
+		skb->csum = hw_csum;
+		skb->ip_summed = CHECKSUM_COMPLETE;
+	}
 }
 
-/* Allocate just enough space, and verify that the allocated
- * space does not cross a 4KB boundary */
-static inline struct sk_buff *myri10ge_alloc_small(struct net_device *dev,
-						   int bytes)
+static inline void
+myri10ge_rx_skb_build(struct sk_buff *skb, u8 * va,
+		      struct skb_frag_struct *rx_frags, int len, int hlen)
 {
-	struct sk_buff *skb;
-	unsigned long roundup, data, end;
-
-	skb = netdev_alloc_skb(dev, bytes + 16 + MXGEFW_PAD);
-	if (unlikely(skb == NULL))
-		return NULL;
-
-	/* Round allocated buffer to 16 byte boundary */
-	data = (unsigned long)(skb->data);
-	roundup = (-data) & 15UL;
-	skb_reserve(skb, roundup);
-	/* Verify that the data buffer does not cross a page boundary */
-	data = (unsigned long)(skb->data);
-	end = data + bytes + MXGEFW_PAD - 1;
-	if (unlikely(((end >> 12) != (data >> 12)) && (data & 4095UL))) {
-		printk(KERN_NOTICE
-		       "myri10ge_alloc_small: small skb crossed 4KB boundary\n");
-		myri10ge_skb_cross_4k = 1;
-		dev_kfree_skb_any(skb);
-		skb = myri10ge_alloc_small_safe(dev, bytes);
-	}
-	return skb;
+	struct skb_frag_struct *skb_frags;
+
+	skb->len = skb->data_len = len;
+	skb->truesize = len + sizeof(struct sk_buff);
+	/* attach the page(s) */
+
+	skb_frags = skb_shinfo(skb)->frags;
+	while (len > 0) {
+		memcpy(skb_frags, rx_frags, sizeof(*skb_frags));
+		len -= rx_frags->size;
+		skb_frags++;
+		rx_frags++;
+		skb_shinfo(skb)->nr_frags++;
+	}
+
+	/* pskb_may_pull is not available in irq context, but
+	 * skb_pull() (for ether_pad and eth_type_trans()) requires
+	 * the beginning of the packet in skb_headlen(), move it
+	 * manually */
+	memcpy(skb->data, va, hlen);
+	skb_shinfo(skb)->frags[0].page_offset += hlen;
+	skb_shinfo(skb)->frags[0].size -= hlen;
+	skb->data_len -= hlen;
+	skb->tail += hlen;
+	skb_pull(skb, MXGEFW_PAD);
 }
 
-static inline int
-myri10ge_getbuf(struct myri10ge_rx_buf *rx, struct myri10ge_priv *mgp,
-		int bytes, int idx)
+static void
+myri10ge_alloc_rx_pages(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
+			int bytes, int watchdog)
 {
-	struct net_device *dev = mgp->dev;
-	struct pci_dev *pdev = mgp->pdev;
-	struct sk_buff *skb;
-	dma_addr_t bus;
-	int len, retval = 0;
+	struct page *page;
+	int idx;
 
-	bytes += VLAN_HLEN;	/* account for 802.1q vlan tag */
+	if (unlikely(rx->watchdog_needed && !watchdog))
+		return;
 
-	if ((bytes + MXGEFW_PAD) > (4096 - 16) /* linux overhead */ )
-		skb = myri10ge_alloc_big(dev, bytes);
-	else if (myri10ge_skb_cross_4k)
-		skb = myri10ge_alloc_small_safe(dev, bytes);
-	else
-		skb = myri10ge_alloc_small(dev, bytes);
+	/* try to refill entire ring */
+	while (rx->fill_cnt != (rx->cnt + rx->mask + 1)) {
+		idx = rx->fill_cnt & rx->mask;
 
-	if (unlikely(skb == NULL)) {
-		rx->alloc_fail++;
-		retval = -ENOBUFS;
-		goto done;
-	}
-
-	/* set len so that it only covers the area we
-	 * need mapped for DMA */
-	len = bytes + MXGEFW_PAD;
-
-	bus = pci_map_single(pdev, skb->data, len, PCI_DMA_FROMDEVICE);
-	rx->info[idx].skb = skb;
-	pci_unmap_addr_set(&rx->info[idx], bus, bus);
-	pci_unmap_len_set(&rx->info[idx], len, len);
-	rx->shadow[idx].addr_low = htonl(MYRI10GE_LOWPART_TO_U32(bus));
-	rx->shadow[idx].addr_high = htonl(MYRI10GE_HIGHPART_TO_U32(bus));
-
-done:
-	/* copy 8 descriptors (64-bytes) to the mcp at a time */
-	if ((idx & 7) == 7) {
-		if (rx->wc_fifo == NULL)
-			myri10ge_submit_8rx(&rx->lanai[idx - 7],
-					    &rx->shadow[idx - 7]);
-		else {
-			mb();
-			myri10ge_pio_copy(rx->wc_fifo,
-					  &rx->shadow[idx - 7], 64);
+		if ((bytes < MYRI10GE_ALLOC_SIZE / 2) &&
+		    (rx->page_offset + bytes <= MYRI10GE_ALLOC_SIZE)) {
+			/* we can use part of previous page */
+			get_page(rx->page);
+		} else {
+			/* we need a new page */
+			page =
+			    alloc_pages(GFP_ATOMIC | __GFP_COMP,
+					MYRI10GE_ALLOC_ORDER);
+			if (unlikely(page == NULL)) {
+				if (rx->fill_cnt - rx->cnt < 16)
+					rx->watchdog_needed = 1;
+				return;
+			}
+			rx->page = page;
+			rx->page_offset = 0;
+			rx->bus = pci_map_page(mgp->pdev, page, 0,
+					       MYRI10GE_ALLOC_SIZE,
+					       PCI_DMA_FROMDEVICE);
+		}
+		rx->info[idx].page = rx->page;
+		rx->info[idx].page_offset = rx->page_offset;
+		/* note that this is the address of the start of the
+		 * page */
+		pci_unmap_addr_set(&rx->info[idx], bus, rx->bus);
+		rx->shadow[idx].addr_low =
+		    htonl(MYRI10GE_LOWPART_TO_U32(rx->bus) + rx->page_offset);
+		rx->shadow[idx].addr_high =
+		    htonl(MYRI10GE_HIGHPART_TO_U32(rx->bus));
+
+		/* start next packet on a cacheline boundary */
+		rx->page_offset += SKB_DATA_ALIGN(bytes);
+		rx->fill_cnt++;
+
+		/* copy 8 descriptors to the firmware at a time */
+		if ((idx & 7) == 7) {
+			if (rx->wc_fifo == NULL)
+				myri10ge_submit_8rx(&rx->lanai[idx - 7],
+						    &rx->shadow[idx - 7]);
+			else {
+				mb();
+				myri10ge_pio_copy(rx->wc_fifo,
+						  &rx->shadow[idx - 7], 64);
+			}
 		}
 	}
-	return retval;
 }
 
-static inline void myri10ge_vlan_ip_csum(struct sk_buff *skb, __wsum hw_csum)
+static inline void
+myri10ge_unmap_rx_page(struct pci_dev *pdev,
+		       struct myri10ge_rx_buffer_state *info, int bytes)
 {
-	struct vlan_hdr *vh = (struct vlan_hdr *)(skb->data);
-
-	if ((skb->protocol == htons(ETH_P_8021Q)) &&
-	    (vh->h_vlan_encapsulated_proto == htons(ETH_P_IP) ||
-	     vh->h_vlan_encapsulated_proto == htons(ETH_P_IPV6))) {
-		skb->csum = hw_csum;
-		skb->ip_summed = CHECKSUM_COMPLETE;
+	/* unmap the recvd page if we're the only or last user of it */
+	if (bytes >= MYRI10GE_ALLOC_SIZE / 2 ||
+	    (info->page_offset + 2 * bytes) > MYRI10GE_ALLOC_SIZE) {
+		pci_unmap_page(pdev, (pci_unmap_addr(info, bus)
+				      & ~(MYRI10GE_ALLOC_SIZE - 1)),
+			       MYRI10GE_ALLOC_SIZE, PCI_DMA_FROMDEVICE);
 	}
 }
 
-static inline unsigned long
+#define MYRI10GE_HLEN 64	/* The number of bytes to copy from a
+				 * page into an skb */
+
+static inline int
 myri10ge_rx_done(struct myri10ge_priv *mgp, struct myri10ge_rx_buf *rx,
 		 int bytes, int len, __wsum csum)
 {
-	dma_addr_t bus;
 	struct sk_buff *skb;
-	int idx, unmap_len;
+	struct skb_frag_struct rx_frags[MYRI10GE_MAX_FRAGS_PER_FRAME];
+	int i, idx, hlen, remainder;
+	struct pci_dev *pdev = mgp->pdev;
+	struct net_device *dev = mgp->dev;
+	u8 *va;
 
+	len += MXGEFW_PAD;
 	idx = rx->cnt & rx->mask;
-	rx->cnt++;
+	va = page_address(rx->info[idx].page) + rx->info[idx].page_offset;
+	prefetch(va);
+	/* Fill skb_frag_struct(s) with data from our receive */
+	for (i = 0, remainder = len; remainder > 0; i++) {
+		myri10ge_unmap_rx_page(pdev, &rx->info[idx], bytes);
+		rx_frags[i].page = rx->info[idx].page;
+		rx_frags[i].page_offset = rx->info[idx].page_offset;
+		if (remainder < MYRI10GE_ALLOC_SIZE)
+			rx_frags[i].size = remainder;
+		else
+			rx_frags[i].size = MYRI10GE_ALLOC_SIZE;
+		rx->cnt++;
+		idx = rx->cnt & rx->mask;
+		remainder -= MYRI10GE_ALLOC_SIZE;
+	}
+
+	hlen = MYRI10GE_HLEN > len ? len : MYRI10GE_HLEN;
 
-	/* save a pointer to the received skb */
-	skb = rx->info[idx].skb;
-	bus = pci_unmap_addr(&rx->info[idx], bus);
-	unmap_len = pci_unmap_len(&rx->info[idx], len);
+	/* allocate an skb to attach the page(s) to. */
 
-	/* try to replace the received skb */
-	if (myri10ge_getbuf(rx, mgp, bytes, idx)) {
-		/* drop the frame -- the old skbuf is re-cycled */
-		mgp->stats.rx_dropped += 1;
+	skb = netdev_alloc_skb(dev, MYRI10GE_HLEN + 16);
+	if (unlikely(skb == NULL)) {
+		mgp->stats.rx_dropped++;
+		do {
+			i--;
+			put_page(rx_frags[i].page);
+		} while (i != 0);
 		return 0;
 	}
 
-	/* unmap the recvd skb */
-	pci_unmap_single(mgp->pdev, bus, unmap_len, PCI_DMA_FROMDEVICE);
-
-	/* mcp implicitly skips 1st bytes so that packet is properly
-	 * aligned */
-	skb_reserve(skb, MXGEFW_PAD);
-
-	/* set the length of the frame */
-	skb_put(skb, len);
+	/* Attach the pages to the skb, and trim off any padding */
+	myri10ge_rx_skb_build(skb, va, rx_frags, len, hlen);
+	if (skb_shinfo(skb)->frags[0].size <= 0) {
+		put_page(skb_shinfo(skb)->frags[0].page);
+		skb_shinfo(skb)->nr_frags = 0;
+	}
+	skb->protocol = eth_type_trans(skb, dev);
+	skb->dev = dev;
 
-	skb->protocol = eth_type_trans(skb, mgp->dev);
 	if (mgp->csum_flag) {
 		if ((skb->protocol == htons(ETH_P_IP)) ||
 		    (skb->protocol == htons(ETH_P_IPV6))) {
@@ -1000,9 +995,8 @@ myri10ge_rx_done(struct myri10ge_priv *m
 		} else
 			myri10ge_vlan_ip_csum(skb, csum);
 	}
-
 	netif_receive_skb(skb);
-	mgp->dev->last_rx = jiffies;
+	dev->last_rx = jiffies;
 	return 1;
 }
 
@@ -1079,7 +1073,7 @@ static inline void myri10ge_clean_rx_don
 						 length, checksum);
 		else
 			rx_ok = myri10ge_rx_done(mgp, &mgp->rx_big,
-						 mgp->dev->mtu + ETH_HLEN,
+						 mgp->big_bytes,
 						 length, checksum);
 		rx_packets += rx_ok;
 		rx_bytes += rx_ok * (unsigned long)length;
@@ -1094,6 +1088,14 @@ static inline void myri10ge_clean_rx_don
 	rx_done->cnt = cnt;
 	mgp->stats.rx_packets += rx_packets;
 	mgp->stats.rx_bytes += rx_bytes;
+
+	/* restock receive rings if needed */
+	if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt < myri10ge_fill_thresh)
+		myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
+					mgp->small_bytes + MXGEFW_PAD, 0);
+	if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt < myri10ge_fill_thresh)
+		myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0);
+
 }
 
 static inline void myri10ge_check_statblock(struct myri10ge_priv *mgp)
@@ -1484,56 +1486,48 @@ static int myri10ge_allocate_rings(struc
 		goto abort_with_rx_small_info;
 
 	/* Fill the receive rings */
+	mgp->rx_big.cnt = 0;
+	mgp->rx_small.cnt = 0;
+	mgp->rx_big.fill_cnt = 0;
+	mgp->rx_small.fill_cnt = 0;
+	mgp->rx_small.page_offset = MYRI10GE_ALLOC_SIZE;
+	mgp->rx_big.page_offset = MYRI10GE_ALLOC_SIZE;
+	mgp->rx_small.watchdog_needed = 0;
+	mgp->rx_big.watchdog_needed = 0;
+	myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
+				mgp->small_bytes + MXGEFW_PAD, 0);
 
-	for (i = 0; i <= mgp->rx_small.mask; i++) {
-		status = myri10ge_getbuf(&mgp->rx_small, mgp,
-					 mgp->small_bytes, i);
-		if (status) {
-			printk(KERN_ERR
-			       "myri10ge: %s: alloced only %d small bufs\n",
-			       dev->name, i);
-			goto abort_with_rx_small_ring;
-		}
+	if (mgp->rx_small.fill_cnt < mgp->rx_small.mask + 1) {
+		printk(KERN_ERR "myri10ge: %s: alloced only %d small bufs\n",
+		       dev->name, mgp->rx_small.fill_cnt);
+		goto abort_with_rx_small_ring;
 	}
 
-	for (i = 0; i <= mgp->rx_big.mask; i++) {
-		status =
-		    myri10ge_getbuf(&mgp->rx_big, mgp, dev->mtu + ETH_HLEN, i);
-		if (status) {
-			printk(KERN_ERR
-			       "myri10ge: %s: alloced only %d big bufs\n",
-			       dev->name, i);
-			goto abort_with_rx_big_ring;
-		}
+	myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 0);
+	if (mgp->rx_big.fill_cnt < mgp->rx_big.mask + 1) {
+		printk(KERN_ERR "myri10ge: %s: alloced only %d big bufs\n",
+		       dev->name, mgp->rx_big.fill_cnt);
+		goto abort_with_rx_big_ring;
 	}
 
 	return 0;
 
 abort_with_rx_big_ring:
-	for (i = 0; i <= mgp->rx_big.mask; i++) {
-		if (mgp->rx_big.info[i].skb != NULL)
-			dev_kfree_skb_any(mgp->rx_big.info[i].skb);
-		if (pci_unmap_len(&mgp->rx_big.info[i], len))
-			pci_unmap_single(mgp->pdev,
-					 pci_unmap_addr(&mgp->rx_big.info[i],
-							bus),
-					 pci_unmap_len(&mgp->rx_big.info[i],
-						       len),
-					 PCI_DMA_FROMDEVICE);
+	for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) {
+		int idx = i & mgp->rx_big.mask;
+		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx],
+				       mgp->big_bytes);
+		put_page(mgp->rx_big.info[idx].page);
 	}
 
 abort_with_rx_small_ring:
-	for (i = 0; i <= mgp->rx_small.mask; i++) {
-		if (mgp->rx_small.info[i].skb != NULL)
-			dev_kfree_skb_any(mgp->rx_small.info[i].skb);
-		if (pci_unmap_len(&mgp->rx_small.info[i], len))
-			pci_unmap_single(mgp->pdev,
-					 pci_unmap_addr(&mgp->rx_small.info[i],
-							bus),
-					 pci_unmap_len(&mgp->rx_small.info[i],
-						       len),
-					 PCI_DMA_FROMDEVICE);
+	for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) {
+		int idx = i & mgp->rx_small.mask;
+		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx],
+				       mgp->small_bytes + MXGEFW_PAD);
+		put_page(mgp->rx_small.info[idx].page);
 	}
+
 	kfree(mgp->rx_big.info);
 
 abort_with_rx_small_info:
@@ -1566,30 +1560,24 @@ static void myri10ge_free_rings(struct n
 
 	mgp = netdev_priv(dev);
 
-	for (i = 0; i <= mgp->rx_big.mask; i++) {
-		if (mgp->rx_big.info[i].skb != NULL)
-			dev_kfree_skb_any(mgp->rx_big.info[i].skb);
-		if (pci_unmap_len(&mgp->rx_big.info[i], len))
-			pci_unmap_single(mgp->pdev,
-					 pci_unmap_addr(&mgp->rx_big.info[i],
-							bus),
-					 pci_unmap_len(&mgp->rx_big.info[i],
-						       len),
-					 PCI_DMA_FROMDEVICE);
-	}
-
-	for (i = 0; i <= mgp->rx_small.mask; i++) {
-		if (mgp->rx_small.info[i].skb != NULL)
-			dev_kfree_skb_any(mgp->rx_small.info[i].skb);
-		if (pci_unmap_len(&mgp->rx_small.info[i], len))
-			pci_unmap_single(mgp->pdev,
-					 pci_unmap_addr(&mgp->rx_small.info[i],
-							bus),
-					 pci_unmap_len(&mgp->rx_small.info[i],
-						       len),
-					 PCI_DMA_FROMDEVICE);
+	for (i = mgp->rx_big.cnt; i < mgp->rx_big.fill_cnt; i++) {
+		idx = i & mgp->rx_big.mask;
+		if (i == mgp->rx_big.fill_cnt - 1)
+			mgp->rx_big.info[idx].page_offset = MYRI10GE_ALLOC_SIZE;
+		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_big.info[idx],
+				       mgp->big_bytes);
+		put_page(mgp->rx_big.info[idx].page);
 	}
 
+	for (i = mgp->rx_small.cnt; i < mgp->rx_small.fill_cnt; i++) {
+		idx = i & mgp->rx_small.mask;
+		if (i == mgp->rx_small.fill_cnt - 1)
+			mgp->rx_small.info[idx].page_offset =
+			    MYRI10GE_ALLOC_SIZE;
+		myri10ge_unmap_rx_page(mgp->pdev, &mgp->rx_small.info[idx],
+				       mgp->small_bytes + MXGEFW_PAD);
+		put_page(mgp->rx_small.info[idx].page);
+	}
 	tx = &mgp->tx;
 	while (tx->done != tx->req) {
 		idx = tx->done & tx->mask;
@@ -1657,19 +1645,18 @@ static int myri10ge_open(struct net_devi
 	 */
 
 	if (dev->mtu <= ETH_DATA_LEN)
-		mgp->small_bytes = 128;	/* enough for a TCP header */
+		/* enough for a TCP header */
+		mgp->small_bytes = (128 > SMP_CACHE_BYTES)
+		    ? (128 - MXGEFW_PAD)
+		    : (SMP_CACHE_BYTES - MXGEFW_PAD);
 	else
-		mgp->small_bytes = ETH_FRAME_LEN;	/* enough for an ETH_DATA_LEN frame */
+		/* enough for a vlan encapsulated ETH_DATA_LEN frame */
+		mgp->small_bytes = VLAN_ETH_FRAME_LEN;
 
 	/* Override the small buffer size? */
 	if (myri10ge_small_bytes > 0)
 		mgp->small_bytes = myri10ge_small_bytes;
 
-	/* If the user sets an obscenely small MTU, adjust the small
-	 * bytes down to nearly nothing */
-	if (mgp->small_bytes >= (dev->mtu + ETH_HLEN))
-		mgp->small_bytes = 64;
-
 	/* get the lanai pointers to the send and receive rings */
 
 	status |= myri10ge_send_cmd(mgp, MXGEFW_CMD_GET_SEND_OFFSET, &cmd, 0);
@@ -1705,17 +1692,23 @@ static int myri10ge_open(struct net_devi
 		mgp->rx_big.wc_fifo = NULL;
 	}
 
-	status = myri10ge_allocate_rings(dev);
-	if (status != 0)
-		goto abort_with_nothing;
-
 	/* Firmware needs the big buff size as a power of 2.  Lie and
 	 * tell him the buffer is larger, because we only use 1
 	 * buffer/pkt, and the mtu will prevent overruns.
 	 */
-	big_pow2 = dev->mtu + ETH_HLEN + MXGEFW_PAD;
-	while ((big_pow2 & (big_pow2 - 1)) != 0)
-		big_pow2++;
+	big_pow2 = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD;
+	if (big_pow2 < MYRI10GE_ALLOC_SIZE / 2) {
+		while ((big_pow2 & (big_pow2 - 1)) != 0)
+			big_pow2++;
+		mgp->big_bytes = dev->mtu + ETH_HLEN + VLAN_HLEN + MXGEFW_PAD;
+	} else {
+		big_pow2 = MYRI10GE_ALLOC_SIZE;
+		mgp->big_bytes = big_pow2;
+	}
+
+	status = myri10ge_allocate_rings(dev);
+	if (status != 0)
+		goto abort_with_nothing;
 
 	/* now give firmware buffers sizes, and MTU */
 	cmd.data0 = dev->mtu + ETH_HLEN + VLAN_HLEN;
@@ -2206,7 +2199,7 @@ static void myri10ge_set_multicast_list(
 	struct myri10ge_cmd cmd;
 	struct myri10ge_priv *mgp;
 	struct dev_mc_list *mc_list;
-	__be32 data[2] = {0, 0};
+	__be32 data[2] = { 0, 0 };
 	int err;
 
 	mgp = netdev_priv(dev);
@@ -2625,7 +2618,7 @@ static u32 myri10ge_read_reboot(struct m
 static void myri10ge_watchdog(struct work_struct *work)
 {
 	struct myri10ge_priv *mgp =
-		container_of(work, struct myri10ge_priv, watchdog_work);
+	    container_of(work, struct myri10ge_priv, watchdog_work);
 	u32 reboot;
 	int status;
 	u16 cmd, vendor;
@@ -2698,6 +2691,21 @@ static void myri10ge_watchdog_timer(unsi
 	struct myri10ge_priv *mgp;
 
 	mgp = (struct myri10ge_priv *)arg;
+
+	if (mgp->rx_small.watchdog_needed) {
+		myri10ge_alloc_rx_pages(mgp, &mgp->rx_small,
+					mgp->small_bytes + MXGEFW_PAD, 1);
+		if (mgp->rx_small.fill_cnt - mgp->rx_small.cnt >=
+		    myri10ge_fill_thresh)
+			mgp->rx_small.watchdog_needed = 0;
+	}
+	if (mgp->rx_big.watchdog_needed) {
+		myri10ge_alloc_rx_pages(mgp, &mgp->rx_big, mgp->big_bytes, 1);
+		if (mgp->rx_big.fill_cnt - mgp->rx_big.cnt >=
+		    myri10ge_fill_thresh)
+			mgp->rx_big.watchdog_needed = 0;
+	}
+
 	if (mgp->tx.req != mgp->tx.done &&
 	    mgp->tx.done == mgp->watchdog_tx_done &&
 	    mgp->watchdog_tx_req != mgp->watchdog_tx_done)
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index 9367c57..d2767e6 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -362,96 +362,6 @@ #define SMC_outsl(a, r, p, l)	writesl((a
 
 #define SMC_IRQ_FLAGS		(0)
 
-#elif	defined(CONFIG_ARCH_VERSATILE)
-
-#define SMC_CAN_USE_8BIT	1
-#define SMC_CAN_USE_16BIT	1
-#define SMC_CAN_USE_32BIT	1
-#define SMC_NOWAIT		1
-
-#define SMC_inb(a, r)		readb((a) + (r))
-#define SMC_inw(a, r)		readw((a) + (r))
-#define SMC_inl(a, r)		readl((a) + (r))
-#define SMC_outb(v, a, r)	writeb(v, (a) + (r))
-#define SMC_outw(v, a, r)	writew(v, (a) + (r))
-#define SMC_outl(v, a, r)	writel(v, (a) + (r))
-#define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
-#define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
-
-#define SMC_IRQ_FLAGS		(0)
-
-#elif	defined(CONFIG_ARCH_VERSATILE)
-
-#define SMC_CAN_USE_8BIT	1
-#define SMC_CAN_USE_16BIT	1
-#define SMC_CAN_USE_32BIT	1
-#define SMC_NOWAIT		1
-
-#define SMC_inb(a, r)		readb((a) + (r))
-#define SMC_inw(a, r)		readw((a) + (r))
-#define SMC_inl(a, r)		readl((a) + (r))
-#define SMC_outb(v, a, r)	writeb(v, (a) + (r))
-#define SMC_outw(v, a, r)	writew(v, (a) + (r))
-#define SMC_outl(v, a, r)	writel(v, (a) + (r))
-#define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
-#define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
-
-#define SMC_IRQ_FLAGS		(0)
-
-#elif	defined(CONFIG_ARCH_VERSATILE)
-
-#define SMC_CAN_USE_8BIT	1
-#define SMC_CAN_USE_16BIT	1
-#define SMC_CAN_USE_32BIT	1
-#define SMC_NOWAIT		1
-
-#define SMC_inb(a, r)		readb((a) + (r))
-#define SMC_inw(a, r)		readw((a) + (r))
-#define SMC_inl(a, r)		readl((a) + (r))
-#define SMC_outb(v, a, r)	writeb(v, (a) + (r))
-#define SMC_outw(v, a, r)	writew(v, (a) + (r))
-#define SMC_outl(v, a, r)	writel(v, (a) + (r))
-#define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
-#define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
-
-#define SMC_IRQ_FLAGS		(0)
-
-#elif	defined(CONFIG_ARCH_VERSATILE)
-
-#define SMC_CAN_USE_8BIT	1
-#define SMC_CAN_USE_16BIT	1
-#define SMC_CAN_USE_32BIT	1
-#define SMC_NOWAIT		1
-
-#define SMC_inb(a, r)		readb((a) + (r))
-#define SMC_inw(a, r)		readw((a) + (r))
-#define SMC_inl(a, r)		readl((a) + (r))
-#define SMC_outb(v, a, r)	writeb(v, (a) + (r))
-#define SMC_outw(v, a, r)	writew(v, (a) + (r))
-#define SMC_outl(v, a, r)	writel(v, (a) + (r))
-#define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
-#define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
-
-#define SMC_IRQ_FLAGS		(0)
-
-#elif	defined(CONFIG_ARCH_VERSATILE)
-
-#define SMC_CAN_USE_8BIT	1
-#define SMC_CAN_USE_16BIT	1
-#define SMC_CAN_USE_32BIT	1
-#define SMC_NOWAIT		1
-
-#define SMC_inb(a, r)		readb((a) + (r))
-#define SMC_inw(a, r)		readw((a) + (r))
-#define SMC_inl(a, r)		readl((a) + (r))
-#define SMC_outb(v, a, r)	writeb(v, (a) + (r))
-#define SMC_outw(v, a, r)	writew(v, (a) + (r))
-#define SMC_outl(v, a, r)	writel(v, (a) + (r))
-#define SMC_insl(a, r, p, l)	readsl((a) + (r), p, l)
-#define SMC_outsl(a, r, p, l)	writesl((a) + (r), p, l)
-
-#define SMC_IRQ_FLAGS		(0)
-
 #else
 
 #define SMC_CAN_USE_8BIT	1
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 1f05511..8243150 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -194,9 +194,9 @@ static void enqueue(struct list_head *no
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(ugeth_lock, flags);
+	spin_lock_irqsave(&ugeth_lock, flags);
 	list_add_tail(node, lh);
-	spin_unlock_irqrestore(ugeth_lock, flags);
+	spin_unlock_irqrestore(&ugeth_lock, flags);
 }
 #endif /* CONFIG_UGETH_FILTERING */
 
@@ -204,14 +204,14 @@ static struct list_head *dequeue(struct 
 {
 	unsigned long flags;
 
-	spin_lock_irqsave(ugeth_lock, flags);
+	spin_lock_irqsave(&ugeth_lock, flags);
 	if (!list_empty(lh)) {
 		struct list_head *node = lh->next;
 		list_del(node);
-		spin_unlock_irqrestore(ugeth_lock, flags);
+		spin_unlock_irqrestore(&ugeth_lock, flags);
 		return node;
 	} else {
-		spin_unlock_irqrestore(ugeth_lock, flags);
+		spin_unlock_irqrestore(&ugeth_lock, flags);
 		return NULL;
 	}
 }
@@ -1852,6 +1852,8 @@ static int init_phy(struct net_device *d
 	mii_info->mdio_read = &read_phy_reg;
 	mii_info->mdio_write = &write_phy_reg;
 
+	spin_lock_init(&mii_info->mdio_lock);
+
 	ugeth->mii_info = mii_info;
 
 	spin_lock_irq(&ugeth->lock);

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-12-07 12:14 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2006-12-07 12:14 UTC (permalink / raw)
  To: netdev, LKML

[just sent this upstream]

Random schtuff.

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 drivers/net/3c501.c                            |    2 
 drivers/net/3c503.c                            |    2 
 drivers/net/3c505.c                            |    2 
 drivers/net/3c507.c                            |    2 
 drivers/net/3c523.c                            |    2 
 drivers/net/3c527.c                            |    2 
 drivers/net/ac3200.c                           |    2 
 drivers/net/apne.c                             |    4 
 drivers/net/appletalk/cops.c                   |    2 
 drivers/net/arm/at91_ether.c                   |   88 ++--
 drivers/net/arm/at91_ether.h                   |    1 
 drivers/net/arm/ether1.c                       |    6 
 drivers/net/arm/ether3.c                       |    8 
 drivers/net/at1700.c                           |    2 
 drivers/net/atarilance.c                       |    4 
 drivers/net/bonding/bond_main.c                |    2 
 drivers/net/cs89x0.c                           |    2 
 drivers/net/declance.c                         |  404 ++++++++++----------
 drivers/net/e2100.c                            |    2 
 drivers/net/eepro.c                            |    2 
 drivers/net/eexpress.c                         |    2 
 drivers/net/es3210.c                           |    2 
 drivers/net/eth16i.c                           |    2 
 drivers/net/hp-plus.c                          |    2 
 drivers/net/hp.c                               |    2 
 drivers/net/lance.c                            |    2 
 drivers/net/lne390.c                           |    2 
 drivers/net/mv643xx_eth.c                      |    4 
 drivers/net/mvme147.c                          |    4 
 drivers/net/myri10ge/myri10ge.c                |   95 +++--
 drivers/net/myri10ge/myri10ge_mcp.h            |   56 +--
 drivers/net/myri10ge/myri10ge_mcp_gen_header.h |    2 
 drivers/net/ne.c                               |    2 
 drivers/net/ne2.c                              |    2 
 drivers/net/netxen/netxen_nic.h                |  331 ++++++++++++----
 drivers/net/netxen/netxen_nic_ethtool.c        |   65 ++-
 drivers/net/netxen/netxen_nic_hdr.h            |    6 
 drivers/net/netxen/netxen_nic_hw.c             |  483 +++++++++++++++++++-----
 drivers/net/netxen/netxen_nic_hw.h             |   10 
 drivers/net/netxen/netxen_nic_init.c           |  361 ++++++++++++++----
 drivers/net/netxen/netxen_nic_ioctl.h          |    8 
 drivers/net/netxen/netxen_nic_isr.c            |   51 +--
 drivers/net/netxen/netxen_nic_main.c           |  306 +++++++++------
 drivers/net/netxen/netxen_nic_niu.c            |   32 +-
 drivers/net/netxen/netxen_nic_phan_reg.h       |  228 +++++++----
 drivers/net/ni52.c                             |    2 
 drivers/net/ni65.c                             |    2 
 drivers/net/ns83820.c                          |   25 +
 drivers/net/r8169.c                            |   84 +++-
 drivers/net/seeq8005.c                         |    2 
 drivers/net/sk98lin/skgesirq.c                 |    2 
 drivers/net/skge.h                             |  150 ++++---
 drivers/net/sky2.c                             |  117 +++---
 drivers/net/sky2.h                             |   54 +--
 drivers/net/smc-ultra.c                        |    2 
 drivers/net/smc-ultra32.c                      |    2 
 drivers/net/smc9194.c                          |    2 
 drivers/net/smc91x.h                           |   24 +
 drivers/net/sun3lance.c                        |    4 
 drivers/net/tokenring/smctr.c                  |    2 
 drivers/net/wd.c                               |    2 
 drivers/net/wireless/hostap/hostap_ap.c        |    4 
 drivers/net/wireless/hostap/hostap_cs.c        |    3 
 drivers/net/wireless/hostap/hostap_download.c  |    4 
 drivers/net/wireless/hostap/hostap_hw.c        |   12 -
 drivers/net/wireless/hostap/hostap_info.c      |    3 
 drivers/net/wireless/hostap/hostap_ioctl.c     |   12 -
 drivers/net/wireless/hostap/hostap_pci.c       |    3 
 drivers/net/wireless/hostap/hostap_plx.c       |    3 
 drivers/net/wireless/ipw2100.c                 |    2 
 drivers/net/wireless/ipw2200.c                 |   24 +
 drivers/net/wireless/prism54/isl_ioctl.c       |    9 
 drivers/net/wireless/prism54/oid_mgt.c         |    4 
 drivers/net/wireless/zd1211rw/zd_chip.c        |   13 +
 drivers/net/wireless/zd1211rw/zd_chip.h        |   43 ++
 drivers/net/wireless/zd1211rw/zd_mac.c         |   53 ++-
 drivers/net/wireless/zd1211rw/zd_mac.h         |    3 
 drivers/net/wireless/zd1211rw/zd_netdev.c      |    2 
 net/ieee80211/softmac/ieee80211softmac_assoc.c |   14 +
 net/ieee80211/softmac/ieee80211softmac_auth.c  |    2 
 net/ieee80211/softmac/ieee80211softmac_priv.h  |    2 
 net/ieee80211/softmac/ieee80211softmac_wx.c    |    3 
 82 files changed, 2115 insertions(+), 1180 deletions(-)

Al Viro:
      __iomem annotations: smc91x
      mv643xx_eth.c NULL noise removal
      trivial missing __init in drivers/net/*
      drivers/net/arm missing __devinit
      myri10ge annotations
      ns83820 annotations

Amit S. Kale:
      NetXen: whitespace cleaup and more cleanup fixes
      NetXen: multiport firmware support, ioctl interface

Andrew Victor:
      AT91RM9200 Ethernet: Remove 'at91_dev' and use netdev_priv()
      AT91RM9200 Ethernet: Move check_timer variable and use mod_timer()
      AT91RM9200 Ethernet: Add netpoll / netconsole support
      AT91RM9200 Ethernet: Use dev_alloc_skb()

Andy Gospodarek:
      bonding: incorrect bonding state reported via ioctl

Brice Goglin:
      myri10ge: write as 2 32-byte blocks in myri10ge_submit_8rx

Daniel Drake:
      zd1211rw: zd_mac_rx isn't always called in IRQ context
      zd1211rw: Fill enc_capa in GIWRANGE handler

Deepak Saxena:
      Update smc91x driver with ARM Versatile board info

Francois Romieu:
      r8169: more magic during initialization of the hardware
      r8169: tweak the PCI data parity error recovery
      r8169: phy program update
      r8169: more alignment for the 0x8168

Jeff Garzik:
      [netdrvr] netxen: workqueue-related build fixes
      [wireless] zd1211rw: workqueue-related build fixes

Maciej W. Rozycki:
      declance: Fix PMAX and PMAD support
      declance: Support the I/O ASIC LANCE w/o TURBOchannel

Mariusz Kozlowski:
      sk98lin debug build fix
      net: smc91x add missing bracket

Maxime Austruy:
      softmac: fix unbalanced mutex_lock/unlock in ieee80211softmac_wx_set_mlme

Stephen Hemminger:
      sky2: add PCI for 88ec033
      sky2: add comments to PCI ids
      sky2: beter ram buffer partitioning
      sky2: receive queue watermark tweak
      skge: fix sparse warnings
      sky2: sparse warnings

Ulrich Kunitz:
      zd1211rw: Support for multicast addresses
      softmac: Fixed handling of deassociation from AP

Yan Burman:
      hostap: replace kmalloc+memset with kzalloc
      prism54: replace kmalloc+memset with kzalloc
      ipw2200: replace kmalloc+memset with kcalloc

Zhu Yi:
      ipw2200: Add IEEE80211_RADIOTAP_TSFT for promiscuous mode
      ipw2200: Update version stamp to 1.2.0
      ipw2200: Fix a typo
      ipw2200: Fix debug output endian issue


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
       [not found] <20061002154831.GA8929@havoc.gtf.org>
@ 2006-10-02 18:04 ` Andrew Morton
  0 siblings, 0 replies; 101+ messages in thread
From: Andrew Morton @ 2006-10-02 18:04 UTC (permalink / raw)
  To: Jeff Garzik, Auke Kok; +Cc: Linus Torvalds, LKML


> Cc: linux-ide@vger.kernel.org, LKML <linux-kernel@vger.kernel.org>

wrong mailing list ;)

On Mon, 2 Oct 2006 11:48:31 -0400
Jeff Garzik <jeff@garzik.org> wrote:

> 
> Please pull from 'upstream-linus' branch of
> master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus
> 
> to receive the following updates:
> 
>  drivers/net/e100.c                |   82 +--
>  drivers/net/e1000/LICENSE         |  339 ------------
>  drivers/net/e1000/Makefile        |   35 +
>  drivers/net/e1000/e1000.h         |   59 +-
>  drivers/net/e1000/e1000_ethtool.c |  150 +++--
>  drivers/net/e1000/e1000_hw.c      | 1074 +++++++++++++++++--------------------
>  drivers/net/e1000/e1000_hw.h      |   86 ++-
>  drivers/net/e1000/e1000_main.c    |  271 ++++++---
>  drivers/net/e1000/e1000_osdep.h   |   35 +
>  drivers/net/e1000/e1000_param.c   |   47 +-
>  drivers/net/hp100.c               |    5 
>  drivers/net/ixgb/Makefile         |   38 +
>  drivers/net/ixgb/ixgb.h           |   38 +
>  drivers/net/ixgb/ixgb_ee.c        |   36 +
>  drivers/net/ixgb/ixgb_ee.h        |   36 +
>  drivers/net/ixgb/ixgb_ethtool.c   |   36 +
>  drivers/net/ixgb/ixgb_hw.c        |   36 +
>  drivers/net/ixgb/ixgb_hw.h        |   36 +
>  drivers/net/ixgb/ixgb_ids.h       |   36 +
>  drivers/net/ixgb/ixgb_main.c      |   46 +-
>  drivers/net/ixgb/ixgb_osdep.h     |   36 +
>  drivers/net/ixgb/ixgb_param.c     |   36 +
>  drivers/net/phy/fixed.c           |    6 
>  drivers/net/phy/phy_device.c      |    8 
>  drivers/net/sky2.c                |  548 ++++++++++++-------
>  drivers/net/sky2.h                |   62 --
>  drivers/net/spider_net.c          |    6 
>  drivers/net/wireless/airo.c       |   23 +
>  drivers/net/wireless/ipw2100.c    |   11 
>  29 files changed, 1502 insertions(+), 1755 deletions(-)
>  delete mode 100644 drivers/net/e1000/LICENSE
> 
> Auke Kok:
>       e100, e1000, ixgb: update copyright header and remove LICENSE
>       e100, e1000, ixgb: Fix an impossible memory overwrite bug
>       e1000: keep .suspend and .resume driver methods in CONFIG_PM
>       e100: rework WoL and shutdown handling
>       e1000: driver state fixes (race fix)
>       ixgb: convert to netdev_priv(netdev)
>       e100, e1000, ixgb: increment version numbers

Does this include the e100 change which caused
reboot-with-netconsole-enabled to hang?

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-09-24 16:24 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2006-09-24 16:24 UTC (permalink / raw)
  To: netdev; +Cc: LKML

[just sent upstream to Andrew & Linus; patch available in git, it's too
large to post]

Nothing major of interest.  A couple new drivers (ehea, qla3xxx,
ep93xx_eth), a lot of trailing whitespace killed, a deleted MIPS driver,
e1000 update, ...

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 Documentation/networking/LICENSE.qla3xxx        |   46 
 MAINTAINERS                                     |   37 
 drivers/isdn/i4l/Kconfig                        |    1 
 drivers/net/3c501.c                             |   61 
 drivers/net/3c501.h                             |    4 
 drivers/net/3c503.c                             |   16 
 drivers/net/3c503.h                             |    4 
 drivers/net/3c505.c                             |   24 
 drivers/net/3c505.h                             |    2 
 drivers/net/3c507.c                             |   14 
 drivers/net/3c509.c                             |   53 
 drivers/net/3c515.c                             |   64 
 drivers/net/3c523.c                             |   28 
 drivers/net/3c523.h                             |   14 
 drivers/net/3c527.c                             |  530 
 drivers/net/3c527.h                             |    4 
 drivers/net/3c59x.c                             |   36 
 drivers/net/7990.c                              |   60 
 drivers/net/7990.h                              |   24 
 drivers/net/8139cp.c                            |  122 
 drivers/net/8139too.c                           |   11 
 drivers/net/82596.c                             |   12 
 drivers/net/8390.c                              |  246 
 drivers/net/8390.h                              |    2 
 drivers/net/Kconfig                             |   67 
 drivers/net/Makefile                            |   13 
 drivers/net/Space.c                             |   24 
 drivers/net/a2065.c                             |   40 
 drivers/net/a2065.h                             |    4 
 drivers/net/ac3200.c                            |    6 
 drivers/net/acenic.c                            |   46 
 drivers/net/acenic.h                            |    6 
 drivers/net/acenic_firmware.h                   |18808 ++++++++++++------------
 drivers/net/amd8111e.c                          |  489 
 drivers/net/amd8111e.h                          |  102 
 drivers/net/apne.c                              |   10 
 drivers/net/arcnet/com20020-pci.c               |    2 
 drivers/net/ariadne.c                           |    2 
 drivers/net/arm/Kconfig                         |    7 
 drivers/net/arm/Makefile                        |    1 
 drivers/net/arm/at91_ether.c                    |    2 
 drivers/net/arm/ep93xx_eth.c                    |  944 +
 drivers/net/arm/etherh.c                        |    2 
 drivers/net/at1700.c                            |   30 
 drivers/net/atari_bionet.c                      |   14 
 drivers/net/atari_pamsnet.c                     |    2 
 drivers/net/atarilance.c                        |   22 
 drivers/net/atp.c                               |    2 
 drivers/net/au1000_eth.c                        |   71 
 drivers/net/au1000_eth.h                        |   12 
 drivers/net/b44.c                               |    4 
 drivers/net/bmac.c                              |   54 
 drivers/net/bmac.h                              |    2 
 drivers/net/bnx2.c                              |  166 
 drivers/net/bnx2.h                              |   82 
 drivers/net/bonding/bond_main.c                 |    2 
 drivers/net/bsd_comp.c                          |   68 
 drivers/net/cassini.c                           |  540 
 drivers/net/cassini.h                           |  766 
 drivers/net/chelsio/cxgb2.c                     |    4 
 drivers/net/cris/eth_v10.c                      |    4 
 drivers/net/cs89x0.c                            |   82 
 drivers/net/cs89x0.h                            |    4 
 drivers/net/de600.c                             |    4 
 drivers/net/de620.c                             |   38 
 drivers/net/declance.c                          |    8 
 drivers/net/defxx.c                             |  270 
 drivers/net/defxx.h                             |  192 
 drivers/net/depca.c                             |  110 
 drivers/net/depca.h                             |   28 
 drivers/net/dgrs.c                              |   26 
 drivers/net/dgrs.h                              |    4 
 drivers/net/dgrs_asstruct.h                     |    2 
 drivers/net/dgrs_bcomm.h                        |    2 
 drivers/net/dgrs_ether.h                        |    4 
 drivers/net/dgrs_i82596.h                       |    2 
 drivers/net/dl2k.c                              |  164 
 drivers/net/dl2k.h                              |    6 
 drivers/net/dummy.c                             |   28 
 drivers/net/e100.c                              |   32 
 drivers/net/e1000/e1000.h                       |    6 
 drivers/net/e1000/e1000_ethtool.c               |  279 
 drivers/net/e1000/e1000_hw.c                    | 1167 -
 drivers/net/e1000/e1000_hw.h                    |   26 
 drivers/net/e1000/e1000_main.c                  |  154 
 drivers/net/e1000/e1000_osdep.h                 |   19 
 drivers/net/e1000/e1000_param.c                 |  161 
 drivers/net/e2100.c                             |    4 
 drivers/net/eepro.c                             |    7 
 drivers/net/eepro100.c                          |   40 
 drivers/net/eexpress.c                          |   98 
 drivers/net/eexpress.h                          |   14 
 drivers/net/ehea/Makefile                       |    6 
 drivers/net/ehea/ehea.h                         |  447 
 drivers/net/ehea/ehea_ethtool.c                 |  294 
 drivers/net/ehea/ehea_hcall.h                   |   51 
 drivers/net/ehea/ehea_hw.h                      |  292 
 drivers/net/ehea/ehea_main.c                    | 2654 +++
 drivers/net/ehea/ehea_phyp.c                    |  705 
 drivers/net/ehea/ehea_phyp.h                    |  455 
 drivers/net/ehea/ehea_qmr.c                     |  582 
 drivers/net/ehea/ehea_qmr.h                     |  358 
 drivers/net/epic100.c                           |   11 
 drivers/net/eql.c                               |   32 
 drivers/net/eth16i.c                            |  308 
 drivers/net/ewrk3.c                             |   68 
 drivers/net/ewrk3.h                             |   30 
 drivers/net/fealnx.c                            |   44 
 drivers/net/fec.c                               |   84 
 drivers/net/fec_8xx/fec_main.c                  |   28 
 drivers/net/forcedeth.c                         |  562 
 drivers/net/fs_enet/fs_enet-main.c              |    2 
 drivers/net/gianfar.c                           |   11 
 drivers/net/gianfar.h                           |    2 
 drivers/net/gianfar_ethtool.c                   |   18 
 drivers/net/gianfar_mii.c                       |    4 
 drivers/net/gianfar_mii.h                       |    2 
 drivers/net/gianfar_sysfs.c                     |    2 
 drivers/net/gt64240eth.h                        |    2 
 drivers/net/gt96100eth.c                        | 1566 -
 drivers/net/gt96100eth.h                        |  346 
 drivers/net/hamachi.c                           |  240 
 drivers/net/hp-plus.c                           |    4 
 drivers/net/hp.c                                |    2 
 drivers/net/hp100.c                             |  155 
 drivers/net/hp100.h                             |   44 
 drivers/net/hplance.c                           |   12 
 drivers/net/ibm_emac/ibm_emac_core.c            |    2 
 drivers/net/ibmveth.c                           |    2 
 drivers/net/ifb.c                               |   42 
 drivers/net/ioc3-eth.c                          |    8 
 drivers/net/irda/mcs7780.c                      |    1 
 drivers/net/irda/w83977af_ir.c                  |    1 
 drivers/net/isa-skeleton.c                      |   16 
 drivers/net/iseries_veth.c                      |    2 
 drivers/net/ixgb/ixgb.h                         |    5 
 drivers/net/ixgb/ixgb_ethtool.c                 |    8 
 drivers/net/ixgb/ixgb_hw.c                      |   17 
 drivers/net/ixgb/ixgb_ids.h                     |    1 
 drivers/net/ixgb/ixgb_main.c                    |  152 
 drivers/net/ixgb/ixgb_osdep.h                   |   12 
 drivers/net/jazzsonic.c                         |   12 
 drivers/net/lance.c                             |   38 
 drivers/net/lasi_82596.c                        |   48 
 drivers/net/lne390.c                            |    4 
 drivers/net/loopback.c                          |    6 
 drivers/net/lp486e.c                            |   22 
 drivers/net/mac8390.c                           |   48 
 drivers/net/mac89x0.c                           |   18 
 drivers/net/mace.c                              |   10 
 drivers/net/macmace.c                           |   88 
 drivers/net/macsonic.c                          |   38 
 drivers/net/meth.c                              |   14 
 drivers/net/mii.c                               |   18 
 drivers/net/mv643xx_eth.c                       |    6 
 drivers/net/myri10ge/myri10ge.c                 |  230 
 drivers/net/myri10ge/myri10ge_mcp.h             |   47 
 drivers/net/myri_code.h                         | 9538 ++++++------
 drivers/net/myri_sbus.c                         |   28 
 drivers/net/natsemi.c                           |   41 
 drivers/net/ne-h8300.c                          |    2 
 drivers/net/ne.c                                |    4 
 drivers/net/ne2.c                               |   70 
 drivers/net/ne2k-pci.c                          |   12 
 drivers/net/ne3210.c                            |   16 
 drivers/net/netx-eth.c                          |    1 
 drivers/net/ni5010.c                            |  118 
 drivers/net/ni52.c                              |    2 
 drivers/net/ni52.h                              |   16 
 drivers/net/ni65.c                              |   20 
 drivers/net/ni65.h                              |    6 
 drivers/net/ns83820.c                           |   42 
 drivers/net/oaknet.c                            |   14 
 drivers/net/pci-skeleton.c                      |    9 
 drivers/net/pcmcia/3c574_cs.c                   |    4 
 drivers/net/pcmcia/3c589_cs.c                   |    4 
 drivers/net/pcmcia/axnet_cs.c                   |    7 
 drivers/net/pcmcia/fmvj18x_cs.c                 |    8 
 drivers/net/pcmcia/ibmtr_cs.c                   |    2 
 drivers/net/pcmcia/nmclan_cs.c                  |    4 
 drivers/net/pcmcia/pcnet_cs.c                   |   19 
 drivers/net/pcmcia/smc91c92_cs.c                |    9 
 drivers/net/pcmcia/xirc2ps_cs.c                 |    4 
 drivers/net/pcnet32.c                           |  692 
 drivers/net/phy/fixed.c                         |    4 
 drivers/net/phy/smsc.c                          |    1 
 drivers/net/phy/vitesse.c                       |    1 
 drivers/net/plip.c                              |   42 
 drivers/net/ppp_async.c                         |    6 
 drivers/net/ppp_deflate.c                       |    4 
 drivers/net/ppp_generic.c                       |   16 
 drivers/net/ppp_synctty.c                       |    2 
 drivers/net/pppoe.c                             |   16 
 drivers/net/qla3xxx.c                           | 3537 ++++
 drivers/net/qla3xxx.h                           | 1194 +
 drivers/net/r8169.c                             |  660 
 drivers/net/rionet.c                            |    2 
 drivers/net/rrunner.c                           |   52 
 drivers/net/rrunner.h                           |    8 
 drivers/net/s2io-regs.h                         |    4 
 drivers/net/s2io.c                              |   57 
 drivers/net/s2io.h                              |   10 
 drivers/net/saa9730.c                           |    2 
 drivers/net/saa9730.h                           |   16 
 drivers/net/sb1000.c                            |   24 
 drivers/net/sb1250-mac.c                        |    9 
 drivers/net/seeq8005.c                          |   98 
 drivers/net/seeq8005.h                          |    4 
 drivers/net/sgiseeq.h                           |    4 
 drivers/net/shaper.c                            |  104 
 drivers/net/sis190.c                            |    7 
 drivers/net/sis900.c                            |  227 
 drivers/net/sis900.h                            |   18 
 drivers/net/sk98lin/skethtool.c                 |    2 
 drivers/net/sk98lin/skge.c                      |    4 
 drivers/net/sk_mca.c                            |   18 
 drivers/net/sk_mca.h                            |    4 
 drivers/net/skfp/skfddi.c                       |    2 
 drivers/net/skge.c                              |  206 
 drivers/net/skge.h                              |    1 
 drivers/net/sky2.c                              |  423 
 drivers/net/sky2.h                              |   35 
 drivers/net/slhc.c                              |   34 
 drivers/net/slip.c                              |   32 
 drivers/net/slip.h                              |    4 
 drivers/net/smc-mca.c                           |   10 
 drivers/net/smc-ultra.c                         |    6 
 drivers/net/smc-ultra32.c                       |    6 
 drivers/net/smc911x.c                           |    4 
 drivers/net/smc9194.c                           |    4 
 drivers/net/smc9194.h                           |   72 
 drivers/net/smc91x.c                            |    8 
 drivers/net/sonic.c                             |   22 
 drivers/net/sonic.h                             |    4 
 drivers/net/spider_net.c                        |   10 
 drivers/net/spider_net.h                        |   13 
 drivers/net/spider_net_ethtool.c                |   57 
 drivers/net/starfire.c                          |    8 
 drivers/net/stnic.c                             |    8 
 drivers/net/sun3_82586.c                        |   18 
 drivers/net/sun3_82586.h                        |   18 
 drivers/net/sun3lance.c                         |   74 
 drivers/net/sunbmac.c                           |    2 
 drivers/net/sundance.c                          |   69 
 drivers/net/sungem.c                            |   88 
 drivers/net/sungem.h                            |   12 
 drivers/net/sungem_phy.c                        |   50 
 drivers/net/sungem_phy.h                        |    2 
 drivers/net/sunhme.c                            |   14 
 drivers/net/sunlance.c                          |   60 
 drivers/net/sunqe.c                             |    6 
 drivers/net/tc35815.c                           |   10 
 drivers/net/tg3.c                               |  128 
 drivers/net/tlan.c                              |  344 
 drivers/net/tlan.h                              |   24 
 drivers/net/tokenring/3c359.c                   |    2 
 drivers/net/tokenring/lanstreamer.c             |    2 
 drivers/net/tulip/21142.c                       |    6 
 drivers/net/tulip/de2104x.c                     |   20 
 drivers/net/tulip/de4x5.c                       |    2 
 drivers/net/tulip/dmfe.c                        |    6 
 drivers/net/tulip/eeprom.c                      |    2 
 drivers/net/tulip/interrupt.c                   |    2 
 drivers/net/tulip/media.c                       |    2 
 drivers/net/tulip/pnic.c                        |    2 
 drivers/net/tulip/pnic2.c                       |    2 
 drivers/net/tulip/timer.c                       |   16 
 drivers/net/tulip/tulip.h                       |   36 
 drivers/net/tulip/tulip_core.c                  |  104 
 drivers/net/tulip/uli526x.c                     |   16 
 drivers/net/tulip/winbond-840.c                 |   94 
 drivers/net/tulip/xircom_cb.c                   |    2 
 drivers/net/tulip/xircom_tulip_cb.c             |    6 
 drivers/net/tun.c                               |   58 
 drivers/net/typhoon-firmware.h                  | 7488 ++++-----
 drivers/net/typhoon.c                           |   20 
 drivers/net/typhoon.h                           |    4 
 drivers/net/ucc_geth.c                          |   19 
 drivers/net/via-rhine.c                         |   13 
 drivers/net/via-velocity.c                      |  228 
 drivers/net/via-velocity.h                      |   23 
 drivers/net/wan/cycx_main.c                     |    1 
 drivers/net/wan/dlci.c                          |    1 
 drivers/net/wan/dscc4.c                         |    2 
 drivers/net/wan/farsync.c                       |    2 
 drivers/net/wan/lmc/lmc_main.c                  |    2 
 drivers/net/wan/pc300_drv.c                     |    2 
 drivers/net/wan/pci200syn.c                     |    2 
 drivers/net/wan/sdla.c                          |    1 
 drivers/net/wan/wanxl.c                         |    2 
 drivers/net/wd.c                                |   12 
 drivers/net/wireless/Kconfig                    |   23 
 drivers/net/wireless/airo.c                     |   52 
 drivers/net/wireless/atmel_pci.c                |    2 
 drivers/net/wireless/bcm43xx/bcm43xx.h          |  181 
 drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c  |   80 
 drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h  |    1 
 drivers/net/wireless/bcm43xx/bcm43xx_dma.c      |  583 
 drivers/net/wireless/bcm43xx/bcm43xx_dma.h      |  296 
 drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c  |    2 
 drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h  |    2 
 drivers/net/wireless/bcm43xx/bcm43xx_leds.c     |   10 
 drivers/net/wireless/bcm43xx/bcm43xx_main.c     |  900 -
 drivers/net/wireless/bcm43xx/bcm43xx_main.h     |    6 
 drivers/net/wireless/bcm43xx/bcm43xx_phy.c      |   33 
 drivers/net/wireless/bcm43xx/bcm43xx_pio.c      |    4 
 drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c    |  178 
 drivers/net/wireless/bcm43xx/bcm43xx_wx.c       |  166 
 drivers/net/wireless/bcm43xx/bcm43xx_xmit.c     |    5 
 drivers/net/wireless/hostap/hostap.h            |    2 
 drivers/net/wireless/hostap/hostap_cs.c         |    1 
 drivers/net/wireless/hostap/hostap_ioctl.c      |    2 
 drivers/net/wireless/ipw2100.c                  |    9 
 drivers/net/wireless/ipw2200.c                  |  248 
 drivers/net/wireless/ipw2200.h                  |   51 
 drivers/net/wireless/orinoco.c                  |    5 
 drivers/net/wireless/orinoco.h                  |    8 
 drivers/net/wireless/orinoco_nortel.c           |    2 
 drivers/net/wireless/orinoco_pci.c              |    2 
 drivers/net/wireless/orinoco_plx.c              |    2 
 drivers/net/wireless/orinoco_tmd.c              |    2 
 drivers/net/wireless/prism54/isl_ioctl.c        |  597 
 drivers/net/wireless/prism54/isl_ioctl.h        |    6 
 drivers/net/wireless/prism54/islpci_dev.c       |    4 
 drivers/net/wireless/prism54/islpci_dev.h       |    2 
 drivers/net/wireless/prism54/islpci_hotplug.c   |    2 
 drivers/net/wireless/ray_cs.c                   |    6 
 drivers/net/wireless/wavelan_cs.c               |    2 
 drivers/net/wireless/wl3501_cs.c                |    2 
 drivers/net/wireless/zd1211rw/Makefile          |    1 
 drivers/net/wireless/zd1211rw/zd_chip.c         |   62 
 drivers/net/wireless/zd1211rw/zd_chip.h         |   15 
 drivers/net/wireless/zd1211rw/zd_def.h          |    6 
 drivers/net/wireless/zd1211rw/zd_ieee80211.h    |    2 
 drivers/net/wireless/zd1211rw/zd_mac.c          |    8 
 drivers/net/wireless/zd1211rw/zd_mac.h          |    6 
 drivers/net/wireless/zd1211rw/zd_netdev.c       |   17 
 drivers/net/wireless/zd1211rw/zd_rf.c           |    7 
 drivers/net/wireless/zd1211rw/zd_rf.h           |    1 
 drivers/net/wireless/zd1211rw/zd_rf_al2230.c    |  155 
 drivers/net/wireless/zd1211rw/zd_rf_al7230b.c   |  274 
 drivers/net/wireless/zd1211rw/zd_usb.c          |  124 
 drivers/net/wireless/zd1211rw/zd_usb.h          |   15 
 drivers/net/yellowfin.c                         |   56 
 drivers/net/znet.c                              |   72 
 include/asm-arm/arch-ep93xx/ep93xx-regs.h       |    1 
 include/asm-arm/arch-ep93xx/platform.h          |    6 
 include/linux/netdevice.h                       |    2 
 include/net/ieee80211.h                         |    9 
 include/net/ieee80211softmac.h                  |   60 
 net/core/ethtool.c                              |   14 
 net/ieee80211/ieee80211_crypt_ccmp.c            |   23 
 net/ieee80211/ieee80211_crypt_tkip.c            |  114 
 net/ieee80211/ieee80211_crypt_wep.c             |   38 
 net/ieee80211/ieee80211_rx.c                    |   56 
 net/ieee80211/ieee80211_tx.c                    |    9 
 net/ieee80211/softmac/ieee80211softmac_assoc.c  |   21 
 net/ieee80211/softmac/ieee80211softmac_io.c     |   14 
 net/ieee80211/softmac/ieee80211softmac_module.c |   90 
 net/ieee80211/softmac/ieee80211softmac_priv.h   |    8 
 360 files changed, 40596 insertions(+), 28263 deletions(-)

Adrian Bunk:
      make drivers/net/e1000/e1000_hw.c:e1000_phy_igp_get_info() static

Alan Cox:
      gt96100: move to pci_get_device API
      s2io: Switch to pci_get_device

Andy Gospodarek:
      cleanup unnecessary forcedeth printk
      Remove more unnecessary driver printk's

Arjan van de Ven:
      resend of 8390 patch for lockdep

Auke Kok:
      e100: increment version to 3.5.10-k4
      e1000: Same cosmetic fix as earlier sent out for IPV4.
      e1000: Increment driver version to 7.1.9-k6
      ixgb: Increment version to 1.0.109-k4
      e1000: Whitespace cleanup, cosmetic changes
      e1000: error out if we cannot enable PCI device on resume
      e1000: remove unused part_num reading code
      e1000: Use module param array code
      e1000: Increment driver version to 7.2.7-k2
      e100: Convert e100 to use netdev_alloc_skb().
      e100: remove skb->dev assignment
      e100: increment version to 3.5.16-k2
      ixgb: Convert dev_alloc_skb to netdev_alloc_skb.
      ixgb: convert dev->priv to netdev_priv(dev).
      ixgb: recalculate after how many descriptors to wake the queue
      ixgb: remove skb->dev assignment
      ixgb: Increment version to 1.0.112-k2

Auke-Jan H Kok:
      e1000: revert 'e1000: Remove 0x1000 as supported device'

Ayaz Abdulla:
      forcedeth: move mac address setup/teardown
      forcedeth: mac address corrected
      forcedeth: errata for marvell phys
      forcedeth: decouple vlan and rx checksum dependency

Brice Goglin:
      myri10ge: define some previously hardwired firmware constants
      myri10ge: convert to netdev_alloc_skb
      myri10ge: use netif_msg_link
      myri10ge: use multicast support in the firmware
      myri10ge: improve firmware selection

Christian Steineck:
      hostap_cs: added support for Proxim Harmony PCI W-Lan card

Christoph Hellwig:
      e1000: clean up skb allocation code

Dale Farnsworth:
      mv643xx_eth: restrict to 32-bit PPC_MULTIPLATFORM

Dan Williams:
      prism54: update to WE-19 for WPA support

Daniel Drake:
      zd1211rw: Add Sagem device ID's
      zd1211rw: Implement SIOCGIWNICKN
      Add zd1211rw MAINTAINERS entry
      ieee80211: small ERP handling additions
      softmac: ERP handling and driver-level notifications
      softmac: export highest_supported_rate function
      ieee80211: Make ieee80211_rx_any usable
      softmac: Add MAINTAINERS entry
      zd1211rw: ZD1211B ASIC/FWT, not jointly decoder
      zd1211rw: Match vendor driver IFS values
      zd1211rw: AL2230 ZD1211B vendor sync
      zd1211rw: Support AL7230B RF
      zd1211rw: Add ID for Senao NUB-8301
      zd1211rw: Add ID for Allnet ALLSPOT Hotspot finder
      zd1211rw: Firmware version vs bootcode version mismatch handling
      zd1211rw: Add ID for ZyXEL G220F
      zd1211rw: Convert installer CDROM device into WLAN device
      zd1211rw: Add ID for Siemens Gigaset USB Stick 54
      zd1211rw: Add ID for Asus WL-159g

Daniele Venzano:
      Add new PHY to sis900 supported list

Dave Jones:
      remove unnecessary config.h includes from drivers/net/

Don Fry:
      pcnet32: remove unnecessary save/restore register accesses.
      pcnet32: magic number cleanup
      pcnet32: move/create receive and transmit routines
      pcnet32: break receive routine into two pieces.
      pcnet32: NAPI implementation

Francois Romieu:
      r8169: mac address change support
      r8169: RX fifo overflow recovery
      r8169: hardware flow control
      r8169: remove rtl8169_init_board
      r8169: sync with vendor's driver
      r8169: use NETDEV_TX_{BUSY/OK}
      r8169: udelay() removal
      r8169: trim trailing whitespaces and convert whitespaces to tabs
      r8169: use standard #defines from mii.h instead of declaring private ones
      r8169: add basic MII ioctl support
      r8169: the 0x8136 needs a 8 bytes alignment
      8139cp: trim ring_info
      8139cp: remove gratuitous indirection
      8139cp: ring_info removal for the receive path
      8139cp: sync the device private data with its r8169 counterpart
      8139cp: removal of useless BUG_ON() check
      8139cp: use PCI_DEVICE() to shorten the PCI device table
      Defer tulip_select_media() to process context
      r8169: quirk for the 8110sb on arm platform
      8139cp: ring_info removal for the transmit path
      r8169: the MMIO region of the 8167 stands behin BAR#1

François Romieu:
      8139cp: pci_get_drvdata(pdev) can not be NULL in suspend handler

Grant Grundler:
      Print physical address in tulip_init_one
      Flush MMIO writes in reset sequence
      Clean up tulip.h
      Use tulip.h in winbond-840.c

Henrik Kretzschmar:
      initialisation cleanup for ULI526x-net-driver
      remove an unused function from the header

Jan-Bernd Themann:
      ehea: IBM eHEA Ethernet Device Driver
      ehea: bugfix for register access functions

Jean Tourrilhes:
      Prism54 : add bitrates to scan result

Jeff Garzik:
      drivers/net: Remove deprecated use of pci_module_init()
      drivers/net: Trim trailing whitespace
      drivers/net: const-ify ethtool_ops declarations
      drivers/net/phy/fixed: #if 0 some incomplete code
      e1000, ixgb: Remove pointless wrappers
      net/ieee80211: fix more crypto-related build breakage

Jeff Kirsher:
      e100: Fix MDIO/MDIO-X
      e1000: Remove 0x1000 as supported device
      e1000: Allow NVM to setup LPLU for IGP2 and IGP3
      e1000: Force full DMA clocking for 10/100 speed
      e1000: Disable aggressive clocking on esb2 with SERDES port

Jesse Brandeburg:
      e1000: Explicitly power up the PHY during loopback testing.
      e1000: explicit locking for two ethtool path functions
      ixgb: fix cache miss due to miscalculation
      e1000: unify WoL capability detection code
      e1000: Add PCI ID 0x10a4 for our new 4-port PCI-Express device
      ixgb: Set a constant blink rate for ixgb adapter identify (1sec on, 1sec off)
      ixgb: Cache-align all TX components of the adapter struct.
      ixgb: Add buffer_info and test like e1000 has.

Jim Lewis:
      Spidernet: add ethtool -S (show statistics)

John W. Linville:
      bcm43xx: fix-up build breakage from merging patches out of order
      bcm43xx: reduce mac_suspend delay loop count

Komuro:
      network: pcnet_cs.c: remove unnecessary 'mdio_reset'
      network: axnet_cs.c: add new id (0x021b, 0x0202)

Larry Finger:
      bcm43xx: improved statistics
      bcm43xx: improved statistics
      bcm43xx: add missing mac_suspended initialization
      bcm43xx: optimization of DMA bitfields
      bcm43xx: return correct hard_start_xmit error code
      bcm43xx - set correct value in mac_suspended for ifdown/ifup sequence
      bcm43xx: Set floor of wireless signal and noise at -110 dBm
      bcm43xx-softmac: Init, shutdown and restart fixes
      bcm43xx: Correct out of sequence initialization step
      bcm43xx: remove dead statistics code
      bcm43xx: Add firmware version printout
      bcm43xx: ucode debug status via sysfs
      bcm43xx: remove dead code in bcm43xx_sysfs.c

Lennert Buytenhek:
      Cirrus Logic ep93xx ethernet driver

Linas Vepstas:
      e100: fix error recovery
      ixgb: Add PCI Error recovery callbacks
      e1000 disable device on PCI error

Manasi Deval:
      ixgb: Add CX4 PHY type detection and subdevice ID.

Michael Buesch:
      bcm43xx: opencoded locking
      bcm43xx: voluntary preemtion in the calibration loops
      bcm43xx: suspend MAC while executing long pwork
      bcm43xx: lower mac_suspend udelay
      bcm43xx: fix mac_suspend refcount
      bcm43xx: init routine rewrite
      bcm43xx: >1G and 64bit DMA support
      bcm43xx: re-add bcm43xx_rng_init() call
      MAINTAINERS: Add Larry Finger for bcm43xx (softmac)

Michael Wu:
      ray_cs: Remove dependency on ieee80211

Pavel Machek:
      cleanup // comments from ipw2200

Pavel Roskin:
      orinoco: Don't use "extern inline" on locking functions
      orinoco: include linux/if_arp.h directly

Philippe De Muyter:
      sundance: small cleanup

Ralf Baechle:
      Cleanup SLHC configuration
      Convert to kzalloc
      Remove useless casts
      Remove useless #ifdef MODULE stuff and printout
      [NET] GT96100: Delete bitrotting ethernet driver

Robert Schulze:
      airo: collapse debugging-messages in issuecommand to one line

Ron Mercer:
      qla3xxx NIC driver

shemminger@osdl.org:
      sky2: remove cloned/pskb_expand_head check
      sky2: use netdev_alloc_skb
      sky2: dont use force status bit
      sky2: MSI test timing
      sky2: TSO mss optimization
      sky2: optimize checksum offload information
      sky2: power down PHY when not up
      sky2: pci post bug
      sky2: version 1.7

Stephen Hemminger:
      sky2: add another PCI ID
      forcedeth: coding style cleanups
      forcedeth: le32 annotation
      sky2: more pci device ids
      sky2: status interrupt handling improvement
      forcdeth: revised NAPI support
      skge: cleanup suspend/resume code
      skge: pci bus post fixes
      skge: use dev_alloc_skb
      skge: use ethX for irq assigments
      skge: version 1.7
      sky2: more pci device id's
      skge: use netdev_alloc_skb
      skge: irq lock race
      skge: use NAPI for transmit complete
      skge: version 1.8
      skge: check for PCI hotplug during IRQ
      sky2: tx pause bug fix
      sky2: fiber support
      sky2: big endian
      ethtool: allow const ethtool_ops

Stephen Rothwell:
      Remove powerpc specific parts of 3c509 driver

Sukadev Bhattiprolu:
      kthread: airo.c

Thibaut Varene:
      Make DS21143 printout match lspci output

Ulrich Kunitz:
      zd1211rw: USB id 1582:6003 for Longshine 8131G3 added
      zd1211rw: cleanups
      zd1211rw: Removed unneeded packed attributes

Valerie Henson:
      Change tulip maintainer
      Handle pci_enable_device() errors in resume

Vasily Averin:
      e1000: IRQ resources cleanup
      e1000: e1000_probe resources cleanup
      e1000: ring buffers resources cleanup

Zhu Yi:
      ieee80211: Fix header->qos_ctl endian issue
      ieee80211: remove ieee80211_tx() is_queue_full warning
      ieee80211: TKIP and CCMP replay check rework
      ieee80211: Fix TKIP and WEP decryption error on SMP machines
      ieee80211: Workaround malformed 802.11 frames from AP
      ipw2200: always enable frequently used debugging code
      ipw2200: SIOCGIWFREQ ioctl returns frequency rather than channel
      ipw2200: ipw_wx_set_essid fix
      ipw2200: Reassociate even if set the same essid.
      ipw2200: remove unused struct ipw_rx_buffer
      ipw2200: Fix ipw2200 QOS parameters endian issue
      ipw2200: remove the MAC timestamp present field from radiotap head
      ipw2200: mark "iwconfig retry 255" as invalid
      ipw2200: Fix kernel Oops if cmdlog debug is enabled
      ipw2200: Add pci .shutdown handler
      ipw2100: Fix deadlock detected by lockdep
      ipw2200: enable wireless extension passive scan
      ipw2200: Update version stamp to 1.1.4
      ipw2200: Fix compile error when CONFIG_IPW2200_DEBUG is not selected


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-07-05 18:18 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2006-07-05 18:18 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel

Just sent this to Andrew/Linus...

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git upstream-linus

to receive the following updates:

 MAINTAINERS                                    |    7 
 drivers/net/8139cp.c                           |   35 
 drivers/net/8139too.c                          |   34 
 drivers/net/b44.c                              |   27 
 drivers/net/bnx2.c                             |   30 
 drivers/net/cassini.c                          |   25 
 drivers/net/declance.c                         |    7 
 drivers/net/dl2k.c                             |   43 
 drivers/net/eepro100.c                         |    6 
 drivers/net/epic100.c                          |   93 -
 drivers/net/fealnx.c                           |   36 
 drivers/net/gt96100eth.c                       |    3 
 drivers/net/gt96100eth.h                       |    2 
 drivers/net/hamachi.c                          |   16 
 drivers/net/myri10ge/myri10ge.c                |   17 
 drivers/net/natsemi.c                          |  117 -
 drivers/net/ne2k-pci.c                         |    9 
 drivers/net/ni5010.c                           |   52 
 drivers/net/ns83820.c                          |   41 
 drivers/net/pci-skeleton.c                     |   19 
 drivers/net/pcnet32.c                          |  520 +++++---
 drivers/net/phy/cicada.c                       |   42 
 drivers/net/r8169.c                            |   40 
 drivers/net/starfire.c                         |  123 -
 drivers/net/sundance.c                         |  106 -
 drivers/net/tulip/winbond-840.c                |   29 
 drivers/net/tulip/xircom_tulip_cb.c            |   27 
 drivers/net/via-rhine.c                        |  121 -
 drivers/net/via-velocity.c                     |  102 -
 drivers/net/via-velocity.h                     |    4 
 drivers/net/wan/Kconfig                        |   12 
 drivers/net/wan/Makefile                       |    1 
 drivers/net/wireless/Kconfig                   |    1 
 drivers/net/wireless/Makefile                  |    1 
 drivers/net/wireless/bcm43xx/bcm43xx_main.c    |   31 
 drivers/net/wireless/bcm43xx/bcm43xx_main.h    |   24 
 drivers/net/wireless/bcm43xx/bcm43xx_radio.c   |    7 
 drivers/net/wireless/bcm43xx/bcm43xx_wx.c      |    2 
 drivers/net/wireless/bcm43xx/bcm43xx_xmit.c    |    5 
 drivers/net/wireless/hostap/hostap_plx.c       |    2 
 drivers/net/wireless/zd1211rw/Kconfig          |   19 
 drivers/net/wireless/zd1211rw/Makefile         |   11 
 drivers/net/wireless/zd1211rw/zd_chip.c        | 1615 +++++++++++++++++++++++++
 drivers/net/wireless/zd1211rw/zd_chip.h        |  825 ++++++++++++
 drivers/net/wireless/zd1211rw/zd_def.h         |   48 
 drivers/net/wireless/zd1211rw/zd_ieee80211.c   |  191 ++
 drivers/net/wireless/zd1211rw/zd_ieee80211.h   |   85 +
 drivers/net/wireless/zd1211rw/zd_mac.c         | 1057 ++++++++++++++++
 drivers/net/wireless/zd1211rw/zd_mac.h         |  190 ++
 drivers/net/wireless/zd1211rw/zd_netdev.c      |  267 ++++
 drivers/net/wireless/zd1211rw/zd_netdev.h      |   45 
 drivers/net/wireless/zd1211rw/zd_rf.c          |  151 ++
 drivers/net/wireless/zd1211rw/zd_rf.h          |   82 +
 drivers/net/wireless/zd1211rw/zd_rf_al2230.c   |  308 ++++
 drivers/net/wireless/zd1211rw/zd_rf_rf2959.c   |  279 ++++
 drivers/net/wireless/zd1211rw/zd_types.h       |   71 +
 drivers/net/wireless/zd1211rw/zd_usb.c         | 1316 ++++++++++++++++++++
 drivers/net/wireless/zd1211rw/zd_usb.h         |  240 +++
 drivers/net/wireless/zd1211rw/zd_util.c        |   82 +
 drivers/net/wireless/zd1211rw/zd_util.h        |   29 
 drivers/net/yellowfin.c                        |   39 
 include/net/ieee80211softmac.h                 |    1 
 net/ieee80211/ieee80211_rx.c                   |    4 
 net/ieee80211/ieee80211_tx.c                   |   15 
 net/ieee80211/softmac/ieee80211softmac_assoc.c |   31 
 net/ieee80211/softmac/ieee80211softmac_auth.c  |    4 
 net/ieee80211/softmac/ieee80211softmac_io.c    |    3 
 net/ieee80211/softmac/ieee80211softmac_wx.c    |   36 
 68 files changed, 7760 insertions(+), 1103 deletions(-)

Andreas Mohr:
      NI5010 netcard cleanup

Brice Goglin:
      myri10ge - Use dev_info() when printing parameters after probe
      myri10ge - Export more parameters to ethtool

brice@myri.com:
      myri10ge - Drop unused pm_state
      myri10ge - Drop ununsed nvidia chipset id

Daniel Drake:
      bcm43xx: use softmac-suggested TX rate
      bcm43xx: enable shared key authentication
      ZyDAS ZD1211 USB-WLAN driver
      zd1211rw: disable TX queue during stop

Don Fry:
      pcnet32: Fix Section mismatch error
      pcnet32: Use PCI_DEVICE macro
      pcnet32: Fix off-by-one in get_ringparam
      pcnet32: Use kcalloc instead of kmalloc and memset
      pcnet32: Handle memory allocation failures cleanly when resizing tx/rx rings
      pcnet32: Suspend the chip rather than restart when changing multicast/promisc
      pcnet32: Cleanup rx buffers after loopback test.

Eric Sesterhenn:
      skb used after passing to netif_rx in net/ieee80211/ieee80211_rx.c

Faidon Liambotis:
      Add two PLX device IDs

Hong Liu:
      ieee80211: fix not allocating IV+ICV space when usingencryption in ieee80211_tx_frame

Horms:
      CONFIG_WIRELESS_EXT is neccessary after all

Ingo Molnar:
      lock validator: fix ns83820.c irq-flags bug

Jeff Garzik:
      [netdrvr] epic100: minor cleanups
      [netdrvr] Remove Linux-specific changelogs from several Becker template drivers
      [netdrvr] Remove Becker-template 'io_size' member, when invariant
      [netdrvr] via-velocity: use netdev_priv() where appropriate
      [netdrvr] minor cleanups in Becker-derived drivers
      [netdrvr] via-velocity: misc. cleanups
      [netdrvr] via-velocity: remove io_size struct member, it is invariant
      [netdrvr] Use dev_printk() when ethernet interface isn't available
      [netdrvr] use dev_xxx() printk helpers, rather than dev_printk(KERN_xxx, ...

John W. Linville:
      softmac: fix build-break from 881ee6999d66c8fc903b429b73bbe6045b38c549

Joseph Jezak:
      SoftMAC: Prevent multiple authentication attempts on the same network
      SoftMAC: Add network to ieee80211softmac_call_events when associate times out

Kim Phillips:
      Add support for the Cicada 8201 PHY

Larry Finger:
      Convert bcm43xx-softmac to use the ieee80211_is_valid_channel routine
      2.6.17 missing a call to ieee80211softmac_capabilities from ieee80211softmac_assoc_req

Michael Buesch:
      bcm43xx: workaround init_board vs. IRQ race

Paul Fulghum:
      remove dead entry in net wan Kconfig

Ralf Baechle:
      Fix freeing of net device



^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-06-27  3:57 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2006-06-27  3:57 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, linux-kernel


Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

to receive the following updates:

 drivers/net/3c59x.c             |   79 +++++++++++++++----------------
 drivers/net/dl2k.h              |   12 +---
 drivers/net/dm9000.c            |   34 +++++++------
 drivers/net/eepro100.c          |    5 --
 drivers/net/epic100.c           |   20 +-------
 drivers/net/fealnx.c            |   10 ----
 drivers/net/hamradio/dmascc.c   |    2 
 drivers/net/natsemi.c           |  100 +++++++++++++++++++---------------------
 drivers/net/pcnet32.c           |    6 --
 drivers/net/phy/lxt.c           |    8 +--
 drivers/net/tulip/winbond-840.c |   26 ++--------
 drivers/net/wan/c101.c          |    2 
 drivers/net/wan/n2.c            |    2 
 drivers/net/wan/pci200syn.c     |    2 
 drivers/net/yellowfin.c         |   24 ++-------
 15 files changed, 133 insertions(+), 199 deletions(-)

Adrian Bunk:
      drivers/net/hamradio/dmascc.c: fix section mismatch

Ben Dooks:
      DM9000 - better checks for platform resources
      DM9000 - check for MAC left in by bootloader
      DM9000 - do no re-init spin lock
      DM9000 - minor code cleanups

Jeff Garzik:
      [netdrvr] natsemi: Separate out media initialization code
      [netdrvr] natsemi: minor cleanups
      [netdrvr] Remove long-unused bits from Becker template drivers

Krzysztof Halasa:
      WAN: update info page for a bunch of my drivers

Uwe Zeisberger:
      Fix phy id for LXT971A/LXT972A

diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index e277789..b467c38 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -375,8 +375,7 @@ limit of 4K.
    of the drivers, and will likely be provided by some future kernel.
 */
 enum pci_flags_bit {
-	PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
-	PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
+	PCI_USES_MASTER=4,
 };
 
 enum {	IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, IS_TORNADO=8,
@@ -446,95 +445,95 @@ static struct vortex_chip_info {
 	int io_size;
 } vortex_info_tbl[] __devinitdata = {
 	{"3c590 Vortex 10Mbps",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
+	 PCI_USES_MASTER, IS_VORTEX, 32, },
 	{"3c592 EISA 10Mbps Demon/Vortex",					/* AKPM: from Don's 3c59x_cb.c 0.49H */
-	 PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
+	 PCI_USES_MASTER, IS_VORTEX, 32, },
 	{"3c597 EISA Fast Demon/Vortex",					/* AKPM: from Don's 3c59x_cb.c 0.49H */
-	 PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
+	 PCI_USES_MASTER, IS_VORTEX, 32, },
 	{"3c595 Vortex 100baseTx",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
+	 PCI_USES_MASTER, IS_VORTEX, 32, },
 	{"3c595 Vortex 100baseT4",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
+	 PCI_USES_MASTER, IS_VORTEX, 32, },
 
 	{"3c595 Vortex 100base-MII",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_VORTEX, 32, },
+	 PCI_USES_MASTER, IS_VORTEX, 32, },
 	{"3c900 Boomerang 10baseT",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, },
+	 PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, },
 	{"3c900 Boomerang 10Mbps Combo",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, },
+	 PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, },
 	{"3c900 Cyclone 10Mbps TPO",						/* AKPM: from Don's 0.99M */
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c900 Cyclone 10Mbps Combo",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 
 	{"3c900 Cyclone 10Mbps TPC",						/* AKPM: from Don's 0.99M */
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c900B-FL Cyclone 10base-FL",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c905 Boomerang 100baseTx",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
+	 PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
 	{"3c905 Boomerang 100baseT4",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
+	 PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
 	{"3c905B Cyclone 100baseTx",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 
 	{"3c905B Cyclone 10/100/BNC",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3c905B-FX Cyclone 100baseFx",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 	{"3c905C Tornado",
-	PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
+	PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 	{"3c920B-EMB-WNM (ATI Radeon 9100 IGP)",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_TORNADO|HAS_MII|HAS_HWCKSM, 128, },
 	{"3c980 Cyclone",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
 
 	{"3c980C Python-T",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3cSOHO100-TX Hurricane",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3c555 Laptop Hurricane",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, },
 	{"3c556 Laptop Tornado",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_8BIT|HAS_CB_FNS|INVERT_MII_PWR|
+	 PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_8BIT|HAS_CB_FNS|INVERT_MII_PWR|
 									HAS_HWCKSM, 128, },
 	{"3c556B Laptop Hurricane",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR|
+	 PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_OFFSET|HAS_CB_FNS|INVERT_MII_PWR|
 	                                WNO_XCVR_PWR|HAS_HWCKSM, 128, },
 
 	{"3c575 [Megahertz] 10/100 LAN 	CardBus",
-	PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
+	PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
 	{"3c575 Boomerang CardBus",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
+	 PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
 	{"3CCFE575BT Cyclone CardBus",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|
 									INVERT_LED_PWR|HAS_HWCKSM, 128, },
 	{"3CCFE575CT Tornado CardBus",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
+	 PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
 									MAX_COLLISION_RESET|HAS_HWCKSM, 128, },
 	{"3CCFE656 Cyclone CardBus",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
 									INVERT_LED_PWR|HAS_HWCKSM, 128, },
 
 	{"3CCFEM656B Cyclone+Winmodem CardBus",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
 									INVERT_LED_PWR|HAS_HWCKSM, 128, },
 	{"3CXFEM656C Tornado+Winmodem CardBus",			/* From pcmcia-cs-3.1.5 */
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
+	 PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|INVERT_MII_PWR|
 									MAX_COLLISION_RESET|HAS_HWCKSM, 128, },
 	{"3c450 HomePNA Tornado",						/* AKPM: from Don's 0.99Q */
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3c920 Tornado",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
 	{"3c982 Hydra Dual Port A",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
+	 PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
 
 	{"3c982 Hydra Dual Port B",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
+	 PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
 	{"3c905B-T4",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
+	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
 	{"3c920B-EMB-WNM Tornado",
-	 PCI_USES_IO|PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
+	 PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
 
 	{NULL,}, /* NULL terminated list. */
 };
diff --git a/drivers/net/dl2k.h b/drivers/net/dl2k.h
index 6e75482..5344920 100644
--- a/drivers/net/dl2k.h
+++ b/drivers/net/dl2k.h
@@ -683,11 +683,6 @@ struct netdev_private {
 };
 
 /* The station address location in the EEPROM. */
-#ifdef MEM_MAPPING
-#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
-#else
-#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO  | PCI_ADDR0)
-#endif
 /* The struct pci_device_id consist of:
         vendor, device          Vendor and device ID to match (or PCI_ANY_ID)
         subvendor, subdevice    Subsystem vendor and device ID to match (or PCI_ANY_ID)
@@ -695,9 +690,10 @@ #endif
         class_mask              of the class are honored during the comparison.
         driver_data             Data private to the driver.
 */
-static struct pci_device_id rio_pci_tbl[] = {
-	{0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
-	{0,}
+
+static const struct pci_device_id rio_pci_tbl[] = {
+	{0x1186, 0x4000, PCI_ANY_ID, PCI_ANY_ID, },
+	{ }
 };
 MODULE_DEVICE_TABLE (pci, rio_pci_tbl);
 #define TX_TIMEOUT  (4*HZ)
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
index 24996da..7965a9b 100644
--- a/drivers/net/dm9000.c
+++ b/drivers/net/dm9000.c
@@ -410,10 +410,7 @@ dm9000_probe(struct platform_device *pde
 	if (pdev->num_resources < 2) {
 		ret = -ENODEV;
 		goto out;
-	}
-
-	switch (pdev->num_resources) {
-	case 2:
+	} else if (pdev->num_resources == 2) {
 		base = pdev->resource[0].start;
 
 		if (!request_mem_region(base, 4, ndev->name)) {
@@ -423,17 +420,16 @@ dm9000_probe(struct platform_device *pde
 
 		ndev->base_addr = base;
 		ndev->irq = pdev->resource[1].start;
-		db->io_addr = (void *)base;
-		db->io_data = (void *)(base + 4);
-
-		break;
+		db->io_addr = (void __iomem *)base;
+		db->io_data = (void __iomem *)(base + 4);
 
-	case 3:
+	} else {
 		db->addr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 		db->data_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 		db->irq_res  = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
 
-		if (db->addr_res == NULL || db->data_res == NULL) {
+		if (db->addr_res == NULL || db->data_res == NULL ||
+		    db->irq_res == NULL) {
 			printk(KERN_ERR PFX "insufficient resources\n");
 			ret = -ENOENT;
 			goto out;
@@ -482,7 +478,6 @@ dm9000_probe(struct platform_device *pde
 
 		/* ensure at least we have a default set of IO routines */
 		dm9000_set_io(db, iosize);
-
 	}
 
 	/* check to see if anything is being over-ridden */
@@ -564,6 +559,13 @@ #endif
 	for (i = 0; i < 6; i++)
 		ndev->dev_addr[i] = db->srom[i];
 
+	if (!is_valid_ether_addr(ndev->dev_addr)) {
+		/* try reading from mac */
+
+		for (i = 0; i < 6; i++)
+			ndev->dev_addr[i] = ior(db, i+DM9000_PAR);
+	}
+
 	if (!is_valid_ether_addr(ndev->dev_addr))
 		printk("%s: Invalid ethernet MAC address.  Please "
 		       "set using ifconfig\n", ndev->name);
@@ -663,7 +665,6 @@ dm9000_init_dm9000(struct net_device *de
 	db->tx_pkt_cnt = 0;
 	db->queue_pkt_len = 0;
 	dev->trans_start = 0;
-	spin_lock_init(&db->lock);
 }
 
 /*
@@ -767,7 +768,7 @@ dm9000_stop(struct net_device *ndev)
  * receive the packet to upper layer, free the transmitted packet
  */
 
-void
+static void
 dm9000_tx_done(struct net_device *dev, board_info_t * db)
 {
 	int tx_status = ior(db, DM9000_NSR);	/* Got TX status */
@@ -1187,13 +1188,14 @@ dm9000_drv_remove(struct platform_device
 }
 
 static struct platform_driver dm9000_driver = {
+	.driver	= {
+		.name    = "dm9000",
+		.owner	 = THIS_MODULE,
+	},
 	.probe   = dm9000_probe,
 	.remove  = dm9000_drv_remove,
 	.suspend = dm9000_drv_suspend,
 	.resume  = dm9000_drv_resume,
-	.driver	= {
-		.name	= "dm9000",
-	},
 };
 
 static int __init
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 467fc86..ecf5ad8 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -278,11 +278,6 @@ having to sign an Intel NDA when I'm hel
 
 static int speedo_found1(struct pci_dev *pdev, void __iomem *ioaddr, int fnd_cnt, int acpi_idle_state);
 
-enum pci_flags_bit {
-	PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
-	PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
-};
-
 /* Offsets to the various registers.
    All accesses need not be longword aligned. */
 enum speedo_offsets {
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 724d7dc..ee34a16 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -191,23 +191,10 @@ IVc. Errata
 */
 
 
-enum pci_id_flags_bits {
-        /* Set PCI command register bits before calling probe1(). */
-        PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
-        /* Read and map the single following PCI BAR. */
-        PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
-        PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
-};
-
 enum chip_capability_flags { MII_PWRDWN=1, TYPE2_INTR=2, NO_MII=4 };
 
 #define EPIC_TOTAL_SIZE 0x100
 #define USE_IO_OPS 1
-#ifdef USE_IO_OPS
-#define EPIC_IOTYPE PCI_USES_MASTER|PCI_USES_IO|PCI_ADDR0
-#else
-#define EPIC_IOTYPE PCI_USES_MASTER|PCI_USES_MEM|PCI_ADDR1
-#endif
 
 typedef enum {
 	SMSC_83C170_0,
@@ -218,7 +205,6 @@ typedef enum {
 
 struct epic_chip_info {
 	const char *name;
-	enum pci_id_flags_bits pci_flags;
         int io_size;                            /* Needed for I/O region check or ioremap(). */
         int drv_flags;                          /* Driver use, intended as capability flags. */
 };
@@ -227,11 +213,11 @@ struct epic_chip_info {
 /* indexed by chip_t */
 static const struct epic_chip_info pci_id_tbl[] = {
 	{ "SMSC EPIC/100 83c170",
-	 EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR | NO_MII | MII_PWRDWN },
+	  EPIC_TOTAL_SIZE, TYPE2_INTR | NO_MII | MII_PWRDWN },
 	{ "SMSC EPIC/100 83c170",
-	 EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR },
+	  EPIC_TOTAL_SIZE, TYPE2_INTR },
 	{ "SMSC EPIC/C 83c175",
-	 EPIC_IOTYPE, EPIC_TOTAL_SIZE, TYPE2_INTR | MII_PWRDWN },
+	  EPIC_TOTAL_SIZE, TYPE2_INTR | MII_PWRDWN },
 };
 
 
diff --git a/drivers/net/fealnx.c b/drivers/net/fealnx.c
index a844926..13eca7e 100644
--- a/drivers/net/fealnx.c
+++ b/drivers/net/fealnx.c
@@ -126,16 +126,6 @@ MODULE_PARM_DESC(full_duplex, "fealnx fu
 
 #define MIN_REGION_SIZE 136
 
-enum pci_flags_bit {
-	PCI_USES_IO = 1,
-	PCI_USES_MEM = 2,
-	PCI_USES_MASTER = 4,
-	PCI_ADDR0 = 0x10 << 0,
-	PCI_ADDR1 = 0x10 << 1,
-	PCI_ADDR2 = 0x10 << 2,
-	PCI_ADDR3 = 0x10 << 3,
-};
-
 /* A chip capabilities table, matching the entries in pci_tbl[] above. */
 enum chip_capability_flags {
 	HAS_MII_XCVR,
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 0d5fccc..c9a46b8 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -436,7 +436,7 @@ static int __init dmascc_init(void)
 module_init(dmascc_init);
 module_exit(dmascc_exit);
 
-static void dev_setup(struct net_device *dev)
+static void __init dev_setup(struct net_device *dev)
 {
 	dev->type = ARPHRD_AX25;
 	dev->hard_header_len = AX25_MAX_HEADER_LEN;
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 2e4eced..5657049 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -226,7 +226,6 @@ #define NATSEMI_NREGS		(NATSEMI_PG0_NREG
 				 NATSEMI_PG1_NREGS)
 #define NATSEMI_REGS_VER	1 /* v1 added RFDR registers */
 #define NATSEMI_REGS_SIZE	(NATSEMI_NREGS * sizeof(u32))
-#define NATSEMI_DEF_EEPROM_SIZE	24 /* 12 16-bit values */
 
 /* Buffer sizes:
  * The nic writes 32-bit values, even if the upper bytes of
@@ -344,18 +343,6 @@ None characterised.
 
 
 
-enum pcistuff {
-	PCI_USES_IO = 0x01,
-	PCI_USES_MEM = 0x02,
-	PCI_USES_MASTER = 0x04,
-	PCI_ADDR0 = 0x08,
-	PCI_ADDR1 = 0x10,
-};
-
-/* MMIO operations required */
-#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
-
-
 /*
  * Support for fibre connections on Am79C874:
  * This phy needs a special setup when connected to a fibre cable.
@@ -363,22 +350,25 @@ #define PCI_IOTYPE (PCI_USES_MASTER | PC
  */
 #define PHYID_AM79C874	0x0022561b
 
-#define MII_MCTRL	0x15	/* mode control register */
-#define MII_FX_SEL	0x0001	/* 100BASE-FX (fiber) */
-#define MII_EN_SCRM	0x0004	/* enable scrambler (tp) */
+enum {
+	MII_MCTRL	= 0x15,		/* mode control register */
+	MII_FX_SEL	= 0x0001,	/* 100BASE-FX (fiber) */
+	MII_EN_SCRM	= 0x0004,	/* enable scrambler (tp) */
+};
 
  
 /* array of board data directly indexed by pci_tbl[x].driver_data */
 static const struct {
 	const char *name;
 	unsigned long flags;
+	unsigned int eeprom_size;
 } natsemi_pci_info[] __devinitdata = {
-	{ "NatSemi DP8381[56]", PCI_IOTYPE },
+	{ "NatSemi DP8381[56]", 0, 24 },
 };
 
-static struct pci_device_id natsemi_pci_tbl[] = {
-	{ PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_83815, PCI_ANY_ID, PCI_ANY_ID, },
-	{ 0, },
+static const struct pci_device_id natsemi_pci_tbl[] __devinitdata = {
+	{ PCI_VENDOR_ID_NS, 0x0020, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
+	{ }	/* terminate list */
 };
 MODULE_DEVICE_TABLE(pci, natsemi_pci_tbl);
 
@@ -813,6 +803,42 @@ static void move_int_phy(struct net_devi
 	udelay(1);
 }
 
+static void __devinit natsemi_init_media (struct net_device *dev)
+{
+	struct netdev_private *np = netdev_priv(dev);
+	u32 tmp;
+
+	netif_carrier_off(dev);
+
+	/* get the initial settings from hardware */
+	tmp            = mdio_read(dev, MII_BMCR);
+	np->speed      = (tmp & BMCR_SPEED100)? SPEED_100     : SPEED_10;
+	np->duplex     = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL   : DUPLEX_HALF;
+	np->autoneg    = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE;
+	np->advertising= mdio_read(dev, MII_ADVERTISE);
+
+	if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL
+	 && netif_msg_probe(np)) {
+		printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s "
+			"10%s %s duplex.\n",
+			pci_name(np->pci_dev),
+			(mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)?
+			  "enabled, advertise" : "disabled, force",
+			(np->advertising &
+			  (ADVERTISE_100FULL|ADVERTISE_100HALF))?
+			    "0" : "",
+			(np->advertising &
+			  (ADVERTISE_100FULL|ADVERTISE_10FULL))?
+			    "full" : "half");
+	}
+	if (netif_msg_probe(np))
+		printk(KERN_INFO
+			"natsemi %s: Transceiver status %#04x advertising %#04x.\n",
+			pci_name(np->pci_dev), mdio_read(dev, MII_BMSR),
+			np->advertising);
+
+}
+
 static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 	const struct pci_device_id *ent)
 {
@@ -852,8 +878,7 @@ #endif
 	iosize = pci_resource_len(pdev, pcibar);
 	irq = pdev->irq;
 
-	if (natsemi_pci_info[chip_idx].flags & PCI_USES_MASTER)
-		pci_set_master(pdev);
+	pci_set_master(pdev);
 
 	dev = alloc_etherdev(sizeof (struct netdev_private));
 	if (!dev)
@@ -892,7 +917,7 @@ #endif
 	np->msg_enable = (debug >= 0) ? (1<<debug)-1 : NATSEMI_DEF_MSG;
 	np->hands_off = 0;
 	np->intr_status = 0;
-	np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE;
+	np->eeprom_size = natsemi_pci_info[chip_idx].eeprom_size;
 
 	/* Initial port:
 	 * - If the nic was configured to use an external phy and if find_mii
@@ -957,34 +982,7 @@ #endif
 	if (mtu)
 		dev->mtu = mtu;
 
-	netif_carrier_off(dev);
-
-	/* get the initial settings from hardware */
-	tmp            = mdio_read(dev, MII_BMCR);
-	np->speed      = (tmp & BMCR_SPEED100)? SPEED_100     : SPEED_10;
-	np->duplex     = (tmp & BMCR_FULLDPLX)? DUPLEX_FULL   : DUPLEX_HALF;
-	np->autoneg    = (tmp & BMCR_ANENABLE)? AUTONEG_ENABLE: AUTONEG_DISABLE;
-	np->advertising= mdio_read(dev, MII_ADVERTISE);
-
-	if ((np->advertising & ADVERTISE_ALL) != ADVERTISE_ALL
-	 && netif_msg_probe(np)) {
-		printk(KERN_INFO "natsemi %s: Transceiver default autonegotiation %s "
-			"10%s %s duplex.\n",
-			pci_name(np->pci_dev),
-			(mdio_read(dev, MII_BMCR) & BMCR_ANENABLE)?
-			  "enabled, advertise" : "disabled, force",
-			(np->advertising &
-			  (ADVERTISE_100FULL|ADVERTISE_100HALF))?
-			    "0" : "",
-			(np->advertising &
-			  (ADVERTISE_100FULL|ADVERTISE_10FULL))?
-			    "full" : "half");
-	}
-	if (netif_msg_probe(np))
-		printk(KERN_INFO
-			"natsemi %s: Transceiver status %#04x advertising %#04x.\n",
-			pci_name(np->pci_dev), mdio_read(dev, MII_BMSR),
-			np->advertising);
+	natsemi_init_media(dev);
 
 	/* save the silicon revision for later querying */
 	np->srr = readl(ioaddr + SiliconRev);
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index fc08c4a..0e01c75 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -309,12 +309,6 @@ static int pcnet32_alloc_ring(struct net
 static void pcnet32_free_ring(struct net_device *dev);
 static void pcnet32_check_media(struct net_device *dev, int verbose);
 
-enum pci_flags_bit {
-	PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4,
-	PCI_ADDR0 = 0x10 << 0, PCI_ADDR1 = 0x10 << 1, PCI_ADDR2 =
-	    0x10 << 2, PCI_ADDR3 = 0x10 << 3,
-};
-
 static u16 pcnet32_wio_read_csr(unsigned long addr, int index)
 {
 	outw(index, addr + PCNET32_WIO_RAP);
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c
index bef79e4..3f702c5 100644
--- a/drivers/net/phy/lxt.c
+++ b/drivers/net/phy/lxt.c
@@ -123,9 +123,9 @@ static int lxt971_config_intr(struct phy
 }
 
 static struct phy_driver lxt970_driver = {
-	.phy_id		= 0x07810000,
+	.phy_id		= 0x78100000,
 	.name		= "LXT970",
-	.phy_id_mask	= 0x0fffffff,
+	.phy_id_mask	= 0xfffffff0,
 	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.config_init	= lxt970_config_init,
@@ -137,9 +137,9 @@ static struct phy_driver lxt970_driver =
 };
 
 static struct phy_driver lxt971_driver = {
-	.phy_id		= 0x0001378e,
+	.phy_id		= 0x001378e0,
 	.name		= "LXT971",
-	.phy_id_mask	= 0x0fffffff,
+	.phy_id_mask	= 0xfffffff0,
 	.features	= PHY_BASIC_FEATURES,
 	.flags		= PHY_HAS_INTERRUPT,
 	.config_aneg	= genphy_config_aneg,
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index 8fea2aa..602a6e5 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -212,26 +212,15 @@ Test with 'ping -s 10000' on a fast comp
 /*
   PCI probe table.
 */
-enum pci_id_flags_bits {
-        /* Set PCI command register bits before calling probe1(). */
-        PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
-        /* Read and map the single following PCI BAR. */
-        PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
-        PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
-};
 enum chip_capability_flags {
-	CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8,};
-#ifdef USE_IO_OPS
-#define W840_FLAGS (PCI_USES_IO | PCI_ADDR0 | PCI_USES_MASTER)
-#else
-#define W840_FLAGS (PCI_USES_MEM | PCI_ADDR1 | PCI_USES_MASTER)
-#endif
+	CanHaveMII=1, HasBrokenTx=2, AlwaysFDX=4, FDXOnNoMII=8,
+};
 
-static struct pci_device_id w840_pci_tbl[] = {
+static const struct pci_device_id w840_pci_tbl[] = {
 	{ 0x1050, 0x0840, PCI_ANY_ID, 0x8153,     0, 0, 0 },
 	{ 0x1050, 0x0840, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
 	{ 0x11f6, 0x2011, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 },
-	{ 0, }
+	{ }
 };
 MODULE_DEVICE_TABLE(pci, w840_pci_tbl);
 
@@ -241,18 +230,17 @@ struct pci_id_info {
                 int     pci, pci_mask, subsystem, subsystem_mask;
                 int revision, revision_mask;                            /* Only 8 bits. */
         } id;
-        enum pci_id_flags_bits pci_flags;
         int io_size;                            /* Needed for I/O region check or ioremap(). */
         int drv_flags;                          /* Driver use, intended as capability flags. */
 };
 static struct pci_id_info pci_id_tbl[] = {
 	{"Winbond W89c840",			/* Sometime a Level-One switch card. */
 	 { 0x08401050, 0xffffffff, 0x81530000, 0xffff0000 },
-	 W840_FLAGS, 128, CanHaveMII | HasBrokenTx | FDXOnNoMII},
+	   128, CanHaveMII | HasBrokenTx | FDXOnNoMII},
 	{"Winbond W89c840", { 0x08401050, 0xffffffff, },
-	 W840_FLAGS, 128, CanHaveMII | HasBrokenTx},
+	   128, CanHaveMII | HasBrokenTx},
 	{"Compex RL100-ATX", { 0x201111F6, 0xffffffff,},
-	 W840_FLAGS, 128, CanHaveMII | HasBrokenTx},
+	   128, CanHaveMII | HasBrokenTx},
 	{NULL,},					/* 0 terminated list. */
 };
 
diff --git a/drivers/net/wan/c101.c b/drivers/net/wan/c101.c
index b60ef02..c92ac9f 100644
--- a/drivers/net/wan/c101.c
+++ b/drivers/net/wan/c101.c
@@ -7,7 +7,7 @@
  * under the terms of version 2 of the GNU General Public License
  * as published by the Free Software Foundation.
  *
- * For information see http://hq.pm.waw.pl/hdlc/
+ * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/>
  *
  * Sources of information:
  *    Hitachi HD64570 SCA User's Manual
diff --git a/drivers/net/wan/n2.c b/drivers/net/wan/n2.c
index b7d88db..e013b81 100644
--- a/drivers/net/wan/n2.c
+++ b/drivers/net/wan/n2.c
@@ -7,7 +7,7 @@
  * under the terms of version 2 of the GNU General Public License
  * as published by the Free Software Foundation.
  *
- * For information see http://hq.pm.waw.pl/hdlc/
+ * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/>
  *
  * Note: integrated CSU/DSU/DDS are not supported by this driver
  *
diff --git a/drivers/net/wan/pci200syn.c b/drivers/net/wan/pci200syn.c
index 670e8bd..24c3c57 100644
--- a/drivers/net/wan/pci200syn.c
+++ b/drivers/net/wan/pci200syn.c
@@ -7,7 +7,7 @@
  * under the terms of version 2 of the GNU General Public License
  * as published by the Free Software Foundation.
  *
- * For information see http://hq.pm.waw.pl/hdlc/
+ * For information see <http://www.kernel.org/pub/linux/utils/net/hdlc/>
  *
  * Sources of information:
  *    Hitachi HD64572 SCA-II User's Manual
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index ecec8e5..569305f 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -234,14 +234,6 @@ See Packet Engines confidential appendix
 
 \f
 
-enum pci_id_flags_bits {
-	/* Set PCI command register bits before calling probe1(). */
-	PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
-	/* Read and map the single following PCI BAR. */
-	PCI_ADDR0=0<<4, PCI_ADDR1=1<<4, PCI_ADDR2=2<<4, PCI_ADDR3=3<<4,
-	PCI_ADDR_64BITS=0x100, PCI_NO_ACPI_WAKE=0x200, PCI_NO_MIN_LATENCY=0x400,
-	PCI_UNUSED_IRQ=0x800,
-};
 enum capability_flags {
 	HasMII=1, FullTxStatus=2, IsGigabit=4, HasMulticastBug=8, FullRxStatus=16,
 	HasMACAddrBug=32, /* Only on early revs.  */
@@ -249,11 +241,6 @@ enum capability_flags {
 };
 /* The PCI I/O space extent. */
 #define YELLOWFIN_SIZE 0x100
-#ifdef USE_IO_OPS
-#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO  | PCI_ADDR0)
-#else
-#define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_MEM | PCI_ADDR1)
-#endif
 
 struct pci_id_info {
         const char *name;
@@ -261,24 +248,23 @@ struct pci_id_info {
                 int     pci, pci_mask, subsystem, subsystem_mask;
                 int revision, revision_mask;                            /* Only 8 bits. */
         } id;
-        enum pci_id_flags_bits pci_flags;
         int io_size;                            /* Needed for I/O region check or ioremap(). */
         int drv_flags;                          /* Driver use, intended as capability flags. */
 };
 
 static const struct pci_id_info pci_id_tbl[] = {
 	{"Yellowfin G-NIC Gigabit Ethernet", { 0x07021000, 0xffffffff},
-	 PCI_IOTYPE, YELLOWFIN_SIZE,
+	 YELLOWFIN_SIZE,
 	 FullTxStatus | IsGigabit | HasMulticastBug | HasMACAddrBug | DontUseEeprom},
 	{"Symbios SYM83C885", { 0x07011000, 0xffffffff},
-	 PCI_IOTYPE, YELLOWFIN_SIZE, HasMII | DontUseEeprom },
-	{NULL,},
+	 YELLOWFIN_SIZE, HasMII | DontUseEeprom },
+	{ }
 };
 
-static struct pci_device_id yellowfin_pci_tbl[] = {
+static const struct pci_device_id yellowfin_pci_tbl[] = {
 	{ 0x1000, 0x0702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
 	{ 0x1000, 0x0701, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 },
-	{ 0, }
+	{ }
 };
 MODULE_DEVICE_TABLE (pci, yellowfin_pci_tbl);
 

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2006-05-21 14:56             ` Manfred Spraul
@ 2006-05-22 12:46               ` Andi Kleen
  0 siblings, 0 replies; 101+ messages in thread
From: Andi Kleen @ 2006-05-22 12:46 UTC (permalink / raw)
  To: Manfred Spraul
  Cc: Andrew Morton, Linus Torvalds, jeff, netdev, linux-kernel, Ayaz Abdulla


> I don't have any good ideas, please try to figure out what's wrong. Is 
> there a debug switch for the network layer that forces the network layer 
> to verify the CHECKSUM_UNNECESSARY blocks?
> 

Good news. The latest -git driver seems to fix the problem.

So maybe something got broken with the double request_irq.

-Andi

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2006-05-21 13:24           ` Andreas Kleen
@ 2006-05-21 14:56             ` Manfred Spraul
  2006-05-22 12:46               ` Andi Kleen
  0 siblings, 1 reply; 101+ messages in thread
From: Manfred Spraul @ 2006-05-21 14:56 UTC (permalink / raw)
  To: Andreas Kleen
  Cc: Andrew Morton, Linus Torvalds, jeff, netdev, linux-kernel, Ayaz Abdulla

Andreas Kleen wrote:

>>No idea, but unlikely. The fix removes a duplicate request_irq call.
>>Is
>>it possible that the both instances run concurrently?
>>    
>>
>
>The system has two Forcedeth ports, but only one has a cable connected.
>I don't think there is any parallelism. Just one connection with a lot
>of data. It didn't happen with 2.6.16.
>
>  
>
You misunderstood me:
Due to a broken patch, the driver did
    request_irq(irqnum, handler,...)
twice. Thus the irq handler was registered twice. The rx synchronization 
assumes that the irq handler doesn't run concurrently. I'm not sure what 
happens if the irq handler is registered twice: is it possible that it 
runs twice at the same time, i.e. is the synchronization in the irq 
subsystem irq number or registration call based?

>If you don't have any other good ideas I will try to track it down.
>
>  
>
I don't have any good ideas, please try to figure out what's wrong. Is 
there a debug switch for the network layer that forces the network layer 
to verify the CHECKSUM_UNNECESSARY blocks?

--
    Manfred

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2006-05-21  7:11         ` Manfred Spraul
@ 2006-05-21 13:24           ` Andreas Kleen
  2006-05-21 14:56             ` Manfred Spraul
  0 siblings, 1 reply; 101+ messages in thread
From: Andreas Kleen @ 2006-05-21 13:24 UTC (permalink / raw)
  To: Manfred Spraul
  Cc: Andrew Morton, Linus Torvalds, jeff, netdev, linux-kernel, Ayaz Abdulla


> No idea, but unlikely. The fix removes a duplicate request_irq call.
> Is
> it possible that the both instances run concurrently?

The system has two Forcedeth ports, but only one has a cable connected.
I don't think there is any parallelism. Just one connection with a lot
of data. It didn't happen with 2.6.16.

If you don't have any other good ideas I will try to track it down.

-Andi


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2006-05-20 22:15       ` Andi Kleen
@ 2006-05-21  7:11         ` Manfred Spraul
  2006-05-21 13:24           ` Andreas Kleen
  0 siblings, 1 reply; 101+ messages in thread
From: Manfred Spraul @ 2006-05-21  7:11 UTC (permalink / raw)
  To: Andi Kleen
  Cc: Andrew Morton, Linus Torvalds, jeff, netdev, linux-kernel, Ayaz Abdulla

Andi Kleen wrote:

>My NF4Pro machine now reliably does
>
>Disconnecting: Bad packet length 3742984839.
>
>when I display a lot of data through ssh.  Apparently it generates some 
>corruption that's not caught by the TCP checksum.
>
The nic does hw checksumming - thus the tcp checksum won't catch driver 
bugs.

> Would that be fixed by this
>change too? 
>
>  
>
No idea, but unlikely. The fix removes a duplicate request_irq call. Is 
it possible that the both instances run concurrently?

--
    Manfred

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2006-05-20 17:55     ` Andrew Morton
@ 2006-05-20 22:15       ` Andi Kleen
  2006-05-21  7:11         ` Manfred Spraul
  0 siblings, 1 reply; 101+ messages in thread
From: Andi Kleen @ 2006-05-20 22:15 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Linus Torvalds, jeff, netdev, linux-kernel, Manfred Spraul, Ayaz Abdulla

On Saturday 20 May 2006 19:55, Andrew Morton wrote:
> Linus Torvalds <torvalds@osdl.org> wrote:
> >
> > 
> > 
> > On Sat, 20 May 2006, Andrew Morton wrote:
> > > Jeff Garzik <jeff@garzik.org> wrote:
> > > >
> > > > Andrew Morton:
> > > >        revert "forcedeth: fix multi irq issues"
> > > 
> > > Manfred just found the fix for this, so we should no longer need to revert.
> > 
> > Hmm. I already pulled. I guess we can revert the revert and apply 
> > Manfreds fix. Jeff?
> > 
> 
> I can cook up the necessary pieces.

My NF4Pro machine now reliably does

Disconnecting: Bad packet length 3742984839.

when I display a lot of data through ssh.  Apparently it generates some 
corruption that's not caught by the TCP checksum. Would that be fixed by this
change too? 

-Andi


^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2006-05-20 17:36   ` Linus Torvalds
@ 2006-05-20 17:55     ` Andrew Morton
  2006-05-20 22:15       ` Andi Kleen
  0 siblings, 1 reply; 101+ messages in thread
From: Andrew Morton @ 2006-05-20 17:55 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: jeff, netdev, linux-kernel

Linus Torvalds <torvalds@osdl.org> wrote:
>
> 
> 
> On Sat, 20 May 2006, Andrew Morton wrote:
> > Jeff Garzik <jeff@garzik.org> wrote:
> > >
> > > Andrew Morton:
> > >        revert "forcedeth: fix multi irq issues"
> > 
> > Manfred just found the fix for this, so we should no longer need to revert.
> 
> Hmm. I already pulled. I guess we can revert the revert and apply 
> Manfreds fix. Jeff?
> 

I can cook up the necessary pieces.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2006-05-20 16:20 ` Andrew Morton
@ 2006-05-20 17:36   ` Linus Torvalds
  2006-05-20 17:55     ` Andrew Morton
  0 siblings, 1 reply; 101+ messages in thread
From: Linus Torvalds @ 2006-05-20 17:36 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Jeff Garzik, netdev, linux-kernel



On Sat, 20 May 2006, Andrew Morton wrote:
> Jeff Garzik <jeff@garzik.org> wrote:
> >
> > Andrew Morton:
> >        revert "forcedeth: fix multi irq issues"
> 
> Manfred just found the fix for this, so we should no longer need to revert.

Hmm. I already pulled. I guess we can revert the revert and apply 
Manfreds fix. Jeff?

		Linus

^ permalink raw reply	[flat|nested] 101+ messages in thread

* Re: [git patches] net driver updates
  2006-05-20  4:28 Jeff Garzik
@ 2006-05-20 16:20 ` Andrew Morton
  2006-05-20 17:36   ` Linus Torvalds
  0 siblings, 1 reply; 101+ messages in thread
From: Andrew Morton @ 2006-05-20 16:20 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: torvalds, netdev, linux-kernel

Jeff Garzik <jeff@garzik.org> wrote:
>
> Andrew Morton:
>        revert "forcedeth: fix multi irq issues"

Manfred just found the fix for this, so we should no longer need to revert.

^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-05-20  4:28 Jeff Garzik
  2006-05-20 16:20 ` Andrew Morton
  0 siblings, 1 reply; 101+ messages in thread
From: Jeff Garzik @ 2006-05-20  4:28 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, linux-kernel


Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

to receive the following updates:

 drivers/net/forcedeth.c                     |  312 +++++++---------------------
 drivers/net/pcmcia/axnet_cs.c               |   13 -
 drivers/net/skge.c                          |    8 
 drivers/net/sky2.c                          |   54 ++--
 drivers/net/sky2.h                          |    2 
 drivers/net/tulip/winbond-840.c             |    4 
 drivers/net/via-rhine.c                     |   34 ---
 drivers/net/wireless/bcm43xx/bcm43xx_main.c |    6 
 8 files changed, 131 insertions(+), 302 deletions(-)

Andrew Morton:
      revert "forcedeth: fix multi irq issues"

David Woodhouse:
      bcm43xx: associate on 'ifconfig up'

Erling A. Jacobsen:
      winbond-840-remove-badness-in-pci_map_single

John W. Linville:
      via-rhine: revert "change mdelay to msleep and remove from ISR path"

Komuro:
      network: axnet_cs: bug fix multicast code (support older ax88190 chipset)

Stephen Hemminger:
      sky2: allow dual port usage
      Subjec: sky2, skge: correct PCI id for DGE-560T
      sky2: more fixes for Yukon Ultra
      sky2: force NAPI repoll if busy
      sky2 version 1.4
      skge: bad checksums on big-endian platforms
      skge: don't allow transmit ring to be too small

diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index f7235c9..7e078b4 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -106,7 +106,6 @@
  *	0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings.
  *	0.52: 20 Jan 2006: Add MSI/MSIX support.
  *	0.53: 19 Mar 2006: Fix init from low power mode and add hw reset.
- *	0.54: 21 Mar 2006: Fix spin locks for multi irqs and cleanup.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -118,7 +117,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION		"0.54"
+#define FORCEDETH_VERSION		"0.53"
 #define DRV_NAME			"forcedeth"
 
 #include <linux/module.h>
@@ -711,72 +710,6 @@ static void setup_hw_rings(struct net_de
 	}
 }
 
-static int using_multi_irqs(struct net_device *dev)
-{
-	struct fe_priv *np = get_nvpriv(dev);
-
-	if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
-	    ((np->msi_flags & NV_MSI_X_ENABLED) &&
-	     ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1)))
-		return 0;
-	else
-		return 1;
-}
-
-static void nv_enable_irq(struct net_device *dev)
-{
-	struct fe_priv *np = get_nvpriv(dev);
-
-	if (!using_multi_irqs(dev)) {
-		if (np->msi_flags & NV_MSI_X_ENABLED)
-			enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
-		else
-			enable_irq(dev->irq);
-	} else {
-		enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
-		enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
-		enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
-	}
-}
-
-static void nv_disable_irq(struct net_device *dev)
-{
-	struct fe_priv *np = get_nvpriv(dev);
-
-	if (!using_multi_irqs(dev)) {
-		if (np->msi_flags & NV_MSI_X_ENABLED)
-			disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
-		else
-			disable_irq(dev->irq);
-	} else {
-		disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
-		disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
-		disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
-	}
-}
-
-/* In MSIX mode, a write to irqmask behaves as XOR */
-static void nv_enable_hw_interrupts(struct net_device *dev, u32 mask)
-{
-	u8 __iomem *base = get_hwbase(dev);
-
-	writel(mask, base + NvRegIrqMask);
-}
-
-static void nv_disable_hw_interrupts(struct net_device *dev, u32 mask)
-{
-	struct fe_priv *np = get_nvpriv(dev);
-	u8 __iomem *base = get_hwbase(dev);
-
-	if (np->msi_flags & NV_MSI_X_ENABLED) {
-		writel(mask, base + NvRegIrqMask);
-	} else {
-		if (np->msi_flags & NV_MSI_ENABLED)
-			writel(0, base + NvRegMSIIrqMask);
-		writel(0, base + NvRegIrqMask);
-	}
-}
-
 #define MII_READ	(-1)
 /* mii_rw: read/write a register on the PHY.
  *
@@ -1086,25 +1019,24 @@ static void nv_do_rx_refill(unsigned lon
 	struct net_device *dev = (struct net_device *) data;
 	struct fe_priv *np = netdev_priv(dev);
 
-	if (!using_multi_irqs(dev)) {
-		if (np->msi_flags & NV_MSI_X_ENABLED)
-			disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
-		else
-			disable_irq(dev->irq);
+
+	if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
+	    ((np->msi_flags & NV_MSI_X_ENABLED) &&
+	     ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) {
+		disable_irq(dev->irq);
 	} else {
 		disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
 	}
 	if (nv_alloc_rx(dev)) {
-		spin_lock_irq(&np->lock);
+		spin_lock(&np->lock);
 		if (!np->in_shutdown)
 			mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-		spin_unlock_irq(&np->lock);
+		spin_unlock(&np->lock);
 	}
-	if (!using_multi_irqs(dev)) {
-		if (np->msi_flags & NV_MSI_X_ENABLED)
-			enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
-		else
-			enable_irq(dev->irq);
+	if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
+	    ((np->msi_flags & NV_MSI_X_ENABLED) &&
+	     ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) {
+		enable_irq(dev->irq);
 	} else {
 		enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
 	}
@@ -1736,7 +1668,15 @@ static int nv_change_mtu(struct net_devi
 		 * guessed, there is probably a simpler approach.
 		 * Changing the MTU is a rare event, it shouldn't matter.
 		 */
-		nv_disable_irq(dev);
+		if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
+		    ((np->msi_flags & NV_MSI_X_ENABLED) &&
+		     ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) {
+			disable_irq(dev->irq);
+		} else {
+			disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
+			disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
+			disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
+		}
 		spin_lock_bh(&dev->xmit_lock);
 		spin_lock(&np->lock);
 		/* stop engines */
@@ -1769,7 +1709,15 @@ static int nv_change_mtu(struct net_devi
 		nv_start_tx(dev);
 		spin_unlock(&np->lock);
 		spin_unlock_bh(&dev->xmit_lock);
-		nv_enable_irq(dev);
+		if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
+		    ((np->msi_flags & NV_MSI_X_ENABLED) &&
+		     ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) {
+			enable_irq(dev->irq);
+		} else {
+			enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector);
+			enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector);
+			enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector);
+		}
 	}
 	return 0;
 }
@@ -2160,16 +2108,16 @@ static irqreturn_t nv_nic_irq_tx(int foo
 		if (!(events & np->irqmask))
 			break;
 
-		spin_lock_irq(&np->lock);
+		spin_lock(&np->lock);
 		nv_tx_done(dev);
-		spin_unlock_irq(&np->lock);
+		spin_unlock(&np->lock);
 		
 		if (events & (NVREG_IRQ_TX_ERR)) {
 			dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
 						dev->name, events);
 		}
 		if (i > max_interrupt_work) {
-			spin_lock_irq(&np->lock);
+			spin_lock(&np->lock);
 			/* disable interrupts on the nic */
 			writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask);
 			pci_push(base);
@@ -2179,7 +2127,7 @@ static irqreturn_t nv_nic_irq_tx(int foo
 				mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
 			}
 			printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
-			spin_unlock_irq(&np->lock);
+			spin_unlock(&np->lock);
 			break;
 		}
 
@@ -2209,14 +2157,14 @@ static irqreturn_t nv_nic_irq_rx(int foo
 		
 		nv_rx_process(dev);
 		if (nv_alloc_rx(dev)) {
-			spin_lock_irq(&np->lock);
+			spin_lock(&np->lock);
 			if (!np->in_shutdown)
 				mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
-			spin_unlock_irq(&np->lock);
+			spin_unlock(&np->lock);
 		}
 		
 		if (i > max_interrupt_work) {
-			spin_lock_irq(&np->lock);
+			spin_lock(&np->lock);
 			/* disable interrupts on the nic */
 			writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
 			pci_push(base);
@@ -2226,7 +2174,7 @@ static irqreturn_t nv_nic_irq_rx(int foo
 				mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
 			}
 			printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
-			spin_unlock_irq(&np->lock);
+			spin_unlock(&np->lock);
 			break;
 		}
 
@@ -2255,14 +2203,14 @@ static irqreturn_t nv_nic_irq_other(int 
 			break;
 		
 		if (events & NVREG_IRQ_LINK) {
-			spin_lock_irq(&np->lock);
+			spin_lock(&np->lock);
 			nv_link_irq(dev);
-			spin_unlock_irq(&np->lock);
+			spin_unlock(&np->lock);
 		}
 		if (np->need_linktimer && time_after(jiffies, np->link_timeout)) {
-			spin_lock_irq(&np->lock);
+			spin_lock(&np->lock);
 			nv_linkchange(dev);
-			spin_unlock_irq(&np->lock);
+			spin_unlock(&np->lock);
 			np->link_timeout = jiffies + LINK_TIMEOUT;
 		}
 		if (events & (NVREG_IRQ_UNKNOWN)) {
@@ -2270,7 +2218,7 @@ static irqreturn_t nv_nic_irq_other(int 
 						dev->name, events);
 		}
 		if (i > max_interrupt_work) {
-			spin_lock_irq(&np->lock);
+			spin_lock(&np->lock);
 			/* disable interrupts on the nic */
 			writel(NVREG_IRQ_OTHER, base + NvRegIrqMask);
 			pci_push(base);
@@ -2280,7 +2228,7 @@ static irqreturn_t nv_nic_irq_other(int 
 				mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
 			}
 			printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
-			spin_unlock_irq(&np->lock);
+			spin_unlock(&np->lock);
 			break;
 		}
 
@@ -2303,11 +2251,10 @@ static void nv_do_nic_poll(unsigned long
 	 * nv_nic_irq because that may decide to do otherwise
 	 */
 
-	if (!using_multi_irqs(dev)) {
-		if (np->msi_flags & NV_MSI_X_ENABLED)
-			disable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
-		else
-			disable_irq(dev->irq);
+	if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
+	    ((np->msi_flags & NV_MSI_X_ENABLED) &&
+	     ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) {
+		disable_irq(dev->irq);
 		mask = np->irqmask;
 	} else {
 		if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
@@ -2330,12 +2277,11 @@ static void nv_do_nic_poll(unsigned long
 	writel(mask, base + NvRegIrqMask);
 	pci_push(base);
 
-	if (!using_multi_irqs(dev)) {
+	if (!(np->msi_flags & NV_MSI_X_ENABLED) ||
+	    ((np->msi_flags & NV_MSI_X_ENABLED) &&
+	     ((np->msi_flags & NV_MSI_X_VECTORS_MASK) == 0x1))) {
 		nv_nic_irq((int) 0, (void *) data, (struct pt_regs *) NULL);
-		if (np->msi_flags & NV_MSI_X_ENABLED)
-			enable_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector);
-		else
-			enable_irq(dev->irq);
+		enable_irq(dev->irq);
 	} else {
 		if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
 			nv_nic_irq_rx((int) 0, (void *) data, (struct pt_regs *) NULL);
@@ -2682,113 +2628,6 @@ static void set_msix_vector_map(struct n
 	writel(readl(base + NvRegMSIXMap1) | msixmap, base + NvRegMSIXMap1);
 }
 
-static int nv_request_irq(struct net_device *dev)
-{
-	struct fe_priv *np = get_nvpriv(dev);
-	u8 __iomem *base = get_hwbase(dev);
-	int ret = 1;
-	int i;
-
-	if (np->msi_flags & NV_MSI_X_CAPABLE) {
-		for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) {
-			np->msi_x_entry[i].entry = i;
-		}
-		if ((ret = pci_enable_msix(np->pci_dev, np->msi_x_entry, (np->msi_flags & NV_MSI_X_VECTORS_MASK))) == 0) {
-			np->msi_flags |= NV_MSI_X_ENABLED;
-			if (optimization_mode == NV_OPTIMIZATION_MODE_THROUGHPUT) {
-				/* Request irq for rx handling */
-				if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, &nv_nic_irq_rx, SA_SHIRQ, dev->name, dev) != 0) {
-					printk(KERN_INFO "forcedeth: request_irq failed for rx %d\n", ret);
-					pci_disable_msix(np->pci_dev);
-					np->msi_flags &= ~NV_MSI_X_ENABLED;
-					goto out_err;
-				}
-				/* Request irq for tx handling */
-				if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, &nv_nic_irq_tx, SA_SHIRQ, dev->name, dev) != 0) {
-					printk(KERN_INFO "forcedeth: request_irq failed for tx %d\n", ret);
-					pci_disable_msix(np->pci_dev);
-					np->msi_flags &= ~NV_MSI_X_ENABLED;
-					goto out_free_rx;
-				}
-				/* Request irq for link and timer handling */
-				if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_OTHER].vector, &nv_nic_irq_other, SA_SHIRQ, dev->name, dev) != 0) {
-					printk(KERN_INFO "forcedeth: request_irq failed for link %d\n", ret);
-					pci_disable_msix(np->pci_dev);
-					np->msi_flags &= ~NV_MSI_X_ENABLED;
-					goto out_free_tx;
-				}
-				/* map interrupts to their respective vector */
-				writel(0, base + NvRegMSIXMap0);
-				writel(0, base + NvRegMSIXMap1);
-				set_msix_vector_map(dev, NV_MSI_X_VECTOR_RX, NVREG_IRQ_RX_ALL);
-				set_msix_vector_map(dev, NV_MSI_X_VECTOR_TX, NVREG_IRQ_TX_ALL);
-				set_msix_vector_map(dev, NV_MSI_X_VECTOR_OTHER, NVREG_IRQ_OTHER);
-			} else {
-				/* Request irq for all interrupts */
-				if (request_irq(np->msi_x_entry[NV_MSI_X_VECTOR_ALL].vector, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) {
-					printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
-					pci_disable_msix(np->pci_dev);
-					np->msi_flags &= ~NV_MSI_X_ENABLED;
-					goto out_err;
-				}
-
-				/* map interrupts to vector 0 */
-				writel(0, base + NvRegMSIXMap0);
-				writel(0, base + NvRegMSIXMap1);
-			}
-		}
-	}
-	if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
-		if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
-			np->msi_flags |= NV_MSI_ENABLED;
-			if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0) {
-				printk(KERN_INFO "forcedeth: request_irq failed %d\n", ret);
-				pci_disable_msi(np->pci_dev);
-				np->msi_flags &= ~NV_MSI_ENABLED;
-				goto out_err;
-			}
-
-			/* map interrupts to vector 0 */
-			writel(0, base + NvRegMSIMap0);
-			writel(0, base + NvRegMSIMap1);
-			/* enable msi vector 0 */
-			writel(NVREG_MSI_VECTOR_0_ENABLED, base + NvRegMSIIrqMask);
-		}
-	}
-	if (ret != 0) {
-		if (request_irq(np->pci_dev->irq, &nv_nic_irq, SA_SHIRQ, dev->name, dev) != 0)
-			goto out_err;
-	}
-
-	return 0;
-out_free_tx:
-	free_irq(np->msi_x_entry[NV_MSI_X_VECTOR_TX].vector, dev);
-out_free_rx:
-	free_irq(np->msi_x_entry[NV_MSI_X_VECTOR_RX].vector, dev);
-out_err:
-	return 1;
-}
-
-static void nv_free_irq(struct net_device *dev)
-{
-	struct fe_priv *np = get_nvpriv(dev);
-	int i;
-
-	if (np->msi_flags & NV_MSI_X_ENABLED) {
-		for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) {
-			free_irq(np->msi_x_entry[i].vector, dev);
-		}
-		pci_disable_msix(np->pci_dev);
-		np->msi_flags &= ~NV_MSI_X_ENABLED;
-	} else {
-		free_irq(np->pci_dev->irq, dev);
-		if (np->msi_flags & NV_MSI_ENABLED) {
-			pci_disable_msi(np->pci_dev);
-			np->msi_flags &= ~NV_MSI_ENABLED;
-		}
-	}
-}
-
 static int nv_open(struct net_device *dev)
 {
 	struct fe_priv *np = netdev_priv(dev);
@@ -2881,16 +2720,12 @@ static int nv_open(struct net_device *de
 	udelay(10);
 	writel(readl(base + NvRegPowerState) | NVREG_POWERSTATE_VALID, base + NvRegPowerState);
 
-	nv_disable_hw_interrupts(dev, np->irqmask);
+	writel(0, base + NvRegIrqMask);
 	pci_push(base);
 	writel(NVREG_MIISTAT_MASK2, base + NvRegMIIStatus);
 	writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
 	pci_push(base);
 
-	if (nv_request_irq(dev)) {
-		goto out_drain;
-	}
-
 	if (np->msi_flags & NV_MSI_X_CAPABLE) {
 		for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) {
 			np->msi_x_entry[i].entry = i;
@@ -2964,7 +2799,7 @@ static int nv_open(struct net_device *de
 	}
 
 	/* ask for interrupts */
-	nv_enable_hw_interrupts(dev, np->irqmask);
+	writel(np->irqmask, base + NvRegIrqMask);
 
 	spin_lock_irq(&np->lock);
 	writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
@@ -3008,6 +2843,7 @@ static int nv_close(struct net_device *d
 {
 	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base;
+	int i;
 
 	spin_lock_irq(&np->lock);
 	np->in_shutdown = 1;
@@ -3025,13 +2861,31 @@ static int nv_close(struct net_device *d
 
 	/* disable interrupts on the nic or we will lock up */
 	base = get_hwbase(dev);
-	nv_disable_hw_interrupts(dev, np->irqmask);
+	if (np->msi_flags & NV_MSI_X_ENABLED) {
+		writel(np->irqmask, base + NvRegIrqMask);
+	} else {
+		if (np->msi_flags & NV_MSI_ENABLED)
+			writel(0, base + NvRegMSIIrqMask);
+		writel(0, base + NvRegIrqMask);
+	}
 	pci_push(base);
 	dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name);
 
 	spin_unlock_irq(&np->lock);
 
-	nv_free_irq(dev);
+	if (np->msi_flags & NV_MSI_X_ENABLED) {
+		for (i = 0; i < (np->msi_flags & NV_MSI_X_VECTORS_MASK); i++) {
+			free_irq(np->msi_x_entry[i].vector, dev);
+		}
+		pci_disable_msix(np->pci_dev);
+		np->msi_flags &= ~NV_MSI_X_ENABLED;
+	} else {
+		free_irq(np->pci_dev->irq, dev);
+		if (np->msi_flags & NV_MSI_ENABLED) {
+			pci_disable_msi(np->pci_dev);
+			np->msi_flags &= ~NV_MSI_ENABLED;
+		}
+	}
 
 	drain_ring(dev);
 
@@ -3120,18 +2974,20 @@ static int __devinit nv_probe(struct pci
 	if (id->driver_data & DEV_HAS_HIGH_DMA) {
 		/* packet format 3: supports 40-bit addressing */
 		np->desc_ver = DESC_VER_3;
-		np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
 		if (pci_set_dma_mask(pci_dev, DMA_39BIT_MASK)) {
 			printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
 					pci_name(pci_dev));
 		} else {
-			dev->features |= NETIF_F_HIGHDMA;
-			printk(KERN_INFO "forcedeth: using HIGHDMA\n");
-		}
-		if (pci_set_consistent_dma_mask(pci_dev, 0x0000007fffffffffULL)) {
-			printk(KERN_INFO "forcedeth: 64-bit DMA (consistent) failed for device %s.\n",
-			       pci_name(pci_dev));
+			if (pci_set_consistent_dma_mask(pci_dev, 0x0000007fffffffffULL)) {
+				printk(KERN_INFO "forcedeth: 64-bit DMA (consistent) failed for device %s.\n",
+					pci_name(pci_dev));
+				goto out_relreg;
+			} else {
+				dev->features |= NETIF_F_HIGHDMA;
+				printk(KERN_INFO "forcedeth: using HIGHDMA\n");
+			}
 		}
+		np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
 	} else if (id->driver_data & DEV_HAS_LARGEDESC) {
 		/* packet format 2: supports jumbo frames */
 		np->desc_ver = DESC_VER_2;
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 448a094..2ea66ac 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -1691,17 +1691,6 @@ static void do_set_multicast_list(struct
 		memset(ei_local->mcfilter, 0xFF, 8);
 	}
 
-	/* 
-	 * DP8390 manuals don't specify any magic sequence for altering
-	 * the multicast regs on an already running card. To be safe, we
-	 * ensure multicast mode is off prior to loading up the new hash
-	 * table. If this proves to be not enough, we can always resort
-	 * to stopping the NIC, loading the table and then restarting.
-	 */
-	 
-	if (netif_running(dev))
-		outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR);
-
 	outb_p(E8390_NODMA + E8390_PAGE1, e8390_base + E8390_CMD);
 	for(i = 0; i < 8; i++) 
 	{
@@ -1715,6 +1704,8 @@ static void do_set_multicast_list(struct
   		outb_p(E8390_RXCONFIG | 0x48, e8390_base + EN0_RXCR);
   	else
   		outb_p(E8390_RXCONFIG | 0x40, e8390_base + EN0_RXCR);
+
+	outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base+E8390_CMD);
 }
 
 /*
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index a70c2b0..5ca5a1b 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -78,8 +78,7 @@ static const struct pci_device_id skge_i
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_GE) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, PCI_DEVICE_ID_SYSKONNECT_YU) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_DGE510T), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },
-	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b01) },	/* DGE-530T */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */
 	{ PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) },
@@ -402,7 +401,7 @@ static int skge_set_ring_param(struct ne
 	int err;
 
 	if (p->rx_pending == 0 || p->rx_pending > MAX_RX_RING_SIZE ||
-	    p->tx_pending == 0 || p->tx_pending > MAX_TX_RING_SIZE)
+	    p->tx_pending < MAX_SKB_FRAGS+1 || p->tx_pending > MAX_TX_RING_SIZE)
 		return -EINVAL;
 
 	skge->rx_ring.count = p->rx_pending;
@@ -2717,8 +2716,7 @@ static int skge_poll(struct net_device *
 		if (control & BMU_OWN)
 			break;
 
-		skb = skge_rx_get(skge, e, control, rd->status,
-				  le16_to_cpu(rd->csum2));
+		skb = skge_rx_get(skge, e, control, rd->status, rd->csum2);
 		if (likely(skb)) {
 			dev->last_rx = jiffies;
 			netif_receive_skb(skb);
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 62be6d9..60779eb 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -51,7 +51,7 @@ #endif
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"1.3"
+#define DRV_VERSION		"1.4"
 #define PFX			DRV_NAME " "
 
 /*
@@ -105,6 +105,7 @@ MODULE_PARM_DESC(idle_timeout, "Idle tim
 static const struct pci_device_id sky2_id_table[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) },	/* DGE-560T */
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
@@ -235,6 +236,7 @@ static int sky2_set_power_state(struct s
 		}
 
 		if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
+			sky2_write16(hw, B0_CTST, Y2_HW_WOL_ON);
 			sky2_pci_write32(hw, PCI_DEV_REG3, 0);
 			reg1 = sky2_pci_read32(hw, PCI_DEV_REG4);
 			reg1 &= P_ASPM_CONTROL_MSK;
@@ -306,7 +308,7 @@ static void sky2_phy_init(struct sky2_hw
 	u16 ctrl, ct1000, adv, pg, ledctrl, ledover;
 
 	if (sky2->autoneg == AUTONEG_ENABLE &&
-	    (hw->chip_id != CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
+	    !(hw->chip_id == CHIP_ID_YUKON_XL || hw->chip_id == CHIP_ID_YUKON_EC_U)) {
 		u16 ectrl = gm_phy_read(hw, port, PHY_MARV_EXT_CTRL);
 
 		ectrl &= ~(PHY_M_EC_M_DSC_MSK | PHY_M_EC_S_DSC_MSK |
@@ -1020,19 +1022,26 @@ static int sky2_up(struct net_device *de
 	struct sky2_hw *hw = sky2->hw;
 	unsigned port = sky2->port;
 	u32 ramsize, rxspace, imask;
-	int err;
+	int cap, err = -ENOMEM;
 	struct net_device *otherdev = hw->dev[sky2->port^1];
 
-	/* Block bringing up both ports at the same time on a dual port card.
-	 * There is an unfixed bug where receiver gets confused and picks up
-	 * packets out of order. Until this is fixed, prevent data corruption.
+	/*
+ 	 * On dual port PCI-X card, there is an problem where status
+	 * can be received out of order due to split transactions
 	 */
-	if (otherdev && netif_running(otherdev)) {
-		printk(KERN_INFO PFX "dual port support is disabled.\n");
-		return -EBUSY;
-	}
+	if (otherdev && netif_running(otherdev) &&
+ 	    (cap = pci_find_capability(hw->pdev, PCI_CAP_ID_PCIX))) {
+ 		struct sky2_port *osky2 = netdev_priv(otherdev);
+ 		u16 cmd;
+
+ 		cmd = sky2_pci_read16(hw, cap + PCI_X_CMD);
+ 		cmd &= ~PCI_X_CMD_MAX_SPLIT;
+ 		sky2_pci_write16(hw, cap + PCI_X_CMD, cmd);
+
+ 		sky2->rx_csum = 0;
+ 		osky2->rx_csum = 0;
+ 	}
 
-	err = -ENOMEM;
 	if (netif_msg_ifup(sky2))
 		printk(KERN_INFO PFX "%s: enabling interface\n", dev->name);
 
@@ -1910,6 +1919,12 @@ static inline void sky2_tx_done(struct n
 	}
 }
 
+/* Is status ring empty or is there more to do? */
+static inline int sky2_more_work(const struct sky2_hw *hw)
+{
+	return (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX));
+}
+
 /* Process status response ring */
 static int sky2_status_intr(struct sky2_hw *hw, int to_do)
 {
@@ -2182,19 +2197,19 @@ static int sky2_poll(struct net_device *
 	if (status & Y2_IS_CHK_TXA2)
 		sky2_descriptor_error(hw, 1, "transmit", Y2_IS_CHK_TXA2);
 
-	if (status & Y2_IS_STAT_BMU)
-		sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
-
 	work_done = sky2_status_intr(hw, work_limit);
 	*budget -= work_done;
 	dev0->quota -= work_done;
 
-	if (work_done >= work_limit)
+	if (status & Y2_IS_STAT_BMU)
+		sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ);
+
+	if (sky2_more_work(hw))
 		return 1;
 
 	netif_rx_complete(dev0);
 
-	status = sky2_read32(hw, B0_Y2_SP_LISR);
+	sky2_read32(hw, B0_Y2_SP_LISR);
 	return 0;
 }
 
@@ -3078,12 +3093,7 @@ #endif
 	sky2->duplex = -1;
 	sky2->speed = -1;
 	sky2->advertising = sky2_supported_modes(hw);
-
-	/* Receive checksum disabled for Yukon XL
-	 * because of observed problems with incorrect
-	 * values when multiple packets are received in one interrupt
-	 */
-	sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
+	sky2->rx_csum = 1;
 
 	spin_lock_init(&sky2->phy_lock);
 	sky2->tx_pending = TX_DEF_PENDING;
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index 8012994..8a0bc55 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -214,6 +214,8 @@ #define RAM_BUFFER(port, reg)	(reg | (po
 enum {
 	Y2_VMAIN_AVAIL	= 1<<17,/* VMAIN available (YUKON-2 only) */
 	Y2_VAUX_AVAIL	= 1<<16,/* VAUX available (YUKON-2 only) */
+	Y2_HW_WOL_ON	= 1<<15,/* HW WOL On  (Yukon-EC Ultra A1 only) */
+	Y2_HW_WOL_OFF	= 1<<14,/* HW WOL On  (Yukon-EC Ultra A1 only) */
 	Y2_ASF_ENABLE	= 1<<13,/* ASF Unit Enable (YUKON-2 only) */
 	Y2_ASF_DISABLE	= 1<<12,/* ASF Unit Disable (YUKON-2 only) */
 	Y2_CLK_RUN_ENA	= 1<<11,/* CLK_RUN Enable  (YUKON-2 only) */
diff --git a/drivers/net/tulip/winbond-840.c b/drivers/net/tulip/winbond-840.c
index ba05ded..136a70c 100644
--- a/drivers/net/tulip/winbond-840.c
+++ b/drivers/net/tulip/winbond-840.c
@@ -850,7 +850,7 @@ static void init_rxtx_rings(struct net_d
 			break;
 		skb->dev = dev;			/* Mark as being used by this device. */
 		np->rx_addr[i] = pci_map_single(np->pci_dev,skb->data,
-					skb->len,PCI_DMA_FROMDEVICE);
+					np->rx_buf_sz,PCI_DMA_FROMDEVICE);
 
 		np->rx_ring[i].buffer1 = np->rx_addr[i];
 		np->rx_ring[i].status = DescOwn;
@@ -1316,7 +1316,7 @@ #endif
 			skb->dev = dev;			/* Mark as being used by this device. */
 			np->rx_addr[entry] = pci_map_single(np->pci_dev,
 							skb->data,
-							skb->len, PCI_DMA_FROMDEVICE);
+							np->rx_buf_sz, PCI_DMA_FROMDEVICE);
 			np->rx_ring[entry].buffer1 = np->rx_addr[entry];
 		}
 		wmb();
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index a6dc53b..fdc2103 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -491,8 +491,6 @@ struct rhine_private {
 	u8 tx_thresh, rx_thresh;
 
 	struct mii_if_info mii_if;
-	struct work_struct tx_timeout_task;
-	struct work_struct check_media_task;
 	void __iomem *base;
 };
 
@@ -500,8 +498,6 @@ static int  mdio_read(struct net_device 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int  rhine_open(struct net_device *dev);
 static void rhine_tx_timeout(struct net_device *dev);
-static void rhine_tx_timeout_task(struct net_device *dev);
-static void rhine_check_media_task(struct net_device *dev);
 static int  rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
 static void rhine_tx(struct net_device *dev);
@@ -856,12 +852,6 @@ #endif
 	if (rp->quirks & rqRhineI)
 		dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
 
-	INIT_WORK(&rp->tx_timeout_task,
-		  (void (*)(void *))rhine_tx_timeout_task, dev);
-
-	INIT_WORK(&rp->check_media_task,
-		  (void (*)(void *))rhine_check_media_task, dev);
-
 	/* dev->name not defined before register_netdev()! */
 	rc = register_netdev(dev);
 	if (rc)
@@ -1108,11 +1098,6 @@ static void rhine_set_carrier(struct mii
 		       netif_carrier_ok(mii->dev));
 }
 
-static void rhine_check_media_task(struct net_device *dev)
-{
-	rhine_check_media(dev, 0);
-}
-
 static void init_registers(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
@@ -1166,8 +1151,8 @@ static void rhine_disable_linkmon(void _
 	if (quirks & rqRhineI) {
 		iowrite8(0x01, ioaddr + MIIRegAddr);	// MII_BMSR
 
-		/* Do not call from ISR! */
-		msleep(1);
+		/* Can be called from ISR. Evil. */
+		mdelay(1);
 
 		/* 0x80 must be set immediately before turning it off */
 		iowrite8(0x80, ioaddr + MIICmd);
@@ -1257,16 +1242,6 @@ static int rhine_open(struct net_device 
 static void rhine_tx_timeout(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
-
-	/*
-	 * Move bulk of work outside of interrupt context
-	 */
-	schedule_work(&rp->tx_timeout_task);
-}
-
-static void rhine_tx_timeout_task(struct net_device *dev)
-{
-	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
 
 	printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
@@ -1677,7 +1652,7 @@ static void rhine_error(struct net_devic
 	spin_lock(&rp->lock);
 
 	if (intr_status & IntrLinkChange)
-		schedule_work(&rp->check_media_task);
+		rhine_check_media(dev, 0);
 	if (intr_status & IntrStatsMax) {
 		rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
 		rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
@@ -1927,9 +1902,6 @@ static int rhine_close(struct net_device
 	spin_unlock_irq(&rp->lock);
 
 	free_irq(rp->pdev->irq, dev);
-
-	flush_scheduled_work();
-
 	free_rbufs(dev);
 	free_tbufs(dev);
 	free_ring(dev);
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
index e2982a8..7ed18ca 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c
@@ -3271,6 +3271,9 @@ static int bcm43xx_init_board(struct bcm
 	bcm43xx_sysfs_register(bcm);
 	//FIXME: check for bcm43xx_sysfs_register failure. This function is a bit messy regarding unwinding, though...
 
+	/*FIXME: This should be handled by softmac instead. */
+	schedule_work(&bcm->softmac->associnfo.work);
+
 	assert(err == 0);
 out:
 	return err;
@@ -3946,9 +3949,6 @@ static int bcm43xx_resume(struct pci_dev
 
 	netif_device_attach(net_dev);
 	
-	/*FIXME: This should be handled by softmac instead. */
-	schedule_work(&bcm->softmac->associnfo.work);
-
 	dprintk(KERN_INFO PFX "Device resumed.\n");
 
 	return 0;

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-03-29 23:00 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2006-03-29 23:00 UTC (permalink / raw)
  To: netdev, linux-kernel


[just sent upstream]

The 'upstream-linus' branch of
git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

contains the following updates:

 Documentation/networking/bcm43xx.txt            |   36 
 drivers/net/8390.h                              |    2 
 drivers/net/acenic_firmware.h                   |   10 
 drivers/net/b44.c                               |   14 
 drivers/net/bonding/bond_3ad.c                  |   28 
 drivers/net/bonding/bond_3ad.h                  |    1 
 drivers/net/bonding/bond_main.c                 |   97 
 drivers/net/bonding/bonding.h                   |    4 
 drivers/net/ixp2000/ixpdev.c                    |    5 
 drivers/net/natsemi.c                           |   18 
 drivers/net/pcmcia/axnet_cs.c                   |   61 
 drivers/net/pcnet32.c                           |    4 
 drivers/net/spider_net.c                        |    4 
 drivers/net/via-rhine.c                         |   21 
 drivers/net/wireless/Kconfig                    |    7 
 drivers/net/wireless/Makefile                   |    1 
 drivers/net/wireless/bcm43xx/Kconfig            |   62 
 drivers/net/wireless/bcm43xx/Makefile           |   12 
 drivers/net/wireless/bcm43xx/bcm43xx.h          |  926 +++++
 drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c  |  499 +++
 drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h  |  117 
 drivers/net/wireless/bcm43xx/bcm43xx_dma.c      |  968 +++++
 drivers/net/wireless/bcm43xx/bcm43xx_dma.h      |  218 +
 drivers/net/wireless/bcm43xx/bcm43xx_ethtool.c  |   50 
 drivers/net/wireless/bcm43xx/bcm43xx_ethtool.h  |    8 
 drivers/net/wireless/bcm43xx/bcm43xx_ilt.c      |  337 ++
 drivers/net/wireless/bcm43xx/bcm43xx_ilt.h      |   32 
 drivers/net/wireless/bcm43xx/bcm43xx_leds.c     |  293 +
 drivers/net/wireless/bcm43xx/bcm43xx_leds.h     |   56 
 drivers/net/wireless/bcm43xx/bcm43xx_main.c     | 3973 ++++++++++++++++++++++++
 drivers/net/wireless/bcm43xx/bcm43xx_main.h     |  168 +
 drivers/net/wireless/bcm43xx/bcm43xx_phy.c      | 2345 ++++++++++++++
 drivers/net/wireless/bcm43xx/bcm43xx_phy.h      |   74 
 drivers/net/wireless/bcm43xx/bcm43xx_pio.c      |  606 +++
 drivers/net/wireless/bcm43xx/bcm43xx_pio.h      |  138 
 drivers/net/wireless/bcm43xx/bcm43xx_power.c    |  358 ++
 drivers/net/wireless/bcm43xx/bcm43xx_power.h    |   47 
 drivers/net/wireless/bcm43xx/bcm43xx_radio.c    | 2026 ++++++++++++
 drivers/net/wireless/bcm43xx/bcm43xx_radio.h    |   99 
 drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c    |  322 +
 drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h    |   25 
 drivers/net/wireless/bcm43xx/bcm43xx_wx.c       | 1002 ++++++
 drivers/net/wireless/bcm43xx/bcm43xx_wx.h       |   36 
 drivers/net/wireless/bcm43xx/bcm43xx_xmit.c     |  582 +++
 drivers/net/wireless/bcm43xx/bcm43xx_xmit.h     |  156 
 drivers/net/wireless/hostap/hostap_80211.h      |    2 
 drivers/net/wireless/hostap/hostap_80211_tx.c   |    9 
 drivers/usb/net/zd1201.c                        |    2 
 net/ieee80211/ieee80211_wx.c                    |    4 
 net/ieee80211/softmac/ieee80211softmac_module.c |   17 
 net/ieee80211/softmac/ieee80211softmac_priv.h   |    2 
 net/ieee80211/softmac/ieee80211softmac_wx.c     |   12 
 52 files changed, 15820 insertions(+), 76 deletions(-)

Adrian Bunk:
      PCMCIA_SPECTRUM must select FW_LOADER

Arthur Othieno:
      net: remove CONFIG_NET_CBUS conditional for NS8390

Danny van Dyk:
      Sync bcm43xx_phy_initb6() with specs

David Woodhouse:
      softmac: reduce scan dwell time
      softmac: reduce default rate to 11Mbps.

Gary Zambrano:
      b44: fix force mac address before ifconfig up
      b44: ensure valid mac addr

Jay Vosburgh:
      bonding: support carrier state for master

Jean Tourrilhes:
      zd1201 wireless stat update

Jens Osterkamp:
      spidernet : reduce console spam
      spidernet : enable tx checksum offloading by default

John W. Linville:
      wireless: import bcm43xx sources
      bcm43xx: patch Kconfig and wireless/Makefile for import

Jouni Malinen:
      hostap: Make hostap_tx_encrypt() static
      hostap: Fix EAPOL frame encryption

Komuro:
      axnet_cs.c : add hardware multicast support

Larry Finger:
      Minor (janitorial) change to ieee80211

Lennert Buytenhek:
      ixp2000: fix gcc4 breakage

Linas Vepstas:
      Janitor: drivers/net/pcnet32: fix incorrect comments

Mark Brown:
      natsemi: Support oversized EEPROMs

Michael Buesch:
      bcm43xx: sync with svn.berlios.de
      bcm43xx: remove linux version compatibility code.
      bcm43xx: Move README file to Documentation directory.
      bcm43xx: remove redundant COPYING file.
      bcm43xx: add DEBUG Kconfig option. Also fix indention.
      bcm43xx: Fix makefile. Remove all the "out-of-tree" stuff.
      bcm43xx: Add more initvals sanity checks and error out, if one sanity check fails.
      bcm43xx: Remove function bcm43xx_channel_is_allowed()
      bcm43xx: basic ethtool support
      bcm43xx: Wireless Ext update
      bcm43xx: fix txpower reporting in WE.
      bcm43xx: enable SPROM writing.
      bcm43xx: heavily increase mac_suspend timeout.
      bcm43xx: fix compiletime warning (phy_xmitpower)
      bcm43xx: remove WX debugging.
      bcm43xx: Partially fix PIO code. Add Kconfig option for PIO or DMA mode (or both).
      bcm43xx: add a note that not all devices support PIO.
      Apple Airport: Add Kconfig note that the bcm43xx driver has to be used for Airport Extreme cards.
      bcm43xx: update README
      bcm43xx: fix LED code.
      bcm43xx: rewrite and simplify the periodic task handling.
      bcm43xx: Code cleanups. This removes various "inline" statements and reduces codesize.
      bcm43xx: Move sprom lowlevel reading/writing to its own functions.
      bcm43xx: make bcm43xx_sprom_crc() static.
      bcm43xx: split the channel helper functions, so that they can be used without a valid running core.
      bcm43xx: remove old unused struct.
      bcm43xx: Fix Kconfig typo (transfer mode default)
      bcm43xx: Workaround init_board vs IRQ race.
      bcm43xx: move initialized = 1 to the end of init_board.
      bcm43xx: add assert(bcm->initialized) to periodic_tasks_setup().
      bcm43xx: Move TX/RX related functions to its own file. Add basic RTS/CTS code.
      bcm43xx: Add sysfs attributes for device specific tunables.
      bcm43xx: Set both, the DMAmask and the coherent DMAmask.
      bcm43xx: Abstract the locking mechanism.
      bcm43xx: Remove the mmio access printing facility overhead.
      bcm43xx: fix some stuff, add a few missing mmiowb(), remove dead code.
      bcm43xx: receive TX status on MMIO or DMA unconditionally regarding the 80211 core rev.
      bcm43xx: add functions bcm43xx_dma_read/write, bcm43xx_dma_tx_suspend/resume.
      bcm43xx: reduce the size of bcm43xx_private by removing unneeded members.
      bcm43xx: Fix crash on ifdown, by being careful in pio/dma freeing.
      bcm43xx: Remove the workaround in dummy_transmission,
      bcm43xx: Do boardflags workarounds for specific boards.
      bcm43xx: properly mask txctl1 before writing it to hardware.
      bcm43xx: remove check for mmio length, as it differs among platforms. (especially embedded)
      bcm43xx: fix some gpio register trashing (hopefully :D)
      bcm43xx: merge all iwmode code into the set_iwmode function.
      bcm43xx: some IRQ handler cleanups.
      bcm43xx: set default attenuation values.
      bcm43xx: sync interference mitigation code to the specs.
      bcm43xx: fix nrssi_threshold calculation.
      bcm43xx: add useless and broken statistics stuff. People seem to want it. well...
      bcm43xx: get rid of "/* vim: ..." lines at the end of several files.
      bcm43xx: fix "include" issues on some platforms.
      bcm43xx: remove some compilerwarnings.
      bcm43xx: fix the remaining sparse warnings.
      bcm43xx: sync GPHY init with the specs.
      bcm43xx: don't set the channel on a device, which is down.

Pete Zaitcev:
      bcm43xx: fix DMA TX skb freeing in case of fragmented packets.

Randy Dunlap:
      acenic: fix section mismatches

Roger Luethi:
      via-rhine: link state fix


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-03-24 17:19 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2006-03-24 17:19 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, linux-kernel


Main thing is the ne2k-pci build fix.



Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

to receive the following updates:

 drivers/net/arm/Kconfig                           |    8 
 drivers/net/arm/Makefile                          |    1 
 drivers/net/arm/at91_ether.c                      | 1110 ++++++++++++++++++++++
 drivers/net/arm/at91_ether.h                      |  101 ++
 drivers/net/ne2k-pci.c                            |    2 
 include/asm-arm/arch-at91rm9200/at91rm9200_emac.h |  138 ++
 6 files changed, 1359 insertions(+), 1 deletion(-)

Andrew Victor:
      AT91RM9200 Ethernet driver

Horms:
      net: ne2k.c won't compile if pci_clone_list is const

diff --git a/drivers/net/arm/Kconfig b/drivers/net/arm/Kconfig
index 625184b..77fe20d 100644
--- a/drivers/net/arm/Kconfig
+++ b/drivers/net/arm/Kconfig
@@ -31,3 +31,11 @@ config ARM_ETHERH
 	help
 	  If you have an Acorn system with one of these network cards, you
 	  should say Y to this option if you wish to use it with Linux.
+
+config ARM_AT91_ETHER
+	tristate "AT91RM9200 Ethernet support"
+	depends on NET_ETHERNET && ARM && ARCH_AT91RM9200
+	select MII
+	help
+	  If you wish to compile a kernel for the AT91RM9200 and enable
+	  ethernet support, then you should always answer Y to this.
diff --git a/drivers/net/arm/Makefile b/drivers/net/arm/Makefile
index bc263ed..42c95b7 100644
--- a/drivers/net/arm/Makefile
+++ b/drivers/net/arm/Makefile
@@ -7,3 +7,4 @@ obj-$(CONFIG_ARM_AM79C961A)	+= am79c961a
 obj-$(CONFIG_ARM_ETHERH)	+= etherh.o
 obj-$(CONFIG_ARM_ETHER3)	+= ether3.o
 obj-$(CONFIG_ARM_ETHER1)	+= ether1.o
+obj-$(CONFIG_ARM_AT91_ETHER)	+= at91_ether.o
diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
new file mode 100644
index 0000000..5503dc8
--- /dev/null
+++ b/drivers/net/arm/at91_ether.c
@@ -0,0 +1,1110 @@
+/*
+ * Ethernet driver for the Atmel AT91RM9200 (Thunder)
+ *
+ *  Copyright (C) 2003 SAN People (Pty) Ltd
+ *
+ * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc.
+ * Initial version by Rick Bronson 01/11/2003
+ *
+ * Intel LXT971A PHY support by Christopher Bahns & David Knickerbocker
+ *   (Polaroid Corporation)
+ *
+ * Realtek RTL8201(B)L PHY support by Roman Avramenko <roman@imsystems.ru>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/config.h>
+#include <linux/mii.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/dma-mapping.h>
+#include <linux/ethtool.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+#include <asm/mach-types.h>
+
+#include <asm/arch/at91rm9200_emac.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/board.h>
+
+#include "at91_ether.h"
+
+#define DRV_NAME	"at91_ether"
+#define DRV_VERSION	"1.0"
+
+static struct net_device *at91_dev;
+static struct clk *ether_clk;
+
+/* ..................................................................... */
+
+/*
+ * Read from a EMAC register.
+ */
+static inline unsigned long at91_emac_read(unsigned int reg)
+{
+	void __iomem *emac_base = (void __iomem *)AT91_VA_BASE_EMAC;
+
+	return __raw_readl(emac_base + reg);
+}
+
+/*
+ * Write to a EMAC register.
+ */
+static inline void at91_emac_write(unsigned int reg, unsigned long value)
+{
+	void __iomem *emac_base = (void __iomem *)AT91_VA_BASE_EMAC;
+
+	__raw_writel(value, emac_base + reg);
+}
+
+/* ........................... PHY INTERFACE ........................... */
+
+/*
+ * Enable the MDIO bit in MAC control register
+ * When not called from an interrupt-handler, access to the PHY must be
+ *  protected by a spinlock.
+ */
+static void enable_mdi(void)
+{
+	unsigned long ctl;
+
+	ctl = at91_emac_read(AT91_EMAC_CTL);
+	at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_MPE);	/* enable management port */
+}
+
+/*
+ * Disable the MDIO bit in the MAC control register
+ */
+static void disable_mdi(void)
+{
+	unsigned long ctl;
+
+	ctl = at91_emac_read(AT91_EMAC_CTL);
+	at91_emac_write(AT91_EMAC_CTL, ctl & ~AT91_EMAC_MPE);	/* disable management port */
+}
+
+/*
+ * Wait until the PHY operation is complete.
+ */
+static inline void at91_phy_wait(void) {
+	unsigned long timeout = jiffies + 2;
+
+	while (!(at91_emac_read(AT91_EMAC_SR) & AT91_EMAC_SR_IDLE)) {
+		if (time_after(jiffies, timeout)) {
+			printk("at91_ether: MIO timeout\n");
+			break;
+		}
+		cpu_relax();
+	}
+}
+
+/*
+ * Write value to the a PHY register
+ * Note: MDI interface is assumed to already have been enabled.
+ */
+static void write_phy(unsigned char phy_addr, unsigned char address, unsigned int value)
+{
+	at91_emac_write(AT91_EMAC_MAN, AT91_EMAC_MAN_802_3 | AT91_EMAC_RW_W
+		| ((phy_addr & 0x1f) << 23) | (address << 18) | (value & AT91_EMAC_DATA));
+
+	/* Wait until IDLE bit in Network Status register is cleared */
+	at91_phy_wait();
+}
+
+/*
+ * Read value stored in a PHY register.
+ * Note: MDI interface is assumed to already have been enabled.
+ */
+static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int *value)
+{
+	at91_emac_write(AT91_EMAC_MAN, AT91_EMAC_MAN_802_3 | AT91_EMAC_RW_R
+		| ((phy_addr & 0x1f) << 23) | (address << 18));
+
+	/* Wait until IDLE bit in Network Status register is cleared */
+	at91_phy_wait();
+
+	*value = at91_emac_read(AT91_EMAC_MAN) & AT91_EMAC_DATA;
+}
+
+/* ........................... PHY MANAGEMENT .......................... */
+
+/*
+ * Access the PHY to determine the current link speed and mode, and update the
+ * MAC accordingly.
+ * If no link or auto-negotiation is busy, then no changes are made.
+ */
+static void update_linkspeed(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	unsigned int bmsr, bmcr, lpa, mac_cfg;
+	unsigned int speed, duplex;
+
+	if (!mii_link_ok(&lp->mii)) {		/* no link */
+		netif_carrier_off(dev);
+		printk(KERN_INFO "%s: Link down.\n", dev->name);
+		return;
+	}
+
+	/* Link up, or auto-negotiation still in progress */
+	read_phy(lp->phy_address, MII_BMSR, &bmsr);
+	read_phy(lp->phy_address, MII_BMCR, &bmcr);
+	if (bmcr & BMCR_ANENABLE) {				/* AutoNegotiation is enabled */
+		if (!(bmsr & BMSR_ANEGCOMPLETE))
+			return;			/* Do nothing - another interrupt generated when negotiation complete */
+
+		read_phy(lp->phy_address, MII_LPA, &lpa);
+		if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF)) speed = SPEED_100;
+		else speed = SPEED_10;
+		if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL)) duplex = DUPLEX_FULL;
+		else duplex = DUPLEX_HALF;
+	} else {
+		speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
+		duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
+	}
+
+	/* Update the MAC */
+	mac_cfg = at91_emac_read(AT91_EMAC_CFG) & ~(AT91_EMAC_SPD | AT91_EMAC_FD);
+	if (speed == SPEED_100) {
+		if (duplex == DUPLEX_FULL)		/* 100 Full Duplex */
+			mac_cfg |= AT91_EMAC_SPD | AT91_EMAC_FD;
+		else					/* 100 Half Duplex */
+			mac_cfg |= AT91_EMAC_SPD;
+	} else {
+		if (duplex == DUPLEX_FULL)		/* 10 Full Duplex */
+			mac_cfg |= AT91_EMAC_FD;
+		else {}					/* 10 Half Duplex */
+	}
+	at91_emac_write(AT91_EMAC_CFG, mac_cfg);
+
+	printk(KERN_INFO "%s: Link now %i-%s\n", dev->name, speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
+	netif_carrier_on(dev);
+}
+
+/*
+ * Handle interrupts from the PHY
+ */
+static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	unsigned int phy;
+
+	/*
+	 * This hander is triggered on both edges, but the PHY chips expect
+	 * level-triggering.  We therefore have to check if the PHY actually has
+	 * an IRQ pending.
+	 */
+	enable_mdi();
+	if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) {
+		read_phy(lp->phy_address, MII_DSINTR_REG, &phy);	/* ack interrupt in Davicom PHY */
+		if (!(phy & (1 << 0)))
+			goto done;
+	}
+	else if (lp->phy_type == MII_LXT971A_ID) {
+		read_phy(lp->phy_address, MII_ISINTS_REG, &phy);	/* ack interrupt in Intel PHY */
+		if (!(phy & (1 << 2)))
+			goto done;
+	}
+	else if (lp->phy_type == MII_BCM5221_ID) {
+		read_phy(lp->phy_address, MII_BCMINTR_REG, &phy);	/* ack interrupt in Broadcom PHY */
+		if (!(phy & (1 << 0)))
+			goto done;
+	}
+	else if (lp->phy_type == MII_KS8721_ID) {
+		read_phy(lp->phy_address, MII_TPISTATUS, &phy);		/* ack interrupt in Micrel PHY */
+		if (!(phy & ((1 << 2) | 1)))
+			goto done;
+	}
+
+	update_linkspeed(dev);
+
+done:
+	disable_mdi();
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Initialize and enable the PHY interrupt for link-state changes
+ */
+static void enable_phyirq(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	unsigned int dsintr, irq_number;
+	int status;
+
+	if (lp->phy_type == MII_RTL8201_ID)	/* RTL8201 does not have an interrupt */
+		return;
+	if (lp->phy_type == MII_DP83847_ID)	/* DP83847 does not have an interrupt */
+		return;
+	if (lp->phy_type == MII_AC101L_ID)	/* AC101L interrupt not supported yet */
+		return;
+
+	irq_number = lp->board_data.phy_irq_pin;
+	status = request_irq(irq_number, at91ether_phy_interrupt, 0, dev->name, dev);
+	if (status) {
+		printk(KERN_ERR "at91_ether: PHY IRQ %d request failed - status %d!\n", irq_number, status);
+		return;
+	}
+
+	spin_lock_irq(&lp->lock);
+	enable_mdi();
+
+	if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) {	/* for Davicom PHY */
+		read_phy(lp->phy_address, MII_DSINTR_REG, &dsintr);
+		dsintr = dsintr & ~0xf00;		/* clear bits 8..11 */
+		write_phy(lp->phy_address, MII_DSINTR_REG, dsintr);
+	}
+	else if (lp->phy_type == MII_LXT971A_ID) {	/* for Intel PHY */
+		read_phy(lp->phy_address, MII_ISINTE_REG, &dsintr);
+		dsintr = dsintr | 0xf2;			/* set bits 1, 4..7 */
+		write_phy(lp->phy_address, MII_ISINTE_REG, dsintr);
+	}
+	else if (lp->phy_type == MII_BCM5221_ID) {	/* for Broadcom PHY */
+		dsintr = (1 << 15) | ( 1 << 14);
+		write_phy(lp->phy_address, MII_BCMINTR_REG, dsintr);
+	}
+	else if (lp->phy_type == MII_KS8721_ID) {	/* for Micrel PHY */
+		dsintr = (1 << 10) | ( 1 << 8);
+		write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
+	}
+
+	disable_mdi();
+	spin_unlock_irq(&lp->lock);
+}
+
+/*
+ * Disable the PHY interrupt
+ */
+static void disable_phyirq(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	unsigned int dsintr;
+	unsigned int irq_number;
+
+	if (lp->phy_type == MII_RTL8201_ID) 	/* RTL8201 does not have an interrupt */
+		return;
+	if (lp->phy_type == MII_DP83847_ID)	/* DP83847 does not have an interrupt */
+		return;
+	if (lp->phy_type == MII_AC101L_ID)	/* AC101L interrupt not supported yet */
+		return;
+
+	spin_lock_irq(&lp->lock);
+	enable_mdi();
+
+	if ((lp->phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) {	/* for Davicom PHY */
+		read_phy(lp->phy_address, MII_DSINTR_REG, &dsintr);
+		dsintr = dsintr | 0xf00;			/* set bits 8..11 */
+		write_phy(lp->phy_address, MII_DSINTR_REG, dsintr);
+	}
+	else if (lp->phy_type == MII_LXT971A_ID) {	/* for Intel PHY */
+		read_phy(lp->phy_address, MII_ISINTE_REG, &dsintr);
+		dsintr = dsintr & ~0xf2;			/* clear bits 1, 4..7 */
+		write_phy(lp->phy_address, MII_ISINTE_REG, dsintr);
+	}
+	else if (lp->phy_type == MII_BCM5221_ID) {	/* for Broadcom PHY */
+		read_phy(lp->phy_address, MII_BCMINTR_REG, &dsintr);
+		dsintr = ~(1 << 14);
+		write_phy(lp->phy_address, MII_BCMINTR_REG, dsintr);
+	}
+	else if (lp->phy_type == MII_KS8721_ID) {	/* for Micrel PHY */
+		read_phy(lp->phy_address, MII_TPISTATUS, &dsintr);
+		dsintr = ~((1 << 10) | (1 << 8));
+		write_phy(lp->phy_address, MII_TPISTATUS, dsintr);
+	}
+
+	disable_mdi();
+	spin_unlock_irq(&lp->lock);
+
+	irq_number = lp->board_data.phy_irq_pin;
+	free_irq(irq_number, dev);			/* Free interrupt handler */
+}
+
+/*
+ * Perform a software reset of the PHY.
+ */
+#if 0
+static void reset_phy(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	unsigned int bmcr;
+
+	spin_lock_irq(&lp->lock);
+	enable_mdi();
+
+	/* Perform PHY reset */
+	write_phy(lp->phy_address, MII_BMCR, BMCR_RESET);
+
+	/* Wait until PHY reset is complete */
+	do {
+		read_phy(lp->phy_address, MII_BMCR, &bmcr);
+	} while (!(bmcr && BMCR_RESET));
+
+	disable_mdi();
+	spin_unlock_irq(&lp->lock);
+}
+#endif
+
+/* ......................... ADDRESS MANAGEMENT ........................ */
+
+/*
+ * NOTE: Your bootloader must always set the MAC address correctly before
+ * booting into Linux.
+ *
+ * - It must always set the MAC address after reset, even if it doesn't
+ *   happen to access the Ethernet while it's booting.  Some versions of
+ *   U-Boot on the AT91RM9200-DK do not do this.
+ *
+ * - Likewise it must store the addresses in the correct byte order.
+ *   MicroMonitor (uMon) on the CSB337 does this incorrectly (and
+ *   continues to do so, for bug-compatibility).
+ */
+
+static short __init unpack_mac_address(struct net_device *dev, unsigned int hi, unsigned int lo)
+{
+	char addr[6];
+
+	if (machine_is_csb337()) {
+		addr[5] = (lo & 0xff);			/* The CSB337 bootloader stores the MAC the wrong-way around */
+		addr[4] = (lo & 0xff00) >> 8;
+		addr[3] = (lo & 0xff0000) >> 16;
+		addr[2] = (lo & 0xff000000) >> 24;
+		addr[1] = (hi & 0xff);
+		addr[0] = (hi & 0xff00) >> 8;
+	}
+	else {
+		addr[0] = (lo & 0xff);
+		addr[1] = (lo & 0xff00) >> 8;
+		addr[2] = (lo & 0xff0000) >> 16;
+		addr[3] = (lo & 0xff000000) >> 24;
+		addr[4] = (hi & 0xff);
+		addr[5] = (hi & 0xff00) >> 8;
+	}
+
+	if (is_valid_ether_addr(addr)) {
+		memcpy(dev->dev_addr, &addr, 6);
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Set the ethernet MAC address in dev->dev_addr
+ */
+static void __init get_mac_address(struct net_device *dev)
+{
+	/* Check Specific-Address 1 */
+	if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA1H), at91_emac_read(AT91_EMAC_SA1L)))
+		return;
+	/* Check Specific-Address 2 */
+	if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA2H), at91_emac_read(AT91_EMAC_SA2L)))
+		return;
+	/* Check Specific-Address 3 */
+	if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA3H), at91_emac_read(AT91_EMAC_SA3L)))
+		return;
+	/* Check Specific-Address 4 */
+	if (unpack_mac_address(dev, at91_emac_read(AT91_EMAC_SA4H), at91_emac_read(AT91_EMAC_SA4L)))
+		return;
+
+	printk(KERN_ERR "at91_ether: Your bootloader did not configure a MAC address.\n");
+}
+
+/*
+ * Program the hardware MAC address from dev->dev_addr.
+ */
+static void update_mac_address(struct net_device *dev)
+{
+	at91_emac_write(AT91_EMAC_SA1L, (dev->dev_addr[3] << 24) | (dev->dev_addr[2] << 16) | (dev->dev_addr[1] << 8) | (dev->dev_addr[0]));
+	at91_emac_write(AT91_EMAC_SA1H, (dev->dev_addr[5] << 8) | (dev->dev_addr[4]));
+
+	at91_emac_write(AT91_EMAC_SA2L, 0);
+	at91_emac_write(AT91_EMAC_SA2H, 0);
+}
+
+/*
+ * Store the new hardware address in dev->dev_addr, and update the MAC.
+ */
+static int set_mac_address(struct net_device *dev, void* addr)
+{
+	struct sockaddr *address = addr;
+
+	if (!is_valid_ether_addr(address->sa_data))
+		return -EADDRNOTAVAIL;
+
+	memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
+	update_mac_address(dev);
+
+	printk("%s: Setting MAC address to %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+
+	return 0;
+}
+
+static int inline hash_bit_value(int bitnr, __u8 *addr)
+{
+	if (addr[bitnr / 8] & (1 << (bitnr % 8)))
+		return 1;
+	return 0;
+}
+
+/*
+ * The hash address register is 64 bits long and takes up two locations in the memory map.
+ * The least significant bits are stored in EMAC_HSL and the most significant
+ * bits in EMAC_HSH.
+ *
+ * The unicast hash enable and the multicast hash enable bits in the network configuration
+ *  register enable the reception of hash matched frames. The destination address is
+ *  reduced to a 6 bit index into the 64 bit hash register using the following hash function.
+ * The hash function is an exclusive or of every sixth bit of the destination address.
+ *   hash_index[5] = da[5] ^ da[11] ^ da[17] ^ da[23] ^ da[29] ^ da[35] ^ da[41] ^ da[47]
+ *   hash_index[4] = da[4] ^ da[10] ^ da[16] ^ da[22] ^ da[28] ^ da[34] ^ da[40] ^ da[46]
+ *   hash_index[3] = da[3] ^ da[09] ^ da[15] ^ da[21] ^ da[27] ^ da[33] ^ da[39] ^ da[45]
+ *   hash_index[2] = da[2] ^ da[08] ^ da[14] ^ da[20] ^ da[26] ^ da[32] ^ da[38] ^ da[44]
+ *   hash_index[1] = da[1] ^ da[07] ^ da[13] ^ da[19] ^ da[25] ^ da[31] ^ da[37] ^ da[43]
+ *   hash_index[0] = da[0] ^ da[06] ^ da[12] ^ da[18] ^ da[24] ^ da[30] ^ da[36] ^ da[42]
+ * da[0] represents the least significant bit of the first byte received, that is, the multicast/
+ *  unicast indicator, and da[47] represents the most significant bit of the last byte
+ *  received.
+ * If the hash index points to a bit that is set in the hash register then the frame will be
+ *  matched according to whether the frame is multicast or unicast.
+ * A multicast match will be signalled if the multicast hash enable bit is set, da[0] is 1 and
+ *  the hash index points to a bit set in the hash register.
+ * A unicast match will be signalled if the unicast hash enable bit is set, da[0] is 0 and the
+ *  hash index points to a bit set in the hash register.
+ * To receive all multicast frames, the hash register should be set with all ones and the
+ *  multicast hash enable bit should be set in the network configuration register.
+ */
+
+/*
+ * Return the hash index value for the specified address.
+ */
+static int hash_get_index(__u8 *addr)
+{
+	int i, j, bitval;
+	int hash_index = 0;
+
+	for (j = 0; j < 6; j++) {
+		for (i = 0, bitval = 0; i < 8; i++)
+			bitval ^= hash_bit_value(i*6 + j, addr);
+
+		hash_index |= (bitval << j);
+	}
+
+        return hash_index;
+}
+
+/*
+ * Add multicast addresses to the internal multicast-hash table.
+ */
+static void at91ether_sethashtable(struct net_device *dev)
+{
+	struct dev_mc_list *curr;
+	unsigned long mc_filter[2];
+	unsigned int i, bitnr;
+
+	mc_filter[0] = mc_filter[1] = 0;
+
+	curr = dev->mc_list;
+	for (i = 0; i < dev->mc_count; i++, curr = curr->next) {
+		if (!curr) break;	/* unexpected end of list */
+
+		bitnr = hash_get_index(curr->dmi_addr);
+		mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
+	}
+
+	at91_emac_write(AT91_EMAC_HSH, mc_filter[0]);
+	at91_emac_write(AT91_EMAC_HSL, mc_filter[1]);
+}
+
+/*
+ * Enable/Disable promiscuous and multicast modes.
+ */
+static void at91ether_set_rx_mode(struct net_device *dev)
+{
+	unsigned long cfg;
+
+	cfg = at91_emac_read(AT91_EMAC_CFG);
+
+	if (dev->flags & IFF_PROMISC)			/* Enable promiscuous mode */
+		cfg |= AT91_EMAC_CAF;
+	else if (dev->flags & (~IFF_PROMISC))		/* Disable promiscuous mode */
+		cfg &= ~AT91_EMAC_CAF;
+
+	if (dev->flags & IFF_ALLMULTI) {		/* Enable all multicast mode */
+		at91_emac_write(AT91_EMAC_HSH, -1);
+		at91_emac_write(AT91_EMAC_HSL, -1);
+		cfg |= AT91_EMAC_MTI;
+	} else if (dev->mc_count > 0) {			/* Enable specific multicasts */
+		at91ether_sethashtable(dev);
+		cfg |= AT91_EMAC_MTI;
+	} else if (dev->flags & (~IFF_ALLMULTI)) {	/* Disable all multicast mode */
+		at91_emac_write(AT91_EMAC_HSH, 0);
+		at91_emac_write(AT91_EMAC_HSL, 0);
+		cfg &= ~AT91_EMAC_MTI;
+	}
+
+	at91_emac_write(AT91_EMAC_CFG, cfg);
+}
+
+
+/* ......................... ETHTOOL SUPPORT ........................... */
+
+
+static int mdio_read(struct net_device *dev, int phy_id, int location)
+{
+	unsigned int value;
+
+	read_phy(phy_id, location, &value);
+	return value;
+}
+
+static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
+{
+	write_phy(phy_id, location, value);
+}
+
+static int at91ether_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	int ret;
+
+	spin_lock_irq(&lp->lock);
+	enable_mdi();
+
+	ret = mii_ethtool_gset(&lp->mii, cmd);
+
+	disable_mdi();
+	spin_unlock_irq(&lp->lock);
+
+	if (lp->phy_media == PORT_FIBRE) {		/* override media type since mii.c doesn't know */
+		cmd->supported = SUPPORTED_FIBRE;
+		cmd->port = PORT_FIBRE;
+	}
+
+	return ret;
+}
+
+static int at91ether_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	int ret;
+
+	spin_lock_irq(&lp->lock);
+	enable_mdi();
+
+	ret = mii_ethtool_sset(&lp->mii, cmd);
+
+	disable_mdi();
+	spin_unlock_irq(&lp->lock);
+
+	return ret;
+}
+
+static int at91ether_nwayreset(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	int ret;
+
+	spin_lock_irq(&lp->lock);
+	enable_mdi();
+
+	ret = mii_nway_restart(&lp->mii);
+
+	disable_mdi();
+	spin_unlock_irq(&lp->lock);
+
+	return ret;
+}
+
+static void at91ether_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
+{
+	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
+	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
+	strlcpy(info->bus_info, dev->class_dev.dev->bus_id, sizeof(info->bus_info));
+}
+
+static struct ethtool_ops at91ether_ethtool_ops = {
+	.get_settings	= at91ether_get_settings,
+	.set_settings	= at91ether_set_settings,
+	.get_drvinfo	= at91ether_get_drvinfo,
+	.nway_reset	= at91ether_nwayreset,
+	.get_link	= ethtool_op_get_link,
+};
+
+
+/* ................................ MAC ................................ */
+
+/*
+ * Initialize and start the Receiver and Transmit subsystems
+ */
+static void at91ether_start(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	struct recv_desc_bufs *dlist, *dlist_phys;
+	int i;
+	unsigned long ctl;
+
+	dlist = lp->dlist;
+	dlist_phys = lp->dlist_phys;
+
+	for (i = 0; i < MAX_RX_DESCR; i++) {
+		dlist->descriptors[i].addr = (unsigned int) &dlist_phys->recv_buf[i][0];
+		dlist->descriptors[i].size = 0;
+	}
+
+	/* Set the Wrap bit on the last descriptor */
+	dlist->descriptors[i-1].addr |= EMAC_DESC_WRAP;
+
+	/* Reset buffer index */
+	lp->rxBuffIndex = 0;
+
+	/* Program address of descriptor list in Rx Buffer Queue register */
+	at91_emac_write(AT91_EMAC_RBQP, (unsigned long) dlist_phys);
+
+	/* Enable Receive and Transmit */
+	ctl = at91_emac_read(AT91_EMAC_CTL);
+	at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_RE | AT91_EMAC_TE);
+}
+
+/*
+ * Open the ethernet interface
+ */
+static int at91ether_open(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	unsigned long ctl;
+
+        if (!is_valid_ether_addr(dev->dev_addr))
+        	return -EADDRNOTAVAIL;
+
+	clk_enable(ether_clk);			/* Re-enable Peripheral clock */
+
+	/* Clear internal statistics */
+	ctl = at91_emac_read(AT91_EMAC_CTL);
+	at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_CSR);
+
+	/* Update the MAC address (incase user has changed it) */
+	update_mac_address(dev);
+
+	/* Enable PHY interrupt */
+	enable_phyirq(dev);
+
+	/* Enable MAC interrupts */
+	at91_emac_write(AT91_EMAC_IER, AT91_EMAC_RCOM | AT91_EMAC_RBNA
+				| AT91_EMAC_TUND | AT91_EMAC_RTRY | AT91_EMAC_TCOM
+				| AT91_EMAC_ROVR | AT91_EMAC_ABT);
+
+	/* Determine current link speed */
+	spin_lock_irq(&lp->lock);
+	enable_mdi();
+	update_linkspeed(dev);
+	disable_mdi();
+	spin_unlock_irq(&lp->lock);
+
+	at91ether_start(dev);
+	netif_start_queue(dev);
+	return 0;
+}
+
+/*
+ * Close the interface
+ */
+static int at91ether_close(struct net_device *dev)
+{
+	unsigned long ctl;
+
+	/* Disable Receiver and Transmitter */
+	ctl = at91_emac_read(AT91_EMAC_CTL);
+	at91_emac_write(AT91_EMAC_CTL, ctl & ~(AT91_EMAC_TE | AT91_EMAC_RE));
+
+	/* Disable PHY interrupt */
+	disable_phyirq(dev);
+
+	/* Disable MAC interrupts */
+	at91_emac_write(AT91_EMAC_IDR, AT91_EMAC_RCOM | AT91_EMAC_RBNA
+				| AT91_EMAC_TUND | AT91_EMAC_RTRY | AT91_EMAC_TCOM
+				| AT91_EMAC_ROVR | AT91_EMAC_ABT);
+
+	netif_stop_queue(dev);
+
+	clk_disable(ether_clk);			/* Disable Peripheral clock */
+
+	return 0;
+}
+
+/*
+ * Transmit packet.
+ */
+static int at91ether_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+
+	if (at91_emac_read(AT91_EMAC_TSR) & AT91_EMAC_TSR_BNQ) {
+		netif_stop_queue(dev);
+
+		/* Store packet information (to free when Tx completed) */
+		lp->skb = skb;
+		lp->skb_length = skb->len;
+		lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, DMA_TO_DEVICE);
+		lp->stats.tx_bytes += skb->len;
+
+		/* Set address of the data in the Transmit Address register */
+		at91_emac_write(AT91_EMAC_TAR, lp->skb_physaddr);
+		/* Set length of the packet in the Transmit Control register */
+		at91_emac_write(AT91_EMAC_TCR, skb->len);
+
+		dev->trans_start = jiffies;
+	} else {
+		printk(KERN_ERR "at91_ether.c: at91ether_tx() called, but device is busy!\n");
+		return 1;	/* if we return anything but zero, dev.c:1055 calls kfree_skb(skb)
+				on this skb, he also reports -ENETDOWN and printk's, so either
+				we free and return(0) or don't free and return 1 */
+	}
+
+	return 0;
+}
+
+/*
+ * Update the current statistics from the internal statistics registers.
+ */
+static struct net_device_stats *at91ether_stats(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	int ale, lenerr, seqe, lcol, ecol;
+
+	if (netif_running(dev)) {
+		lp->stats.rx_packets += at91_emac_read(AT91_EMAC_OK);		/* Good frames received */
+		ale = at91_emac_read(AT91_EMAC_ALE);
+		lp->stats.rx_frame_errors += ale;				/* Alignment errors */
+		lenerr = at91_emac_read(AT91_EMAC_ELR) + at91_emac_read(AT91_EMAC_USF);
+		lp->stats.rx_length_errors += lenerr;				/* Excessive Length or Undersize Frame error */
+		seqe = at91_emac_read(AT91_EMAC_SEQE);
+		lp->stats.rx_crc_errors += seqe;				/* CRC error */
+		lp->stats.rx_fifo_errors += at91_emac_read(AT91_EMAC_DRFC);	/* Receive buffer not available */
+		lp->stats.rx_errors += (ale + lenerr + seqe
+			+ at91_emac_read(AT91_EMAC_CDE) + at91_emac_read(AT91_EMAC_RJB));
+
+		lp->stats.tx_packets += at91_emac_read(AT91_EMAC_FRA);		/* Frames successfully transmitted */
+		lp->stats.tx_fifo_errors += at91_emac_read(AT91_EMAC_TUE);	/* Transmit FIFO underruns */
+		lp->stats.tx_carrier_errors += at91_emac_read(AT91_EMAC_CSE);	/* Carrier Sense errors */
+		lp->stats.tx_heartbeat_errors += at91_emac_read(AT91_EMAC_SQEE);/* Heartbeat error */
+
+		lcol = at91_emac_read(AT91_EMAC_LCOL);
+		ecol = at91_emac_read(AT91_EMAC_ECOL);
+		lp->stats.tx_window_errors += lcol;			/* Late collisions */
+		lp->stats.tx_aborted_errors += ecol;			/* 16 collisions */
+
+		lp->stats.collisions += (at91_emac_read(AT91_EMAC_SCOL) + at91_emac_read(AT91_EMAC_MCOL) + lcol + ecol);
+	}
+	return &lp->stats;
+}
+
+/*
+ * Extract received frame from buffer descriptors and sent to upper layers.
+ * (Called from interrupt context)
+ */
+static void at91ether_rx(struct net_device *dev)
+{
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	struct recv_desc_bufs *dlist;
+	unsigned char *p_recv;
+	struct sk_buff *skb;
+	unsigned int pktlen;
+
+	dlist = lp->dlist;
+	while (dlist->descriptors[lp->rxBuffIndex].addr & EMAC_DESC_DONE) {
+		p_recv = dlist->recv_buf[lp->rxBuffIndex];
+		pktlen = dlist->descriptors[lp->rxBuffIndex].size & 0x7ff;	/* Length of frame including FCS */
+		skb = alloc_skb(pktlen + 2, GFP_ATOMIC);
+		if (skb != NULL) {
+			skb_reserve(skb, 2);
+			memcpy(skb_put(skb, pktlen), p_recv, pktlen);
+
+			skb->dev = dev;
+			skb->protocol = eth_type_trans(skb, dev);
+			skb->len = pktlen;
+			dev->last_rx = jiffies;
+			lp->stats.rx_bytes += pktlen;
+			netif_rx(skb);
+		}
+		else {
+			lp->stats.rx_dropped += 1;
+			printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
+		}
+
+		if (dlist->descriptors[lp->rxBuffIndex].size & EMAC_MULTICAST)
+			lp->stats.multicast++;
+
+		dlist->descriptors[lp->rxBuffIndex].addr &= ~EMAC_DESC_DONE;	/* reset ownership bit */
+		if (lp->rxBuffIndex == MAX_RX_DESCR-1)				/* wrap after last buffer */
+			lp->rxBuffIndex = 0;
+		else
+			lp->rxBuffIndex++;
+	}
+}
+
+/*
+ * MAC interrupt handler
+ */
+static irqreturn_t at91ether_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_id;
+	struct at91_private *lp = (struct at91_private *) dev->priv;
+	unsigned long intstatus, ctl;
+
+	/* MAC Interrupt Status register indicates what interrupts are pending.
+	   It is automatically cleared once read. */
+	intstatus = at91_emac_read(AT91_EMAC_ISR);
+
+	if (intstatus & AT91_EMAC_RCOM)		/* Receive complete */
+		at91ether_rx(dev);
+
+	if (intstatus & AT91_EMAC_TCOM) {		/* Transmit complete */
+		/* The TCOM bit is set even if the transmission failed. */
+		if (intstatus & (AT91_EMAC_TUND | AT91_EMAC_RTRY))
+			lp->stats.tx_errors += 1;
+
+		if (lp->skb) {
+			dev_kfree_skb_irq(lp->skb);
+			lp->skb = NULL;
+			dma_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, DMA_TO_DEVICE);
+		}
+		netif_wake_queue(dev);
+	}
+
+	/* Work-around for Errata #11 */
+	if (intstatus & AT91_EMAC_RBNA) {
+		ctl = at91_emac_read(AT91_EMAC_CTL);
+		at91_emac_write(AT91_EMAC_CTL, ctl & ~AT91_EMAC_RE);
+		at91_emac_write(AT91_EMAC_CTL, ctl | AT91_EMAC_RE);
+	}
+
+	if (intstatus & AT91_EMAC_ROVR)
+		printk("%s: ROVR error\n", dev->name);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Initialize the ethernet interface
+ */
+static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_address, struct platform_device *pdev)
+{
+	struct at91_eth_data *board_data = pdev->dev.platform_data;
+	struct net_device *dev;
+	struct at91_private *lp;
+	unsigned int val;
+	int res;
+
+	if (at91_dev)			/* already initialized */
+		return 0;
+
+	dev = alloc_etherdev(sizeof(struct at91_private));
+	if (!dev)
+		return -ENOMEM;
+
+	dev->base_addr = AT91_VA_BASE_EMAC;
+	dev->irq = AT91_ID_EMAC;
+	SET_MODULE_OWNER(dev);
+
+	/* Install the interrupt handler */
+	if (request_irq(dev->irq, at91ether_interrupt, 0, dev->name, dev)) {
+		free_netdev(dev);
+		return -EBUSY;
+	}
+
+	/* Allocate memory for DMA Receive descriptors */
+	lp = (struct at91_private *)dev->priv;
+	lp->dlist = (struct recv_desc_bufs *) dma_alloc_coherent(NULL, sizeof(struct recv_desc_bufs), (dma_addr_t *) &lp->dlist_phys, GFP_KERNEL);
+	if (lp->dlist == NULL) {
+		free_irq(dev->irq, dev);
+		free_netdev(dev);
+		return -ENOMEM;
+	}
+	lp->board_data = *board_data;
+	platform_set_drvdata(pdev, dev);
+
+	spin_lock_init(&lp->lock);
+
+	ether_setup(dev);
+	dev->open = at91ether_open;
+	dev->stop = at91ether_close;
+	dev->hard_start_xmit = at91ether_tx;
+	dev->get_stats = at91ether_stats;
+	dev->set_multicast_list = at91ether_set_rx_mode;
+	dev->set_mac_address = set_mac_address;
+	dev->ethtool_ops = &at91ether_ethtool_ops;
+
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
+	get_mac_address(dev);		/* Get ethernet address and store it in dev->dev_addr */
+	update_mac_address(dev);	/* Program ethernet address into MAC */
+
+	at91_emac_write(AT91_EMAC_CTL, 0);
+
+	if (lp->board_data.is_rmii)
+		at91_emac_write(AT91_EMAC_CFG, AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG | AT91_EMAC_RMII);
+	else
+		at91_emac_write(AT91_EMAC_CFG, AT91_EMAC_CLK_DIV32 | AT91_EMAC_BIG);
+
+	/* Perform PHY-specific initialization */
+	spin_lock_irq(&lp->lock);
+	enable_mdi();
+	if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID)) {
+		read_phy(phy_address, MII_DSCR_REG, &val);
+		if ((val & (1 << 10)) == 0)			/* DSCR bit 10 is 0 -- fiber mode */
+			lp->phy_media = PORT_FIBRE;
+	} else if (machine_is_csb337()) {
+		/* mix link activity status into LED2 link state */
+		write_phy(phy_address, MII_LEDCTRL_REG, 0x0d22);
+	}
+	disable_mdi();
+	spin_unlock_irq(&lp->lock);
+
+	lp->mii.dev = dev;		/* Support for ethtool */
+	lp->mii.mdio_read = mdio_read;
+	lp->mii.mdio_write = mdio_write;
+
+	lp->phy_type = phy_type;	/* Type of PHY connected */
+	lp->phy_address = phy_address;	/* MDI address of PHY */
+
+	/* Register the network interface */
+	res = register_netdev(dev);
+	if (res) {
+		free_irq(dev->irq, dev);
+		free_netdev(dev);
+		dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys);
+		return res;
+	}
+	at91_dev = dev;
+
+	/* Determine current link speed */
+	spin_lock_irq(&lp->lock);
+	enable_mdi();
+	update_linkspeed(dev);
+	disable_mdi();
+	spin_unlock_irq(&lp->lock);
+	netif_carrier_off(dev);		/* will be enabled in open() */
+
+	/* Display ethernet banner */
+	printk(KERN_INFO "%s: AT91 ethernet at 0x%08x int=%d %s%s (%02x:%02x:%02x:%02x:%02x:%02x)\n",
+		dev->name, (uint) dev->base_addr, dev->irq,
+		at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_SPD ? "100-" : "10-",
+		at91_emac_read(AT91_EMAC_CFG) & AT91_EMAC_FD ? "FullDuplex" : "HalfDuplex",
+		dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+		dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+	if ((phy_type == MII_DM9161_ID) || (lp->phy_type == MII_DM9161A_ID))
+		printk(KERN_INFO "%s: Davicom 9196 PHY %s\n", dev->name, (lp->phy_media == PORT_FIBRE) ? "(Fiber)" : "(Copper)");
+	else if (phy_type == MII_LXT971A_ID)
+		printk(KERN_INFO "%s: Intel LXT971A PHY\n", dev->name);
+	else if (phy_type == MII_RTL8201_ID)
+		printk(KERN_INFO "%s: Realtek RTL8201(B)L PHY\n", dev->name);
+	else if (phy_type == MII_BCM5221_ID)
+		printk(KERN_INFO "%s: Broadcom BCM5221 PHY\n", dev->name);
+	else if (phy_type == MII_DP83847_ID)
+		printk(KERN_INFO "%s: National Semiconductor DP83847 PHY\n", dev->name);
+	else if (phy_type == MII_AC101L_ID)
+		printk(KERN_INFO "%s: Altima AC101L PHY\n", dev->name);
+	else if (phy_type == MII_KS8721_ID)
+		printk(KERN_INFO "%s: Micrel KS8721 PHY\n", dev->name);
+
+	return 0;
+}
+
+/*
+ * Detect MAC and PHY and perform initialization
+ */
+static int __init at91ether_probe(struct platform_device *pdev)
+{
+	unsigned int phyid1, phyid2;
+	int detected = -1;
+	unsigned long phy_id;
+	unsigned short phy_address = 0;
+
+	ether_clk = clk_get(&pdev->dev, "ether_clk");
+	if (!ether_clk) {
+		printk(KERN_ERR "at91_ether: no clock defined\n");
+		return -ENODEV;
+	}
+	clk_enable(ether_clk);					/* Enable Peripheral clock */
+
+	while ((detected != 0) && (phy_address < 32)) {
+		/* Read the PHY ID registers */
+		enable_mdi();
+		read_phy(phy_address, MII_PHYSID1, &phyid1);
+		read_phy(phy_address, MII_PHYSID2, &phyid2);
+		disable_mdi();
+
+		phy_id = (phyid1 << 16) | (phyid2 & 0xfff0);
+		switch (phy_id) {
+			case MII_DM9161_ID:		/* Davicom 9161: PHY_ID1 = 0x181, PHY_ID2 = B881 */
+			case MII_DM9161A_ID:		/* Davicom 9161A: PHY_ID1 = 0x181, PHY_ID2 = B8A0 */
+			case MII_LXT971A_ID:		/* Intel LXT971A: PHY_ID1 = 0x13, PHY_ID2 = 78E0 */
+			case MII_RTL8201_ID:		/* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */
+			case MII_BCM5221_ID:		/* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */
+			case MII_DP83847_ID:		/* National Semiconductor DP83847:  */
+			case MII_AC101L_ID:		/* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */
+			case MII_KS8721_ID:		/* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */
+				detected = at91ether_setup(phy_id, phy_address, pdev);
+				break;
+		}
+
+		phy_address++;
+	}
+
+	clk_disable(ether_clk);					/* Disable Peripheral clock */
+
+	return detected;
+}
+
+static int __devexit at91ether_remove(struct platform_device *pdev)
+{
+	struct at91_private *lp = (struct at91_private *) at91_dev->priv;
+
+	unregister_netdev(at91_dev);
+	free_irq(at91_dev->irq, at91_dev);
+	dma_free_coherent(NULL, sizeof(struct recv_desc_bufs), lp->dlist, (dma_addr_t)lp->dlist_phys);
+	clk_put(ether_clk);
+
+	free_netdev(at91_dev);
+	at91_dev = NULL;
+	return 0;
+}
+
+static struct platform_driver at91ether_driver = {
+	.probe		= at91ether_probe,
+	.remove		= __devexit_p(at91ether_remove),
+	/* FIXME:  support suspend and resume */
+	.driver		= {
+		.name	= DRV_NAME,
+		.owner	= THIS_MODULE,
+	},
+};
+
+static int __init at91ether_init(void)
+{
+	return platform_driver_register(&at91ether_driver);
+}
+
+static void __exit at91ether_exit(void)
+{
+	platform_driver_unregister(&at91ether_driver);
+}
+
+module_init(at91ether_init)
+module_exit(at91ether_exit)
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver");
+MODULE_AUTHOR("Andrew Victor");
diff --git a/drivers/net/arm/at91_ether.h b/drivers/net/arm/at91_ether.h
new file mode 100644
index 0000000..9885735
--- /dev/null
+++ b/drivers/net/arm/at91_ether.h
@@ -0,0 +1,101 @@
+/*
+ * Ethernet driver for the Atmel AT91RM9200 (Thunder)
+ *
+ *  Copyright (C) SAN People (Pty) Ltd
+ *
+ * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc.
+ * Initial version by Rick Bronson.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef AT91_ETHERNET
+#define AT91_ETHERNET
+
+
+/* Davicom 9161 PHY */
+#define MII_DM9161_ID	0x0181b880
+#define MII_DM9161A_ID	0x0181b8a0
+
+/* Davicom specific registers */
+#define MII_DSCR_REG	16
+#define MII_DSCSR_REG	17
+#define MII_DSINTR_REG	21
+
+/* Intel LXT971A PHY */
+#define MII_LXT971A_ID	0x001378E0
+
+/* Intel specific registers */
+#define MII_ISINTE_REG	18
+#define MII_ISINTS_REG	19
+#define MII_LEDCTRL_REG	20
+
+/* Realtek RTL8201 PHY */
+#define MII_RTL8201_ID	0x00008200
+
+/* Broadcom BCM5221 PHY */
+#define MII_BCM5221_ID	0x004061e0
+
+/* Broadcom specific registers */
+#define MII_BCMINTR_REG	26
+
+/* National Semiconductor DP83847 */
+#define MII_DP83847_ID	0x20005c30
+
+/* Altima AC101L PHY */
+#define MII_AC101L_ID	0x00225520
+
+/* Micrel KS8721 PHY */
+#define MII_KS8721_ID	0x00221610
+
+/* ........................................................................ */
+
+#define MAX_RBUFF_SZ	0x600		/* 1518 rounded up */
+#define MAX_RX_DESCR	9		/* max number of receive buffers */
+
+#define EMAC_DESC_DONE	0x00000001	/* bit for if DMA is done */
+#define EMAC_DESC_WRAP	0x00000002	/* bit for wrap */
+
+#define EMAC_BROADCAST	0x80000000	/* broadcast address */
+#define EMAC_MULTICAST	0x40000000	/* multicast address */
+#define EMAC_UNICAST	0x20000000	/* unicast address */
+
+struct rbf_t
+{
+	unsigned int addr;
+	unsigned long size;
+};
+
+struct recv_desc_bufs
+{
+	struct rbf_t descriptors[MAX_RX_DESCR];		/* must be on sizeof (rbf_t) boundary */
+	char recv_buf[MAX_RX_DESCR][MAX_RBUFF_SZ];	/* must be on long boundary */
+};
+
+struct at91_private
+{
+	struct net_device_stats stats;
+	struct mii_if_info mii;			/* ethtool support */
+	struct at91_eth_data board_data;	/* board-specific configuration */
+
+	/* PHY */
+	unsigned long phy_type;			/* type of PHY (PHY_ID) */
+	spinlock_t lock;			/* lock for MDI interface */
+	short phy_media;			/* media interface type */
+	unsigned short phy_address;		/* 5-bit MDI address of PHY (0..31) */
+
+	/* Transmit */
+	struct sk_buff *skb;			/* holds skb until xmit interrupt completes */
+	dma_addr_t skb_physaddr;		/* phys addr from pci_map_single */
+	int skb_length;				/* saved skb length for pci_unmap_single */
+
+	/* Receive */
+	int rxBuffIndex;			/* index into receive descriptor list */
+	struct recv_desc_bufs *dlist;		/* descriptor list address */
+	struct recv_desc_bufs *dlist_phys;	/* descriptor list physical address */
+};
+
+#endif
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index e3ebb58..d11821d 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -117,7 +117,7 @@ enum ne2k_pci_chipsets {
 };
 
 
-static const struct {
+static struct {
 	char *name;
 	int flags;
 } pci_clone_list[] __devinitdata = {
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_emac.h b/include/asm-arm/arch-at91rm9200/at91rm9200_emac.h
new file mode 100644
index 0000000..fbc091e
--- /dev/null
+++ b/include/asm-arm/arch-at91rm9200/at91rm9200_emac.h
@@ -0,0 +1,138 @@
+/*
+ * include/asm-arm/arch-at91rm9200/at91rm9200_emac.h
+ *
+ * Copyright (C) 2005 Ivan Kokshaysky
+ * Copyright (C) SAN People
+ *
+ * Ethernet MAC registers.
+ * Based on AT91RM9200 datasheet revision E.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef AT91RM9200_EMAC_H
+#define AT91RM9200_EMAC_H
+
+#define	AT91_EMAC_CTL		0x00	/* Control Register */
+#define		AT91_EMAC_LB		(1 <<  0)	/* Loopback */
+#define		AT91_EMAC_LBL		(1 <<  1)	/* Loopback Local */
+#define		AT91_EMAC_RE		(1 <<  2)	/* Receive Enable */
+#define		AT91_EMAC_TE		(1 <<  3)	/* Transmit Enable */
+#define		AT91_EMAC_MPE		(1 <<  4)	/* Management Port Enable */
+#define		AT91_EMAC_CSR		(1 <<  5)	/* Clear Statistics Registers */
+#define		AT91_EMAC_INCSTAT	(1 <<  6)	/* Increment Statistics Registers */
+#define		AT91_EMAC_WES		(1 <<  7)	/* Write Enable for Statistics Registers */
+#define		AT91_EMAC_BP		(1 <<  8)	/* Back Pressure */
+
+#define	AT91_EMAC_CFG		0x04	/* Configuration Register */
+#define		AT91_EMAC_SPD		(1 <<  0)	/* Speed */
+#define		AT91_EMAC_FD		(1 <<  1)	/* Full Duplex */
+#define		AT91_EMAC_BR		(1 <<  2)	/* Bit Rate */
+#define		AT91_EMAC_CAF		(1 <<  4)	/* Copy All Frames */
+#define		AT91_EMAC_NBC		(1 <<  5)	/* No Broadcast */
+#define		AT91_EMAC_MTI		(1 <<  6)	/* Multicast Hash Enable */
+#define		AT91_EMAC_UNI		(1 <<  7)	/* Unicast Hash Enable */
+#define		AT91_EMAC_BIG		(1 <<  8)	/* Receive 1522 Bytes */
+#define		AT91_EMAC_EAE		(1 <<  9)	/* External Address Match Enable */
+#define		AT91_EMAC_CLK		(3 << 10)	/* MDC Clock Divisor */
+#define		AT91_EMAC_CLK_DIV8		(0 << 10)
+#define		AT91_EMAC_CLK_DIV16		(1 << 10)
+#define		AT91_EMAC_CLK_DIV32		(2 << 10)
+#define		AT91_EMAC_CLK_DIV64		(3 << 10)
+#define		AT91_EMAC_RTY		(1 << 12)	/* Retry Test */
+#define		AT91_EMAC_RMII		(1 << 13)	/* Reduce MII (RMII) */
+
+#define	AT91_EMAC_SR		0x08	/* Status Register */
+#define		AT91_EMAC_SR_LINK	(1 <<  0)	/* Link */
+#define		AT91_EMAC_SR_MDIO	(1 <<  1)	/* MDIO pin */
+#define		AT91_EMAC_SR_IDLE	(1 <<  2)	/* PHY idle */
+
+#define	AT91_EMAC_TAR		0x0c	/* Transmit Address Register */
+
+#define	AT91_EMAC_TCR		0x10	/* Transmit Control Register */
+#define		AT91_EMAC_LEN		(0x7ff << 0)	/* Transmit Frame Length */
+#define		AT91_EMAC_NCRC		(1     << 15)	/* No CRC */
+
+#define	AT91_EMAC_TSR		0x14	/* Transmit Status Register */
+#define		AT91_EMAC_TSR_OVR	(1 <<  0)	/* Transmit Buffer Overrun */
+#define		AT91_EMAC_TSR_COL	(1 <<  1)	/* Collision Occurred */
+#define		AT91_EMAC_TSR_RLE	(1 <<  2)	/* Retry Limit Exceeded */
+#define		AT91_EMAC_TSR_IDLE	(1 <<  3)	/* Transmitter Idle */
+#define		AT91_EMAC_TSR_BNQ	(1 <<  4)	/* Transmit Buffer not Queued */
+#define		AT91_EMAC_TSR_COMP	(1 <<  5)	/* Transmit Complete */
+#define		AT91_EMAC_TSR_UND	(1 <<  6)	/* Transmit Underrun */
+
+#define	AT91_EMAC_RBQP		0x18	/* Receive Buffer Queue Pointer */
+
+#define	AT91_EMAC_RSR		0x20	/* Receive Status Register */
+#define		AT91_EMAC_RSR_BNA	(1 <<  0)	/* Buffer Not Available */
+#define		AT91_EMAC_RSR_REC	(1 <<  1)	/* Frame Received */
+#define		AT91_EMAC_RSR_OVR	(1 <<  2)	/* RX Overrun */
+
+#define	AT91_EMAC_ISR		0x24	/* Interrupt Status Register */
+#define		AT91_EMAC_DONE		(1 <<  0)	/* Management Done */
+#define		AT91_EMAC_RCOM		(1 <<  1)	/* Receive Complete */
+#define		AT91_EMAC_RBNA		(1 <<  2)	/* Receive Buffer Not Available */
+#define		AT91_EMAC_TOVR		(1 <<  3)	/* Transmit Buffer Overrun */
+#define		AT91_EMAC_TUND		(1 <<  4)	/* Transmit Buffer Underrun */
+#define		AT91_EMAC_RTRY		(1 <<  5)	/* Retry Limit */
+#define		AT91_EMAC_TBRE		(1 <<  6)	/* Transmit Buffer Register Empty */
+#define		AT91_EMAC_TCOM		(1 <<  7)	/* Transmit Complete */
+#define		AT91_EMAC_TIDLE		(1 <<  8)	/* Transmit Idle */
+#define		AT91_EMAC_LINK		(1 <<  9)	/* Link */
+#define		AT91_EMAC_ROVR		(1 << 10)	/* RX Overrun */
+#define		AT91_EMAC_ABT		(1 << 11)	/* Abort */
+
+#define	AT91_EMAC_IER		0x28	/* Interrupt Enable Register */
+#define	AT91_EMAC_IDR		0x2c	/* Interrupt Disable Register */
+#define	AT91_EMAC_IMR		0x30	/* Interrupt Mask Register */
+
+#define	AT91_EMAC_MAN		0x34	/* PHY Maintenance Register */
+#define		AT91_EMAC_DATA		(0xffff << 0)	/* MDIO Data */
+#define		AT91_EMAC_REGA		(0x1f	<< 18)	/* MDIO Register */
+#define		AT91_EMAC_PHYA		(0x1f	<< 23)	/* MDIO PHY Address */
+#define		AT91_EMAC_RW		(3	<< 28)	/* Read/Write operation */
+#define			AT91_EMAC_RW_W		(1 << 28)
+#define			AT91_EMAC_RW_R		(2 << 28)
+#define		AT91_EMAC_MAN_802_3	0x40020000	/* IEEE 802.3 value */
+
+/*
+ * Statistics Registers.
+ */
+#define AT91_EMAC_FRA		0x40	/* Frames Transmitted OK */
+#define AT91_EMAC_SCOL		0x44	/* Single Collision Frame */
+#define AT91_EMAC_MCOL		0x48	/* Multiple Collision Frame */
+#define AT91_EMAC_OK		0x4c	/* Frames Received OK */
+#define AT91_EMAC_SEQE		0x50	/* Frame Check Sequence Error */
+#define AT91_EMAC_ALE		0x54	/* Alignmemt Error */
+#define AT91_EMAC_DTE		0x58	/* Deffered Transmission Frame */
+#define AT91_EMAC_LCOL		0x5c	/* Late Collision */
+#define AT91_EMAC_ECOL		0x60	/* Excessive Collision */
+#define AT91_EMAC_TUE		0x64	/* Transmit Underrun Error */
+#define AT91_EMAC_CSE		0x68	/* Carrier Sense Error */
+#define AT91_EMAC_DRFC		0x6c	/* Discard RX Frame */
+#define AT91_EMAC_ROV		0x70	/* Receive Overrun */
+#define AT91_EMAC_CDE		0x74	/* Code Error */
+#define AT91_EMAC_ELR		0x78	/* Excessive Length Error */
+#define AT91_EMAC_RJB		0x7c	/* Receive Jabber */
+#define AT91_EMAC_USF		0x80	/* Undersize Frame */
+#define AT91_EMAC_SQEE		0x84	/* SQE Test Error */
+
+/*
+ * Address Registers.
+ */
+#define AT91_EMAC_HSL		0x90	/* Hash Address Low [31:0] */
+#define AT91_EMAC_HSH		0x94	/* Hash Address High [63:32] */
+#define AT91_EMAC_SA1L		0x98	/* Specific Address 1 Low, bytes 0-3 */
+#define AT91_EMAC_SA1H		0x9c	/* Specific Address 1 High, bytes 4-5 */
+#define AT91_EMAC_SA2L		0xa0	/* Specific Address 2 Low, bytes 0-3 */
+#define AT91_EMAC_SA2H		0xa4	/* Specific Address 2 High, bytes 4-5 */
+#define AT91_EMAC_SA3L		0xa8	/* Specific Address 3 Low, bytes 0-3 */
+#define AT91_EMAC_SA3H		0xac	/* Specific Address 3 High, bytes 4-5 */
+#define AT91_EMAC_SA4L		0xb0	/* Specific Address 4 Low, bytes 0-3 */
+#define AT91_EMAC_SA4H		0xb4	/* Specific Address 4 High, bytes 4-5 */
+
+#endif

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-03-23  1:34 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2006-03-23  1:34 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: netdev, linux-kernel


Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

to receive the following updates:

 drivers/net/Makefile         |    4 +-
 drivers/net/au1000_eth.c     |   18 ++++------
 drivers/net/depca.c          |    2 -
 drivers/net/sis900.c         |    1 
 drivers/net/sky2.c           |   27 +++++++++++++---
 drivers/net/sky2.h           |   71 +++++++++++++++++++++----------------------
 drivers/net/tulip/de2104x.c  |    2 -
 drivers/s390/net/qeth_main.c |   57 +++-------------------------------
 drivers/s390/net/qeth_proc.c |   56 ++++++++++++++++-----------------
 drivers/s390/net/qeth_sys.c  |    2 -
 10 files changed, 104 insertions(+), 136 deletions(-)

Artur Skawina:
      sis900 adm7001 PHY support

Eric Sesterhenn:
      Use after free in net/tulip/de2104x.c
      Use of uninitialized variable in drivers/net/depca.c

Frank Pavlic:
      s390: qeth driver statistics fixes
      s390: qeth driver cleanups
      s390: qeth :allow setting of attribute "route6" to "no_router".

Jens Osterkamp:
      fix spidernet build issue

Sergei Shtylylov:
      AMD Au1xx0: fix Ethernet TX stats

Stephen Hemminger:
      sky2: more ethtool stats

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 00e72b1..b90468a 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -58,8 +58,8 @@ obj-$(CONFIG_STNIC) += stnic.o 8390.o
 obj-$(CONFIG_FEALNX) += fealnx.o
 obj-$(CONFIG_TIGON3) += tg3.o
 obj-$(CONFIG_BNX2) += bnx2.o
-spidernet-y += spider_net.o spider_net_ethtool.o sungem_phy.o
-obj-$(CONFIG_SPIDER_NET) += spidernet.o
+spidernet-y += spider_net.o spider_net_ethtool.o
+obj-$(CONFIG_SPIDER_NET) += spidernet.o sungem_phy.o
 obj-$(CONFIG_TC35815) += tc35815.o
 obj-$(CONFIG_SKGE) += skge.o
 obj-$(CONFIG_SKY2) += sky2.o
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index cd0b1dc..1363083 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -90,8 +90,6 @@ static void au1000_tx_timeout(struct net
 static int au1000_set_config(struct net_device *dev, struct ifmap *map);
 static void set_rx_mode(struct net_device *);
 static struct net_device_stats *au1000_get_stats(struct net_device *);
-static inline void update_tx_stats(struct net_device *, u32, u32);
-static inline void update_rx_stats(struct net_device *, u32);
 static void au1000_timer(unsigned long);
 static int au1000_ioctl(struct net_device *, struct ifreq *, int);
 static int mdio_read(struct net_device *, int, int);
@@ -1825,16 +1823,11 @@ static void __exit au1000_cleanup_module
 	}
 }
 
-
-static inline void 
-update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
+static void update_tx_stats(struct net_device *dev, u32 status)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
 	struct net_device_stats *ps = &aup->stats;
 
-	ps->tx_packets++;
-	ps->tx_bytes += pkt_len;
-
 	if (status & TX_FRAME_ABORTED) {
 		if (dev->if_port == IF_PORT_100BASEFX) {
 			if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
@@ -1867,7 +1860,7 @@ static void au1000_tx_ack(struct net_dev
 	ptxd = aup->tx_dma_ring[aup->tx_tail];
 
 	while (ptxd->buff_stat & TX_T_DONE) {
-		update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff);
+		update_tx_stats(dev, ptxd->status);
 		ptxd->buff_stat &= ~TX_T_DONE;
 		ptxd->len = 0;
 		au_sync();
@@ -1889,6 +1882,7 @@ static void au1000_tx_ack(struct net_dev
 static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
+	struct net_device_stats *ps = &aup->stats;
 	volatile tx_dma_t *ptxd;
 	u32 buff_stat;
 	db_dest_t *pDB;
@@ -1908,7 +1902,7 @@ static int au1000_tx(struct sk_buff *skb
 		return 1;
 	}
 	else if (buff_stat & TX_T_DONE) {
-		update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff);
+		update_tx_stats(dev, ptxd->status);
 		ptxd->len = 0;
 	}
 
@@ -1928,6 +1922,9 @@ static int au1000_tx(struct sk_buff *skb
 	else
 		ptxd->len = skb->len;
 
+	ps->tx_packets++;
+	ps->tx_bytes += ptxd->len;
+
 	ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
 	au_sync();
 	dev_kfree_skb(skb);
@@ -1936,7 +1933,6 @@ static int au1000_tx(struct sk_buff *skb
 	return 0;
 }
 
-
 static inline void update_rx_stats(struct net_device *dev, u32 status)
 {
 	struct au1000_private *aup = (struct au1000_private *) dev->priv;
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 03804cc..0941d40 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -1412,7 +1412,7 @@ static int __init depca_mca_probe(struct
 		irq = 11;
 		break;
 	default:
-		printk("%s: mca_probe IRQ error.  You should never get here (%d).\n", dev->name, where);
+		printk("%s: mca_probe IRQ error.  You should never get here (%d).\n", mdev->name, where);
 		return -EINVAL;
 	}
 
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index a1cb07c..253440a 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -128,6 +128,7 @@ static const struct mii_chip_info {
 	{ "SiS 900 Internal MII PHY", 		0x001d, 0x8000, LAN },
 	{ "SiS 7014 Physical Layer Solution", 	0x0016, 0xf830, LAN },
 	{ "Altimata AC101LF PHY",               0x0022, 0x5520, LAN },
+	{ "ADM 7001 LAN PHY",			0x002e, 0xcc60, LAN },
 	{ "AMD 79C901 10BASE-T PHY",  		0x0000, 0x6B70, LAN },
 	{ "AMD 79C901 HomePNA PHY",		0x0000, 0x6B90, HOME},
 	{ "ICS LAN PHY",			0x0015, 0xF440, LAN },
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index f08fe6c..36db938 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -2478,17 +2478,34 @@ static const struct sky2_stat {
 	{ "rx_unicast",    GM_RXF_UC_OK },
 	{ "tx_mac_pause",  GM_TXF_MPAUSE },
 	{ "rx_mac_pause",  GM_RXF_MPAUSE },
-	{ "collisions",    GM_TXF_SNG_COL },
+	{ "collisions",    GM_TXF_COL },
 	{ "late_collision",GM_TXF_LAT_COL },
 	{ "aborted", 	   GM_TXF_ABO_COL },
+	{ "single_collisions", GM_TXF_SNG_COL },
 	{ "multi_collisions", GM_TXF_MUL_COL },
-	{ "fifo_underrun", GM_TXE_FIFO_UR },
-	{ "fifo_overflow", GM_RXE_FIFO_OV },
-	{ "rx_toolong",    GM_RXF_LNG_ERR },
-	{ "rx_jabber",     GM_RXF_JAB_PKT },
+
+	{ "rx_short",      GM_RXE_SHT },
 	{ "rx_runt", 	   GM_RXE_FRAG },
+	{ "rx_64_byte_packets", GM_RXF_64B },
+	{ "rx_65_to_127_byte_packets", GM_RXF_127B },
+	{ "rx_128_to_255_byte_packets", GM_RXF_255B },
+	{ "rx_256_to_511_byte_packets", GM_RXF_511B },
+	{ "rx_512_to_1023_byte_packets", GM_RXF_1023B },
+	{ "rx_1024_to_1518_byte_packets", GM_RXF_1518B },
+	{ "rx_1518_to_max_byte_packets", GM_RXF_MAX_SZ },
 	{ "rx_too_long",   GM_RXF_LNG_ERR },
+	{ "rx_fifo_overflow", GM_RXE_FIFO_OV },
+	{ "rx_jabber",     GM_RXF_JAB_PKT },
 	{ "rx_fcs_error",   GM_RXF_FCS_ERR },
+
+	{ "tx_64_byte_packets", GM_TXF_64B },
+	{ "tx_65_to_127_byte_packets", GM_TXF_127B },
+	{ "tx_128_to_255_byte_packets", GM_TXF_255B },
+	{ "tx_256_to_511_byte_packets", GM_TXF_511B },
+	{ "tx_512_to_1023_byte_packets", GM_TXF_1023B },
+	{ "tx_1024_to_1518_byte_packets", GM_TXF_1518B },
+	{ "tx_1519_to_max_byte_packets", GM_TXF_MAX_SZ },
+	{ "tx_fifo_underrun", GM_TXE_FIFO_UR },
 };
 
 static u32 sky2_get_rx_csum(struct net_device *dev)
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h
index d63cd5a..2838f66 100644
--- a/drivers/net/sky2.h
+++ b/drivers/net/sky2.h
@@ -1373,23 +1373,23 @@ enum {
 	GM_SMI_CTRL	= 0x0080,	/* 16 bit r/w	SMI Control Register */
 	GM_SMI_DATA	= 0x0084,	/* 16 bit r/w	SMI Data Register */
 	GM_PHY_ADDR	= 0x0088,	/* 16 bit r/w	GPHY Address Register */
+/* MIB Counters */
+	GM_MIB_CNT_BASE	= 0x0100,	/* Base Address of MIB Counters */
+	GM_MIB_CNT_SIZE	= 256,
 };
 
-/* MIB Counters */
-#define GM_MIB_CNT_BASE	0x0100		/* Base Address of MIB Counters */
-#define GM_MIB_CNT_SIZE	44		/* Number of MIB Counters */
 
 /*
  * MIB Counters base address definitions (low word) -
  * use offset 4 for access to high word	(32 bit r/o)
  */
 enum {
-	GM_RXF_UC_OK  = GM_MIB_CNT_BASE + 0,	/* Unicast Frames Received OK */
+	GM_RXF_UC_OK    = GM_MIB_CNT_BASE + 0,	/* Unicast Frames Received OK */
 	GM_RXF_BC_OK	= GM_MIB_CNT_BASE + 8,	/* Broadcast Frames Received OK */
 	GM_RXF_MPAUSE	= GM_MIB_CNT_BASE + 16,	/* Pause MAC Ctrl Frames Received */
 	GM_RXF_MC_OK	= GM_MIB_CNT_BASE + 24,	/* Multicast Frames Received OK */
 	GM_RXF_FCS_ERR	= GM_MIB_CNT_BASE + 32,	/* Rx Frame Check Seq. Error */
-	/* GM_MIB_CNT_BASE + 40:	reserved */
+
 	GM_RXO_OK_LO	= GM_MIB_CNT_BASE + 48,	/* Octets Received OK Low */
 	GM_RXO_OK_HI	= GM_MIB_CNT_BASE + 56,	/* Octets Received OK High */
 	GM_RXO_ERR_LO	= GM_MIB_CNT_BASE + 64,	/* Octets Received Invalid Low */
@@ -1397,37 +1397,36 @@ enum {
 	GM_RXF_SHT	= GM_MIB_CNT_BASE + 80,	/* Frames <64 Byte Received OK */
 	GM_RXE_FRAG	= GM_MIB_CNT_BASE + 88,	/* Frames <64 Byte Received with FCS Err */
 	GM_RXF_64B	= GM_MIB_CNT_BASE + 96,	/* 64 Byte Rx Frame */
-	GM_RXF_127B	= GM_MIB_CNT_BASE + 104,	/* 65-127 Byte Rx Frame */
-	GM_RXF_255B	= GM_MIB_CNT_BASE + 112,	/* 128-255 Byte Rx Frame */
-	GM_RXF_511B	= GM_MIB_CNT_BASE + 120,	/* 256-511 Byte Rx Frame */
-	GM_RXF_1023B	= GM_MIB_CNT_BASE + 128,	/* 512-1023 Byte Rx Frame */
-	GM_RXF_1518B	= GM_MIB_CNT_BASE + 136,	/* 1024-1518 Byte Rx Frame */
-	GM_RXF_MAX_SZ	= GM_MIB_CNT_BASE + 144,	/* 1519-MaxSize Byte Rx Frame */
-	GM_RXF_LNG_ERR	= GM_MIB_CNT_BASE + 152,	/* Rx Frame too Long Error */
-	GM_RXF_JAB_PKT	= GM_MIB_CNT_BASE + 160,	/* Rx Jabber Packet Frame */
-	/* GM_MIB_CNT_BASE + 168:	reserved */
-	GM_RXE_FIFO_OV	= GM_MIB_CNT_BASE + 176,	/* Rx FIFO overflow Event */
-	/* GM_MIB_CNT_BASE + 184:	reserved */
-	GM_TXF_UC_OK	= GM_MIB_CNT_BASE + 192,	/* Unicast Frames Xmitted OK */
-	GM_TXF_BC_OK	= GM_MIB_CNT_BASE + 200,	/* Broadcast Frames Xmitted OK */
-	GM_TXF_MPAUSE	= GM_MIB_CNT_BASE + 208,	/* Pause MAC Ctrl Frames Xmitted */
-	GM_TXF_MC_OK	= GM_MIB_CNT_BASE + 216,	/* Multicast Frames Xmitted OK */
-	GM_TXO_OK_LO	= GM_MIB_CNT_BASE + 224,	/* Octets Transmitted OK Low */
-	GM_TXO_OK_HI	= GM_MIB_CNT_BASE + 232,	/* Octets Transmitted OK High */
-	GM_TXF_64B	= GM_MIB_CNT_BASE + 240,	/* 64 Byte Tx Frame */
-	GM_TXF_127B	= GM_MIB_CNT_BASE + 248,	/* 65-127 Byte Tx Frame */
-	GM_TXF_255B	= GM_MIB_CNT_BASE + 256,	/* 128-255 Byte Tx Frame */
-	GM_TXF_511B	= GM_MIB_CNT_BASE + 264,	/* 256-511 Byte Tx Frame */
-	GM_TXF_1023B	= GM_MIB_CNT_BASE + 272,	/* 512-1023 Byte Tx Frame */
-	GM_TXF_1518B	= GM_MIB_CNT_BASE + 280,	/* 1024-1518 Byte Tx Frame */
-	GM_TXF_MAX_SZ	= GM_MIB_CNT_BASE + 288,	/* 1519-MaxSize Byte Tx Frame */
-
-	GM_TXF_COL	= GM_MIB_CNT_BASE + 304,	/* Tx Collision */
-	GM_TXF_LAT_COL	= GM_MIB_CNT_BASE + 312,	/* Tx Late Collision */
-	GM_TXF_ABO_COL	= GM_MIB_CNT_BASE + 320,	/* Tx aborted due to Exces. Col. */
-	GM_TXF_MUL_COL	= GM_MIB_CNT_BASE + 328,	/* Tx Multiple Collision */
-	GM_TXF_SNG_COL	= GM_MIB_CNT_BASE + 336,	/* Tx Single Collision */
-	GM_TXE_FIFO_UR	= GM_MIB_CNT_BASE + 344,	/* Tx FIFO Underrun Event */
+	GM_RXF_127B	= GM_MIB_CNT_BASE + 104,/* 65-127 Byte Rx Frame */
+	GM_RXF_255B	= GM_MIB_CNT_BASE + 112,/* 128-255 Byte Rx Frame */
+	GM_RXF_511B	= GM_MIB_CNT_BASE + 120,/* 256-511 Byte Rx Frame */
+	GM_RXF_1023B	= GM_MIB_CNT_BASE + 128,/* 512-1023 Byte Rx Frame */
+	GM_RXF_1518B	= GM_MIB_CNT_BASE + 136,/* 1024-1518 Byte Rx Frame */
+	GM_RXF_MAX_SZ	= GM_MIB_CNT_BASE + 144,/* 1519-MaxSize Byte Rx Frame */
+	GM_RXF_LNG_ERR	= GM_MIB_CNT_BASE + 152,/* Rx Frame too Long Error */
+	GM_RXF_JAB_PKT	= GM_MIB_CNT_BASE + 160,/* Rx Jabber Packet Frame */
+
+	GM_RXE_FIFO_OV	= GM_MIB_CNT_BASE + 176,/* Rx FIFO overflow Event */
+	GM_TXF_UC_OK	= GM_MIB_CNT_BASE + 192,/* Unicast Frames Xmitted OK */
+	GM_TXF_BC_OK	= GM_MIB_CNT_BASE + 200,/* Broadcast Frames Xmitted OK */
+	GM_TXF_MPAUSE	= GM_MIB_CNT_BASE + 208,/* Pause MAC Ctrl Frames Xmitted */
+	GM_TXF_MC_OK	= GM_MIB_CNT_BASE + 216,/* Multicast Frames Xmitted OK */
+	GM_TXO_OK_LO	= GM_MIB_CNT_BASE + 224,/* Octets Transmitted OK Low */
+	GM_TXO_OK_HI	= GM_MIB_CNT_BASE + 232,/* Octets Transmitted OK High */
+	GM_TXF_64B	= GM_MIB_CNT_BASE + 240,/* 64 Byte Tx Frame */
+	GM_TXF_127B	= GM_MIB_CNT_BASE + 248,/* 65-127 Byte Tx Frame */
+	GM_TXF_255B	= GM_MIB_CNT_BASE + 256,/* 128-255 Byte Tx Frame */
+	GM_TXF_511B	= GM_MIB_CNT_BASE + 264,/* 256-511 Byte Tx Frame */
+	GM_TXF_1023B	= GM_MIB_CNT_BASE + 272,/* 512-1023 Byte Tx Frame */
+	GM_TXF_1518B	= GM_MIB_CNT_BASE + 280,/* 1024-1518 Byte Tx Frame */
+	GM_TXF_MAX_SZ	= GM_MIB_CNT_BASE + 288,/* 1519-MaxSize Byte Tx Frame */
+
+	GM_TXF_COL	= GM_MIB_CNT_BASE + 304,/* Tx Collision */
+	GM_TXF_LAT_COL	= GM_MIB_CNT_BASE + 312,/* Tx Late Collision */
+	GM_TXF_ABO_COL	= GM_MIB_CNT_BASE + 320,/* Tx aborted due to Exces. Col. */
+	GM_TXF_MUL_COL	= GM_MIB_CNT_BASE + 328,/* Tx Multiple Collision */
+	GM_TXF_SNG_COL	= GM_MIB_CNT_BASE + 336,/* Tx Single Collision */
+	GM_TXE_FIFO_UR	= GM_MIB_CNT_BASE + 344,/* Tx FIFO Underrun Event */
 };
 
 /* GMAC Bit Definitions */
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 6299e18..e3dd144 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1327,11 +1327,11 @@ static void de_clean_rings (struct de_pr
 		struct sk_buff *skb = de->tx_skb[i].skb;
 		if ((skb) && (skb != DE_DUMMY_SKB)) {
 			if (skb != DE_SETUP_SKB) {
-				dev_kfree_skb(skb);
 				de->net_stats.tx_dropped++;
 				pci_unmap_single(de->pdev,
 					de->tx_skb[i].mapping,
 					skb->len, PCI_DMA_TODEVICE);
+				dev_kfree_skb(skb);
 			} else {
 				pci_unmap_single(de->pdev,
 					de->tx_skb[i].mapping,
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index dba7f7f..021cd5d 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -1364,7 +1364,7 @@ qeth_wait_for_buffer(struct qeth_channel
 static void
 qeth_clear_cmd_buffers(struct qeth_channel *channel)
 {
-	int cnt = 0;
+	int cnt;
 
 	for (cnt=0; cnt < QETH_CMD_BUFFER_NO; cnt++)
 		qeth_release_buffer(channel,&channel->iob[cnt]);
@@ -2814,11 +2814,11 @@ qeth_handle_send_error(struct qeth_card 
 		QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
 		return QETH_SEND_ERROR_LINK_FAILURE;
 	case 3:
+	default:
 		QETH_DBF_TEXT(trace, 1, "SIGAcc3");
 		QETH_DBF_TEXT_(trace,1,"%s",CARD_BUS_ID(card));
 		return QETH_SEND_ERROR_KICK_IT;
 	}
-	return QETH_SEND_ERROR_LINK_FAILURE;
 }
 
 void
@@ -3865,6 +3865,7 @@ qeth_get_cast_type(struct qeth_card *car
 	        	if ((hdr_mac == QETH_TR_MAC_NC) ||
 			    (hdr_mac == QETH_TR_MAC_C))
 				return RTN_MULTICAST;
+			break;
 	        /* eth or so multicast? */
                 default:
                       	if ((hdr_mac == QETH_ETH_MAC_V4) ||
@@ -4419,6 +4420,7 @@ qeth_send_packet(struct qeth_card *card,
 	int elements_needed = 0;
 	enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
 	struct qeth_eddp_context *ctx = NULL;
+	int tx_bytes = skb->len;
 	int rc;
 
 	QETH_DBF_TEXT(trace, 6, "sendpkt");
@@ -4499,7 +4501,7 @@ qeth_send_packet(struct qeth_card *card,
 					      elements_needed, ctx);
 	if (!rc){
 		card->stats.tx_packets++;
-		card->stats.tx_bytes += skb->len;
+		card->stats.tx_bytes += tx_bytes;
 #ifdef CONFIG_QETH_PERF_STATS
 		if (skb_shinfo(skb)->tso_size &&
 		   !(large_send == QETH_LARGE_SEND_NO)) {
@@ -4585,38 +4587,11 @@ qeth_mdio_read(struct net_device *dev, i
 	case MII_NCONFIG: /* network interface config */
 		break;
 	default:
-		rc = 0;
 		break;
 	}
 	return rc;
 }
 
-static void
-qeth_mdio_write(struct net_device *dev, int phy_id, int regnum, int value)
-{
-	switch(regnum){
-	case MII_BMCR: /* Basic mode control register */
-	case MII_BMSR: /* Basic mode status register */
-	case MII_PHYSID1: /* PHYS ID 1 */
-	case MII_PHYSID2: /* PHYS ID 2 */
-	case MII_ADVERTISE: /* Advertisement control reg */
-	case MII_LPA: /* Link partner ability reg */
-	case MII_EXPANSION: /* Expansion register */
-	case MII_DCOUNTER: /* disconnect counter */
-	case MII_FCSCOUNTER: /* false carrier counter */
-	case MII_NWAYTEST: /* N-way auto-neg test register */
-	case MII_RERRCOUNTER: /* rx error counter */
-	case MII_SREVISION: /* silicon revision */
-	case MII_RESV1: /* reserved 1 */
-	case MII_LBRERROR: /* loopback, rx, bypass error */
-	case MII_PHYADDR: /* physical address */
-	case MII_RESV2: /* reserved 2 */
-	case MII_TPISTATUS: /* TPI status for 10mbps */
-	case MII_NCONFIG: /* network interface config */
-	default:
-		break;
-	}
-}
 
 static inline const char *
 qeth_arp_get_error_cause(int *rc)
@@ -5236,21 +5211,6 @@ qeth_do_ioctl(struct net_device *dev, st
 			mii_data->val_out = qeth_mdio_read(dev,mii_data->phy_id,
 							   mii_data->reg_num);
 		break;
-	case SIOCSMIIREG:
-		rc = -EOPNOTSUPP;
-		break;
-		/* TODO: remove return if qeth_mdio_write does something */
-		if (!capable(CAP_NET_ADMIN)){
-			rc = -EPERM;
-			break;
-		}
-		mii_data = if_mii(rq);
-		if (mii_data->phy_id != 0)
-			rc = -EINVAL;
-		else
-			qeth_mdio_write(dev, mii_data->phy_id, mii_data->reg_num,
-					mii_data->val_in);
-		break;
 	default:
 		rc = -EOPNOTSUPP;
 	}
@@ -6900,7 +6860,7 @@ qeth_send_setassparms(struct qeth_card *
 	cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE);
 	if (len <= sizeof(__u32))
 		cmd->data.setassparms.data.flags_32bit = (__u32) data;
-	else if (len > sizeof(__u32))
+	else   /* (len > sizeof(__u32)) */
 		memcpy(&cmd->data.setassparms.data, (void *) data, len);
 
 	rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param);
@@ -7379,11 +7339,6 @@ qeth_setrouting_v6(struct qeth_card *car
 	qeth_correct_routing_type(card, &card->options.route6.type,
 				  QETH_PROT_IPV6);
 
-	if ((card->options.route6.type == NO_ROUTER) ||
-	    ((card->info.type == QETH_CARD_TYPE_OSAE) &&
-	     (card->options.route6.type == MULTICAST_ROUTER) &&
-	     !qeth_is_supported6(card,IPA_OSA_MC_ROUTER)))
-		return 0;
 	rc = qeth_send_setrouting(card, card->options.route6.type,
 				  QETH_PROT_IPV6);
 	if (rc) {
diff --git a/drivers/s390/net/qeth_proc.c b/drivers/s390/net/qeth_proc.c
index 3c6339d..360d782 100644
--- a/drivers/s390/net/qeth_proc.c
+++ b/drivers/s390/net/qeth_proc.c
@@ -74,7 +74,7 @@ qeth_procfile_seq_next(struct seq_file *
 static inline const char *
 qeth_get_router_str(struct qeth_card *card, int ipv)
 {
-	int routing_type = 0;
+	enum qeth_routing_types routing_type = NO_ROUTER;
 
 	if (ipv == 4) {
 		routing_type = card->options.route4.type;
@@ -86,26 +86,26 @@ qeth_get_router_str(struct qeth_card *ca
 #endif /* CONFIG_QETH_IPV6 */
 	}
 
-	if (routing_type == PRIMARY_ROUTER)
+	switch (routing_type){
+	case PRIMARY_ROUTER:
 		return "pri";
-	else if (routing_type == SECONDARY_ROUTER)
+	case SECONDARY_ROUTER:
 		return "sec";
-	else if (routing_type == MULTICAST_ROUTER) {
+	case MULTICAST_ROUTER:
 		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
 			return "mc+";
 		return "mc";
-	} else if (routing_type == PRIMARY_CONNECTOR) {
+	case PRIMARY_CONNECTOR:
 		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
 			return "p+c";
 		return "p.c";
-	} else if (routing_type == SECONDARY_CONNECTOR) {
+	case SECONDARY_CONNECTOR:
 		if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
 			return "s+c";
 		return "s.c";
-	} else if (routing_type == NO_ROUTER)
+	default:   /* NO_ROUTER */
 		return "no";
-	else
-		return "unk";
+	}
 }
 
 static int
@@ -192,27 +192,27 @@ qeth_perf_procfile_seq_show(struct seq_f
 			CARD_DDEV_ID(card),
 			QETH_CARD_IFNAME(card)
 		  );
-	seq_printf(s, "  Skb's/buffers received                 : %li/%i\n"
-		      "  Skb's/buffers sent                     : %li/%i\n\n",
+	seq_printf(s, "  Skb's/buffers received                 : %lu/%u\n"
+		      "  Skb's/buffers sent                     : %lu/%u\n\n",
 		        card->stats.rx_packets, card->perf_stats.bufs_rec,
 		        card->stats.tx_packets, card->perf_stats.bufs_sent
 		  );
-	seq_printf(s, "  Skb's/buffers sent without packing     : %li/%i\n"
-		      "  Skb's/buffers sent with packing        : %i/%i\n\n",
+	seq_printf(s, "  Skb's/buffers sent without packing     : %lu/%u\n"
+		      "  Skb's/buffers sent with packing        : %u/%u\n\n",
 		   card->stats.tx_packets - card->perf_stats.skbs_sent_pack,
 		   card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack,
 		   card->perf_stats.skbs_sent_pack,
 		   card->perf_stats.bufs_sent_pack
 		  );
-	seq_printf(s, "  Skbs sent in SG mode                   : %i\n"
-		      "  Skb fragments sent in SG mode          : %i\n\n",
+	seq_printf(s, "  Skbs sent in SG mode                   : %u\n"
+		      "  Skb fragments sent in SG mode          : %u\n\n",
 		      card->perf_stats.sg_skbs_sent,
 		      card->perf_stats.sg_frags_sent);
-	seq_printf(s, "  large_send tx (in Kbytes)              : %i\n"
-		      "  large_send count                       : %i\n\n",
+	seq_printf(s, "  large_send tx (in Kbytes)              : %u\n"
+		      "  large_send count                       : %u\n\n",
 		      card->perf_stats.large_send_bytes >> 10,
 		      card->perf_stats.large_send_cnt);
-	seq_printf(s, "  Packing state changes no pkg.->packing : %i/%i\n"
+	seq_printf(s, "  Packing state changes no pkg.->packing : %u/%u\n"
 		      "  Watermarks L/H                         : %i/%i\n"
 		      "  Current buffer usage (outbound q's)    : "
 		      "%i/%i/%i/%i\n\n",
@@ -229,16 +229,16 @@ qeth_perf_procfile_seq_show(struct seq_f
 				atomic_read(&card->qdio.out_qs[3]->used_buffers)
 				: 0
 		  );
-	seq_printf(s, "  Inbound handler time (in us)           : %i\n"
-		      "  Inbound handler count                  : %i\n"
-		      "  Inbound do_QDIO time (in us)           : %i\n"
-		      "  Inbound do_QDIO count                  : %i\n\n"
-		      "  Outbound handler time (in us)          : %i\n"
-		      "  Outbound handler count                 : %i\n\n"
-		      "  Outbound time (in us, incl QDIO)       : %i\n"
-		      "  Outbound count                         : %i\n"
-		      "  Outbound do_QDIO time (in us)          : %i\n"
-		      "  Outbound do_QDIO count                 : %i\n\n",
+	seq_printf(s, "  Inbound handler time (in us)           : %u\n"
+		      "  Inbound handler count                  : %u\n"
+		      "  Inbound do_QDIO time (in us)           : %u\n"
+		      "  Inbound do_QDIO count                  : %u\n\n"
+		      "  Outbound handler time (in us)          : %u\n"
+		      "  Outbound handler count                 : %u\n\n"
+		      "  Outbound time (in us, incl QDIO)       : %u\n"
+		      "  Outbound count                         : %u\n"
+		      "  Outbound do_QDIO time (in us)          : %u\n"
+		      "  Outbound do_QDIO count                 : %u\n\n",
 		        card->perf_stats.inbound_time,
 			card->perf_stats.inbound_cnt,
 		        card->perf_stats.inbound_do_qdio_time,
diff --git a/drivers/s390/net/qeth_sys.c b/drivers/s390/net/qeth_sys.c
index c1831f5..f2a076a 100644
--- a/drivers/s390/net/qeth_sys.c
+++ b/drivers/s390/net/qeth_sys.c
@@ -115,7 +115,7 @@ qeth_dev_portno_store(struct device *dev
 		return -EPERM;
 
 	portno = simple_strtoul(buf, &tmp, 16);
-	if ((portno < 0) || (portno > MAX_PORTNO)){
+	if (portno > MAX_PORTNO){
 		PRINT_WARN("portno 0x%X is out of range\n", portno);
 		return -EINVAL;
 	}

^ permalink raw reply related	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-03-21 21:55 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2006-03-21 21:55 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel

[just pushed upstream; patch too big to inline]

Please pull from 'upstream-linus' branch of
master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

to receive the following updates:

 Documentation/networking/e100.txt  |  158 -
 Documentation/networking/e1000.txt |  634 +++--
 MAINTAINERS                        |   16 
 drivers/net/mv643xx_eth.h          |   18 
 drivers/net/pcnet32.c              | 4161 +++++++++++++++++++------------------
 drivers/net/skfp/fplustm.c         |   12 
 drivers/net/skge.c                 |  275 +-
 drivers/net/skge.h                 |    1 
 drivers/net/sky2.c                 |  583 ++---
 drivers/net/sky2.h                 |   22 
 drivers/net/smc91x.c               |   53 
 drivers/net/smc91x.h               |  478 ++--
 12 files changed, 3467 insertions(+), 2944 deletions(-)

Andrew Morton:
      skfp warning fixes

Dale Farnsworth:
      mv643xx_eth: Cache align skb->data if CONFIG_NOT_COHERENT_CACHE

Don Fry:
      pcnet32: support boards with multiple phys

Jeff Garzik:
      [netdrvr] pcnet32: Lindent
      [netdrvr] pcnet32: other source formatting cleanups

Jesse Brandeburg:
      e100/e1000/ixgb: update MAINTAINERS to current developers
      e100: update e100.txt
      e1000: update the readme with the latest text

Nicolas Pitre:
      smc91x: allow for dynamic bus access configs

Stephen Hemminger:
      skge: use NAPI for tx cleanup.
      skge: use auto masking of irqs
      skge: check the allocation of ring buffer
      skge: dma configuration cleanup
      skge: use kcalloc
      skge: use mmiowb
      skge: formmating and whitespace cleanup
      skge: handle pci errors better
      skge: version 1.4
      sky2: remove support for untested Yukon EC/rev 0
      sky2: drop broken wake on lan support
      sky2: rework of NAPI and IRQ management
      sky2: coalescing parameters
      sky2: add MSI support
      sky2: whitespace fixes
      sky2: transmit recovery
      sky2: handle all error irqs
      sky2 version 1.1


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2006-03-20 11:17 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2006-03-20 11:17 UTC (permalink / raw)
  To: netdev; +Cc: linux-kernel

[just sent upstream; patch snipped due to size]

Please pull from 'upstream-linus' branch of
git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

to receive the following updates:

 Documentation/DocBook/sis900.tmpl          |  585 ----------
 Documentation/networking/sis900.txt        |  257 ----
 Documentation/DocBook/Makefile             |    2 
 Documentation/feature-removal-schedule.txt |    7 
 Documentation/networking/00-INDEX          |    2 
 Documentation/networking/README.ipw2100    |   12 
 Documentation/networking/README.ipw2200    |   44 
 arch/ppc/platforms/hdpu.c                  |    5 
 drivers/net/3c509.c                        |   70 -
 drivers/net/3c523.c                        |    9 
 drivers/net/3c59x.c                        |    7 
 drivers/net/7990.c                         |    2 
 drivers/net/8139cp.c                       |    2 
 drivers/net/8139too.c                      |    4 
 drivers/net/82596.c                        |    2 
 drivers/net/Kconfig                        |   29 
 drivers/net/apne.c                         |    7 
 drivers/net/arcnet/Kconfig                 |    4 
 drivers/net/arcnet/arc-rawmode.c           |    2 
 drivers/net/arcnet/arc-rimi.c              |   68 -
 drivers/net/arcnet/arcnet.c                |   20 
 drivers/net/arcnet/com90xx.c               |  132 +-
 drivers/net/arcnet/rfc1051.c               |    2 
 drivers/net/arcnet/rfc1201.c               |    2 
 drivers/net/arm/etherh.c                   |    3 
 drivers/net/bnx2.c                         |   10 
 drivers/net/bnx2_fw.h                      |   84 -
 drivers/net/bonding/bond_alb.c             |    2 
 drivers/net/bonding/bond_main.c            |   45 
 drivers/net/bonding/bond_sysfs.c           |    6 
 drivers/net/bonding/bonding.h              |   33 
 drivers/net/chelsio/espi.c                 |   14 
 drivers/net/chelsio/subr.c                 |    2 
 drivers/net/dgrs.c                         |    2 
 drivers/net/dgrs_firmware.c                |    4 
 drivers/net/dl2k.c                         |    4 
 drivers/net/e100.c                         |    6 
 drivers/net/e1000/e1000.h                  |   68 -
 drivers/net/e1000/e1000_ethtool.c          |  110 --
 drivers/net/e1000/e1000_hw.c               |  734 +++++++++++++
 drivers/net/e1000/e1000_hw.h               |  319 +++++
 drivers/net/e1000/e1000_main.c             |  609 ++++-------
 drivers/net/e1000/e1000_param.c            |    2 
 drivers/net/eepro100.c                     |    4 
 drivers/net/epic100.c                      |    4 
 drivers/net/eth16i.c                       |   11 
 drivers/net/fealnx.c                       |    2 
 drivers/net/forcedeth.c                    |  593 ++++++++++-
 drivers/net/hamachi.c                      |    2 
 drivers/net/hamradio/baycom_epp.c          |    2 
 drivers/net/hp100.c                        |   35 
 drivers/net/ibm_emac/ibm_emac_core.c       |   40 
 drivers/net/ibm_emac/ibm_emac_core.h       |    2 
 drivers/net/ibm_emac/ibm_emac_debug.c      |    2 
 drivers/net/ibm_emac/ibm_emac_rgmii.h      |    2 
 drivers/net/ibm_emac/ibm_emac_zmii.c       |    7 
 drivers/net/ibm_emac/ibm_emac_zmii.h       |    2 
 drivers/net/irda/Kconfig                   |    4 
 drivers/net/macsonic.c                     |    2 
 drivers/net/mv643xx_eth.c                  | 1560 ++++++++++-------------------
 drivers/net/mv643xx_eth.h                  |  250 +---
 drivers/net/natsemi.c                      |  192 ++-
 drivers/net/ne-h8300.c                     |    5 
 drivers/net/ne.c                           |    7 
 drivers/net/ne2.c                          |    7 
 drivers/net/ne2k-pci.c                     |    2 
 drivers/net/ns83820.c                      |    7 
 drivers/net/oaknet.c                       |    3 
 drivers/net/pcmcia/3c574_cs.c              |    2 
 drivers/net/pcmcia/3c589_cs.c              |    5 
 drivers/net/pcmcia/fmvj18x_cs.c            |    2 
 drivers/net/pcmcia/nmclan_cs.c             |    2 
 drivers/net/pcmcia/pcnet_cs.c              |    3 
 drivers/net/pcmcia/smc91c92_cs.c           |    4 
 drivers/net/pcmcia/xirc2ps_cs.c            |    2 
 drivers/net/pcnet32.c                      |    6 
 drivers/net/phy/phy.c                      |    2 
 drivers/net/plip.c                         |    4 
 drivers/net/ppp_async.c                    |    3 
 drivers/net/ppp_synctty.c                  |    2 
 drivers/net/r8169.c                        |    4 
 drivers/net/s2io.c                         |  617 ++++++++++-
 drivers/net/s2io.h                         |   55 -
 drivers/net/sb1000.c                       |    2 
 drivers/net/sb1250-mac.c                   |  109 +-
 drivers/net/seeq8005.c                     |    5 
 drivers/net/sgiseeq.c                      |   17 
 drivers/net/shaper.c                       |    3 
 drivers/net/sis190.c                       |    2 
 drivers/net/sis900.c                       |    8 
 drivers/net/sk98lin/h/skaddr.h             |   48 
 drivers/net/sk98lin/h/skcsum.h             |    6 
 drivers/net/sk98lin/h/skgeinit.h           |   56 -
 drivers/net/sk98lin/h/skgepnmi.h           |    4 
 drivers/net/sk98lin/h/skgesirq.h           |    1 
 drivers/net/sk98lin/h/ski2c.h              |    3 
 drivers/net/sk98lin/h/skvpd.h              |   15 
 drivers/net/sk98lin/skaddr.c               |   35 
 drivers/net/sk98lin/skgeinit.c             |  148 --
 drivers/net/sk98lin/skgemib.c              |    7 
 drivers/net/sk98lin/skgepnmi.c             |  153 --
 drivers/net/sk98lin/skgesirq.c             |   24 
 drivers/net/sk98lin/ski2c.c                |    6 
 drivers/net/sk98lin/sklm80.c               |   72 -
 drivers/net/sk98lin/skrlmt.c               |    1 
 drivers/net/sk98lin/skvpd.c                |  108 --
 drivers/net/sk98lin/skxmac2.c              |  461 --------
 drivers/net/skfp/fplustm.c                 |   14 
 drivers/net/skfp/pcmplc.c                  |    4 
 drivers/net/skfp/skfddi.c                  |    2 
 drivers/net/starfire.c                     |   40 
 drivers/net/sundance.c                     |   10 
 drivers/net/sungem_phy.c                   |    2 
 drivers/net/tg3.c                          |    4 
 drivers/net/tokenring/lanstreamer.c        |    3 
 drivers/net/tokenring/olympic.c            |    9 
 drivers/net/tulip/de2104x.c                |   18 
 drivers/net/tulip/pnic.c                   |    3 
 drivers/net/tulip/winbond-840.c            |    2 
 drivers/net/tulip/xircom_cb.c              |    9 
 drivers/net/typhoon.c                      |    2 
 drivers/net/wan/Kconfig                    |    2 
 drivers/net/wan/hostess_sv11.c             |    1 
 drivers/net/wan/sealevel.c                 |    1 
 drivers/net/wireless/Kconfig               |   32 
 drivers/net/wireless/airo.c                |  338 +++++-
 drivers/net/wireless/atmel.c               |  110 --
 drivers/net/wireless/ipw2100.c             |  266 +++-
 drivers/net/wireless/ipw2100.h             |   17 
 drivers/net/wireless/ipw2200.c             | 1239 +++++++++++------------
 drivers/net/wireless/ipw2200.h             |  103 -
 drivers/net/wireless/netwave_cs.c          |    2 
 drivers/net/wireless/strip.c               |    4 
 drivers/net/wireless/wavelan.p.h           |    6 
 drivers/net/wireless/wavelan_cs.p.h        |    9 
 drivers/net/yellowfin.c                    |    6 
 drivers/net/zorro8390.c                    |    7 
 include/linux/arcdevice.h                  |    9 
 include/linux/if.h                         |    3 
 include/linux/if_ether.h                   |    1 
 include/linux/mv643xx.h                    |   27 
 include/net/ieee80211.h                    |  177 +++
 include/net/ieee80211_crypt.h              |    3 
 net/Kconfig                                |    3 
 net/core/Makefile                          |    2 
 net/core/dev.c                             |   36 
 net/ieee80211/ieee80211_crypt.c            |   11 
 net/ieee80211/ieee80211_crypt_ccmp.c       |    8 
 net/ieee80211/ieee80211_crypt_tkip.c       |   56 -
 net/ieee80211/ieee80211_crypt_wep.c        |    5 
 net/ieee80211/ieee80211_geo.c              |   48 
 net/ieee80211/ieee80211_module.c           |   20 
 net/ieee80211/ieee80211_rx.c               |  167 ++-
 net/ieee80211/ieee80211_tx.c               |   30 
 net/ieee80211/ieee80211_wx.c               |  152 ++
 net/socket.c                               |    9 
 156 files changed, 5816 insertions(+), 5303 deletions(-)

Adrian Bunk:
      drivers/net/sk98lin/: possible cleanups
      drivers/net/arcnet/: possible cleanups
      drivers/net/s2io.c: make code static
      net/: fix the WIRELESS_EXT abuse
      AIRO{,_CS} <-> CRYPTO fixes
      drivers/net/wireless/ipw2100.c: make ipw2100_wpa_assoc_frame() static
      drivers/net/wireless/ipw2200: possible cleanups
      [netdrvr] schedule eepro100 for removal
      remove obsolete sis900 documentation
      CONFIG_FORCEDETH updates
      chelsio/espi.c:tricn_init(): remove dead code
      drivers/net/e1000/: proper prototypes
      drivers/net/wireless/ipw2200.c: make ipw_qos_current_mode() static
      drivers/net/wireless/ipw2200.c: fix an array overun

Al Viro:
      arcnet probing cleanups and fixes
      ibm_emac sparse annotations
      appletalk/cops.h: missing const in struct ltfirmware
      macsonic.c: missed s/driver_unregister/platform_driver_unregister/
      missing include of asm/irq.h in drivers/net
      bogus include of linux/irq.h in 7990.c
      wrong ifdefs in 82596.c
      dead code removed in hp100

Andreas Happe:
      ipw2200: add monitor and qos entries to Kconfig

Andrew Morton:
      git-netdev-all: s2io fixes
      s2io c99 warning fix

Arjan van de Ven:
      Massive net driver const-ification.

Arnaldo Carvalho de Melo:
      sundance: Really read addr 0

Ayaz Abdulla:
      forcedeth: Add vlan support
      forcedeth: Add support for 64bit rings
      forcedeth: Add support for MSI/MSIX

Bill Moss:
      ipw2200: Add signal level to iwlist scan output

Cahill, Ben M:
      ipw2200: Set a meaningful silence threshold value
      ipw2200: Enables the "slow diversity" algorithm

Catalin(ux aka Dino) BOIE:
      Fix io ordering problems in e100

Dale Farnsworth:
      mv643xx_eth: Remove needless mp->port_mac_addr
      mv643xx_eth: Merge unicast and multicast address filtering code
      mv643xx_eth: Rename mp->tx_ring_skbs to mp->tx_desc_count
      mv643xx_eth: Make port queue enable/disable code consistent
      mv643xx_eth: Clean up platform_data configuration
      mv643xx_eth: Remove duplicate includes of linux/in.h and linux/ip.h
      mv643xx_eth: Fix misplaced parenthesis in mv643xx_eth_port_disable_rx
      mv643xx_eth: Rename "channels" to "queues"
      mv643xx_eth: Select CONFIG_MII on CONFIG_MV643XX_ETH
      mv643xx_eth: Refactor tx command queuing code
      mv643xx_eth: Refactor/clean up tx queue handling
      mv643xx_eth: Move #defines of constants to mv643xx_eth.h
      mv643xx_eth: Clean up interrupt handling
      mv643xx_eth: Remove non-working feature: task level rx queue refill
      mv643xx_eth: Remove BIT0-BIT31 #defines

Dan Williams:
      wireless/airo: add IWENCODEEXT and IWAUTH support
      wireless/ipw2200: support WE-18 WPA enc_capa
      wireless/atmel: convert constants to ieee80211 layer equivalents
      wireless/airo: fix setting TX key index plus key in ENCODEEXT
      wireless/airo: Remove 'Setting transmit key' info messages

Denis Vlasenko:
      WEP fields are incorrectly shown to be INSIDE snap in the doc
      ieee80211: trivial fix for misplaced ()'s

Eric Sesterhenn / snakebyte:
      BUG_ON() Conversion in net/tulip/xircom_cb.c
      BUG_ON() Conversion in net/tulip/de2104x.c
      BUG_ON() Conversion in net/tulip/winbond-840.c

Henrik Brix Andersen:
      ipw2200: print geography code upon module load

Ingo Molnar:
      ipw2100: semaphore to mutexes conversion

James Chapman:
      mv643xx_eth: use MII library for PHY management
      mv643xx_eth: use MII library for ethtool functions

James Ketrenos:
      ipw2200: stop netdev queue if h/w doesn't have space for new packets
      ipw2200: switch to the new ipw2200-fw-3.0 image format
      ieee80211: Don't update network statistics from off-channel packets.

Jan Niehusmann:
      let IPW2{1,2}00 select IEEE80211

Jay Vosburgh:
      bonding: suppress duplicate packets

Jeff Kirsher:
      e1000: Remove Multiqueue code until we have support for MSI-X in our hardware
      e1000: Fix dead counters
      e1000: Fix lock up while setting ring parameters
      e1000: Fix unecessary delay for 82573 controllers
      e1000: Fix AMT losing connectivity when switching VLAN in passive mode
      e1000: Fix dhcp issue when the skb structure fields are not filled properly
      e1000: Fix 82543 issue when reading eeprom
      e1000: Fix RSS if enabled in mid-connection
      e1000: Fix Quadport Wake on LAN
      e1000: Fix network problems when forced at 100Mb/s and to fix TSO when forced at 100Mb/s
      e1000: Fix filling skb descriptors while using packet split
      e1000: Add 82573 controller support to TSO fix
      e1000: Add enabled Jumbo frame support for 82573L
      e1000: Add performance enahancement by balancing TX and RX
      e1000: Add support for new hardware (ESB2)
      e1000: Fixed the following issues with ESB2 (requires ESB2 support):
      e1000: Add copybreak when using packet split
      e1000: Added a performance enhancement - prefetch
      e1000: Added driver comments and whitespace changes.  Modified long lines of code to ensure they would not wrap beyond 80 characters.
      e1000: Fix mii-tool access to setting speed and duplex

Johannes Berg:
      ieee80211: fix sparse warning about missing "static"

Jon Mason:
      trivial: fix spelling errors in Kconfigs

Komuro:
      pcnet_cs: add new id (Logitec LPM-LN100TE)

Larry Finger:
      ieee80211: common wx auth code
      Add two management functions to ieee80211_rx.c
      Remove duplicated code from ipw2200.c

Marcelo Feitoza Parisi:
      drivers/net/*: use time_after() and friends

Mark Brown:
      natsemi: NAPI and a bugfix
      natsemi: NAPI and a bugfix

Olivier Hochreutiner:
      ipw2200: wireless extension sensitivity threshold support

Pekka Enberg:
      3c509: use proper suspend/resume API

Pete Zaitcev:
      ieee80211_geo.c: remove frivolous BUG_ON's

Ralf Baechle:
      sb1250-mac: Add support for the BCM1480
      Sparse: Cleanup sgiseeq sparse warnings.

Ravinandan Arakali:
      S2io: Large Receive Offload (LRO) feature(v2) for Neterion (s2io) 10GbE Xframe PCI-X and PCI-E NICs

Stefan Rompf:
      starfire: Implement suspend/resume
      ipw2200: Fix WPA network selection problem
      ipw2100: add radiotap headers to packtes captured in monitor mode

Zhu Yi:
      ieee80211: Log if netif_rx() drops the packet
      ieee80211: Add LEAP authentication type
      ieee80211: add flags for all geo channels
      ieee80211: Add spectrum management information
      ieee80211: kmalloc+memset -> kzalloc cleanups
      ieee80211: TIM information element parsing
      ieee80211: Add TKIP crypt->build_iv
      ieee80211: Add 802.11h data type and structures
      ieee80211: Add helpers for IBSS DFS handling
      ieee80211: Add 802.11h information element parsing
      ipw2100: Add LEAP authentication algorithm support
      ipw2100: Make iwconfig txpower setting consistent with user input
      ipw2100: Add generic geo information
      ipw2100: remove white space and better format the code
      increase ipw2100 driver version to git-1.1.4
      ipw2200: Fix indirect SRAM/register 8/16-bit write routines
      ipw2200: Mask out the WEP_KEY command dump from debug log for security reason
      ipw2200: Add LEAP authentication algorithm support
      ipw2200: Bluetooth coexistence support
      ipw2200: use jiffies_to_msec() wherever possible
      ipw2200: Make LED blinking frequency independent of HZ
      ipw2200: add module parameter to enable/disable roaming
      ipw2200: Scale firmware loading watchdog with the firmware size
      ipw2200: stack reduction
      ipw2200: Fix qos_cmd param switch bug
      ipw2200: increase ipw2200 driver version
      ipw2200: remove white space and better format the code
      ipw2200: Semaphore to mutexes conversion
      ipw2200: Disable hwcrypto by default
      ieee80211: Use IWEVGENIE to set WPA IE
      ipw2200: Fix software crypto shared WEP authentication problem
      ipw2200: fix a potential NULL pointer dereference
      ipw2200: use generic ieee80211_get_hdrlen() to get packet length
      ipw2200: remove the WPA card associates to non-WPA AP checking
      ipw2200: Fix rf_kill is activated after mode change with 'disable=1'
      ipw2200: Fix ipw_sw_reset() implementation inconsistent with comment
      ipw2200: Filter unsupported channels out in ad-hoc mode
      ipw2200: Change debug level for firmware error logging
      ipw2200: export `debug' module param only if CONFIG_IPW2200_DEBUG
      ipw2200: Update ipw2200 version stamp to 1.1.1
      ipw2x00: expend Copyright to 2006
      ipw2100: Fix radiotap code gcc warning
      ipw2100: move mutex.h include from ipw2100.c to ipw2100.h
      ipw2100: Update version ipw2100 stamp to 1.2.2


^ permalink raw reply	[flat|nested] 101+ messages in thread

* [git patches] net driver updates
@ 2005-09-05 22:47 Jeff Garzik
  0 siblings, 0 replies; 101+ messages in thread
From: Jeff Garzik @ 2005-09-05 22:47 UTC (permalink / raw)
  To: Andrew Morton, Linus Torvalds; +Cc: linux-kernel, netdev


Please pull from the 'upstream' branch of
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/netdev-2.6.git

to obtain the following changes:


 drivers/net/Kconfig                   |    9 
 drivers/net/chelsio/common.h          |    4 
 drivers/net/chelsio/cxgb2.c           |    2 
 drivers/net/e1000/e1000_hw.h          |    2 
 drivers/net/mv643xx_eth.c             |  139 +---
 drivers/net/mv643xx_eth.h             |    4 
 drivers/net/ne3210.c                  |    9 
 drivers/net/phy/Kconfig               |    2 
 drivers/net/phy/mdio_bus.c            |    2 
 drivers/net/s2io.c                    |   14 
 drivers/net/sis190.c                  |  131 ++-
 drivers/net/tulip/uli526x.c           |    2 
 drivers/net/wireless/Kconfig          |   38 -
 drivers/net/wireless/Makefile         |    2 
 drivers/net/wireless/ipw2100.c        |   69 +-
 drivers/net/wireless/ipw2200.h        |    1 
 drivers/net/wireless/orinoco.c        |   93 +-
 drivers/net/wireless/orinoco_cs.c     |    1 
 drivers/net/wireless/orinoco_nortel.c |  324 +++++++++
 drivers/net/wireless/spectrum_cs.c    | 1120 ++++++++++++++++++++++++++++++++++
 net/core/ethtool.c                    |    2 
 21 files changed, 1736 insertions(+), 234 deletions(-)



Adrian Bunk:
  drivers/net/ne3210.c: cleanups

Al Viro:
  (15/22) Kconfig fix (82596)

Dale Farnsworth:
  mv643xx: fix skb memory leak
  mv643xx: fix outstanding tx skb counter
  mv643xx: Disable per port bandwidth limits
  mv643xx: Fix promiscuous mode handling
  mv643xx: add netpoll api support

Francois Romieu:
  sis190: unmask the link change events
  sis190: recent chipsets from SiS include a RGMII
  sis190: make 10Mbps the default when handling the StationControl register
  sis190: RGMII Tx internal delay fiddling
  sis190: basic sis191 support

Pavel Roskin:
  orinoco: Change orinoco_translate_scan() to return error code on error.
  orinoco: Remove entry for Intel PRO/Wireless 2011B.
  orinoco: Fix memory leak on error in processing hostscan frames.
  orinoco: Optimize orinoco_join_ap()
  orinoco: Remove EXPERIMENTAL mark from PLX_HERMES, TMD_HERMES and PCI_HERMES.
  orinoco: New driver - orinoco_nortel.
  orinoco: New driver - spectrum_cs.

Peter Chubb:
  'mdio_bus_exit' in discarded section .text.exit

viro@ftp.linux.org.uk:
  (1/7) chelsio sparse annotations
  (2/7) iomem annotations (e1000)
  (3/7) iomem annotations (s2io)
  (4/7) missing include (uli526x)
  (5/7) iomem annotations, NULL noise removal (ipw2100)
  (6/7) missing include (ipw2200)
  (7/7) __user annotations (ethtool)

viro@ZenIV.linux.org.uk:
  Kconfig fix (PHYLIB vs. s390)




diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -397,7 +397,7 @@ config SUN3LANCE
 	  If you're not building a kernel for a Sun 3, say N.
 
 config SUN3_82586
-	tristate "Sun3 on-board Intel 82586 support"
+	bool "Sun3 on-board Intel 82586 support"
 	depends on NET_ETHERNET && SUN3
 	help
 	  This driver enables support for the on-board Intel 82586 based
@@ -1924,12 +1924,15 @@ config R8169_VLAN
 	  If in doubt, say Y.
 
 config SIS190
-	tristate "SiS190 gigabit ethernet support"
+	tristate "SiS190/SiS191 gigabit ethernet support"
 	depends on PCI
 	select CRC32
 	select MII
 	---help---
-	  Say Y here if you have a SiS 190 PCI Gigabit Ethernet adapter.
+	  Say Y here if you have a SiS 190 PCI Fast Ethernet adapter or
+	  a SiS 191 PCI Gigabit Ethernet adapter. Both are expected to
+	  appear in lan on motherboard designs which are based on SiS 965
+	  and SiS 966 south bridge.
 
 	  To compile this driver as a module, choose M here: the module
 	  will be called sis190.  This is recommended.
diff --git a/drivers/net/chelsio/common.h b/drivers/net/chelsio/common.h
--- a/drivers/net/chelsio/common.h
+++ b/drivers/net/chelsio/common.h
@@ -88,7 +88,7 @@ struct t1_rx_mode {
 
 static inline u8 *t1_get_next_mcaddr(struct t1_rx_mode *rm)
 {
-	u8 *addr = 0;
+	u8 *addr = NULL;
 
 	if (rm->idx++ < rm->dev->mc_count) {
 		addr = rm->list->dmi_addr;
@@ -190,7 +190,7 @@ struct sge;
 struct peespi;
 
 struct adapter {
-	u8 *regs;
+	u8 __iomem *regs;
 	struct pci_dev *pdev;
 	unsigned long registered_device_map;
 	unsigned long open_device_map;
diff --git a/drivers/net/chelsio/cxgb2.c b/drivers/net/chelsio/cxgb2.c
--- a/drivers/net/chelsio/cxgb2.c
+++ b/drivers/net/chelsio/cxgb2.c
@@ -824,7 +824,7 @@ static void cxgb_proc_cleanup(struct ada
 static int t1_ioctl(struct net_device *dev, struct ifreq *req, int cmd)
 {
         struct adapter *adapter = dev->priv;
-        struct mii_ioctl_data *data = (struct mii_ioctl_data *)&req->ifr_data;
+        struct mii_ioctl_data *data = if_mii(req);
 
 	switch (cmd) {
         case SIOCGMIIPHY:
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -1270,7 +1270,7 @@ struct e1000_hw_stats {
 
 /* Structure containing variables used by the shared code (e1000_hw.c) */
 struct e1000_hw {
-    uint8_t *hw_addr;
+    uint8_t __iomem *hw_addr;
     uint8_t *flash_address;
     e1000_mac_type mac_type;
     e1000_phy_type phy_type;
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -58,11 +58,10 @@
 
 #define INT_CAUSE_UNMASK_ALL		0x0007ffff
 #define INT_CAUSE_UNMASK_ALL_EXT	0x0011ffff
-#ifdef MV643XX_RX_QUEUE_FILL_ON_TASK
 #define INT_CAUSE_MASK_ALL		0x00000000
+#define INT_CAUSE_MASK_ALL_EXT		0x00000000
 #define INT_CAUSE_CHECK_BITS		INT_CAUSE_UNMASK_ALL
 #define INT_CAUSE_CHECK_BITS_EXT	INT_CAUSE_UNMASK_ALL_EXT
-#endif
 
 #ifdef MV643XX_CHECKSUM_OFFLOAD_TX
 #define MAX_DESCS_PER_SKB	(MAX_SKB_FRAGS + 1)
@@ -259,14 +258,13 @@ static void mv643xx_eth_update_mac_addre
 static void mv643xx_eth_set_rx_mode(struct net_device *dev)
 {
 	struct mv643xx_private *mp = netdev_priv(dev);
-	u32 config_reg;
 
-	config_reg = ethernet_get_config_reg(mp->port_num);
 	if (dev->flags & IFF_PROMISC)
-		config_reg |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
+		mp->port_config |= (u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
 	else
-		config_reg &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
-	ethernet_set_config_reg(mp->port_num, config_reg);
+		mp->port_config &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE;
+
+	mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), mp->port_config);
 }
 
 /*
@@ -369,15 +367,6 @@ static int mv643xx_eth_free_tx_queue(str
 
 			dev_kfree_skb_irq(pkt_info.return_info);
 			released = 0;
-
-			/*
-			 * Decrement the number of outstanding skbs counter on
-			 * the TX queue.
-			 */
-			if (mp->tx_ring_skbs == 0)
-				panic("ERROR - TX outstanding SKBs"
-						" counter is corrupted");
-			mp->tx_ring_skbs--;
 		} else
 			dma_unmap_page(NULL, pkt_info.buf_ptr,
 					pkt_info.byte_cnt, DMA_TO_DEVICE);
@@ -412,15 +401,13 @@ static int mv643xx_eth_receive_queue(str
 	struct pkt_info pkt_info;
 
 #ifdef MV643XX_NAPI
-	while (eth_port_receive(mp, &pkt_info) == ETH_OK && budget > 0) {
+	while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) {
 #else
 	while (eth_port_receive(mp, &pkt_info) == ETH_OK) {
 #endif
 		mp->rx_ring_skbs--;
 		received_packets++;
-#ifdef MV643XX_NAPI
-		budget--;
-#endif
+
 		/* Update statistics. Note byte count includes 4 byte CRC count */
 		stats->rx_packets++;
 		stats->rx_bytes += pkt_info.byte_cnt;
@@ -1044,9 +1031,6 @@ static void mv643xx_tx(struct net_device
 						DMA_TO_DEVICE);
 
 			dev_kfree_skb_irq(pkt_info.return_info);
-
-			if (mp->tx_ring_skbs)
-				mp->tx_ring_skbs--;
 		} else
 			dma_unmap_page(NULL, pkt_info.buf_ptr,
 					pkt_info.byte_cnt, DMA_TO_DEVICE);
@@ -1189,7 +1173,6 @@ linear:
 		pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
 							DMA_TO_DEVICE);
 		pkt_info.return_info = skb;
-		mp->tx_ring_skbs++;
 		status = eth_port_send(mp, &pkt_info);
 		if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
 			printk(KERN_ERR "%s: Error on transmitting packet\n",
@@ -1274,7 +1257,6 @@ linear:
 				pkt_info.cmd_sts |= ETH_TX_ENABLE_INTERRUPT |
 							ETH_TX_LAST_DESC;
 				pkt_info.return_info = skb;
-				mp->tx_ring_skbs++;
 			} else {
 				pkt_info.return_info = 0;
 			}
@@ -1311,7 +1293,6 @@ linear:
 	pkt_info.buf_ptr = dma_map_single(NULL, skb->data, skb->len,
 								DMA_TO_DEVICE);
 	pkt_info.return_info = skb;
-	mp->tx_ring_skbs++;
 	status = eth_port_send(mp, &pkt_info);
 	if ((status == ETH_ERROR) || (status == ETH_QUEUE_FULL))
 		printk(KERN_ERR "%s: Error on transmitting packet\n",
@@ -1356,6 +1337,43 @@ static struct net_device_stats *mv643xx_
 	return &mp->stats;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static inline void mv643xx_enable_irq(struct mv643xx_private *mp)
+{
+	int port_num = mp->port_num;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mp->lock, flags);
+	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
+					INT_CAUSE_UNMASK_ALL);
+	mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
+					INT_CAUSE_UNMASK_ALL_EXT);
+	spin_unlock_irqrestore(&mp->lock, flags);
+}
+
+static inline void mv643xx_disable_irq(struct mv643xx_private *mp)
+{
+	int port_num = mp->port_num;
+	unsigned long flags;
+
+	spin_lock_irqsave(&mp->lock, flags);
+	mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num),
+					INT_CAUSE_MASK_ALL);
+	mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num),
+					INT_CAUSE_MASK_ALL_EXT);
+	spin_unlock_irqrestore(&mp->lock, flags);
+}
+
+static void mv643xx_netpoll(struct net_device *netdev)
+{
+	struct mv643xx_private *mp = netdev_priv(netdev);
+
+	mv643xx_disable_irq(mp);
+	mv643xx_eth_int_handler(netdev->irq, netdev, NULL);
+	mv643xx_enable_irq(mp);
+}
+#endif
+
 /*/
  * mv643xx_eth_probe
  *
@@ -1406,6 +1424,10 @@ static int mv643xx_eth_probe(struct devi
 	dev->weight = 64;
 #endif
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = mv643xx_netpoll;
+#endif
+
 	dev->watchdog_timeo = 2 * HZ;
 	dev->tx_queue_len = mp->tx_ring_size;
 	dev->base_addr = 0;
@@ -1883,6 +1905,9 @@ static void eth_port_start(struct mv643x
 	/* Enable port Rx. */
 	mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num),
 						mp->port_rx_queue_command);
+
+	/* Disable port bandwidth limits by clearing MTU register */
+	mv_write(MV643XX_ETH_MAXIMUM_TRANSMIT_UNIT(port_num), 0);
 }
 
 /*
@@ -2292,34 +2317,6 @@ static void eth_port_reset(unsigned int 
 	mv_write(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(port_num), reg_data);
 }
 
-/*
- * ethernet_set_config_reg - Set specified bits in configuration register.
- *
- * DESCRIPTION:
- *	This function sets specified bits in the given ethernet
- *	configuration register.
- *
- * INPUT:
- *	unsigned int	eth_port_num	Ethernet Port number.
- *	unsigned int	value		32 bit value.
- *
- * OUTPUT:
- *	The set bits in the value parameter are set in the configuration
- *	register.
- *
- * RETURN:
- *	None.
- *
- */
-static void ethernet_set_config_reg(unsigned int eth_port_num,
-							unsigned int value)
-{
-	unsigned int eth_config_reg;
-
-	eth_config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_REG(eth_port_num));
-	eth_config_reg |= value;
-	mv_write(MV643XX_ETH_PORT_CONFIG_REG(eth_port_num), eth_config_reg);
-}
 
 static int eth_port_autoneg_supported(unsigned int eth_port_num)
 {
@@ -2346,31 +2343,6 @@ static int eth_port_link_is_up(unsigned 
 }
 
 /*
- * ethernet_get_config_reg - Get the port configuration register
- *
- * DESCRIPTION:
- *	This function returns the configuration register value of the given
- *	ethernet port.
- *
- * INPUT:
- *	unsigned int	eth_port_num	Ethernet Port number.
- *
- * OUTPUT:
- *	None.
- *
- * RETURN:
- *	Port configuration register value.
- */
-static unsigned int ethernet_get_config_reg(unsigned int eth_port_num)
-{
-	unsigned int eth_config_reg;
-
-	eth_config_reg = mv_read(MV643XX_ETH_PORT_CONFIG_EXTEND_REG
-								(eth_port_num));
-	return eth_config_reg;
-}
-
-/*
  * eth_port_read_smi_reg - Read PHY registers
  *
  * DESCRIPTION:
@@ -2528,6 +2500,9 @@ static ETH_FUNC_RET_STATUS eth_port_send
 		return ETH_ERROR;
 	}
 
+	mp->tx_ring_skbs++;
+	BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
+
 	/* Get the Tx Desc ring indexes */
 	tx_desc_curr = mp->tx_curr_desc_q;
 	tx_desc_used = mp->tx_used_desc_q;
@@ -2594,6 +2569,9 @@ static ETH_FUNC_RET_STATUS eth_port_send
 	if (mp->tx_resource_err)
 		return ETH_QUEUE_FULL;
 
+	mp->tx_ring_skbs++;
+	BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size);
+
 	/* Get the Tx Desc ring indexes */
 	tx_desc_curr = mp->tx_curr_desc_q;
 	tx_desc_used = mp->tx_used_desc_q;
@@ -2694,6 +2672,9 @@ static ETH_FUNC_RET_STATUS eth_tx_return
 	/* Any Tx return cancels the Tx resource error status */
 	mp->tx_resource_err = 0;
 
+	BUG_ON(mp->tx_ring_skbs == 0);
+	mp->tx_ring_skbs--;
+
 	return ETH_OK;
 }
 
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h
--- a/drivers/net/mv643xx_eth.h
+++ b/drivers/net/mv643xx_eth.h
@@ -408,10 +408,6 @@ static void eth_port_init(struct mv643xx
 static void eth_port_reset(unsigned int eth_port_num);
 static void eth_port_start(struct mv643xx_private *mp);
 
-static void ethernet_set_config_reg(unsigned int eth_port_num,
-				    unsigned int value);
-static unsigned int ethernet_get_config_reg(unsigned int eth_port_num);
-
 /* Port MAC address routines */
 static void eth_port_uc_addr_set(unsigned int eth_port_num,
 				 unsigned char *p_addr);
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
--- a/drivers/net/ne3210.c
+++ b/drivers/net/ne3210.c
@@ -26,9 +26,6 @@
 	Updated to EISA probing API 5/2003 by Marc Zyngier.
 */
 
-static const char *version =
-	"ne3210.c: Driver revision v0.03, 30/09/98\n";
-
 #include <linux/module.h>
 #include <linux/eisa.h>
 #include <linux/kernel.h>
@@ -197,7 +194,7 @@ static int __init ne3210_eisa_probe (str
 	ei_status.priv = phys_mem;
 
 	if (ei_debug > 0)
-		printk(version);
+		printk("ne3210 loaded.\n");
 
 	ei_status.reset_8390 = &ne3210_reset_8390;
 	ei_status.block_input = &ne3210_block_input;
@@ -360,12 +357,12 @@ MODULE_DESCRIPTION("NE3210 EISA Ethernet
 MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(eisa, ne3210_ids);
 
-int ne3210_init(void)
+static int ne3210_init(void)
 {
 	return eisa_driver_register (&ne3210_eisa_driver);
 }
 
-void ne3210_cleanup(void)
+static void ne3210_cleanup(void)
 {
 	eisa_driver_unregister (&ne3210_eisa_driver);
 }
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig
--- a/drivers/net/phy/Kconfig
+++ b/drivers/net/phy/Kconfig
@@ -6,7 +6,7 @@ menu "PHY device support"
 
 config PHYLIB
 	tristate "PHY Device support and infrastructure"
-	depends on NET_ETHERNET
+	depends on NET_ETHERNET && (BROKEN || !ARCH_S390)
 	help
 	  Ethernet controllers are usually attached to PHY
 	  devices.  This option provides infrastructure for
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -170,7 +170,7 @@ int __init mdio_bus_init(void)
 	return bus_register(&mdio_bus_type);
 }
 
-void __exit mdio_bus_exit(void)
+void mdio_bus_exit(void)
 {
 	bus_unregister(&mdio_bus_type);
 }
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -686,7 +686,7 @@ static void free_shared_mem(struct s2io_
 
 static int s2io_verify_pci_mode(nic_t *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0;
 	int     mode;
 
@@ -704,7 +704,7 @@ static int s2io_verify_pci_mode(nic_t *n
  */
 static int s2io_print_pci_mode(nic_t *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	register u64 val64 = 0;
 	int	mode;
 	struct config_param *config = &nic->config;
@@ -1403,7 +1403,7 @@ static int init_nic(struct s2io_nic *nic
 	writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7);
 
 	/* Disable RMAC PAD STRIPPING */
-	add = (void *) &bar0->mac_cfg;
+	add = &bar0->mac_cfg;
 	val64 = readq(&bar0->mac_cfg);
 	val64 &= ~(MAC_CFG_RMAC_STRIP_PAD);
 	writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key);
@@ -1934,7 +1934,7 @@ static int start_nic(struct s2io_nic *ni
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *)bar0 + 0x2700);
 	}
 
 	/*
@@ -2395,7 +2395,7 @@ static int s2io_poll(struct net_device *
 	int pkt_cnt = 0, org_pkts_to_process;
 	mac_info_t *mac_control;
 	struct config_param *config;
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u64 val64;
 	int i;
 
@@ -2831,7 +2831,7 @@ void s2io_reset(nic_t * sp)
 		val64 |= 0x0000800000000000ULL;
 		writeq(val64, &bar0->gpio_control);
 		val64 = 0x0411040400000000ULL;
-		writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700));
+		writeq(val64, (void __iomem *)bar0 + 0x2700);
 	}
 
 	/*
@@ -3234,7 +3234,7 @@ s2io_alarm_handle(unsigned long data)
 
 static void s2io_txpic_intr_handle(nic_t *sp)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0;
+	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
 
 	val64 = readq(&bar0->pic_int_status);
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -179,14 +179,6 @@ enum sis190_register_content {
 	TxInterFrameGapShift	= 24,
 	TxDMAShift		= 8, /* DMA burst value (0-7) is shift this many bits */
 
-	/* StationControl */
-	_1000bpsF		= 0x1c00,
-	_1000bpsH		= 0x0c00,
-	_100bpsF		= 0x1800,
-	_100bpsH		= 0x0800,
-	_10bpsF			= 0x1400,
-	_10bpsH			= 0x0400,
-
 	LinkStatus		= 0x02,		// unused
 	FullDup			= 0x01,		// unused
 
@@ -279,6 +271,12 @@ enum sis190_eeprom_address {
 	EEPROMMACAddr	= 0x03
 };
 
+enum sis190_feature {
+	F_HAS_RGMII	= 1,
+	F_PHY_88E1111	= 2,
+	F_PHY_BCM5461	= 4
+};
+
 struct sis190_private {
 	void __iomem *mmio_addr;
 	struct pci_dev *pci_dev;
@@ -300,6 +298,7 @@ struct sis190_private {
 	u32 msg_enable;
 	struct mii_if_info mii_if;
 	struct list_head first_phy;
+	u32 features;
 };
 
 struct sis190_phy {
@@ -321,24 +320,25 @@ static struct mii_chip_info {
         const char *name;
         u16 id[2];
         unsigned int type;
+	u32 feature;
 } mii_chip_table[] = {
-	{ "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN },
-	{ "Agere PHY ET1101B",    { 0x0282, 0xf010 }, LAN },
-	{ "Marvell PHY 88E1111",  { 0x0141, 0x0cc0 }, LAN },
-	{ "Realtek PHY RTL8201",  { 0x0000, 0x8200 }, LAN },
+	{ "Broadcom PHY BCM5461", { 0x0020, 0x60c0 }, LAN, F_PHY_BCM5461 },
+	{ "Agere PHY ET1101B",    { 0x0282, 0xf010 }, LAN, 0 },
+	{ "Marvell PHY 88E1111",  { 0x0141, 0x0cc0 }, LAN, F_PHY_88E1111 },
+	{ "Realtek PHY RTL8201",  { 0x0000, 0x8200 }, LAN, 0 },
 	{ NULL, }
 };
 
 const static struct {
 	const char *name;
-	u8 version;		/* depend on docs */
-	u32 RxConfigMask;	/* clear the bits supported by this chip */
 } sis_chip_info[] = {
-	{ DRV_NAME, 0x00, 0xff7e1880, },
+	{ "SiS 190 PCI Fast Ethernet adapter" },
+	{ "SiS 191 PCI Gigabit Ethernet adapter" },
 };
 
 static struct pci_device_id sis190_pci_tbl[] __devinitdata = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0190), 0, 0, 0 },
+	{ PCI_DEVICE(PCI_VENDOR_ID_SI, 0x0191), 0, 0, 1 },
 	{ 0, },
 };
 
@@ -360,7 +360,7 @@ MODULE_VERSION(DRV_VERSION);
 MODULE_LICENSE("GPL");
 
 static const u32 sis190_intr_mask =
-	RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt;
+	RxQEmpty | RxQInt | TxQ1Int | TxQ0Int | RxHalt | TxHalt | LinkChange;
 
 /*
  * Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
@@ -879,11 +879,6 @@ static void sis190_hw_start(struct net_d
 
 	SIS_W32(IntrStatus, 0xffffffff);
 	SIS_W32(IntrMask, 0x0);
-	/*
-	 * Default is 100Mbps.
-	 * A bit strange: 100Mbps is 0x1801 elsewhere -- FR 2005/06/09
-	 */
-	SIS_W16(StationControl, 0x1901);
 	SIS_W32(GMIIControl, 0x0);
 	SIS_W32(TxMacControl, 0x60);
 	SIS_W16(RxMacControl, 0x02);
@@ -923,35 +918,30 @@ static void sis190_phy_task(void * data)
 		     BMSR_ANEGCOMPLETE)) {
 		net_link(tp, KERN_WARNING "%s: PHY reset until link up.\n",
 			 dev->name);
+		netif_carrier_off(dev);
 		mdio_write(ioaddr, phy_id, MII_BMCR, val | BMCR_RESET);
 		mod_timer(&tp->timer, jiffies + SIS190_PHY_TIMEOUT);
 	} else {
 		/* Rejoice ! */
 		struct {
 			int val;
+			u32 ctl;
 			const char *msg;
-			u16 ctl;
 		} reg31[] = {
-			{ LPA_1000XFULL | LPA_SLCT,
-				"1000 Mbps Full Duplex",
-				0x01 | _1000bpsF },
-			{ LPA_1000XHALF | LPA_SLCT,
-				"1000 Mbps Half Duplex",
-				0x01 | _1000bpsH },
-			{ LPA_100FULL,
-				"100 Mbps Full Duplex",
-				0x01 | _100bpsF },
-			{ LPA_100HALF,
-				"100 Mbps Half Duplex",
-				0x01 | _100bpsH },
-			{ LPA_10FULL,
-				"10 Mbps Full Duplex",
-				0x01 | _10bpsF },
-			{ LPA_10HALF,
-				"10 Mbps Half Duplex",
-				0x01 | _10bpsH },
-			{ 0, "unknown", 0x0000 }
-		}, *p;
+			{ LPA_1000XFULL | LPA_SLCT, 0x07000c00 | 0x00001000,
+				"1000 Mbps Full Duplex" },
+			{ LPA_1000XHALF | LPA_SLCT, 0x07000c00,
+				"1000 Mbps Half Duplex" },
+			{ LPA_100FULL, 0x04000800 | 0x00001000,
+				"100 Mbps Full Duplex" },
+			{ LPA_100HALF, 0x04000800,
+				"100 Mbps Half Duplex" },
+			{ LPA_10FULL, 0x04000400 | 0x00001000,
+				"10 Mbps Full Duplex" },
+			{ LPA_10HALF, 0x04000400,
+				"10 Mbps Half Duplex" },
+			{ 0, 0x04000400, "unknown" }
+ 		}, *p;
 		u16 adv;
 
 		val = mdio_read(ioaddr, phy_id, 0x1f);
@@ -964,12 +954,29 @@ static void sis190_phy_task(void * data)
 
 		val &= adv;
 
-		for (p = reg31; p->ctl; p++) {
+		for (p = reg31; p->val; p++) {
 			if ((val & p->val) == p->val)
 				break;
 		}
-		if (p->ctl)
-			SIS_W16(StationControl, p->ctl);
+
+		p->ctl |= SIS_R32(StationControl) & ~0x0f001c00;
+
+		if ((tp->features & F_HAS_RGMII) &&
+		    (tp->features & F_PHY_BCM5461)) {
+			// Set Tx Delay in RGMII mode.
+			mdio_write(ioaddr, phy_id, 0x18, 0xf1c7);
+			udelay(200);
+			mdio_write(ioaddr, phy_id, 0x1c, 0x8c00);
+			p->ctl |= 0x03000000;
+		}
+
+		SIS_W32(StationControl, p->ctl);
+
+		if (tp->features & F_HAS_RGMII) {
+			SIS_W32(RGDelay, 0x0441);
+			SIS_W32(RGDelay, 0x0440);
+		}
+
 		net_link(tp, KERN_INFO "%s: link on %s mode.\n", dev->name,
 			 p->msg);
 		netif_carrier_on(dev);
@@ -1308,6 +1315,7 @@ static void sis190_init_phy(struct net_d
 		phy->type = (p->type == MIX) ?
 			((mii_status & (BMSR_100FULL | BMSR_100HALF)) ?
 				LAN : HOME) : p->type;
+		tp->features |= p->feature;
 	} else
 		phy->type = UNKNOWN;
 
@@ -1316,6 +1324,25 @@ static void sis190_init_phy(struct net_d
 		  (phy->type == UNKNOWN) ? "Unknown PHY" : p->name, phy_id);
 }
 
+static void sis190_mii_probe_88e1111_fixup(struct sis190_private *tp)
+{
+	if (tp->features & F_PHY_88E1111) {
+		void __iomem *ioaddr = tp->mmio_addr;
+		int phy_id = tp->mii_if.phy_id;
+		u16 reg[2][2] = {
+			{ 0x808b, 0x0ce1 },
+			{ 0x808f, 0x0c60 }
+		}, *p;
+
+		p = (tp->features & F_HAS_RGMII) ? reg[0] : reg[1];
+
+		mdio_write(ioaddr, phy_id, 0x1b, p[0]);
+		udelay(200);
+		mdio_write(ioaddr, phy_id, 0x14, p[1]);
+		udelay(200);
+	}
+}
+
 /**
  *	sis190_mii_probe - Probe MII PHY for sis190
  *	@dev: the net device to probe for
@@ -1366,6 +1393,8 @@ static int __devinit sis190_mii_probe(st
 	/* Select default PHY for mac */
 	sis190_default_phy(dev);
 
+	sis190_mii_probe_88e1111_fixup(tp);
+
 	mii_if->dev = dev;
 	mii_if->mdio_read = __mdio_read;
 	mii_if->mdio_write = __mdio_write;
@@ -1505,6 +1534,11 @@ static void sis190_tx_timeout(struct net
 	netif_wake_queue(dev);
 }
 
+static void sis190_set_rgmii(struct sis190_private *tp, u8 reg)
+{
+	tp->features |= (reg & 0x80) ? F_HAS_RGMII : 0;
+}
+
 static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
 						     struct net_device *dev)
 {
@@ -1532,6 +1566,8 @@ static int __devinit sis190_get_mac_addr
 		((u16 *)dev->dev_addr)[0] = le16_to_cpu(w);
 	}
 
+	sis190_set_rgmii(tp, sis190_read_eeprom(ioaddr, EEPROMInfo));
+
 	return 0;
 }
 
@@ -1577,6 +1613,8 @@ static int __devinit sis190_get_mac_addr
 	outb(0x12, 0x78);
 	reg = inb(0x79);
 
+	sis190_set_rgmii(tp, reg);
+
 	/* Restore the value to ISA Bridge */
 	pci_write_config_byte(isa_bridge, 0x48, tmp8);
 	pci_dev_put(isa_bridge);
@@ -1799,6 +1837,9 @@ static int __devinit sis190_init_one(str
 	       dev->dev_addr[2], dev->dev_addr[3],
 	       dev->dev_addr[4], dev->dev_addr[5]);
 
+	net_probe(tp, KERN_INFO "%s: %s mode.\n", dev->name,
+		  (tp->features & F_HAS_RGMII) ? "RGMII" : "GMII");
+
 	netif_carrier_off(dev);
 
 	sis190_set_speed_auto(dev);
diff --git a/drivers/net/tulip/uli526x.c b/drivers/net/tulip/uli526x.c
--- a/drivers/net/tulip/uli526x.c
+++ b/drivers/net/tulip/uli526x.c
@@ -21,7 +21,6 @@
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/timer.h>
-#include <linux/ptrace.h>
 #include <linux/errno.h>
 #include <linux/ioport.h>
 #include <linux/slab.h>
@@ -34,6 +33,7 @@
 #include <linux/skbuff.h>
 #include <linux/delay.h>
 #include <linux/spinlock.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/processor.h>
 #include <asm/bitops.h>
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -289,8 +289,8 @@ config APPLE_AIRPORT
 	  a non-standard interface
 
 config PLX_HERMES
-	tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.) (EXPERIMENTAL)"
-	depends on PCI && HERMES && EXPERIMENTAL
+	tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)"
+	depends on PCI && HERMES
 	help
 	  Enable support for PCMCIA cards supported by the "Hermes" (aka
 	  orinoco) driver when used in PLX9052 based PCI adaptors.  These
@@ -299,12 +299,9 @@ config PLX_HERMES
 	  802.11b PCMCIA cards can be used in desktop machines.  The Netgear
 	  MA301 is such an adaptor.
 
-	  Support for these adaptors is so far still incomplete and buggy.
-	  You have been warned.
-
 config TMD_HERMES
-	tristate "Hermes in TMD7160 based PCI adaptor support (EXPERIMENTAL)"
-	depends on PCI && HERMES && EXPERIMENTAL
+	tristate "Hermes in TMD7160 based PCI adaptor support"
+	depends on PCI && HERMES
 	help
 	  Enable support for PCMCIA cards supported by the "Hermes" (aka
 	  orinoco) driver when used in TMD7160 based PCI adaptors.  These
@@ -312,12 +309,18 @@ config TMD_HERMES
 	  PCI <-> PCMCIA bridge.  Several vendors sell such adaptors so that
 	  802.11b PCMCIA cards can be used in desktop machines.
 
-	  Support for these adaptors is so far still incomplete and buggy.
-	  You have been warned.
+config NORTEL_HERMES
+	tristate "Nortel emobility PCI adaptor support"
+	depends on PCI && HERMES
+	help
+	  Enable support for PCMCIA cards supported by the "Hermes" (aka
+	  orinoco) driver when used in Nortel emobility PCI adaptors.  These
+	  adaptors are not full PCMCIA controllers, but act as a more limited
+	  PCI <-> PCMCIA bridge.
 
 config PCI_HERMES
-	tristate "Prism 2.5 PCI 802.11b adaptor support (EXPERIMENTAL)"
-	depends on PCI && HERMES && EXPERIMENTAL
+	tristate "Prism 2.5 PCI 802.11b adaptor support"
+	depends on PCI && HERMES
 	help
 	  Enable support for PCI and mini-PCI 802.11b wireless NICs based on
 	  the Prism 2.5 chipset.  These are true PCI cards, not the 802.11b
@@ -372,6 +375,19 @@ config PCMCIA_HERMES
 	  configure your card and that /etc/pcmcia/wireless.opts works:
 	  <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>.
 
+config PCMCIA_SPECTRUM
+	tristate "Symbol Spectrum24 Trilogy PCMCIA card support"
+	depends on NET_RADIO && PCMCIA && HERMES
+	---help---
+
+	  This is a driver for 802.11b cards using RAM-loadable Symbol
+	  firmware, such as Symbol Wireless Networker LA4100, CompactFlash
+	  cards by Socket Communications and Intel PRO/Wireless 2011B.
+
+	  This driver requires firmware download on startup.  Utilities
+	  for downloading Symbol firmware are available at
+	  <http://sourceforge.net/projects/orinoco/>
+
 config AIRO_CS
 	tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards"
 	depends on NET_RADIO && PCMCIA && (BROKEN || !M32R)
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -22,6 +22,8 @@ obj-$(CONFIG_APPLE_AIRPORT)	+= airport.o
 obj-$(CONFIG_PLX_HERMES)	+= orinoco_plx.o
 obj-$(CONFIG_PCI_HERMES)	+= orinoco_pci.o
 obj-$(CONFIG_TMD_HERMES)	+= orinoco_tmd.o
+obj-$(CONFIG_NORTEL_HERMES)	+= orinoco_nortel.o
+obj-$(CONFIG_PCMCIA_SPECTRUM)	+= spectrum_cs.o
 
 obj-$(CONFIG_AIRO)		+= airo.o
 obj-$(CONFIG_AIRO_CS)		+= airo_cs.o airo.o
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -327,38 +327,38 @@ static struct iw_handler_def ipw2100_wx_
 
 static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
 {
-	*val = readl((void *)(dev->base_addr + reg));
+	*val = readl((void __iomem *)(dev->base_addr + reg));
 	IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
 }
 
 static inline void write_register(struct net_device *dev, u32 reg, u32 val)
 {
-	writel(val, (void *)(dev->base_addr + reg));
+	writel(val, (void __iomem *)(dev->base_addr + reg));
 	IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
 }
 
 static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val)
 {
-	*val = readw((void *)(dev->base_addr + reg));
+	*val = readw((void __iomem *)(dev->base_addr + reg));
 	IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
 }
 
 static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val)
 {
-	*val = readb((void *)(dev->base_addr + reg));
+	*val = readb((void __iomem *)(dev->base_addr + reg));
 	IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
 }
 
 static inline void write_register_word(struct net_device *dev, u32 reg, u16 val)
 {
-	writew(val, (void *)(dev->base_addr + reg));
+	writew(val, (void __iomem *)(dev->base_addr + reg));
 	IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
 }
 
 
 static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
 {
-	writeb(val, (void *)(dev->base_addr + reg));
+	writeb(val, (void __iomem *)(dev->base_addr + reg));
 	IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
 }
 
@@ -498,7 +498,7 @@ static inline void read_nic_memory(struc
 static inline int ipw2100_hw_is_adapter_in_system(struct net_device *dev)
 {
 	return (dev->base_addr &&
-		(readl((void *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START))
+		(readl((void __iomem *)(dev->base_addr + IPW_REG_DOA_DEBUG_AREA_START))
 		 == IPW_DATA_DOA_DEBUG_VALUE));
 }
 
@@ -2125,19 +2125,19 @@ static void isr_indicate_scanning(struct
 }
 
 static const struct ipw2100_status_indicator status_handlers[] = {
-	IPW2100_HANDLER(IPW_STATE_INITIALIZED, 0),
-	IPW2100_HANDLER(IPW_STATE_COUNTRY_FOUND, 0),
+	IPW2100_HANDLER(IPW_STATE_INITIALIZED, NULL),
+	IPW2100_HANDLER(IPW_STATE_COUNTRY_FOUND, NULL),
 	IPW2100_HANDLER(IPW_STATE_ASSOCIATED, isr_indicate_associated),
 	IPW2100_HANDLER(IPW_STATE_ASSN_LOST, isr_indicate_association_lost),
-	IPW2100_HANDLER(IPW_STATE_ASSN_CHANGED, 0),
+	IPW2100_HANDLER(IPW_STATE_ASSN_CHANGED, NULL),
 	IPW2100_HANDLER(IPW_STATE_SCAN_COMPLETE, isr_scan_complete),
-	IPW2100_HANDLER(IPW_STATE_ENTERED_PSP, 0),
-	IPW2100_HANDLER(IPW_STATE_LEFT_PSP, 0),
+	IPW2100_HANDLER(IPW_STATE_ENTERED_PSP, NULL),
+	IPW2100_HANDLER(IPW_STATE_LEFT_PSP, NULL),
 	IPW2100_HANDLER(IPW_STATE_RF_KILL, isr_indicate_rf_kill),
-	IPW2100_HANDLER(IPW_STATE_DISABLED, 0),
-	IPW2100_HANDLER(IPW_STATE_POWER_DOWN, 0),
+	IPW2100_HANDLER(IPW_STATE_DISABLED, NULL),
+	IPW2100_HANDLER(IPW_STATE_POWER_DOWN, NULL),
 	IPW2100_HANDLER(IPW_STATE_SCANNING, isr_indicate_scanning),
-	IPW2100_HANDLER(-1, 0)
+	IPW2100_HANDLER(-1, NULL)
 };
 
 
@@ -6327,7 +6327,7 @@ static void ipw2100_irq_tasklet(struct i
 
 static struct net_device *ipw2100_alloc_device(
 	struct pci_dev *pci_dev,
-	char *base_addr,
+	void __iomem *base_addr,
 	unsigned long mem_start,
 	unsigned long mem_len)
 {
@@ -6474,7 +6474,7 @@ static int ipw2100_pci_init_one(struct p
 				const struct pci_device_id *ent)
 {
 	unsigned long mem_start, mem_len, mem_flags;
-	char *base_addr = NULL;
+	void __iomem *base_addr = NULL;
 	struct net_device *dev = NULL;
 	struct ipw2100_priv *priv = NULL;
 	int err = 0;
@@ -6664,7 +6664,7 @@ static int ipw2100_pci_init_one(struct p
 	}
 
 	if (base_addr)
-		iounmap((char*)base_addr);
+		iounmap(base_addr);
 
 	pci_release_regions(pci_dev);
 	pci_disable_device(pci_dev);
@@ -6714,7 +6714,7 @@ static void __devexit ipw2100_pci_remove
 			free_irq(dev->irq, priv);
 
 		if (dev->base_addr)
-			iounmap((unsigned char *)dev->base_addr);
+			iounmap((void __iomem *)dev->base_addr);
 
 		free_ieee80211(dev);
 	}
@@ -8574,6 +8574,7 @@ static int ipw2100_ucode_download(struct
 	struct net_device *dev = priv->net_dev;
 	const unsigned char *microcode_data = fw->uc.data;
 	unsigned int microcode_data_left = fw->uc.size;
+	void __iomem *reg = (void __iomem *)dev->base_addr;
 
 	struct symbol_alive_response response;
 	int i, j;
@@ -8581,23 +8582,23 @@ static int ipw2100_ucode_download(struct
 
 	/* Symbol control */
 	write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
-	readl((void *)(dev->base_addr));
+	readl(reg);
 	write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
-	readl((void *)(dev->base_addr));
+	readl(reg);
 
 	/* HW config */
 	write_nic_byte(dev, 0x210014, 0x72);	/* fifo width =16 */
-	readl((void *)(dev->base_addr));
+	readl(reg);
 	write_nic_byte(dev, 0x210014, 0x72);	/* fifo width =16 */
-	readl((void *)(dev->base_addr));
+	readl(reg);
 
 	/* EN_CS_ACCESS bit to reset control store pointer */
 	write_nic_byte(dev, 0x210000, 0x40);
-	readl((void *)(dev->base_addr));
+	readl(reg);
 	write_nic_byte(dev, 0x210000, 0x0);
-	readl((void *)(dev->base_addr));
+	readl(reg);
 	write_nic_byte(dev, 0x210000, 0x40);
-	readl((void *)(dev->base_addr));
+	readl(reg);
 
 	/* copy microcode from buffer into Symbol */
 
@@ -8609,31 +8610,31 @@ static int ipw2100_ucode_download(struct
 
 	/* EN_CS_ACCESS bit to reset the control store pointer */
 	write_nic_byte(dev, 0x210000, 0x0);
-	readl((void *)(dev->base_addr));
+	readl(reg);
 
 	/* Enable System (Reg 0)
 	 * first enable causes garbage in RX FIFO */
 	write_nic_byte(dev, 0x210000, 0x0);
-	readl((void *)(dev->base_addr));
+	readl(reg);
 	write_nic_byte(dev, 0x210000, 0x80);
-	readl((void *)(dev->base_addr));
+	readl(reg);
 
 	/* Reset External Baseband Reg */
 	write_nic_word(dev, IPW2100_CONTROL_REG, 0x703);
-	readl((void *)(dev->base_addr));
+	readl(reg);
 	write_nic_word(dev, IPW2100_CONTROL_REG, 0x707);
-	readl((void *)(dev->base_addr));
+	readl(reg);
 
 	/* HW Config (Reg 5) */
 	write_nic_byte(dev, 0x210014, 0x72);	// fifo width =16
-	readl((void *)(dev->base_addr));
+	readl(reg);
 	write_nic_byte(dev, 0x210014, 0x72);	// fifo width =16
-	readl((void *)(dev->base_addr));
+	readl(reg);
 
 	/* Enable System (Reg 0)
 	 * second enable should be OK */
 	write_nic_byte(dev, 0x210000, 0x00);	// clear enable system
-	readl((void *)(dev->base_addr));
+	readl(reg);
 	write_nic_byte(dev, 0x210000, 0x80);	// set enable system
 
 	/* check Symbol is enabled - upped this from 5 as it wasn't always
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -42,6 +42,7 @@
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
 #include <linux/random.h>
+#include <linux/dma-mapping.h>
 
 #include <linux/firmware.h>
 #include <linux/wireless.h>
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -1053,8 +1053,9 @@ static void orinoco_join_ap(struct net_d
 		u16 channel;
 	} __attribute__ ((packed)) req;
 	const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
-	struct prism2_scan_apinfo *atom;
+	struct prism2_scan_apinfo *atom = NULL;
 	int offset = 4;
+	int found = 0;
 	u8 *buf;
 	u16 len;
 
@@ -1089,15 +1090,18 @@ static void orinoco_join_ap(struct net_d
 	 * we were requested to join */
 	for (; offset + atom_len <= len; offset += atom_len) {
 		atom = (struct prism2_scan_apinfo *) (buf + offset);
-		if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0)
-			goto found;
+		if (memcmp(&atom->bssid, priv->desired_bssid, ETH_ALEN) == 0) {
+			found = 1;
+			break;
+		}
 	}
 
-	DEBUG(1, "%s: Requested AP not found in scan results\n",
-	      dev->name);
-	goto out;
+	if (! found) {
+		DEBUG(1, "%s: Requested AP not found in scan results\n",
+		      dev->name);
+		goto out;
+	}
 
- found:
 	memcpy(req.bssid, priv->desired_bssid, ETH_ALEN);
 	req.channel = atom->channel;	/* both are little-endian */
 	err = HERMES_WRITE_RECORD(hw, USER_BAP, HERMES_RID_CNFJOINREQUEST,
@@ -1284,8 +1288,10 @@ static void __orinoco_ev_info(struct net
 		/* Read scan data */
 		err = hermes_bap_pread(hw, IRQ_BAP, (void *) buf, len,
 				       infofid, sizeof(info));
-		if (err)
+		if (err) {
+			kfree(buf);
 			break;
+		}
 
 #ifdef ORINOCO_DEBUG
 		{
@@ -4021,7 +4027,8 @@ static int orinoco_ioctl_setscan(struct 
 }
 
 /* Translate scan data returned from the card to a card independant
- * format that the Wireless Tools will understand - Jean II */
+ * format that the Wireless Tools will understand - Jean II
+ * Return message length or -errno for fatal errors */
 static inline int orinoco_translate_scan(struct net_device *dev,
 					 char *buffer,
 					 char *scan,
@@ -4061,13 +4068,19 @@ static inline int orinoco_translate_scan
 		break;
 	case FIRMWARE_TYPE_INTERSIL:
 		offset = 4;
-		if (priv->has_hostscan)
-			atom_len = scan[0] + (scan[1] << 8);
-		else
+		if (priv->has_hostscan) {
+			atom_len = le16_to_cpup((u16 *)scan);
+			/* Sanity check for atom_len */
+			if (atom_len < sizeof(struct prism2_scan_apinfo)) {
+				printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
+				dev->name, atom_len);
+				return -EIO;
+			}
+		} else
 			atom_len = offsetof(struct prism2_scan_apinfo, atim);
 		break;
 	default:
-		return 0;
+		return -EOPNOTSUPP;
 	}
 
 	/* Check that we got an whole number of atoms */
@@ -4075,7 +4088,7 @@ static inline int orinoco_translate_scan
 		printk(KERN_ERR "%s: Unexpected scan data length %d, "
 		       "atom_len %d, offset %d\n", dev->name, scan_len,
 		       atom_len, offset);
-		return 0;
+		return -EIO;
 	}
 
 	/* Read the entries one by one */
@@ -4210,33 +4223,41 @@ static int orinoco_ioctl_getscan(struct 
 		/* We have some results to push back to user space */
 
 		/* Translate to WE format */
-		srq->length = orinoco_translate_scan(dev, extra,
-						     priv->scan_result,
-						     priv->scan_len);
-
-		/* Return flags */
-		srq->flags = (__u16) priv->scan_mode;
+		int ret = orinoco_translate_scan(dev, extra,
+						 priv->scan_result,
+						 priv->scan_len);
+
+		if (ret < 0) {
+			err = ret;
+			kfree(priv->scan_result);
+			priv->scan_result = NULL;
+		} else {
+			srq->length = ret;
 
-		/* Results are here, so scan no longer in progress */
-		priv->scan_inprogress = 0;
+			/* Return flags */
+			srq->flags = (__u16) priv->scan_mode;
 
-		/* In any case, Scan results will be cleaned up in the
-		 * reset function and when exiting the driver.
-		 * The person triggering the scanning may never come to
-		 * pick the results, so we need to do it in those places.
-		 * Jean II */
+			/* In any case, Scan results will be cleaned up in the
+			 * reset function and when exiting the driver.
+			 * The person triggering the scanning may never come to
+			 * pick the results, so we need to do it in those places.
+			 * Jean II */
 
 #ifdef SCAN_SINGLE_READ
-		/* If you enable this option, only one client (the first
-		 * one) will be able to read the result (and only one
-		 * time). If there is multiple concurent clients that
-		 * want to read scan results, this behavior is not
-		 * advisable - Jean II */
-		kfree(priv->scan_result);
-		priv->scan_result = NULL;
+			/* If you enable this option, only one client (the first
+			 * one) will be able to read the result (and only one
+			 * time). If there is multiple concurent clients that
+			 * want to read scan results, this behavior is not
+			 * advisable - Jean II */
+			kfree(priv->scan_result);
+			priv->scan_result = NULL;
 #endif /* SCAN_SINGLE_READ */
-		/* Here, if too much time has elapsed since last scan,
-		 * we may want to clean up scan results... - Jean II */
+			/* Here, if too much time has elapsed since last scan,
+			 * we may want to clean up scan results... - Jean II */
+		}
+
+		/* Scan is no longer in progress */
+		priv->scan_inprogress = 0;
 	}
 	  
 	orinoco_unlock(priv, &flags);
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -604,7 +604,6 @@ static char version[] __initdata = DRIVE
 
 static struct pcmcia_device_id orinoco_cs_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
-	PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001),
 	PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
 	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
 	PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a),
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
new file mode 100644
--- /dev/null
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -0,0 +1,324 @@
+/* orinoco_nortel.c
+ * 
+ * Driver for Prism II devices which would usually be driven by orinoco_cs,
+ * but are connected to the PCI bus by a Nortel PCI-PCMCIA-Adapter. 
+ *
+ * Copyright (C) 2002 Tobias Hoffmann
+ *           (C) 2003 Christoph Jungegger <disdos@traum404.de>
+ *
+ * Some of this code is borrowed from orinoco_plx.c
+ *	Copyright (C) 2001 Daniel Barlow
+ * Some of this code is borrowed from orinoco_pci.c 
+ *  Copyright (C) 2001 Jean Tourrilhes
+ * Some of this code is "inspired" by linux-wlan-ng-0.1.10, but nothing
+ * has been copied from it. linux-wlan-ng-0.1.10 is originally :
+ *	Copyright (C) 1999 AbsoluteValue Systems, Inc.  All Rights Reserved.
+ * 
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License
+ * at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and
+ * limitations under the License.
+ *
+ * Alternatively, the contents of this file may be used under the
+ * terms of the GNU General Public License version 2 (the "GPL"), in
+ * which case the provisions of the GPL are applicable instead of the
+ * above.  If you wish to allow the use of your version of this file
+ * only under the terms of the GPL and not to allow others to use your
+ * version of this file under the MPL, indicate your decision by
+ * deleting the provisions above and replace them with the notice and
+ * other provisions required by the GPL.  If you do not delete the
+ * provisions above, a recipient may use your version of this file
+ * under either the MPL or the GPL.
+ */
+
+#define DRIVER_NAME "orinoco_nortel"
+#define PFX DRIVER_NAME ": "
+
+#include <linux/config.h>
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/ioport.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <linux/fcntl.h>
+
+#include <pcmcia/cisreg.h>
+
+#include "hermes.h"
+#include "orinoco.h"
+
+#define COR_OFFSET    (0xe0)	/* COR attribute offset of Prism2 PC card */
+#define COR_VALUE     (COR_LEVEL_REQ | COR_FUNC_ENA)	/* Enable PC card with interrupt in level trigger */
+
+
+/* Nortel specific data */
+struct nortel_pci_card {
+	unsigned long iobase1;
+	unsigned long iobase2;
+};
+
+/*
+ * Do a soft reset of the PCI card using the Configuration Option Register
+ * We need this to get going...
+ * This is the part of the code that is strongly inspired from wlan-ng
+ *
+ * Note bis : Don't try to access HERMES_CMD during the reset phase.
+ * It just won't work !
+ */
+static int nortel_pci_cor_reset(struct orinoco_private *priv)
+{
+	struct nortel_pci_card *card = priv->card;
+
+	/* Assert the reset until the card notice */
+	outw_p(8, card->iobase1 + 2);
+	inw(card->iobase2 + COR_OFFSET);
+	outw_p(0x80, card->iobase2 + COR_OFFSET);
+	mdelay(1);
+
+	/* Give time for the card to recover from this hard effort */
+	outw_p(0, card->iobase2 + COR_OFFSET);
+	outw_p(0, card->iobase2 + COR_OFFSET);
+	mdelay(1);
+
+	/* set COR as usual */
+	outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
+	outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
+	mdelay(1);
+
+	outw_p(0x228, card->iobase1 + 2);
+
+	return 0;
+}
+
+int nortel_pci_hw_init(struct nortel_pci_card *card)
+{
+	int i;
+	u32 reg;
+
+	/* setup bridge */
+	if (inw(card->iobase1) & 1) {
+		printk(KERN_ERR PFX "brg1 answer1 wrong\n");
+		return -EBUSY;
+	}
+	outw_p(0x118, card->iobase1 + 2);
+	outw_p(0x108, card->iobase1 + 2);
+	mdelay(30);
+	outw_p(0x8, card->iobase1 + 2);
+	for (i = 0; i < 30; i++) {
+		mdelay(30);
+		if (inw(card->iobase1) & 0x10) {
+			break;
+		}
+	}
+	if (i == 30) {
+		printk(KERN_ERR PFX "brg1 timed out\n");
+		return -EBUSY;
+	}
+	if (inw(card->iobase2 + 0xe0) & 1) {
+		printk(KERN_ERR PFX "brg2 answer1 wrong\n");
+		return -EBUSY;
+	}
+	if (inw(card->iobase2 + 0xe2) & 1) {
+		printk(KERN_ERR PFX "brg2 answer2 wrong\n");
+		return -EBUSY;
+	}
+	if (inw(card->iobase2 + 0xe4) & 1) {
+		printk(KERN_ERR PFX "brg2 answer3 wrong\n");
+		return -EBUSY;
+	}
+
+	/* set the PCMCIA COR-Register */
+	outw_p(COR_VALUE, card->iobase2 + COR_OFFSET);
+	mdelay(1);
+	reg = inw(card->iobase2 + COR_OFFSET);
+	if (reg != COR_VALUE) {
+		printk(KERN_ERR PFX "Error setting COR value (reg=%x)\n",
+		       reg);
+		return -EBUSY;
+	}
+
+	/* set leds */
+	outw_p(1, card->iobase1 + 10);
+	return 0;
+}
+
+static int nortel_pci_init_one(struct pci_dev *pdev,
+			       const struct pci_device_id *ent)
+{
+	int err;
+	struct orinoco_private *priv;
+	struct nortel_pci_card *card;
+	struct net_device *dev;
+	void __iomem *iomem;
+
+	err = pci_enable_device(pdev);
+	if (err) {
+		printk(KERN_ERR PFX "Cannot enable PCI device\n");
+		return err;
+	}
+
+	err = pci_request_regions(pdev, DRIVER_NAME);
+	if (err != 0) {
+		printk(KERN_ERR PFX "Cannot obtain PCI resources\n");
+		goto fail_resources;
+	}
+
+	iomem = pci_iomap(pdev, 3, 0);
+	if (!iomem) {
+		err = -ENOMEM;
+		goto fail_map_io;
+	}
+
+	/* Allocate network device */
+	dev = alloc_orinocodev(sizeof(*card), nortel_pci_cor_reset);
+	if (!dev) {
+		printk(KERN_ERR PFX "Cannot allocate network device\n");
+		err = -ENOMEM;
+		goto fail_alloc;
+	}
+
+	priv = netdev_priv(dev);
+	card = priv->card;
+	card->iobase1 = pci_resource_start(pdev, 0);
+	card->iobase2 = pci_resource_start(pdev, 1);
+	dev->base_addr = pci_resource_start(pdev, 2);
+	SET_MODULE_OWNER(dev);
+	SET_NETDEV_DEV(dev, &pdev->dev);
+
+	hermes_struct_init(&priv->hw, iomem, HERMES_16BIT_REGSPACING);
+
+	printk(KERN_DEBUG PFX "Detected Nortel PCI device at %s irq:%d, "
+	       "io addr:0x%lx\n", pci_name(pdev), pdev->irq, dev->base_addr);
+
+	err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ,
+			  dev->name, dev);
+	if (err) {
+		printk(KERN_ERR PFX "Cannot allocate IRQ %d\n", pdev->irq);
+		err = -EBUSY;
+		goto fail_irq;
+	}
+	dev->irq = pdev->irq;
+
+	err = nortel_pci_hw_init(card);
+	if (err) {
+		printk(KERN_ERR PFX "Hardware initialization failed\n");
+		goto fail;
+	}
+
+	err = nortel_pci_cor_reset(priv);
+	if (err) {
+		printk(KERN_ERR PFX "Initial reset failed\n");
+		goto fail;
+	}
+
+
+	err = register_netdev(dev);
+	if (err) {
+		printk(KERN_ERR PFX "Cannot register network device\n");
+		goto fail;
+	}
+
+	pci_set_drvdata(pdev, dev);
+
+	return 0;
+
+ fail:
+	free_irq(pdev->irq, dev);
+
+ fail_irq:
+	pci_set_drvdata(pdev, NULL);
+	free_orinocodev(dev);
+
+ fail_alloc:
+	pci_iounmap(pdev, iomem);
+
+ fail_map_io:
+	pci_release_regions(pdev);
+
+ fail_resources:
+	pci_disable_device(pdev);
+
+	return err;
+}
+
+static void __devexit nortel_pci_remove_one(struct pci_dev *pdev)
+{
+	struct net_device *dev = pci_get_drvdata(pdev);
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct nortel_pci_card *card = priv->card;
+
+	/* clear leds */
+	outw_p(0, card->iobase1 + 10);
+
+	unregister_netdev(dev);
+	free_irq(dev->irq, dev);
+	pci_set_drvdata(pdev, NULL);
+	free_orinocodev(dev);
+	pci_iounmap(pdev, priv->hw.iobase);
+	pci_release_regions(pdev);
+	pci_disable_device(pdev);
+}
+
+
+static struct pci_device_id nortel_pci_id_table[] = {
+	/* Nortel emobility PCI */
+	{0x126c, 0x8030, PCI_ANY_ID, PCI_ANY_ID,},
+	{0,},
+};
+
+MODULE_DEVICE_TABLE(pci, nortel_pci_id_table);
+
+static struct pci_driver nortel_pci_driver = {
+	.name = DRIVER_NAME,
+	.id_table = nortel_pci_id_table,
+	.probe = nortel_pci_init_one,
+	.remove = __devexit_p(nortel_pci_remove_one),
+};
+
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+	" (Tobias Hoffmann & Christoph Jungegger <disdos@traum404.de>)";
+MODULE_AUTHOR("Christoph Jungegger <disdos@traum404.de>");
+MODULE_DESCRIPTION
+    ("Driver for wireless LAN cards using the Nortel PCI bridge");
+MODULE_LICENSE("Dual MPL/GPL");
+
+static int __init nortel_pci_init(void)
+{
+	printk(KERN_DEBUG "%s\n", version);
+	return pci_module_init(&nortel_pci_driver);
+}
+
+static void __exit nortel_pci_exit(void)
+{
+	pci_unregister_driver(&nortel_pci_driver);
+	ssleep(1);
+}
+
+module_init(nortel_pci_init);
+module_exit(nortel_pci_exit);
+
+/*
+ * Local variables:
+ *  c-indent-level: 8
+ *  c-basic-offset: 8
+ *  tab-width: 8
+ * End:
+ */
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
new file mode 100644
--- /dev/null
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -0,0 +1,1120 @@
+/*
+ * Driver for 802.11b cards using RAM-loadable Symbol firmware, such as
+ * Symbol Wireless Networker LA4100, CompactFlash cards by Socket
+ * Communications and Intel PRO/Wireless 2011B.
+ *
+ * The driver implements Symbol firmware download.  The rest is handled
+ * in hermes.c and orinoco.c.
+ *
+ * Utilities for downloading the Symbol firmware are available at
+ * http://sourceforge.net/projects/orinoco/
+ *
+ * Copyright (C) 2002-2005 Pavel Roskin <proski@gnu.org>
+ * Portions based on orinoco_cs.c:
+ * 	Copyright (C) David Gibson, Linuxcare Australia
+ * Portions based on Spectrum24tDnld.c from original spectrum24 driver:
+ * 	Copyright (C) Symbol Technologies.
+ *
+ * See copyright notice in file orinoco.c.
+ */
+
+#define DRIVER_NAME "spectrum_cs"
+#define PFX DRIVER_NAME ": "
+
+#include <linux/config.h>
+#ifdef  __IN_PCMCIA_PACKAGE__
+#include <pcmcia/k_compat.h>
+#endif /* __IN_PCMCIA_PACKAGE__ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/netdevice.h>
+#include <linux/if_arp.h>
+#include <linux/etherdevice.h>
+#include <linux/wireless.h>
+
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ds.h>
+
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include "orinoco.h"
+
+/*
+ * If SPECTRUM_FW_INCLUDED is defined, the firmware is hardcoded into
+ * the driver.  Use get_symbol_fw script to generate spectrum_fw.h and
+ * copy it to the same directory as spectrum_cs.c.
+ *
+ * If SPECTRUM_FW_INCLUDED is not defined, the firmware is loaded at the
+ * runtime using hotplug.  Use the same get_symbol_fw script to generate
+ * files symbol_sp24t_prim_fw symbol_sp24t_sec_fw, copy them to the
+ * hotplug firmware directory (typically /usr/lib/hotplug/firmware) and
+ * make sure that you have hotplug installed and enabled in the kernel.
+ */
+/* #define SPECTRUM_FW_INCLUDED 1 */
+
+#ifdef SPECTRUM_FW_INCLUDED
+/* Header with the firmware */
+#include "spectrum_fw.h"
+#else	/* !SPECTRUM_FW_INCLUDED */
+#include <linux/firmware.h>
+static unsigned char *primsym;
+static unsigned char *secsym;
+static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
+static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
+#endif	/* !SPECTRUM_FW_INCLUDED */
+
+/********************************************************************/
+/* Module stuff							    */
+/********************************************************************/
+
+MODULE_AUTHOR("Pavel Roskin <proski@gnu.org>");
+MODULE_DESCRIPTION("Driver for Symbol Spectrum24 Trilogy cards with firmware downloader");
+MODULE_LICENSE("Dual MPL/GPL");
+
+/* Module parameters */
+
+/* Some D-Link cards have buggy CIS. They do work at 5v properly, but
+ * don't have any CIS entry for it. This workaround it... */
+static int ignore_cis_vcc; /* = 0 */
+module_param(ignore_cis_vcc, int, 0);
+MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket");
+
+/********************************************************************/
+/* Magic constants						    */
+/********************************************************************/
+
+/*
+ * The dev_info variable is the "key" that is used to match up this
+ * device driver with appropriate cards, through the card
+ * configuration database.
+ */
+static dev_info_t dev_info = DRIVER_NAME;
+
+/********************************************************************/
+/* Data structures						    */
+/********************************************************************/
+
+/* PCMCIA specific device information (goes in the card field of
+ * struct orinoco_private */
+struct orinoco_pccard {
+	dev_link_t link;
+	dev_node_t node;
+};
+
+/*
+ * A linked list of "instances" of the device.  Each actual PCMCIA
+ * card corresponds to one device instance, and is described by one
+ * dev_link_t structure (defined in ds.h).
+ */
+static dev_link_t *dev_list; /* = NULL */
+
+/********************************************************************/
+/* Function prototypes						    */
+/********************************************************************/
+
+/* device methods */
+static int spectrum_cs_hard_reset(struct orinoco_private *priv);
+
+/* PCMCIA gumpf */
+static void spectrum_cs_config(dev_link_t * link);
+static void spectrum_cs_release(dev_link_t * link);
+static int spectrum_cs_event(event_t event, int priority,
+			    event_callback_args_t * args);
+
+static dev_link_t *spectrum_cs_attach(void);
+static void spectrum_cs_detach(dev_link_t *);
+
+/********************************************************************/
+/* Firmware downloader						    */
+/********************************************************************/
+
+/* Position of PDA in the adapter memory */
+#define EEPROM_ADDR	0x3000
+#define EEPROM_LEN	0x200
+#define PDA_OFFSET	0x100
+
+#define PDA_ADDR	(EEPROM_ADDR + PDA_OFFSET)
+#define PDA_WORDS	((EEPROM_LEN - PDA_OFFSET) / 2)
+
+/* Constants for the CISREG_CCSR register */
+#define HCR_RUN		0x07	/* run firmware after reset */
+#define HCR_IDLE	0x0E	/* don't run firmware after reset */
+#define HCR_MEM16	0x10	/* memory width bit, should be preserved */
+
+/*
+ * AUX port access.  To unlock the AUX port write the access keys to the
+ * PARAM0-2 registers, then write HERMES_AUX_ENABLE to the HERMES_CONTROL
+ * register.  Then read it and make sure it's HERMES_AUX_ENABLED.
+ */
+#define HERMES_AUX_ENABLE	0x8000	/* Enable auxiliary port access */
+#define HERMES_AUX_DISABLE	0x4000	/* Disable to auxiliary port access */
+#define HERMES_AUX_ENABLED	0xC000	/* Auxiliary port is open */
+
+#define HERMES_AUX_PW0	0xFE01
+#define HERMES_AUX_PW1	0xDC23
+#define HERMES_AUX_PW2	0xBA45
+
+/* End markers */
+#define PDI_END		0x00000000	/* End of PDA */
+#define BLOCK_END	0xFFFFFFFF	/* Last image block */
+#define TEXT_END	0x1A		/* End of text header */
+
+/*
+ * The following structures have little-endian fields denoted by
+ * the leading underscore.  Don't access them directly - use inline
+ * functions defined below.
+ */
+
+/*
+ * The binary image to be downloaded consists of series of data blocks.
+ * Each block has the following structure.
+ */
+struct dblock {
+	u32 _addr;		/* adapter address where to write the block */
+	u16 _len;		/* length of the data only, in bytes */
+	char data[0];		/* data to be written */
+} __attribute__ ((packed));
+
+/*
+ * Plug Data References are located in in the image after the last data
+ * block.  They refer to areas in the adapter memory where the plug data
+ * items with matching ID should be written.
+ */
+struct pdr {
+	u32 _id;		/* record ID */
+	u32 _addr;		/* adapter address where to write the data */
+	u32 _len;		/* expected length of the data, in bytes */
+	char next[0];		/* next PDR starts here */
+} __attribute__ ((packed));
+
+
+/*
+ * Plug Data Items are located in the EEPROM read from the adapter by
+ * primary firmware.  They refer to the device-specific data that should
+ * be plugged into the secondary firmware.
+ */
+struct pdi {
+	u16 _len;		/* length of ID and data, in words */
+	u16 _id;		/* record ID */
+	char data[0];		/* plug data */
+} __attribute__ ((packed));;
+
+
+/* Functions for access to little-endian data */
+static inline u32
+dblock_addr(const struct dblock *blk)
+{
+	return le32_to_cpu(blk->_addr);
+}
+
+static inline u32
+dblock_len(const struct dblock *blk)
+{
+	return le16_to_cpu(blk->_len);
+}
+
+static inline u32
+pdr_id(const struct pdr *pdr)
+{
+	return le32_to_cpu(pdr->_id);
+}
+
+static inline u32
+pdr_addr(const struct pdr *pdr)
+{
+	return le32_to_cpu(pdr->_addr);
+}
+
+static inline u32
+pdr_len(const struct pdr *pdr)
+{
+	return le32_to_cpu(pdr->_len);
+}
+
+static inline u32
+pdi_id(const struct pdi *pdi)
+{
+	return le16_to_cpu(pdi->_id);
+}
+
+/* Return length of the data only, in bytes */
+static inline u32
+pdi_len(const struct pdi *pdi)
+{
+	return 2 * (le16_to_cpu(pdi->_len) - 1);
+}
+
+
+/* Set address of the auxiliary port */
+static inline void
+spectrum_aux_setaddr(hermes_t *hw, u32 addr)
+{
+	hermes_write_reg(hw, HERMES_AUXPAGE, (u16) (addr >> 7));
+	hermes_write_reg(hw, HERMES_AUXOFFSET, (u16) (addr & 0x7F));
+}
+
+
+/* Open access to the auxiliary port */
+static int
+spectrum_aux_open(hermes_t *hw)
+{
+	int i;
+
+	/* Already open? */
+	if (hermes_read_reg(hw, HERMES_CONTROL) == HERMES_AUX_ENABLED)
+		return 0;
+
+	hermes_write_reg(hw, HERMES_PARAM0, HERMES_AUX_PW0);
+	hermes_write_reg(hw, HERMES_PARAM1, HERMES_AUX_PW1);
+	hermes_write_reg(hw, HERMES_PARAM2, HERMES_AUX_PW2);
+	hermes_write_reg(hw, HERMES_CONTROL, HERMES_AUX_ENABLE);
+
+	for (i = 0; i < 20; i++) {
+		udelay(10);
+		if (hermes_read_reg(hw, HERMES_CONTROL) ==
+		    HERMES_AUX_ENABLED)
+			return 0;
+	}
+
+	return -EBUSY;
+}
+
+
+#define CS_CHECK(fn, ret) \
+  do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
+
+/*
+ * Reset the card using configuration registers COR and CCSR.
+ * If IDLE is 1, stop the firmware, so that it can be safely rewritten.
+ */
+static int
+spectrum_reset(dev_link_t *link, int idle)
+{
+	int last_ret, last_fn;
+	conf_reg_t reg;
+	u_int save_cor;
+
+	/* Doing it if hardware is gone is guaranteed crash */
+	if (!(link->state & DEV_CONFIG))
+		return -ENODEV;
+
+	/* Save original COR value */
+	reg.Function = 0;
+	reg.Action = CS_READ;
+	reg.Offset = CISREG_COR;
+	CS_CHECK(AccessConfigurationRegister,
+		 pcmcia_access_configuration_register(link->handle, &reg));
+	save_cor = reg.Value;
+
+	/* Soft-Reset card */
+	reg.Action = CS_WRITE;
+	reg.Offset = CISREG_COR;
+	reg.Value = (save_cor | COR_SOFT_RESET);
+	CS_CHECK(AccessConfigurationRegister,
+		 pcmcia_access_configuration_register(link->handle, &reg));
+	udelay(1000);
+
+	/* Read CCSR */
+	reg.Action = CS_READ;
+	reg.Offset = CISREG_CCSR;
+	CS_CHECK(AccessConfigurationRegister,
+		 pcmcia_access_configuration_register(link->handle, &reg));
+
+	/*
+	 * Start or stop the firmware.  Memory width bit should be
+	 * preserved from the value we've just read.
+	 */
+	reg.Action = CS_WRITE;
+	reg.Offset = CISREG_CCSR;
+	reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
+	CS_CHECK(AccessConfigurationRegister,
+		 pcmcia_access_configuration_register(link->handle, &reg));
+	udelay(1000);
+
+	/* Restore original COR configuration index */
+	reg.Action = CS_WRITE;
+	reg.Offset = CISREG_COR;
+	reg.Value = (save_cor & ~COR_SOFT_RESET);
+	CS_CHECK(AccessConfigurationRegister,
+		 pcmcia_access_configuration_register(link->handle, &reg));
+	udelay(1000);
+	return 0;
+
+      cs_failed:
+	cs_error(link->handle, last_fn, last_ret);
+	return -ENODEV;
+}
+
+
+/*
+ * Scan PDR for the record with the specified RECORD_ID.
+ * If it's not found, return NULL.
+ */
+static struct pdr *
+spectrum_find_pdr(struct pdr *first_pdr, u32 record_id)
+{
+	struct pdr *pdr = first_pdr;
+
+	while (pdr_id(pdr) != PDI_END) {
+		/*
+		 * PDR area is currently not terminated by PDI_END.
+		 * It's followed by CRC records, which have the type
+		 * field where PDR has length.  The type can be 0 or 1.
+		 */
+		if (pdr_len(pdr) < 2)
+			return NULL;
+
+		/* If the record ID matches, we are done */
+		if (pdr_id(pdr) == record_id)
+			return pdr;
+
+		pdr = (struct pdr *) pdr->next;
+	}
+	return NULL;
+}
+
+
+/* Process one Plug Data Item - find corresponding PDR and plug it */
+static int
+spectrum_plug_pdi(hermes_t *hw, struct pdr *first_pdr, struct pdi *pdi)
+{
+	struct pdr *pdr;
+
+	/* Find the PDI corresponding to this PDR */
+	pdr = spectrum_find_pdr(first_pdr, pdi_id(pdi));
+
+	/* No match is found, safe to ignore */
+	if (!pdr)
+		return 0;
+
+	/* Lengths of the data in PDI and PDR must match */
+	if (pdi_len(pdi) != pdr_len(pdr))
+		return -EINVAL;
+
+	/* do the actual plugging */
+	spectrum_aux_setaddr(hw, pdr_addr(pdr));
+	hermes_write_words(hw, HERMES_AUXDATA, pdi->data,
+			   pdi_len(pdi) / 2);
+
+	return 0;
+}
+
+
+/* Read PDA from the adapter */
+static int
+spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
+{
+	int ret;
+	int pda_size;
+
+	/* Issue command to read EEPROM */
+	ret = hermes_docmd_wait(hw, HERMES_CMD_READMIF, 0, NULL);
+	if (ret)
+		return ret;
+
+	/* Open auxiliary port */
+	ret = spectrum_aux_open(hw);
+	if (ret)
+		return ret;
+
+	/* read PDA from EEPROM */
+	spectrum_aux_setaddr(hw, PDA_ADDR);
+	hermes_read_words(hw, HERMES_AUXDATA, pda, pda_len / 2);
+
+	/* Check PDA length */
+	pda_size = le16_to_cpu(pda[0]);
+	if (pda_size > pda_len)
+		return -EINVAL;
+
+	return 0;
+}
+
+
+/* Parse PDA and write the records into the adapter */
+static int
+spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block,
+		   u16 *pda)
+{
+	int ret;
+	struct pdi *pdi;
+	struct pdr *first_pdr;
+	const struct dblock *blk = first_block;
+
+	/* Skip all blocks to locate Plug Data References */
+	while (dblock_addr(blk) != BLOCK_END)
+		blk = (struct dblock *) &blk->data[dblock_len(blk)];
+
+	first_pdr = (struct pdr *) blk;
+
+	/* Go through every PDI and plug them into the adapter */
+	pdi = (struct pdi *) (pda + 2);
+	while (pdi_id(pdi) != PDI_END) {
+		ret = spectrum_plug_pdi(hw, first_pdr, pdi);
+		if (ret)
+			return ret;
+
+		/* Increment to the next PDI */
+		pdi = (struct pdi *) &pdi->data[pdi_len(pdi)];
+	}
+	return 0;
+}
+
+
+/* Load firmware blocks into the adapter */
+static int
+spectrum_load_blocks(hermes_t *hw, const struct dblock *first_block)
+{
+	const struct dblock *blk;
+	u32 blkaddr;
+	u32 blklen;
+
+	blk = first_block;
+	blkaddr = dblock_addr(blk);
+	blklen = dblock_len(blk);
+
+	while (dblock_addr(blk) != BLOCK_END) {
+		spectrum_aux_setaddr(hw, blkaddr);
+		hermes_write_words(hw, HERMES_AUXDATA, blk->data,
+				   blklen / 2);
+
+		blk = (struct dblock *) &blk->data[blklen];
+		blkaddr = dblock_addr(blk);
+		blklen = dblock_len(blk);
+	}
+	return 0;
+}
+
+
+/*
+ * Process a firmware image - stop the card, load the firmware, reset
+ * the card and make sure it responds.  For the secondary firmware take
+ * care of the PDA - read it and then write it on top of the firmware.
+ */
+static int
+spectrum_dl_image(hermes_t *hw, dev_link_t *link,
+		  const unsigned char *image)
+{
+	int ret;
+	const unsigned char *ptr;
+	const struct dblock *first_block;
+
+	/* Plug Data Area (PDA) */
+	u16 pda[PDA_WORDS];
+
+	/* Binary block begins after the 0x1A marker */
+	ptr = image;
+	while (*ptr++ != TEXT_END);
+	first_block = (const struct dblock *) ptr;
+
+	/* Read the PDA */
+	if (image != primsym) {
+		ret = spectrum_read_pda(hw, pda, sizeof(pda));
+		if (ret)
+			return ret;
+	}
+
+	/* Stop the firmware, so that it can be safely rewritten */
+	ret = spectrum_reset(link, 1);
+	if (ret)
+		return ret;
+
+	/* Program the adapter with new firmware */
+	ret = spectrum_load_blocks(hw, first_block);
+	if (ret)
+		return ret;
+
+	/* Write the PDA to the adapter */
+	if (image != primsym) {
+		ret = spectrum_apply_pda(hw, first_block, pda);
+		if (ret)
+			return ret;
+	}
+
+	/* Run the firmware */
+	ret = spectrum_reset(link, 0);
+	if (ret)
+		return ret;
+
+	/* Reset hermes chip and make sure it responds */
+	ret = hermes_init(hw);
+
+	/* hermes_reset() should return 0 with the secondary firmware */
+	if (image != primsym && ret != 0)
+		return -ENODEV;
+
+	/* And this should work with any firmware */
+	if (!hermes_present(hw))
+		return -ENODEV;
+
+	return 0;
+}
+
+
+/*
+ * Download the firmware into the card, this also does a PCMCIA soft
+ * reset on the card, to make sure it's in a sane state.
+ */
+static int
+spectrum_dl_firmware(hermes_t *hw, dev_link_t *link)
+{
+	int ret;
+	client_handle_t handle = link->handle;
+
+#ifndef SPECTRUM_FW_INCLUDED
+	const struct firmware *fw_entry;
+
+	if (request_firmware(&fw_entry, primary_fw_name,
+			     &handle_to_dev(handle)) == 0) {
+		primsym = fw_entry->data;
+	} else {
+		printk(KERN_ERR PFX "Cannot find firmware: %s\n",
+		       primary_fw_name);
+		return -ENOENT;
+	}
+
+	if (request_firmware(&fw_entry, secondary_fw_name,
+			     &handle_to_dev(handle)) == 0) {
+		secsym = fw_entry->data;
+	} else {
+		printk(KERN_ERR PFX "Cannot find firmware: %s\n",
+		       secondary_fw_name);
+		return -ENOENT;
+	}
+#endif
+
+	/* Load primary firmware */
+	ret = spectrum_dl_image(hw, link, primsym);
+	if (ret) {
+		printk(KERN_ERR PFX "Primary firmware download failed\n");
+		return ret;
+	}
+
+	/* Load secondary firmware */
+	ret = spectrum_dl_image(hw, link, secsym);
+
+	if (ret) {
+		printk(KERN_ERR PFX "Secondary firmware download failed\n");
+	}
+
+	return ret;
+}
+
+/********************************************************************/
+/* Device methods     						    */
+/********************************************************************/
+
+static int
+spectrum_cs_hard_reset(struct orinoco_private *priv)
+{
+	struct orinoco_pccard *card = priv->card;
+	dev_link_t *link = &card->link;
+	int err;
+
+	if (!hermes_present(&priv->hw)) {
+		/* The firmware needs to be reloaded */
+		if (spectrum_dl_firmware(&priv->hw, &card->link) != 0) {
+			printk(KERN_ERR PFX "Firmware download failed\n");
+			err = -ENODEV;
+		}
+	} else {
+		/* Soft reset using COR and HCR */
+		spectrum_reset(link, 0);
+	}
+
+	return 0;
+}
+
+/********************************************************************/
+/* PCMCIA stuff     						    */
+/********************************************************************/
+
+/*
+ * This creates an "instance" of the driver, allocating local data
+ * structures for one device.  The device is registered with Card
+ * Services.
+ * 
+ * The dev_link structure is initialized, but we don't actually
+ * configure the card at this point -- we wait until we receive a card
+ * insertion event.  */
+static dev_link_t *
+spectrum_cs_attach(void)
+{
+	struct net_device *dev;
+	struct orinoco_private *priv;
+	struct orinoco_pccard *card;
+	dev_link_t *link;
+	client_reg_t client_reg;
+	int ret;
+
+	dev = alloc_orinocodev(sizeof(*card), spectrum_cs_hard_reset);
+	if (! dev)
+		return NULL;
+	priv = netdev_priv(dev);
+	card = priv->card;
+
+	/* Link both structures together */
+	link = &card->link;
+	link->priv = dev;
+
+	/* Interrupt setup */
+	link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+	link->irq.IRQInfo1 = IRQ_LEVEL_ID;
+	link->irq.Handler = orinoco_interrupt;
+	link->irq.Instance = dev; 
+
+	/* General socket configuration defaults can go here.  In this
+	 * client, we assume very little, and rely on the CIS for
+	 * almost everything.  In most clients, many details (i.e.,
+	 * number, sizes, and attributes of IO windows) are fixed by
+	 * the nature of the device, and can be hard-wired here. */
+	link->conf.Attributes = 0;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+
+	/* Register with Card Services */
+	/* FIXME: need a lock? */
+	link->next = dev_list;
+	dev_list = link;
+
+	client_reg.dev_info = &dev_info;
+	client_reg.Version = 0x0210; /* FIXME: what does this mean? */
+	client_reg.event_callback_args.client_data = link;
+
+	ret = pcmcia_register_client(&link->handle, &client_reg);
+	if (ret != CS_SUCCESS) {
+		cs_error(link->handle, RegisterClient, ret);
+		spectrum_cs_detach(link);
+		return NULL;
+	}
+
+	return link;
+}				/* spectrum_cs_attach */
+
+/*
+ * This deletes a driver "instance".  The device is de-registered with
+ * Card Services.  If it has been released, all local data structures
+ * are freed.  Otherwise, the structures will be freed when the device
+ * is released.
+ */
+static void spectrum_cs_detach(dev_link_t *link)
+{
+	dev_link_t **linkp;
+	struct net_device *dev = link->priv;
+
+	/* Locate device structure */
+	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+		if (*linkp == link)
+			break;
+
+	BUG_ON(*linkp == NULL);
+
+	if (link->state & DEV_CONFIG)
+		spectrum_cs_release(link);
+
+	/* Break the link with Card Services */
+	if (link->handle)
+		pcmcia_deregister_client(link->handle);
+
+	/* Unlink device structure, and free it */
+	*linkp = link->next;
+	DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev);
+	if (link->dev) {
+		DEBUG(0, PFX "About to unregister net device %p\n",
+		      dev);
+		unregister_netdev(dev);
+	}
+	free_orinocodev(dev);
+}				/* spectrum_cs_detach */
+
+/*
+ * spectrum_cs_config() is scheduled to run after a CARD_INSERTION
+ * event is received, to configure the PCMCIA socket, and to make the
+ * device available to the system.
+ */
+
+static void
+spectrum_cs_config(dev_link_t *link)
+{
+	struct net_device *dev = link->priv;
+	client_handle_t handle = link->handle;
+	struct orinoco_private *priv = netdev_priv(dev);
+	struct orinoco_pccard *card = priv->card;
+	hermes_t *hw = &priv->hw;
+	int last_fn, last_ret;
+	u_char buf[64];
+	config_info_t conf;
+	cisinfo_t info;
+	tuple_t tuple;
+	cisparse_t parse;
+	void __iomem *mem;
+
+	CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info));
+
+	/*
+	 * This reads the card's CONFIG tuple to find its
+	 * configuration registers.
+	 */
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	tuple.Attributes = 0;
+	tuple.TupleData = buf;
+	tuple.TupleDataMax = sizeof(buf);
+	tuple.TupleOffset = 0;
+	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
+	CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+
+	/* Configure card */
+	link->state |= DEV_CONFIG;
+
+	/* Look up the current Vcc */
+	CS_CHECK(GetConfigurationInfo,
+		 pcmcia_get_configuration_info(handle, &conf));
+	link->conf.Vcc = conf.Vcc;
+
+	/*
+	 * In this loop, we scan the CIS for configuration table
+	 * entries, each of which describes a valid card
+	 * configuration, including voltage, IO window, memory window,
+	 * and interrupt settings.
+	 *
+	 * We make no assumptions about the card to be configured: we
+	 * use just the information available in the CIS.  In an ideal
+	 * world, this would work for any PCMCIA card, but it requires
+	 * a complete and accurate CIS.  In practice, a driver usually
+	 * "knows" most of these things without consulting the CIS,
+	 * and most client drivers will only use the CIS to fill in
+	 * implementation-defined details.
+	 */
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
+	while (1) {
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+		cistpl_cftable_entry_t dflt = { .index = 0 };
+
+		if ( (pcmcia_get_tuple_data(handle, &tuple) != 0)
+		    || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0))
+			goto next_entry;
+
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			dflt = *cfg;
+		if (cfg->index == 0)
+			goto next_entry;
+		link->conf.ConfigIndex = cfg->index;
+
+		/* Does this card need audio output? */
+		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+			link->conf.Attributes |= CONF_ENABLE_SPKR;
+			link->conf.Status = CCSR_AUDIO_ENA;
+		}
+
+		/* Use power settings for Vcc and Vpp if present */
+		/* Note that the CIS values need to be rescaled */
+		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {
+			if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM] / 10000) {
+				DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, cfg->vcc.param[CISTPL_POWER_VNOM] / 10000);
+				if (!ignore_cis_vcc)
+					goto next_entry;
+			}
+		} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {
+			if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM] / 10000) {
+				DEBUG(2, "spectrum_cs_config: Vcc mismatch (conf.Vcc = %d, CIS = %d)\n",  conf.Vcc, dflt.vcc.param[CISTPL_POWER_VNOM] / 10000);
+				if(!ignore_cis_vcc)
+					goto next_entry;
+			}
+		}
+
+		if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
+			link->conf.Vpp1 = link->conf.Vpp2 =
+			    cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+		else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
+			link->conf.Vpp1 = link->conf.Vpp2 =
+			    dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
+		
+		/* Do we need to allocate an interrupt? */
+		link->conf.Attributes |= CONF_ENABLE_IRQ;
+
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io =
+			    (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+			if (!(io->flags & CISTPL_IO_8BIT))
+				link->io.Attributes1 =
+				    IO_DATA_PATH_WIDTH_16;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 =
+				    IO_DATA_PATH_WIDTH_8;
+			link->io.IOAddrLines =
+			    io->flags & CISTPL_IO_LINES_MASK;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 =
+				    link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+
+			/* This reserves IO space but doesn't actually enable it */
+			if (pcmcia_request_io(link->handle, &link->io) != 0)
+				goto next_entry;
+		}
+
+
+		/* If we got this far, we're cool! */
+
+		break;
+		
+	next_entry:
+		if (link->io.NumPorts1)
+			pcmcia_release_io(link->handle, &link->io);
+		last_ret = pcmcia_get_next_tuple(handle, &tuple);
+		if (last_ret  == CS_NO_MORE_ITEMS) {
+			printk(KERN_ERR PFX "GetNextTuple(): No matching "
+			       "CIS configuration.  Maybe you need the "
+			       "ignore_cis_vcc=1 parameter.\n");
+			goto cs_failed;
+		}
+	}
+
+	/*
+	 * Allocate an interrupt line.  Note that this does not assign
+	 * a handler to the interrupt, unless the 'Handler' member of
+	 * the irq structure is initialized.
+	 */
+	CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
+
+	/* We initialize the hermes structure before completing PCMCIA
+	 * configuration just in case the interrupt handler gets
+	 * called. */
+	mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
+	if (!mem)
+		goto cs_failed;
+
+	hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
+
+	/*
+	 * This actually configures the PCMCIA socket -- setting up
+	 * the I/O windows and the interrupt mapping, and putting the
+	 * card and host interface into "Memory and IO" mode.
+	 */
+	CS_CHECK(RequestConfiguration,
+		 pcmcia_request_configuration(link->handle, &link->conf));
+
+	/* Ok, we have the configuration, prepare to register the netdev */
+	dev->base_addr = link->io.BasePort1;
+	dev->irq = link->irq.AssignedIRQ;
+	SET_MODULE_OWNER(dev);
+	card->node.major = card->node.minor = 0;
+
+	/* Reset card and download firmware */
+	if (spectrum_cs_hard_reset(priv) != 0) {
+		goto failed;
+	}
+
+	SET_NETDEV_DEV(dev, &handle_to_dev(handle));
+	/* Tell the stack we exist */
+	if (register_netdev(dev) != 0) {
+		printk(KERN_ERR PFX "register_netdev() failed\n");
+		goto failed;
+	}
+
+	/* At this point, the dev_node_t structure(s) needs to be
+	 * initialized and arranged in a linked list at link->dev. */
+	strcpy(card->node.dev_name, dev->name);
+	link->dev = &card->node; /* link->dev being non-NULL is also
+                                    used to indicate that the
+                                    net_device has been registered */
+	link->state &= ~DEV_CONFIG_PENDING;
+
+	/* Finally, report what we've done */
+	printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d",
+	       dev->name, link->conf.ConfigIndex,
+	       link->conf.Vcc / 10, link->conf.Vcc % 10);
+	if (link->conf.Vpp1)
+		printk(", Vpp %d.%d", link->conf.Vpp1 / 10,
+		       link->conf.Vpp1 % 10);
+	printk(", irq %d", link->irq.AssignedIRQ);
+	if (link->io.NumPorts1)
+		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
+		       link->io.BasePort1 + link->io.NumPorts1 - 1);
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+		       link->io.BasePort2 + link->io.NumPorts2 - 1);
+	printk("\n");
+
+	return;
+
+ cs_failed:
+	cs_error(link->handle, last_fn, last_ret);
+
+ failed:
+	spectrum_cs_release(link);
+}				/* spectrum_cs_config */
+
+/*
+ * After a card is removed, spectrum_cs_release() will unregister the
+ * device, and release the PCMCIA configuration.  If the device is
+ * still open, this will be postponed until it is closed.
+ */
+static void
+spectrum_cs_release(dev_link_t *link)
+{
+	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = netdev_priv(dev);
+	unsigned long flags;
+
+	/* We're committed to taking the device away now, so mark the
+	 * hardware as unavailable */
+	spin_lock_irqsave(&priv->lock, flags);
+	priv->hw_unavailable++;
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	/* Don't bother checking to see if these succeed or not */
+	pcmcia_release_configuration(link->handle);
+	if (link->io.NumPorts1)
+		pcmcia_release_io(link->handle, &link->io);
+	if (link->irq.AssignedIRQ)
+		pcmcia_release_irq(link->handle, &link->irq);
+	link->state &= ~DEV_CONFIG;
+	if (priv->hw.iobase)
+		ioport_unmap(priv->hw.iobase);
+}				/* spectrum_cs_release */
+
+/*
+ * The card status event handler.  Mostly, this schedules other stuff
+ * to run after an event is received.
+ */
+static int
+spectrum_cs_event(event_t event, int priority,
+		       event_callback_args_t * args)
+{
+	dev_link_t *link = args->client_data;
+	struct net_device *dev = link->priv;
+	struct orinoco_private *priv = netdev_priv(dev);
+	int err = 0;
+	unsigned long flags;
+
+	switch (event) {
+	case CS_EVENT_CARD_REMOVAL:
+		link->state &= ~DEV_PRESENT;
+		if (link->state & DEV_CONFIG) {
+			unsigned long flags;
+
+			spin_lock_irqsave(&priv->lock, flags);
+			netif_device_detach(dev);
+			priv->hw_unavailable++;
+			spin_unlock_irqrestore(&priv->lock, flags);
+		}
+		break;
+
+	case CS_EVENT_CARD_INSERTION:
+		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+		spectrum_cs_config(link);
+		break;
+
+	case CS_EVENT_PM_SUSPEND:
+		link->state |= DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_RESET_PHYSICAL:
+		/* Mark the device as stopped, to block IO until later */
+		if (link->state & DEV_CONFIG) {
+			/* This is probably racy, but I can't think of
+                           a better way, short of rewriting the PCMCIA
+                           layer to not suck :-( */
+			spin_lock_irqsave(&priv->lock, flags);
+
+			err = __orinoco_down(dev);
+			if (err)
+				printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
+				       dev->name,
+				       event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
+				       err);
+
+			netif_device_detach(dev);
+			priv->hw_unavailable++;
+
+			spin_unlock_irqrestore(&priv->lock, flags);
+
+			pcmcia_release_configuration(link->handle);
+		}
+		break;
+
+	case CS_EVENT_PM_RESUME:
+		link->state &= ~DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_CARD_RESET:
+		if (link->state & DEV_CONFIG) {
+			/* FIXME: should we double check that this is
+			 * the same card as we had before */
+			pcmcia_request_configuration(link->handle, &link->conf);
+			netif_device_attach(dev);
+			priv->hw_unavailable--;
+			schedule_work(&priv->reset_work);
+		}
+		break;
+	}
+
+	return err;
+}				/* spectrum_cs_event */
+
+/********************************************************************/
+/* Module initialization					    */
+/********************************************************************/
+
+/* Can't be declared "const" or the whole __initdata section will
+ * become const */
+static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION
+	" (Pavel Roskin <proski@gnu.org>,"
+	" David Gibson <hermes@gibson.dropbear.id.au>, et al)";
+
+static struct pcmcia_device_id spectrum_cs_ids[] = {
+	PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */
+	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
+	PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001), /* Intel PRO/Wireless 2011B */
+	PCMCIA_DEVICE_NULL,
+};
+MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
+
+static struct pcmcia_driver orinoco_driver = {
+	.owner		= THIS_MODULE,
+	.drv		= {
+		.name	= DRIVER_NAME,
+	},
+	.attach		= spectrum_cs_attach,
+	.event		= spectrum_cs_event,
+	.detach		= spectrum_cs_detach,
+	.id_table       = spectrum_cs_ids,
+};
+
+static int __init
+init_spectrum_cs(void)
+{
+	printk(KERN_DEBUG "%s\n", version);
+
+	return pcmcia_register_driver(&orinoco_driver);
+}
+
+static void __exit
+exit_spectrum_cs(void)
+{
+	pcmcia_unregister_driver(&orinoco_driver);
+	BUG_ON(dev_list != NULL);
+}
+
+module_init(init_spectrum_cs);
+module_exit(exit_spectrum_cs);
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -695,7 +695,7 @@ static int ethtool_get_stats(struct net_
 	return ret;
 }
 
-static int ethtool_get_perm_addr(struct net_device *dev, void *useraddr)
+static int ethtool_get_perm_addr(struct net_device *dev, void __user *useraddr)
 {
 	struct ethtool_perm_addr epaddr;
 	u8 *data;

^ permalink raw reply	[flat|nested] 101+ messages in thread

end of thread, other threads:[~2008-10-28 18:11 UTC | newest]

Thread overview: 101+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-02-08  0:29 [git patches] net driver updates Jeff Garzik
2007-02-08  6:30 ` Junio C Hamano
2007-02-08 14:30   ` Jeff Garzik
  -- strict thread matches above, loose matches on Subject: below --
2008-10-27 23:18 Jeff Garzik
2008-10-28 18:10 ` David Miller
2008-08-14  9:32 Jeff Garzik
2008-08-14 21:54 ` David Miller
2008-08-07  8:50 Jeff Garzik
2008-08-07  9:19 ` David Miller
2008-08-07 10:09 ` Martin Michlmayr
2008-07-30 21:41 Jeff Garzik
2008-07-30 22:49 ` David Miller
2008-05-06 16:42 Jeff Garzik
2008-05-08  9:49 ` David Miller
2008-04-25  7:26 Jeff Garzik
2008-04-25  7:32 ` David Miller
2008-04-26 22:07 ` Ben Hutchings
2008-04-27  0:43   ` David Miller
2008-04-27  2:53     ` Jeff Garzik
2008-04-27 11:34       ` Ben Hutchings
2008-03-29  2:24 Jeff Garzik
2008-03-29  3:02 ` David Miller
2008-02-11 17:05 Jeff Garzik
2008-02-11 20:07 ` Divy Le Ray
2008-02-20 20:38   ` Jeff Garzik
2008-02-21  1:16     ` Divy Le Ray
2008-02-21  3:43       ` Krishna Kumar2
2008-02-21  5:46         ` David Miller
2008-02-21  5:57           ` Divy Le Ray
2008-02-21  6:02             ` Krishna Kumar2
2008-02-21  6:15             ` David Miller
2008-02-21  6:54               ` Divy Le Ray
2008-02-25 22:59                 ` Jeff Garzik
2008-02-25 23:34                   ` Marin Mitov
2008-02-25 23:36                     ` Jeff Garzik
2008-02-26 20:52                     ` David Miller
2008-02-26  0:13                   ` Divy Le Ray
2008-02-26  0:17                     ` Jeff Garzik
2008-02-12  5:57 ` David Miller
2008-02-12 12:38 ` Ben Dooks
2008-02-12 16:01   ` Jeff Garzik
2008-02-06 11:49 Jeff Garzik
2008-02-06 11:52 ` David Miller
     [not found] <20080122110231.GA18441@havoc.gtf.org>
2008-01-22 14:20 ` David Miller
2007-10-25  7:49 Jeff Garzik
2007-10-24  1:30 Jeff Garzik
2007-10-15 20:19 Jeff Garzik
2007-10-10  1:03 Jeff Garzik
2007-10-10  1:12 ` David Miller
2007-10-05 18:20 Jeff Garzik
2007-10-08  6:06 ` David Miller
2007-10-03 18:39 Jeff Garzik
2007-10-03 22:33 ` David Miller
2007-10-02 17:41 Jeff Garzik
2007-10-02 23:38 ` David Miller
2007-09-29  6:08 Jeff Garzik
2007-09-20  7:26 Jeff Garzik
2007-09-20 18:42 ` David Miller
2007-07-24 20:55 Jeff Garzik
2007-07-18 23:53 Jeff Garzik
2007-07-16 22:57 Jeff Garzik
2007-07-17  8:02 ` maximilian attems
2007-07-10 18:39 Jeff Garzik
2007-07-11  9:34 ` Jiri Kosina
2007-07-11 16:28   ` Chris Stromsoe
2007-05-11 21:58 Jeff Garzik
2007-05-08  6:33 Jeff Garzik
2007-05-18 21:46 ` Mariusz Kozłowski
2007-05-18 21:54   ` Andrew Morton
2007-05-18 22:16     ` Mariusz Kozlowski
2007-05-18 22:19     ` Gene Heskett
2007-04-29 16:19 Jeff Garzik
2007-04-29 16:21 ` Christoph Hellwig
2007-02-21 11:46 Roger While
2007-02-21 12:01 ` Johannes Berg
2007-02-21 13:27 ` John W. Linville
2007-02-21 13:27   ` John W. Linville
2007-02-22 15:48   ` Dan Williams
2007-02-20 18:16 Jeff Garzik
2007-02-17 22:17 Jeff Garzik
2006-12-11 15:45 Jeff Garzik
2006-12-07 12:14 Jeff Garzik
     [not found] <20061002154831.GA8929@havoc.gtf.org>
2006-10-02 18:04 ` Andrew Morton
2006-09-24 16:24 Jeff Garzik
2006-07-05 18:18 Jeff Garzik
2006-06-27  3:57 Jeff Garzik
2006-05-20  4:28 Jeff Garzik
2006-05-20 16:20 ` Andrew Morton
2006-05-20 17:36   ` Linus Torvalds
2006-05-20 17:55     ` Andrew Morton
2006-05-20 22:15       ` Andi Kleen
2006-05-21  7:11         ` Manfred Spraul
2006-05-21 13:24           ` Andreas Kleen
2006-05-21 14:56             ` Manfred Spraul
2006-05-22 12:46               ` Andi Kleen
2006-03-29 23:00 Jeff Garzik
2006-03-24 17:19 Jeff Garzik
2006-03-23  1:34 Jeff Garzik
2006-03-21 21:55 Jeff Garzik
2006-03-20 11:17 Jeff Garzik
2005-09-05 22:47 Jeff Garzik

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.