فهرست منبع

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1745 commits)
  dp83640: free packet queues on remove
  dp83640: use proper function to free transmit time stamping packets
  ipv6: Do not use routes from locally generated RAs
  |PATCH net-next] tg3: add tx_dropped counter
  be2net: don't create multiple RX/TX rings in multi channel mode
  be2net: don't create multiple TXQs in BE2
  be2net: refactor VF setup/teardown code into be_vf_setup/clear()
  be2net: add vlan/rx-mode/flow-control config to be_setup()
  net_sched: cls_flow: use skb_header_pointer()
  ipv4: avoid useless call of the function check_peer_pmtu
  TCP: remove TCP_DEBUG
  net: Fix driver name for mdio-gpio.c
  ipv4: tcp: fix TOS value in ACK messages sent from TIME_WAIT
  rtnetlink: Add missing manual netlink notification in dev_change_net_namespaces
  ipv4: fix ipsec forward performance regression
  jme: fix irq storm after suspend/resume
  route: fix ICMP redirect validation
  net: hold sock reference while processing tx timestamps
  tcp: md5: add more const attributes
  Add ethtool -g support to virtio_net
  ...

Fix up conflicts in:
 - drivers/net/Kconfig:
	The split-up generated a trivial conflict with removal of a
	stale reference to Documentation/networking/net-modules.txt.
	Remove it from the new location instead.
 - fs/sysfs/dir.c:
	Fairly nasty conflicts with the sysfs rb-tree usage, conflicting
	with Eric Biederman's changes for tagged directories.
Linus Torvalds 13 سال پیش
والد
کامیت
8a9ea3237e
100فایلهای تغییر یافته به همراه2497 افزوده شده و 23505 حذف شده
  1. 8 0
      Documentation/ABI/testing/sysfs-class-net-mesh
  2. 10 1
      Documentation/DocBook/80211.tmpl
  3. 13 50
      Documentation/devicetree/bindings/net/can/fsl-flexcan.txt
  4. 38 0
      Documentation/devicetree/bindings/net/smsc911x.txt
  5. 9 0
      Documentation/feature-removal-schedule.txt
  6. 4 4
      Documentation/networking/batman-adv.txt
  7. 8 9
      Documentation/networking/ip-sysctl.txt
  8. 4 0
      Documentation/networking/mac80211-injection.txt
  9. 2 2
      Documentation/networking/netdevices.txt
  10. 42 2
      Documentation/networking/stmmac.txt
  11. 113 105
      MAINTAINERS
  12. 1 0
      arch/cris/arch-v10/drivers/Kconfig
  13. 1 0
      arch/cris/arch-v32/drivers/Kconfig
  14. 1 1
      arch/ia64/hp/sim/simeth.c
  15. 1 7
      arch/mips/Kconfig
  16. 31 0
      arch/mips/bcm47xx/Kconfig
  17. 2 1
      arch/mips/bcm47xx/Makefile
  18. 61 21
      arch/mips/bcm47xx/gpio.c
  19. 12 0
      arch/mips/bcm47xx/irq.c
  20. 25 4
      arch/mips/bcm47xx/nvram.c
  21. 44 2
      arch/mips/bcm47xx/serial.c
  22. 83 7
      arch/mips/bcm47xx/setup.c
  23. 14 2
      arch/mips/bcm47xx/time.c
  24. 9 5
      arch/mips/bcm47xx/wgt634u.c
  25. 24 2
      arch/mips/include/asm/mach-bcm47xx/bcm47xx.h
  26. 93 15
      arch/mips/include/asm/mach-bcm47xx/gpio.h
  27. 6 0
      arch/mips/pci/pci-bcm47xx.c
  28. 1 1
      arch/mips/txx9/generic/setup_tx4939.c
  29. 2 0
      arch/powerpc/Kconfig
  30. 2 8
      arch/powerpc/boot/dts/p1010rdb.dts
  31. 4 6
      arch/powerpc/boot/dts/p1010si.dtsi
  32. 6 5
      arch/powerpc/configs/40x/acadia_defconfig
  33. 3 2
      arch/powerpc/configs/40x/ep405_defconfig
  34. 3 2
      arch/powerpc/configs/40x/hcu4_defconfig
  35. 5 4
      arch/powerpc/configs/40x/kilauea_defconfig
  36. 5 4
      arch/powerpc/configs/40x/makalu_defconfig
  37. 3 2
      arch/powerpc/configs/40x/walnut_defconfig
  38. 5 4
      arch/powerpc/configs/44x/arches_defconfig
  39. 3 2
      arch/powerpc/configs/44x/bamboo_defconfig
  40. 5 4
      arch/powerpc/configs/44x/bluestone_defconfig
  41. 5 4
      arch/powerpc/configs/44x/canyonlands_defconfig
  42. 3 2
      arch/powerpc/configs/44x/ebony_defconfig
  43. 5 4
      arch/powerpc/configs/44x/eiger_defconfig
  44. 3 2
      arch/powerpc/configs/44x/icon_defconfig
  45. 3 2
      arch/powerpc/configs/44x/katmai_defconfig
  46. 6 5
      arch/powerpc/configs/44x/redwood_defconfig
  47. 3 2
      arch/powerpc/configs/44x/sam440ep_defconfig
  48. 3 2
      arch/powerpc/configs/44x/sequoia_defconfig
  49. 3 2
      arch/powerpc/configs/44x/taishan_defconfig
  50. 3 2
      arch/powerpc/configs/44x/warp_defconfig
  51. 3 2
      arch/powerpc/configs/ppc40x_defconfig
  52. 3 2
      arch/powerpc/configs/ppc44x_defconfig
  53. 6 6
      arch/powerpc/platforms/40x/Kconfig
  54. 27 27
      arch/powerpc/platforms/44x/Kconfig
  55. 4 4
      arch/powerpc/platforms/cell/Kconfig
  56. 75 3
      arch/s390/include/asm/qdio.h
  57. 0 25
      arch/sh/include/asm/sh_eth.h
  58. 1 1
      arch/um/drivers/net_kern.c
  59. 1 1
      arch/xtensa/platforms/iss/network.c
  60. 3 2
      drivers/atm/eni.c
  61. 145 120
      drivers/atm/iphase.c
  62. 192 203
      drivers/atm/iphase.h
  63. 15 2
      drivers/base/class.c
  64. 13 0
      drivers/bcma/Kconfig
  65. 2 0
      drivers/bcma/Makefile
  66. 16 0
      drivers/bcma/bcma_private.h
  67. 2 0
      drivers/bcma/core.c
  68. 53 0
      drivers/bcma/driver_chipcommon.c
  69. 181 10
      drivers/bcma/driver_chipcommon_pmu.c
  70. 256 0
      drivers/bcma/driver_mips.c
  71. 14 2
      drivers/bcma/driver_pci.c
  72. 183 0
      drivers/bcma/host_soc.c
  73. 69 1
      drivers/bcma/main.c
  74. 237 111
      drivers/bcma/scan.c
  75. 15 0
      drivers/bcma/sprom.c
  76. 4 2
      drivers/bluetooth/btusb.c
  77. 26 0
      drivers/connector/cn_proc.c
  78. 4 7
      drivers/infiniband/hw/amso1100/c2.c
  79. 1 1
      drivers/infiniband/hw/cxgb3/Makefile
  80. 1 1
      drivers/infiniband/hw/cxgb4/Makefile
  81. 2 1
      drivers/infiniband/hw/mlx4/Kconfig
  82. 15 14
      drivers/infiniband/hw/nes/nes_nic.c
  83. 4 3
      drivers/infiniband/ulp/ipoib/ipoib_cm.c
  84. 13 10
      drivers/infiniband/ulp/ipoib/ipoib_ib.c
  85. 1 1
      drivers/infiniband/ulp/ipoib/ipoib_main.c
  86. 1 1
      drivers/media/dvb/dvb-core/dvb_net.c
  87. 0 896
      drivers/net/3c501.c
  88. 0 778
      drivers/net/3c503.c
  89. 0 1673
      drivers/net/3c505.c
  90. 0 1594
      drivers/net/3c509.c
  91. 0 1584
      drivers/net/3c515.c
  92. 0 1312
      drivers/net/3c523.c
  93. 0 1661
      drivers/net/3c527.c
  94. 0 3326
      drivers/net/3c59x.c
  95. 0 2064
      drivers/net/8139cp.c
  96. 0 2622
      drivers/net/8139too.c
  97. 0 1632
      drivers/net/82596.c
  98. 0 103
      drivers/net/8390.c
  99. 0 105
      drivers/net/8390p.c
  100. 166 3281
      drivers/net/Kconfig

+ 8 - 0
Documentation/ABI/testing/sysfs-class-net-mesh

@@ -22,6 +22,14 @@ Description:
                 mesh will be fragmented or silently discarded if the
                 packet size exceeds the outgoing interface MTU.
 
+What:		/sys/class/net/<mesh_iface>/mesh/ap_isolation
+Date:		May 2011
+Contact:	Antonio Quartulli <ordex@autistici.org>
+Description:
+		Indicates whether the data traffic going from a
+		wireless client to another wireless client will be
+		silently dropped.
+
 What:           /sys/class/net/<mesh_iface>/mesh/gw_bandwidth
 Date:           October 2010
 Contact:        Marek Lindner <lindner_marek@yahoo.de>

+ 10 - 1
Documentation/DocBook/80211.tmpl

@@ -433,8 +433,18 @@
           Insert notes about VLAN interfaces with hw crypto here or
           in the hw crypto chapter.
         </para>
+      <section id="ps-client">
+        <title>support for powersaving clients</title>
+!Pinclude/net/mac80211.h AP support for powersaving clients
+      </section>
 !Finclude/net/mac80211.h ieee80211_get_buffered_bc
 !Finclude/net/mac80211.h ieee80211_beacon_get
+!Finclude/net/mac80211.h ieee80211_sta_eosp_irqsafe
+!Finclude/net/mac80211.h ieee80211_frame_release_type
+!Finclude/net/mac80211.h ieee80211_sta_ps_transition
+!Finclude/net/mac80211.h ieee80211_sta_ps_transition_ni
+!Finclude/net/mac80211.h ieee80211_sta_set_buffered
+!Finclude/net/mac80211.h ieee80211_sta_block_awake
       </chapter>
 
       <chapter id="multi-iface">
@@ -460,7 +470,6 @@
 !Finclude/net/mac80211.h sta_notify_cmd
 !Finclude/net/mac80211.h ieee80211_find_sta
 !Finclude/net/mac80211.h ieee80211_find_sta_by_ifaddr
-!Finclude/net/mac80211.h ieee80211_sta_block_awake
       </chapter>
 
       <chapter id="hardware-scan-offload">

+ 13 - 50
Documentation/devicetree/bindings/net/can/fsl-flexcan.txt

@@ -1,61 +1,24 @@
-CAN Device Tree Bindings
-------------------------
-2011 Freescale Semiconductor, Inc.
+Flexcan CAN contoller on Freescale's ARM and PowerPC system-on-a-chip (SOC).
 
-fsl,flexcan-v1.0 nodes
------------------------
-In addition to the required compatible-, reg- and interrupt-properties, you can
-also specify which clock source shall be used for the controller.
+Required properties:
 
-CPI Clock- Can Protocol Interface Clock
-	This CLK_SRC bit of CTRL(control register) selects the clock source to
-	the CAN Protocol Interface(CPI) to be either the peripheral clock
-	(driven by the PLL) or the crystal oscillator clock. The selected clock
-	is the one fed to the prescaler to generate the Serial Clock (Sclock).
-	The PRESDIV field of CTRL(control register) controls a prescaler that
-	generates the Serial Clock (Sclock), whose period defines the
-	time quantum used to compose the CAN waveform.
+- compatible : Should be "fsl,<processor>-flexcan"
 
-Can Engine Clock Source
-	There are two sources for CAN clock
-	- Platform Clock  It represents the bus clock
-	- Oscillator Clock
+  An implementation should also claim any of the following compatibles
+  that it is fully backwards compatible with:
 
-	Peripheral Clock (PLL)
-	--------------
-		     |
-		    ---------		      -------------
-		    |       |CPI Clock	      | Prescaler |       Sclock
-		    |       |---------------->| (1.. 256) |------------>
-		    ---------		      -------------
-                     |  |
-	--------------  ---------------------CLK_SRC
-	Oscillator Clock
+  - fsl,p1010-flexcan
 
-- fsl,flexcan-clock-source : CAN Engine Clock Source.This property selects
-			     the peripheral clock. PLL clock is fed to the
-			     prescaler to generate the Serial Clock (Sclock).
-			     Valid values are "oscillator" and "platform"
-			     "oscillator": CAN engine clock source is oscillator clock.
-			     "platform" The CAN engine clock source is the bus clock
-		             (platform clock).
+- reg : Offset and length of the register set for this device
+- interrupts : Interrupt tuple for this device
+- clock-frequency : The oscillator frequency driving the flexcan device
 
-- fsl,flexcan-clock-divider : for the reference and system clock, an additional
-			      clock divider can be specified.
-- clock-frequency: frequency required to calculate the bitrate for FlexCAN.
+Example:
 
-Note:
-	- v1.0 of flexcan-v1.0 represent the IP block version for P1010 SOC.
-	- P1010 does not have oscillator as the Clock Source.So the default
-	  Clock Source is platform clock.
-Examples:
-
-	can0@1c000 {
-		compatible = "fsl,flexcan-v1.0";
+	can@1c000 {
+		compatible = "fsl,p1010-flexcan";
 		reg = <0x1c000 0x1000>;
 		interrupts = <48 0x2>;
 		interrupt-parent = <&mpic>;
-		fsl,flexcan-clock-source = "platform";
-		fsl,flexcan-clock-divider = <2>;
-		clock-frequency = <fixed by u-boot>;
+		clock-frequency = <200000000>; // filled in by bootloader
 	};

+ 38 - 0
Documentation/devicetree/bindings/net/smsc911x.txt

@@ -0,0 +1,38 @@
+* Smart Mixed-Signal Connectivity (SMSC) LAN911x/912x Controller
+
+Required properties:
+- compatible : Should be "smsc,lan<model>", "smsc,lan9115"
+- reg : Address and length of the io space for SMSC LAN
+- interrupts : Should contain SMSC LAN interrupt line
+- interrupt-parent : Should be the phandle for the interrupt controller
+  that services interrupts for this device
+- phy-mode : String, operation mode of the PHY interface.
+  Supported values are: "mii", "gmii", "sgmii", "tbi", "rmii",
+  "rgmii", "rgmii-id", "rgmii-rxid", "rgmii-txid", "rtbi", "smii".
+
+Optional properties:
+- reg-shift : Specify the quantity to shift the register offsets by
+- reg-io-width : Specify the size (in bytes) of the IO accesses that
+  should be performed on the device.  Valid value for SMSC LAN is
+  2 or 4.  If it's omitted or invalid, the size would be 2.
+- smsc,irq-active-high : Indicates the IRQ polarity is active-high
+- smsc,irq-push-pull : Indicates the IRQ type is push-pull
+- smsc,force-internal-phy : Forces SMSC LAN controller to use
+  internal PHY
+- smsc,force-external-phy : Forces SMSC LAN controller to use
+  external PHY
+- smsc,save-mac-address : Indicates that mac address needs to be saved
+  before resetting the controller
+- local-mac-address : 6 bytes, mac address
+
+Examples:
+
+lan9220@f4000000 {
+	compatible = "smsc,lan9220", "smsc,lan9115";
+	reg = <0xf4000000 0x2000000>;
+	phy-mode = "mii";
+	interrupt-parent = <&gpio1>;
+	interrupts = <31>;
+	reg-io-width = <4>;
+	smsc,irq-push-pull;
+};

+ 9 - 0
Documentation/feature-removal-schedule.txt

@@ -594,9 +594,18 @@ Why:    In 3.0, we can now autodetect internal 3G device and already have
 Who:    Lee, Chun-Yi <jlee@novell.com>
 
 ----------------------------
+
 What:	The XFS nodelaylog mount option
 When:	3.3
 Why:	The delaylog mode that has been the default since 2.6.39 has proven
 	stable, and the old code is in the way of additional improvements in
 	the log code.
 Who:	Christoph Hellwig <hch@lst.de>
+
+----------------------------
+
+What:	iwlagn alias support
+When:	3.5
+Why:	The iwlagn module has been renamed iwlwifi.  The alias will be around
+	for backward compatibility for several cycles and then dropped.
+Who:	Don Fry <donald.h.fry@intel.com>

+ 4 - 4
Documentation/networking/batman-adv.txt

@@ -1,4 +1,4 @@
-[state: 17-04-2011]
+[state: 21-08-2011]
 
 BATMAN-ADV
 ----------
@@ -68,9 +68,9 @@ All  mesh  wide  settings  can be found in batman's own interface
 folder:
 
 #  ls  /sys/class/net/bat0/mesh/
-#  aggregated_ogms  gw_bandwidth  hop_penalty
-#  bonding          gw_mode       orig_interval
-#  fragmentation    gw_sel_class  vis_mode
+# aggregated_ogms   fragmentation gw_sel_class   vis_mode
+# ap_isolation      gw_bandwidth  hop_penalty
+# bonding           gw_mode       orig_interval
 
 
 There is a special folder for debugging information:

+ 8 - 9
Documentation/networking/ip-sysctl.txt

@@ -1045,6 +1045,11 @@ conf/interface/*:
 accept_ra - INTEGER
 	Accept Router Advertisements; autoconfigure using them.
 
+	It also determines whether or not to transmit Router
+	Solicitations. If and only if the functional setting is to
+	accept Router Advertisements, Router Solicitations will be
+	transmitted.
+
 	Possible values are:
 		0 Do not accept Router Advertisements.
 		1 Accept Router Advertisements if forwarding is disabled.
@@ -1115,14 +1120,14 @@ forwarding - INTEGER
 	Possible values are:
 		0 Forwarding disabled
 		1 Forwarding enabled
-		2 Forwarding enabled (Hybrid Mode)
 
 	FALSE (0):
 
 	By default, Host behaviour is assumed.  This means:
 
 	1. IsRouter flag is not set in Neighbour Advertisements.
-	2. Router Solicitations are being sent when necessary.
+	2. If accept_ra is TRUE (default), transmit Router
+	   Solicitations.
 	3. If accept_ra is TRUE (default), accept Router
 	   Advertisements (and do autoconfiguration).
 	4. If accept_redirects is TRUE (default), accept Redirects.
@@ -1133,16 +1138,10 @@ forwarding - INTEGER
 	This means exactly the reverse from the above:
 
 	1. IsRouter flag is set in Neighbour Advertisements.
-	2. Router Solicitations are not sent.
+	2. Router Solicitations are not sent unless accept_ra is 2.
 	3. Router Advertisements are ignored unless accept_ra is 2.
 	4. Redirects are ignored.
 
-	TRUE (2):
-
-	Hybrid mode. Same behaviour as TRUE, except for:
-
-	2. Router Solicitations are being sent when necessary.
-
 	Default: 0 (disabled) if global forwarding is disabled (default),
 		 otherwise 1 (enabled).
 

+ 4 - 0
Documentation/networking/mac80211-injection.txt

@@ -23,6 +23,10 @@ radiotap headers and used to control injection:
    IEEE80211_RADIOTAP_F_FRAG: frame will be fragmented if longer than the
 			      current fragmentation threshold.
 
+ * IEEE80211_RADIOTAP_TX_FLAGS
+
+   IEEE80211_RADIOTAP_F_TX_NOACK: frame should be sent without waiting for
+				  an ACK even if it is a unicast frame
 
 The injection code can also skip all other currently defined radiotap fields
 facilitating replay of captured radiotap headers directly.

+ 2 - 2
Documentation/networking/netdevices.txt

@@ -73,7 +73,7 @@ dev->hard_start_xmit:
 	has to lock by itself when needed. It is recommended to use a try lock
 	for this and return NETDEV_TX_LOCKED when the spin lock fails.
 	The locking there should also properly protect against 
-	set_multicast_list. Note that the use of NETIF_F_LLTX is deprecated.
+	set_rx_mode. Note that the use of NETIF_F_LLTX is deprecated.
 	Don't use it for new drivers.
 
 	Context: Process with BHs disabled or BH (timer),
@@ -92,7 +92,7 @@ dev->tx_timeout:
 	Context: BHs disabled
 	Notes: netif_queue_stopped() is guaranteed true
 
-dev->set_multicast_list:
+dev->set_rx_mode:
 	Synchronization: netif_tx_lock spinlock.
 	Context: BHs disabled
 

+ 42 - 2
Documentation/networking/stmmac.txt

@@ -76,7 +76,16 @@ core.
 
 4.5) DMA descriptors
 Driver handles both normal and enhanced descriptors. The latter has been only
-tested on DWC Ether MAC 10/100/1000 Universal version 3.41a.
+tested on DWC Ether MAC 10/100/1000 Universal version 3.41a and later.
+
+STMMAC supports DMA descriptor to operate both in dual buffer (RING)
+and linked-list(CHAINED) mode. In RING each descriptor points to two
+data buffer pointers whereas in CHAINED mode they point to only one data
+buffer pointer. RING mode is the default.
+
+In CHAINED mode each descriptor will have pointer to next descriptor in
+the list, hence creating the explicit chaining in the descriptor itself,
+whereas such explicit chaining is not possible in RING mode.
 
 4.6) Ethtool support
 Ethtool is supported. Driver statistics and internal errors can be taken using:
@@ -235,7 +244,38 @@ reset procedure etc).
  o enh_desc.c: functions for handling enhanced descriptors
  o norm_desc.c: functions for handling normal descriptors
 
-5) TODO:
+5) Debug Information
+
+The driver exports many information i.e. internal statistics,
+debug information, MAC and DMA registers etc.
+
+These can be read in several ways depending on the
+type of the information actually needed.
+
+For example a user can be use the ethtool support
+to get statistics: e.g. using: ethtool -S ethX
+(that shows the Management counters (MMC) if supported)
+or sees the MAC/DMA registers: e.g. using: ethtool -d ethX
+
+Compiling the Kernel with CONFIG_DEBUG_FS and enabling the
+STMMAC_DEBUG_FS option the driver will export the following
+debugfs entries:
+
+/sys/kernel/debug/stmmaceth/descriptors_status
+  To show the DMA TX/RX descriptor rings
+
+Developer can also use the "debug" module parameter to get
+further debug information.
+
+In the end, there are other macros (that cannot be enabled
+via menuconfig) to turn-on the RX/TX DMA debugging,
+specific MAC core debug printk etc. Others to enable the
+debug in the TX and RX processes.
+All these are only useful during the developing stage
+and should never enabled inside the code for general usage.
+In fact, these can generate an huge amount of debug messages.
+
+6) TODO:
  o XGMAC is not supported.
  o Review the timer optimisation code to use an embedded device that will be
   available in new chip generations.

+ 113 - 105
MAINTAINERS

@@ -117,20 +117,20 @@ Maintainers List (try to look for most precise areas first)
 M:	Philip Blundell <philb@gnu.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/3c505*
+F:	drivers/net/ethernet/i825xx/3c505*
 
 3C59X NETWORK DRIVER
 M:	Steffen Klassert <klassert@mathematik.tu-chemnitz.de>
 L:	netdev@vger.kernel.org
 S:	Maintained
 F:	Documentation/networking/vortex.txt
-F:	drivers/net/3c59x.c
+F:	drivers/net/ethernet/3com/3c59x.c
 
 3CR990 NETWORK DRIVER
 M:	David Dillow <dave@thedillows.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/typhoon*
+F:	drivers/net/ethernet/3com/typhoon*
 
 3WARE SAS/SATA-RAID SCSI DRIVERS (3W-XXXX, 3W-9XXX, 3W-SAS)
 M:	Adam Radford <linuxraid@lsi.com>
@@ -156,7 +156,7 @@ M:	Realtek linux nic maintainers <nic_swsd@realtek.com>
 M:	Francois Romieu <romieu@fr.zoreil.com>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/r8169.c
+F:	drivers/net/ethernet/realtek/r8169.c
 
 8250/16?50 (AND CLONE UARTS) SERIAL DRIVER
 M:	Greg Kroah-Hartman <gregkh@suse.de>
@@ -170,8 +170,7 @@ F:	include/linux/serial_8250.h
 8390 NETWORK DRIVERS [WD80x3/SMC-ELITE, SMC-ULTRA, NE2000, 3C503, etc.]
 L:	netdev@vger.kernel.org
 S:	Orphan / Obsolete
-F:	drivers/net/*8390*
-F:	drivers/net/ax88796.c
+F:	drivers/net/ethernet/8390/
 
 9P FILE SYSTEM
 M:	Eric Van Hensbergen <ericvh@gmail.com>
@@ -214,7 +213,7 @@ ACENIC DRIVER
 M:	Jes Sorensen <jes@trained-monkey.org>
 L:	linux-acenic@sunsite.dk
 S:	Maintained
-F:	drivers/net/acenic*
+F:	drivers/net/ethernet/alteon/acenic*
 
 ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER
 M:	Peter Feuerer <peter@piie.net>
@@ -746,7 +745,7 @@ L:	linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 W:	http://www.arm.linux.org.uk/
 S:	Maintained
 F:	arch/arm/mach-ebsa110/
-F:	drivers/net/arm/am79c961a.*
+F:	drivers/net/ethernet/amd/am79c961a.*
 
 ARM/EZX SMARTPHONES (A780, A910, A1200, E680, ROKR E2 and ROKR E6)
 M:	Daniel Ribeiro <drwyrm@gmail.com>
@@ -1015,7 +1014,8 @@ F:	arch/arm/include/asm/hardware/ioc.h
 F:	arch/arm/include/asm/hardware/iomd.h
 F:	arch/arm/include/asm/hardware/memc.h
 F:	arch/arm/mach-rpc/
-F:	drivers/net/arm/ether*
+F:	drivers/net/ethernet/i825xx/ether1*
+F:	drivers/net/ethernet/seeq/ether3*
 F:	drivers/scsi/arm/
 
 ARM/SHARK MACHINE SUPPORT
@@ -1127,7 +1127,7 @@ F:	arch/arm/mach-nuc93x/
 F:	drivers/input/keyboard/w90p910_keypad.c
 F:	drivers/input/touchscreen/w90p910_ts.c
 F:	drivers/watchdog/nuc900_wdt.c
-F:	drivers/net/arm/w90p910_ether.c
+F:	drivers/net/ethernet/nuvoton/w90p910_ether.c
 F:	drivers/mtd/nand/nuc900_nand.c
 F:	drivers/rtc/rtc-nuc900.c
 F:	drivers/spi/spi_nuc900.c
@@ -1230,7 +1230,7 @@ F:	Documentation/aoe/
 F:	drivers/block/aoe/
 
 ATHEROS ATH GENERIC UTILITIES
-M:	"Luis R. Rodriguez" <lrodriguez@atheros.com>
+M:	"Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
 L:	linux-wireless@vger.kernel.org
 S:	Supported
 F:	drivers/net/wireless/ath/*
@@ -1238,7 +1238,7 @@ F:	drivers/net/wireless/ath/*
 ATHEROS ATH5K WIRELESS DRIVER
 M:	Jiri Slaby <jirislaby@gmail.com>
 M:	Nick Kossifidis <mickflemm@gmail.com>
-M:	"Luis R. Rodriguez" <lrodriguez@atheros.com>
+M:	"Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
 M:	Bob Copeland <me@bobcopeland.com>
 L:	linux-wireless@vger.kernel.org
 L:	ath5k-devel@lists.ath5k.org
@@ -1246,11 +1246,19 @@ W:	http://wireless.kernel.org/en/users/Drivers/ath5k
 S:	Maintained
 F:	drivers/net/wireless/ath/ath5k/
 
+ATHEROS ATH6KL WIRELESS DRIVER
+M:	Kalle Valo <kvalo@qca.qualcomm.com>
+L:	linux-wireless@vger.kernel.org
+W:	http://wireless.kernel.org/en/users/Drivers/ath6kl
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath6kl.git
+S:	Supported
+F:	drivers/net/wireless/ath/ath6kl/
+
 ATHEROS ATH9K WIRELESS DRIVER
-M:	"Luis R. Rodriguez" <lrodriguez@atheros.com>
-M:	Jouni Malinen <jmalinen@atheros.com>
-M:	Vasanthakumar Thiagarajan <vasanth@atheros.com>
-M:	Senthil Balasubramanian <senthilkumar@atheros.com>
+M:	"Luis R. Rodriguez" <mcgrof@qca.qualcomm.com>
+M:	Jouni Malinen <jouni@qca.qualcomm.com>
+M:	Vasanthakumar Thiagarajan <vthiagar@qca.qualcomm.com>
+M:	Senthil Balasubramanian <senthilb@qca.qualcomm.com>
 L:	linux-wireless@vger.kernel.org
 L:	ath9k-devel@lists.ath9k.org
 W:	http://wireless.kernel.org/en/users/Drivers/ath9k
@@ -1282,7 +1290,7 @@ L:	netdev@vger.kernel.org
 W:	http://sourceforge.net/projects/atl1
 W:	http://atl1.sourceforge.net
 S:	Maintained
-F:	drivers/net/atlx/
+F:	drivers/net/ethernet/atheros/
 
 ATM
 M:	Chas Williams <chas@cmf.nrl.navy.mil>
@@ -1322,7 +1330,7 @@ F:	include/video/atmel_lcdc.h
 ATMEL MACB ETHERNET DRIVER
 M:	Nicolas Ferre <nicolas.ferre@atmel.com>
 S:	Supported
-F:	drivers/net/macb.*
+F:	drivers/net/ethernet/cadence/
 
 ATMEL SPI DRIVER
 M:	Nicolas Ferre <nicolas.ferre@atmel.com>
@@ -1445,7 +1453,7 @@ BLACKFIN EMAC DRIVER
 L:	uclinux-dist-devel@blackfin.uclinux.org
 W:	http://blackfin.uclinux.org
 S:	Supported
-F:	drivers/net/bfin_mac.*
+F:	drivers/net/ethernet/adi/
 
 BLACKFIN RTC DRIVER
 M:	Mike Frysinger <vapier.adi@gmail.com>
@@ -1526,27 +1534,27 @@ BROADCOM B44 10/100 ETHERNET DRIVER
 M:	Gary Zambrano <zambrano@broadcom.com>
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/b44.*
+F:	drivers/net/ethernet/broadcom/b44.*
 
 BROADCOM BNX2 GIGABIT ETHERNET DRIVER
 M:	Michael Chan <mchan@broadcom.com>
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/bnx2.*
-F:	drivers/net/bnx2_*
+F:	drivers/net/ethernet/broadcom/bnx2.*
+F:	drivers/net/ethernet/broadcom/bnx2_*
 
 BROADCOM BNX2X 10 GIGABIT ETHERNET DRIVER
 M:	Eilon Greenstein <eilong@broadcom.com>
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/bnx2x/
+F:	drivers/net/ethernet/broadcom/bnx2x/
 
 BROADCOM TG3 GIGABIT ETHERNET DRIVER
 M:	Matt Carlson <mcarlson@broadcom.com>
 M:	Michael Chan <mchan@broadcom.com>
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/tg3.*
+F:	drivers/net/ethernet/broadcom/tg3.*
 
 BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER
 M:	Brett Rudley <brudley@broadcom.com>
@@ -1575,7 +1583,7 @@ BROCADE BNA 10 GIGABIT ETHERNET DRIVER
 M:	Rasesh Mody <rmody@brocade.com>
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/bna/
+F:	drivers/net/ethernet/brocade/bna/
 
 BSG (block layer generic sg v4 driver)
 M:	FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
@@ -1663,7 +1671,7 @@ CAN NETWORK LAYER
 M:	Oliver Hartkopp <socketcan@hartkopp.net>
 M:	Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
 M:	Urs Thuermann <urs.thuermann@volkswagen.de>
-L:	socketcan-core@lists.berlios.de (subscribers-only)
+L:	linux-can@vger.kernel.org
 L:	netdev@vger.kernel.org
 W:	http://developer.berlios.de/projects/socketcan/
 S:	Maintained
@@ -1675,7 +1683,7 @@ F:	include/linux/can/raw.h
 
 CAN NETWORK DRIVERS
 M:	Wolfgang Grandegger <wg@grandegger.com>
-L:	socketcan-core@lists.berlios.de (subscribers-only)
+L:	linux-can@vger.kernel.org
 L:	netdev@vger.kernel.org
 W:	http://developer.berlios.de/projects/socketcan/
 S:	Maintained
@@ -1759,13 +1767,13 @@ M:	Christian Benvenuti <benve@cisco.com>
 M:	Roopa Prabhu <roprabhu@cisco.com>
 M:	David Wang <dwang2@cisco.com>
 S:	Supported
-F:	drivers/net/enic/
+F:	drivers/net/ethernet/cisco/enic/
 
 CIRRUS LOGIC EP93XX ETHERNET DRIVER
 M:	Hartley Sweeten <hsweeten@visionengravers.com>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/arm/ep93xx_eth.c
+F:	drivers/net/ethernet/cirrus/ep93xx_eth.c
 
 CIRRUS LOGIC EP93XX OHCI USB HOST DRIVER
 M:	Lennert Buytenhek <kernel@wantstofly.org>
@@ -1905,7 +1913,7 @@ CPMAC ETHERNET DRIVER
 M:	Florian Fainelli <florian@openwrt.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/cpmac.c
+F:	drivers/net/ethernet/ti/cpmac.c
 
 CPU FREQUENCY DRIVERS
 M:	Dave Jones <davej@redhat.com>
@@ -1992,7 +2000,7 @@ M:	Divy Le Ray <divy@chelsio.com>
 L:	netdev@vger.kernel.org
 W:	http://www.chelsio.com
 S:	Supported
-F:	drivers/net/cxgb3/
+F:	drivers/net/ethernet/chelsio/cxgb3/
 
 CXGB3 IWARP RNIC DRIVER (IW_CXGB3)
 M:	Steve Wise <swise@chelsio.com>
@@ -2006,7 +2014,7 @@ M:	Dimitris Michailidis <dm@chelsio.com>
 L:	netdev@vger.kernel.org
 W:	http://www.chelsio.com
 S:	Supported
-F:	drivers/net/cxgb4/
+F:	drivers/net/ethernet/chelsio/cxgb4/
 
 CXGB4 IWARP RNIC DRIVER (IW_CXGB4)
 M:	Steve Wise <swise@chelsio.com>
@@ -2020,14 +2028,14 @@ M:	Casey Leedom <leedom@chelsio.com>
 L:	netdev@vger.kernel.org
 W:	http://www.chelsio.com
 S:	Supported
-F:	drivers/net/cxgb4vf/
+F:	drivers/net/ethernet/chelsio/cxgb4vf/
 
 STMMAC ETHERNET DRIVER
 M:	Giuseppe Cavallaro <peppe.cavallaro@st.com>
 L:	netdev@vger.kernel.org
 W:	http://www.stlinux.com
 S:	Supported
-F:	drivers/net/stmmac/
+F:	drivers/net/ethernet/stmicro/stmmac/
 
 CYBERPRO FB DRIVER
 M:	Russell King <linux@arm.linux.org.uk>
@@ -2071,7 +2079,7 @@ DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER
 L:	netdev@vger.kernel.org
 S:	Orphan
 F:	Documentation/networking/dmfe.txt
-F:	drivers/net/tulip/dmfe.c
+F:	drivers/net/ethernet/tulip/dmfe.c
 
 DC390/AM53C974 SCSI driver
 M:	Kurt Garloff <garloff@suse.de>
@@ -2110,7 +2118,7 @@ F:	net/decnet/
 DEFXX FDDI NETWORK DRIVER
 M:	"Maciej W. Rozycki" <macro@linux-mips.org>
 S:	Maintained
-F:	drivers/net/defxx.*
+F:	drivers/net/fddi/defxx.*
 
 DELL LAPTOP DRIVER
 M:	Matthew Garrett <mjg59@srcf.ucam.org>
@@ -2477,7 +2485,7 @@ EHEA (IBM pSeries eHEA 10Gb ethernet adapter) DRIVER
 M:	Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/ehea/
+F:	drivers/net/ethernet/ibm/ehea/
 
 EMBEDDED LINUX
 M:	Paul Gortmaker <paul.gortmaker@windriver.com>
@@ -2522,7 +2530,7 @@ ETHEREXPRESS-16 NETWORK DRIVER
 M:	Philip Blundell <philb@gnu.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/eexpress.*
+F:	drivers/net/ethernet/i825xx/eexpress.*
 
 ETHERNET BRIDGE
 M:	Stephen Hemminger <shemminger@linux-foundation.org>
@@ -2536,7 +2544,7 @@ F:	net/bridge/
 ETHERTEAM 16I DRIVER
 M:	Mika Kuoppala <miku@iki.fi>
 S:	Maintained
-F:	drivers/net/eth16i.c
+F:	drivers/net/ethernet/fujitsu/eth16i.c
 
 EXT2 FILE SYSTEM
 M:	Jan Kara <jack@suse.cz>
@@ -2705,7 +2713,7 @@ M:	Vitaly Bordug <vbordug@ru.mvista.com>
 L:	linuxppc-dev@lists.ozlabs.org
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/fs_enet/
+F:	drivers/net/ethernet/freescale/fs_enet/
 F:	include/linux/fs_enet_pd.h
 
 FREESCALE QUICC ENGINE LIBRARY
@@ -2727,7 +2735,7 @@ M:	Li Yang <leoli@freescale.com>
 L:	netdev@vger.kernel.org
 L:	linuxppc-dev@lists.ozlabs.org
 S:	Maintained
-F:	drivers/net/ucc_geth*
+F:	drivers/net/ethernet/freescale/ucc_geth*
 
 FREESCALE QUICC ENGINE UCC UART DRIVER
 M:	Timur Tabi <timur@freescale.com>
@@ -3065,6 +3073,7 @@ S:	Maintained
 F:	include/linux/hippidevice.h
 F:	include/linux/if_hippi.h
 F:	net/802/hippi.c
+F:	drivers/net/hippi/
 
 HOST AP DRIVER
 M:	Jouni Malinen <j@w1.fi>
@@ -3082,7 +3091,7 @@ F:	drivers/platform/x86/tc1100-wmi.c
 HP100:	Driver for HP 10/100 Mbit/s Voice Grade Network Adapter Series
 M:	Jaroslav Kysela <perex@perex.cz>
 S:	Maintained
-F:	drivers/net/hp100.*
+F:	drivers/net/ethernet/hp/hp100.*
 
 HPET:	High Precision Event Timers driver
 M:	Clemens Ladisch <clemens@ladisch.de>
@@ -3180,7 +3189,7 @@ IBM Power Virtual Ethernet Device Driver
 M:	Santiago Leon <santil@linux.vnet.ibm.com>
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/ibmveth.*
+F:	drivers/net/ethernet/ibm/ibmveth.*
 
 IBM ServeRAID RAID DRIVER
 P:	Jack Hammer
@@ -3347,7 +3356,7 @@ F:	arch/arm/mach-ixp4xx/include/mach/qmgr.h
 F:	arch/arm/mach-ixp4xx/include/mach/npe.h
 F:	arch/arm/mach-ixp4xx/ixp4xx_qmgr.c
 F:	arch/arm/mach-ixp4xx/ixp4xx_npe.c
-F:	drivers/net/arm/ixp4xx_eth.c
+F:	drivers/net/ethernet/xscale/ixp4xx_eth.c
 F:	drivers/net/wan/ixp4xx_hss.c
 
 INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
@@ -3359,7 +3368,7 @@ INTEL IXP2000 ETHERNET DRIVER
 M:	Lennert Buytenhek <kernel@wantstofly.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/ixp2000/
+F:	drivers/net/ethernet/xscale/ixp2000/
 
 INTEL ETHERNET DRIVERS (e100/e1000/e1000e/igb/igbvf/ixgb/ixgbe/ixgbevf)
 M:	Jeff Kirsher <jeffrey.t.kirsher@intel.com>
@@ -3368,13 +3377,13 @@ M:	Bruce Allan <bruce.w.allan@intel.com>
 M:	Carolyn Wyborny <carolyn.wyborny@intel.com>
 M:	Don Skidmore <donald.c.skidmore@intel.com>
 M:	Greg Rose <gregory.v.rose@intel.com>
-M:	PJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>
+M:	Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
 M:	Alex Duyck <alexander.h.duyck@intel.com>
 M:	John Ronciak <john.ronciak@intel.com>
 L:	e1000-devel@lists.sourceforge.net
 W:	http://e1000.sourceforge.net/
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-2.6.git
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next.git
 S:	Supported
 F:	Documentation/networking/e100.txt
 F:	Documentation/networking/e1000.txt
@@ -3384,14 +3393,7 @@ F:	Documentation/networking/igbvf.txt
 F:	Documentation/networking/ixgb.txt
 F:	Documentation/networking/ixgbe.txt
 F:	Documentation/networking/ixgbevf.txt
-F:	drivers/net/e100.c
-F:	drivers/net/e1000/
-F:	drivers/net/e1000e/
-F:	drivers/net/igb/
-F:	drivers/net/igbvf/
-F:	drivers/net/ixgb/
-F:	drivers/net/ixgbe/
-F:	drivers/net/ixgbevf/
+F:	drivers/net/ethernet/intel/
 
 INTEL MRST PMU DRIVER
 M:	Len Brown <len.brown@intel.com>
@@ -3443,7 +3445,7 @@ M:	Wey-Yi Guy <wey-yi.w.guy@intel.com>
 M:	Intel Linux Wireless <ilw@linux.intel.com>
 L:	linux-wireless@vger.kernel.org
 W:	http://intellinuxwireless.org
-T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
+T:	git git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi.git
 S:	Supported
 F:	drivers/net/wireless/iwlwifi/
 
@@ -3459,7 +3461,7 @@ IOC3 ETHERNET DRIVER
 M:	Ralf Baechle <ralf@linux-mips.org>
 L:	linux-mips@linux-mips.org
 S:	Maintained
-F:	drivers/net/ioc3-eth.c
+F:	drivers/net/ethernet/sgi/ioc3-eth.c
 
 IOC3 SERIAL DRIVER
 M:	Pat Gefre <pfg@sgi.com>
@@ -3477,7 +3479,7 @@ M:	Francois Romieu <romieu@fr.zoreil.com>
 M:	Sorbica Shieh <sorbica@icplus.com.tw>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/ipg.*
+F:	drivers/net/ethernet/icplus/ipg.*
 
 IPATH DRIVER
 M:	Mike Marciniszyn <infinipath@qlogic.com>
@@ -3625,7 +3627,7 @@ JME NETWORK DRIVER
 M:	Guo-Fu Tseng <cooldavid@cooldavid.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/jme.*
+F:	drivers/net/ethernet/jme.*
 
 JOURNALLING FLASH FILE SYSTEM V2 (JFFS2)
 M:	David Woodhouse <dwmw2@infradead.org>
@@ -4156,7 +4158,7 @@ MARVELL MV643XX ETHERNET DRIVER
 M:	Lennert Buytenhek <buytenh@wantstofly.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/mv643xx_eth.*
+F:	drivers/net/ethernet/marvell/mv643xx_eth.*
 F:	include/linux/mv643xx.h
 
 MARVELL MWIFIEX WIRELESS DRIVER
@@ -4370,12 +4372,12 @@ M:	Andrew Gallatin <gallatin@myri.com>
 L:	netdev@vger.kernel.org
 W:	http://www.myri.com/scs/download-Myri10GE.html
 S:	Supported
-F:	drivers/net/myri10ge/
+F:	drivers/net/ethernet/myricom/myri10ge/
 
 NATSEMI ETHERNET DRIVER (DP8381x)
 M:	Tim Hockin <thockin@hockin.org>
 S:	Maintained
-F:	drivers/net/natsemi.c
+F:	drivers/net/ethernet/natsemi/natsemi.c
 
 NATIVE INSTRUMENTS USB SOUND INTERFACE DRIVER
 M:	Daniel Mack <zonque@gmail.com>
@@ -4415,9 +4417,8 @@ W:	http://trac.neterion.com/cgi-bin/trac.cgi/wiki/Linux?Anonymous
 W:	http://trac.neterion.com/cgi-bin/trac.cgi/wiki/X3100Linux?Anonymous
 S:	Supported
 F:	Documentation/networking/s2io.txt
-F:	drivers/net/s2io*
 F:	Documentation/networking/vxge.txt
-F:	drivers/net/vxge/
+F:	drivers/net/ethernet/neterion/
 
 NETFILTER/IPTABLES/IPCHAINS
 P:	Rusty Russell
@@ -4531,11 +4532,23 @@ F:	include/linux/if_*
 F:	include/linux/*device.h
 
 NETXEN (1/10) GbE SUPPORT
-M:	Amit Kumar Salecha <amit.salecha@qlogic.com>
+M:	Sony Chacko <sony.chacko@qlogic.com>
+M:	Rajesh Borundia <rajesh.borundia@qlogic.com>
 L:	netdev@vger.kernel.org
 W:	http://www.qlogic.com
 S:	Supported
-F:	drivers/net/netxen/
+F:	drivers/net/ethernet/qlogic/netxen/
+
+NFC SUBSYSTEM
+M:	Lauro Ramos Venancio <lauro.venancio@openbossa.org>
+M:	Aloisio Almeida Jr <aloisio.almeida@openbossa.org>
+M:	Samuel Ortiz <sameo@linux.intel.com>
+L:	linux-wireless@vger.kernel.org
+S:	Maintained
+F:	net/nfc/
+F:	include/linux/nfc.h
+F:	include/net/nfc/
+F:	drivers/nfc/
 
 NFS, SUNRPC, AND LOCKD CLIENTS
 M:	Trond Myklebust <Trond.Myklebust@netapp.com>
@@ -4556,7 +4569,7 @@ M:	Jan-Pascal van Best <janpascal@vanbest.org>
 M:	Andreas Mohr <andi@lisas.de>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/ni5010.*
+F:	drivers/net/ethernet/racal/ni5010.*
 
 NILFS2 FILESYSTEM
 M:	KONISHI Ryusuke <konishi.ryusuke@lab.ntt.co.jp>
@@ -4822,7 +4835,7 @@ PA SEMI ETHERNET DRIVER
 M:	Olof Johansson <olof@lixom.net>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/pasemi_mac.*
+F:	drivers/net/ethernet/pasemi/*
 
 PA SEMI SMBUS DRIVER
 M:	Olof Johansson <olof@lixom.net>
@@ -4969,7 +4982,7 @@ PCNET32 NETWORK DRIVER
 M:	Don Fry <pcnet32@frontier.com>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/pcnet32.c
+F:	drivers/net/ethernet/amd/pcnet32.c
 
 PCRYPT PARALLEL CRYPTO ENGINE
 M:	Steffen Klassert <steffen.klassert@secunet.com>
@@ -5101,7 +5114,7 @@ PPP PROTOCOL DRIVERS AND COMPRESSORS
 M:	Paul Mackerras <paulus@samba.org>
 L:	linux-ppp@vger.kernel.org
 S:	Maintained
-F:	drivers/net/ppp_*
+F:	drivers/net/ppp/ppp_*
 
 PPP OVER ATM (RFC 2364)
 M:	Mitchell Blank Jr <mitch@sfgoth.com>
@@ -5112,8 +5125,8 @@ F:	include/linux/atmppp.h
 PPP OVER ETHERNET
 M:	Michal Ostrowski <mostrows@earthlink.net>
 S:	Maintained
-F:	drivers/net/pppoe.c
-F:	drivers/net/pppox.c
+F:	drivers/net/ppp/pppoe.c
+F:	drivers/net/ppp/pppox.c
 
 PPP OVER L2TP
 M:	James Chapman <jchapman@katalix.com>
@@ -5134,7 +5147,7 @@ PPTP DRIVER
 M:	Dmitry Kozlov <xeb@mail.ru>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/pptp.c
+F:	drivers/net/ppp/pptp.c
 W:	http://sourceforge.net/projects/accel-pptp
 
 PREEMPTIBLE KERNEL
@@ -5163,7 +5176,7 @@ M:	Geoff Levand <geoff@infradead.org>
 L:	netdev@vger.kernel.org
 L:	cbe-oss-dev@lists.ozlabs.org
 S:	Maintained
-F:	drivers/net/ps3_gelic_net.*
+F:	drivers/net/ethernet/toshiba/ps3_gelic_net.*
 
 PS3 PLATFORM SUPPORT
 M:	Geoff Levand <geoff@infradead.org>
@@ -5281,23 +5294,24 @@ M:	linux-driver@qlogic.com
 L:	netdev@vger.kernel.org
 S:	Supported
 F:	Documentation/networking/LICENSE.qla3xxx
-F:	drivers/net/qla3xxx.*
+F:	drivers/net/ethernet/qlogic/qla3xxx.*
 
 QLOGIC QLCNIC (1/10)Gb ETHERNET DRIVER
-M:	Amit Kumar Salecha <amit.salecha@qlogic.com>
 M:	Anirban Chakraborty <anirban.chakraborty@qlogic.com>
+M:	Sony Chacko <sony.chacko@qlogic.com>
 M:	linux-driver@qlogic.com
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/qlcnic/
+F:	drivers/net/ethernet/qlogic/qlcnic/
 
 QLOGIC QLGE 10Gb ETHERNET DRIVER
+M:	Anirban Chakraborty <anirban.chakraborty@qlogic.com>
 M:	Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
 M:	Ron Mercer <ron.mercer@qlogic.com>
 M:	linux-driver@qlogic.com
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/qlge/
+F:	drivers/net/ethernet/qlogic/qlge/
 
 QNX4 FILESYSTEM
 M:	Anders Larsen <al@alarsen.net>
@@ -5379,7 +5393,7 @@ RDC R6040 FAST ETHERNET DRIVER
 M:	Florian Fainelli <florian@openwrt.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/r6040.c
+F:	drivers/net/ethernet/rdc/r6040.c
 
 RDS - RELIABLE DATAGRAM SOCKETS
 M:	Andy Grover <andy.grover@oracle.com>
@@ -5783,7 +5797,7 @@ M:	Ajit Khaparde <ajit.khaparde@emulex.com>
 L:	netdev@vger.kernel.org
 W:	http://www.emulex.com
 S:	Supported
-F:	drivers/net/benet/
+F:	drivers/net/ethernet/emulex/benet/
 
 SFC NETWORK DRIVER
 M:	Solarflare linux maintainers <linux-net-drivers@solarflare.com>
@@ -5791,7 +5805,7 @@ M:	Steve Hodgson <shodgson@solarflare.com>
 M:	Ben Hutchings <bhutchings@solarflare.com>
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/sfc/
+F:	drivers/net/ethernet/sfc/
 
 SGI GRU DRIVER
 M:	Jack Steiner <steiner@sgi.com>
@@ -5857,14 +5871,14 @@ SIS 190 ETHERNET DRIVER
 M:	Francois Romieu <romieu@fr.zoreil.com>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/sis190.c
+F:	drivers/net/ethernet/sis/sis190.c
 
 SIS 900/7016 FAST ETHERNET DRIVER
 M:	Daniele Venzano <venza@brownhat.org>
 W:	http://www.brownhat.org/sis900.html
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/sis900.*
+F:	drivers/net/ethernet/sis/sis900.*
 
 SIS 96X I2C/SMBUS DRIVER
 M:	"Mark M. Hoffman" <mhoffman@lightlink.com>
@@ -5891,8 +5905,7 @@ SKGE, SKY2 10/100/1000 GIGABIT ETHERNET DRIVERS
 M:	Stephen Hemminger <shemminger@linux-foundation.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/skge.*
-F:	drivers/net/sky2.*
+F:	drivers/net/ethernet/marvell/sk*
 
 SLAB ALLOCATOR
 M:	Christoph Lameter <cl@linux-foundation.org>
@@ -5906,7 +5919,7 @@ F:	mm/sl?b.c
 SMC91x ETHERNET DRIVER
 M:	Nicolas Pitre <nico@fluxnic.net>
 S:	Odd Fixes
-F:	drivers/net/smc91x.*
+F:	drivers/net/ethernet/smsc/smc91x.*
 
 SMM665 HARDWARE MONITOR DRIVER
 M:	Guenter Roeck <linux@roeck-us.net>
@@ -5941,13 +5954,13 @@ M:	Steve Glendinning <steve.glendinning@smsc.com>
 L:	netdev@vger.kernel.org
 S:	Supported
 F:	include/linux/smsc911x.h
-F:	drivers/net/smsc911x.*
+F:	drivers/net/ethernet/smsc/smsc911x.*
 
 SMSC9420 PCI ETHERNET DRIVER
 M:	Steve Glendinning <steve.glendinning@smsc.com>
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/smsc9420.*
+F:	drivers/net/ethernet/smsc/smsc9420.*
 
 SN-IA64 (Itanium) SUB-PLATFORM
 M:	Jes Sorensen <jes@sgi.com>
@@ -5981,7 +5994,7 @@ SONIC NETWORK DRIVER
 M:	Thomas Bogendoerfer <tsbogend@alpha.franken.de>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/sonic.*
+F:	drivers/net/ethernet/natsemi/sonic.*
 
 SONICS SILICON BACKPLANE DRIVER (SSB)
 M:	Michael Buesch <m@bues.ch>
@@ -6122,7 +6135,7 @@ M:	Jens Osterkamp <jens@de.ibm.com>
 L:	netdev@vger.kernel.org
 S:	Supported
 F:	Documentation/networking/spider_net.txt
-F:	drivers/net/spider_net*
+F:	drivers/net/ethernet/toshiba/spider_net*
 
 SPU FILE SYSTEM
 M:	Jeremy Kerr <jk@ozlabs.org>
@@ -6169,12 +6182,6 @@ M:	Jakub Schmidtke <sjakub@gmail.com>
 S:	Odd Fixes
 F:	drivers/staging/asus_oled/
 
-STAGING - ATHEROS ATH6KL WIRELESS DRIVER
-M:	Luis R. Rodriguez <mcgrof@gmail.com>
-M:	Naveen Singh <nsingh@atheros.com>
-S:	Odd Fixes
-F:	drivers/staging/ath6kl/
-
 STAGING - COMEDI
 M:	Ian Abbott <abbotti@mev.co.uk>
 M:	Mori Hess <fmhess@users.sourceforge.net>
@@ -6300,7 +6307,7 @@ F:	drivers/staging/xgifb/
 STARFIRE/DURALAN NETWORK DRIVER
 M:	Ion Badulescu <ionut@badula.org>
 S:	Odd Fixes
-F:	drivers/net/starfire*
+F:	drivers/net/ethernet/adaptec/starfire*
 
 SUN3/3X
 M:	Sam Creasey <sammy@sammy.net>
@@ -6309,6 +6316,7 @@ S:	Maintained
 F:	arch/m68k/kernel/*sun3*
 F:	arch/m68k/sun3*/
 F:	arch/m68k/include/asm/sun3*
+F:	drivers/net/ethernet/i825xx/sun3*
 
 SUPERH
 M:	Paul Mundt <lethal@linux-sh.org>
@@ -6396,7 +6404,7 @@ TEHUTI ETHERNET DRIVER
 M:	Andy Gospodarek <andy@greyhouse.net>
 L:	netdev@vger.kernel.org
 S:	Supported
-F:	drivers/net/tehuti*
+F:	drivers/net/ethernet/tehuti/*
 
 Telecom Clock Driver for MCPL0010
 M:	Mark Gross <mark.gross@intel.com>
@@ -6447,7 +6455,7 @@ W:	http://www.tilera.com/scm/
 S:	Supported
 F:	arch/tile/
 F:	drivers/tty/hvc/hvc_tile.c
-F:	drivers/net/tile/
+F:	drivers/net/ethernet/tile/
 F:	drivers/edac/tile_edac.c
 
 TLAN NETWORK DRIVER
@@ -6456,7 +6464,7 @@ L:	tlan-devel@lists.sourceforge.net (subscribers-only)
 W:	http://sourceforge.net/projects/tlan/
 S:	Maintained
 F:	Documentation/networking/tlan.txt
-F:	drivers/net/tlan.*
+F:	drivers/net/ethernet/ti/tlan.*
 
 TOMOYO SECURITY MODULE
 M:	Kentaro Takeda <takedakn@nttdata.co.jp>
@@ -6550,7 +6558,7 @@ TULIP NETWORK DRIVERS
 M:	Grant Grundler <grundler@parisc-linux.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/tulip/
+F:	drivers/net/ethernet/tulip/
 
 TUN/TAP driver
 M:	Maxim Krasnyansky <maxk@qualcomm.com>
@@ -6596,7 +6604,7 @@ W:	http://uclinux-h8.sourceforge.jp/
 S:	Supported
 F:	arch/h8300/
 F:	drivers/ide/ide-h8300.c
-F:	drivers/net/ne-h8300.c
+F:	drivers/net/ethernet/8390/ne-h8300.c
 
 UDF FILESYSTEM
 M:	Jan Kara <jack@suse.cz>
@@ -7024,7 +7032,7 @@ F:	include/linux/vhost.h
 VIA RHINE NETWORK DRIVER
 M:	Roger Luethi <rl@hellgate.ch>
 S:	Maintained
-F:	drivers/net/via-rhine.c
+F:	drivers/net/ethernet/via/via-rhine.c
 
 VIAPRO SMBUS DRIVER
 M:	Jean Delvare <khali@linux-fr.org>
@@ -7052,7 +7060,7 @@ VIA VELOCITY NETWORK DRIVER
 M:	Francois Romieu <romieu@fr.zoreil.com>
 L:	netdev@vger.kernel.org
 S:	Maintained
-F:	drivers/net/via-velocity.*
+F:	drivers/net/ethernet/via/via-velocity.*
 
 VLAN (802.1Q)
 M:	Patrick McHardy <kaber@trash.net>

+ 1 - 0
arch/cris/arch-v10/drivers/Kconfig

@@ -4,6 +4,7 @@ config ETRAX_ETHERNET
 	bool "Ethernet support"
 	depends on ETRAX_ARCH_V10
 	select NET_ETHERNET
+	select NET_CORE
 	select MII
 	help
 	  This option enables the ETRAX 100LX built-in 10/100Mbit Ethernet

+ 1 - 0
arch/cris/arch-v32/drivers/Kconfig

@@ -4,6 +4,7 @@ config ETRAX_ETHERNET
 	bool "Ethernet support"
 	depends on ETRAX_ARCH_V32
 	select NET_ETHERNET
+	select NET_CORE
 	select MII
 	help
 	  This option enables the ETRAX FS built-in 10/100Mbit Ethernet

+ 1 - 1
arch/ia64/hp/sim/simeth.c

@@ -172,7 +172,7 @@ static const struct net_device_ops simeth_netdev_ops = {
 	.ndo_stop		= simeth_close,
 	.ndo_start_xmit		= simeth_tx,
 	.ndo_get_stats		= simeth_get_stats,
-	.ndo_set_multicast_list	= set_multicast_list, /* not yet used */
+	.ndo_set_rx_mode	= set_multicast_list, /* not yet used */
 
 };
 

+ 1 - 7
arch/mips/Kconfig

@@ -92,15 +92,8 @@ config BCM47XX
 	select DMA_NONCOHERENT
 	select HW_HAS_PCI
 	select IRQ_CPU
-	select SYS_HAS_CPU_MIPS32_R1
 	select SYS_SUPPORTS_32BIT_KERNEL
 	select SYS_SUPPORTS_LITTLE_ENDIAN
-	select SSB
-	select SSB_DRIVER_MIPS
-	select SSB_DRIVER_EXTIF
-	select SSB_EMBEDDED
-	select SSB_B43_PCI_BRIDGE if PCI
-	select SSB_PCICORE_HOSTMODE if PCI
 	select GENERIC_GPIO
 	select SYS_HAS_EARLY_PRINTK
 	select CFE
@@ -791,6 +784,7 @@ endchoice
 
 source "arch/mips/alchemy/Kconfig"
 source "arch/mips/ath79/Kconfig"
+source "arch/mips/bcm47xx/Kconfig"
 source "arch/mips/bcm63xx/Kconfig"
 source "arch/mips/jazz/Kconfig"
 source "arch/mips/jz4740/Kconfig"

+ 31 - 0
arch/mips/bcm47xx/Kconfig

@@ -0,0 +1,31 @@
+if BCM47XX
+
+config BCM47XX_SSB
+	bool "SSB Support for Broadcom BCM47XX"
+	select SYS_HAS_CPU_MIPS32_R1
+	select SSB
+	select SSB_DRIVER_MIPS
+	select SSB_DRIVER_EXTIF
+	select SSB_EMBEDDED
+	select SSB_B43_PCI_BRIDGE if PCI
+	select SSB_PCICORE_HOSTMODE if PCI
+	default y
+	help
+	 Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
+
+	 This will generate an image with support for SSB and MIPS32 R1 instruction set.
+
+config BCM47XX_BCMA
+	bool "BCMA Support for Broadcom BCM47XX"
+	select SYS_HAS_CPU_MIPS32_R2
+	select BCMA
+	select BCMA_HOST_SOC
+	select BCMA_DRIVER_MIPS
+	select BCMA_DRIVER_PCI_HOSTMODE if PCI
+	default y
+	help
+	 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
+
+	 This will generate an image with support for BCMA and MIPS32 R2 instruction set.
+
+endif

+ 2 - 1
arch/mips/bcm47xx/Makefile

@@ -3,4 +3,5 @@
 # under Linux.
 #
 
-obj-y := gpio.o irq.o nvram.o prom.o serial.o setup.o time.o wgt634u.o
+obj-y 				+= gpio.o irq.o nvram.o prom.o serial.o setup.o time.o
+obj-$(CONFIG_BCM47XX_SSB)	+= wgt634u.o

+ 61 - 21
arch/mips/bcm47xx/gpio.c

@@ -20,42 +20,82 @@ static DECLARE_BITMAP(gpio_in_use, BCM47XX_EXTIF_GPIO_LINES);
 
 int gpio_request(unsigned gpio, const char *tag)
 {
-	if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
-	    ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
-		return -EINVAL;
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
+		    ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
+			return -EINVAL;
 
-	if (ssb_extif_available(&ssb_bcm47xx.extif) &&
-	    ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
-		return -EINVAL;
+		if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
+		    ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+			return -EINVAL;
 
-	if (test_and_set_bit(gpio, gpio_in_use))
-		return -EBUSY;
+		if (test_and_set_bit(gpio, gpio_in_use))
+			return -EBUSY;
 
-	return 0;
+		return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
+			return -EINVAL;
+
+		if (test_and_set_bit(gpio, gpio_in_use))
+			return -EBUSY;
+
+		return 0;
+#endif
+	}
+	return -EINVAL;
 }
 EXPORT_SYMBOL(gpio_request);
 
 void gpio_free(unsigned gpio)
 {
-	if (ssb_chipco_available(&ssb_bcm47xx.chipco) &&
-	    ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
-		return;
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco) &&
+		    ((unsigned)gpio >= BCM47XX_CHIPCO_GPIO_LINES))
+			return;
+
+		if (ssb_extif_available(&bcm47xx_bus.ssb.extif) &&
+		    ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+			return;
 
-	if (ssb_extif_available(&ssb_bcm47xx.extif) &&
-	    ((unsigned)gpio >= BCM47XX_EXTIF_GPIO_LINES))
+		clear_bit(gpio, gpio_in_use);
 		return;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		if (gpio >= BCM47XX_CHIPCO_GPIO_LINES)
+			return;
 
-	clear_bit(gpio, gpio_in_use);
+		clear_bit(gpio, gpio_in_use);
+		return;
+#endif
+	}
 }
 EXPORT_SYMBOL(gpio_free);
 
 int gpio_to_irq(unsigned gpio)
 {
-	if (ssb_chipco_available(&ssb_bcm47xx.chipco))
-		return ssb_mips_irq(ssb_bcm47xx.chipco.dev) + 2;
-	else if (ssb_extif_available(&ssb_bcm47xx.extif))
-		return ssb_mips_irq(ssb_bcm47xx.extif.dev) + 2;
-	else
-		return -EINVAL;
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		if (ssb_chipco_available(&bcm47xx_bus.ssb.chipco))
+			return ssb_mips_irq(bcm47xx_bus.ssb.chipco.dev) + 2;
+		else if (ssb_extif_available(&bcm47xx_bus.ssb.extif))
+			return ssb_mips_irq(bcm47xx_bus.ssb.extif.dev) + 2;
+		else
+			return -EINVAL;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		return bcma_core_mips_irq(bcm47xx_bus.bcma.bus.drv_cc.core) + 2;
+#endif
+	}
+	return -EINVAL;
 }
 EXPORT_SYMBOL_GPL(gpio_to_irq);

+ 12 - 0
arch/mips/bcm47xx/irq.c

@@ -26,6 +26,7 @@
 #include <linux/interrupt.h>
 #include <linux/irq.h>
 #include <asm/irq_cpu.h>
+#include <bcm47xx.h>
 
 void plat_irq_dispatch(void)
 {
@@ -51,5 +52,16 @@ void plat_irq_dispatch(void)
 
 void __init arch_init_irq(void)
 {
+#ifdef CONFIG_BCM47XX_BCMA
+	if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) {
+		bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core,
+			     BCMA_MIPS_MIPS74K_INTMASK(5), 1 << 31);
+		/*
+		 * the kernel reads the timer irq from some register and thinks
+		 * it's #5, but we offset it by 2 and route to #7
+		 */
+		cp0_compare_irq = 7;
+	}
+#endif
 	mips_cpu_irq_init();
 }

+ 25 - 4
arch/mips/bcm47xx/nvram.c

@@ -26,14 +26,35 @@ static char nvram_buf[NVRAM_SPACE];
 /* Probe for NVRAM header */
 static void early_nvram_init(void)
 {
-	struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+#ifdef CONFIG_BCM47XX_SSB
+	struct ssb_mipscore *mcore_ssb;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	struct bcma_drv_cc *bcma_cc;
+#endif
 	struct nvram_header *header;
 	int i;
-	u32 base, lim, off;
+	u32 base = 0;
+	u32 lim = 0;
+	u32 off;
 	u32 *src, *dst;
 
-	base = mcore->flash_window;
-	lim = mcore->flash_window_size;
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		mcore_ssb = &bcm47xx_bus.ssb.mipscore;
+		base = mcore_ssb->flash_window;
+		lim = mcore_ssb->flash_window_size;
+		break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		bcma_cc = &bcm47xx_bus.bcma.bus.drv_cc;
+		base = bcma_cc->pflash.window;
+		lim = bcma_cc->pflash.window_size;
+		break;
+#endif
+	}
 
 	off = FLASH_MIN;
 	while (off <= lim) {

+ 44 - 2
arch/mips/bcm47xx/serial.c

@@ -23,10 +23,11 @@ static struct platform_device uart8250_device = {
 	},
 };
 
-static int __init uart8250_init(void)
+#ifdef CONFIG_BCM47XX_SSB
+static int __init uart8250_init_ssb(void)
 {
 	int i;
-	struct ssb_mipscore *mcore = &(ssb_bcm47xx.mipscore);
+	struct ssb_mipscore *mcore = &(bcm47xx_bus.ssb.mipscore);
 
 	memset(&uart8250_data, 0,  sizeof(uart8250_data));
 
@@ -44,6 +45,47 @@ static int __init uart8250_init(void)
 	}
 	return platform_device_register(&uart8250_device);
 }
+#endif
+
+#ifdef CONFIG_BCM47XX_BCMA
+static int __init uart8250_init_bcma(void)
+{
+	int i;
+	struct bcma_drv_cc *cc = &(bcm47xx_bus.bcma.bus.drv_cc);
+
+	memset(&uart8250_data, 0,  sizeof(uart8250_data));
+
+	for (i = 0; i < cc->nr_serial_ports; i++) {
+		struct plat_serial8250_port *p = &(uart8250_data[i]);
+		struct bcma_serial_port *bcma_port;
+		bcma_port = &(cc->serial_ports[i]);
+
+		p->mapbase = (unsigned int) bcma_port->regs;
+		p->membase = (void *) bcma_port->regs;
+		p->irq = bcma_port->irq + 2;
+		p->uartclk = bcma_port->baud_base;
+		p->regshift = bcma_port->reg_shift;
+		p->iotype = UPIO_MEM;
+		p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+	}
+	return platform_device_register(&uart8250_device);
+}
+#endif
+
+static int __init uart8250_init(void)
+{
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		return uart8250_init_ssb();
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		return uart8250_init_bcma();
+#endif
+	}
+	return -EINVAL;
+}
 
 module_init(uart8250_init);
 

+ 83 - 7
arch/mips/bcm47xx/setup.c

@@ -29,21 +29,36 @@
 #include <linux/types.h>
 #include <linux/ssb/ssb.h>
 #include <linux/ssb/ssb_embedded.h>
+#include <linux/bcma/bcma_soc.h>
 #include <asm/bootinfo.h>
 #include <asm/reboot.h>
 #include <asm/time.h>
 #include <bcm47xx.h>
 #include <asm/mach-bcm47xx/nvram.h>
 
-struct ssb_bus ssb_bcm47xx;
-EXPORT_SYMBOL(ssb_bcm47xx);
+union bcm47xx_bus bcm47xx_bus;
+EXPORT_SYMBOL(bcm47xx_bus);
+
+enum bcm47xx_bus_type bcm47xx_bus_type;
+EXPORT_SYMBOL(bcm47xx_bus_type);
 
 static void bcm47xx_machine_restart(char *command)
 {
 	printk(KERN_ALERT "Please stand by while rebooting the system...\n");
 	local_irq_disable();
 	/* Set the watchdog timer to reset immediately */
-	ssb_watchdog_timer_set(&ssb_bcm47xx, 1);
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1);
+		break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1);
+		break;
+#endif
+	}
 	while (1)
 		cpu_relax();
 }
@@ -52,11 +67,23 @@ static void bcm47xx_machine_halt(void)
 {
 	/* Disable interrupts and watchdog and spin forever */
 	local_irq_disable();
-	ssb_watchdog_timer_set(&ssb_bcm47xx, 0);
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0);
+		break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0);
+		break;
+#endif
+	}
 	while (1)
 		cpu_relax();
 }
 
+#ifdef CONFIG_BCM47XX_SSB
 #define READ_FROM_NVRAM(_outvar, name, buf) \
 	if (nvram_getprefix(prefix, name, buf, sizeof(buf)) >= 0)\
 		sprom->_outvar = simple_strtoul(buf, NULL, 0);
@@ -247,7 +274,7 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus,
 	return 0;
 }
 
-void __init plat_mem_setup(void)
+static void __init bcm47xx_register_ssb(void)
 {
 	int err;
 	char buf[100];
@@ -258,12 +285,12 @@ void __init plat_mem_setup(void)
 		printk(KERN_WARNING "bcm47xx: someone else already registered"
 			" a ssb SPROM callback handler (err %d)\n", err);
 
-	err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE,
+	err = ssb_bus_ssbbus_register(&(bcm47xx_bus.ssb), SSB_ENUM_BASE,
 				      bcm47xx_get_invariants);
 	if (err)
 		panic("Failed to initialize SSB bus (err %d)\n", err);
 
-	mcore = &ssb_bcm47xx.mipscore;
+	mcore = &bcm47xx_bus.ssb.mipscore;
 	if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) {
 		if (strstr(buf, "console=ttyS1")) {
 			struct ssb_serial_port port;
@@ -276,8 +303,57 @@ void __init plat_mem_setup(void)
 			memcpy(&mcore->serial_ports[1], &port, sizeof(port));
 		}
 	}
+}
+#endif
+
+#ifdef CONFIG_BCM47XX_BCMA
+static void __init bcm47xx_register_bcma(void)
+{
+	int err;
+
+	err = bcma_host_soc_register(&bcm47xx_bus.bcma);
+	if (err)
+		panic("Failed to initialize BCMA bus (err %d)\n", err);
+}
+#endif
+
+void __init plat_mem_setup(void)
+{
+	struct cpuinfo_mips *c = &current_cpu_data;
+
+	if (c->cputype == CPU_74K) {
+		printk(KERN_INFO "bcm47xx: using bcma bus\n");
+#ifdef CONFIG_BCM47XX_BCMA
+		bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
+		bcm47xx_register_bcma();
+#endif
+	} else {
+		printk(KERN_INFO "bcm47xx: using ssb bus\n");
+#ifdef CONFIG_BCM47XX_SSB
+		bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
+		bcm47xx_register_ssb();
+#endif
+	}
 
 	_machine_restart = bcm47xx_machine_restart;
 	_machine_halt = bcm47xx_machine_halt;
 	pm_power_off = bcm47xx_machine_halt;
 }
+
+static int __init bcm47xx_register_bus_complete(void)
+{
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		/* Nothing to do */
+		break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		bcma_bus_register(&bcm47xx_bus.bcma.bus);
+		break;
+#endif
+	}
+	return 0;
+}
+device_initcall(bcm47xx_register_bus_complete);

+ 14 - 2
arch/mips/bcm47xx/time.c

@@ -30,7 +30,7 @@
 
 void __init plat_time_init(void)
 {
-	unsigned long hz;
+	unsigned long hz = 0;
 
 	/*
 	 * Use deterministic values for initial counter interrupt
@@ -39,7 +39,19 @@ void __init plat_time_init(void)
 	write_c0_count(0);
 	write_c0_compare(0xffff);
 
-	hz = ssb_cpu_clock(&ssb_bcm47xx.mipscore) / 2;
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2;
+		break;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2;
+		break;
+#endif
+	}
+
 	if (!hz)
 		hz = 100000000;
 

+ 9 - 5
arch/mips/bcm47xx/wgt634u.c

@@ -108,7 +108,7 @@ static irqreturn_t gpio_interrupt(int irq, void *ignored)
 
 	/* Interrupts are shared, check if the current one is
 	   a GPIO interrupt. */
-	if (!ssb_chipco_irq_status(&ssb_bcm47xx.chipco,
+	if (!ssb_chipco_irq_status(&bcm47xx_bus.ssb.chipco,
 				   SSB_CHIPCO_IRQ_GPIO))
 		return IRQ_NONE;
 
@@ -132,22 +132,26 @@ static int __init wgt634u_init(void)
 	 * machine. Use the MAC address as an heuristic. Netgear Inc. has
 	 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
 	 */
+	u8 *et0mac;
 
-	u8 *et0mac = ssb_bcm47xx.sprom.et0mac;
+	if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB)
+		return -ENODEV;
+
+	et0mac = bcm47xx_bus.ssb.sprom.et0mac;
 
 	if (et0mac[0] == 0x00 &&
 	    ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
 	     (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
-		struct ssb_mipscore *mcore = &ssb_bcm47xx.mipscore;
+		struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
 
 		printk(KERN_INFO "WGT634U machine detected.\n");
 
 		if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
 				 gpio_interrupt, IRQF_SHARED,
-				 "WGT634U GPIO", &ssb_bcm47xx.chipco)) {
+				 "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
 			gpio_direction_input(WGT634U_GPIO_RESET);
 			gpio_intmask(WGT634U_GPIO_RESET, 1);
-			ssb_chipco_irq_mask(&ssb_bcm47xx.chipco,
+			ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
 					    SSB_CHIPCO_IRQ_GPIO,
 					    SSB_CHIPCO_IRQ_GPIO);
 		}

+ 24 - 2
arch/mips/include/asm/mach-bcm47xx/bcm47xx.h

@@ -19,7 +19,29 @@
 #ifndef __ASM_BCM47XX_H
 #define __ASM_BCM47XX_H
 
-/* SSB bus */
-extern struct ssb_bus ssb_bcm47xx;
+#include <linux/ssb/ssb.h>
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_soc.h>
+
+enum bcm47xx_bus_type {
+#ifdef CONFIG_BCM47XX_SSB
+	BCM47XX_BUS_TYPE_SSB,
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	BCM47XX_BUS_TYPE_BCMA,
+#endif
+};
+
+union bcm47xx_bus {
+#ifdef CONFIG_BCM47XX_SSB
+	struct ssb_bus ssb;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	struct bcma_soc bcma;
+#endif
+};
+
+extern union bcm47xx_bus bcm47xx_bus;
+extern enum bcm47xx_bus_type bcm47xx_bus_type;
 
 #endif /* __ASM_BCM47XX_H */

+ 93 - 15
arch/mips/include/asm/mach-bcm47xx/gpio.h

@@ -10,6 +10,7 @@
 #define __BCM47XX_GPIO_H
 
 #include <linux/ssb/ssb_embedded.h>
+#include <linux/bcma/bcma.h>
 #include <asm/mach-bcm47xx/bcm47xx.h>
 
 #define BCM47XX_EXTIF_GPIO_LINES	5
@@ -21,41 +22,118 @@ extern int gpio_to_irq(unsigned gpio);
 
 static inline int gpio_get_value(unsigned gpio)
 {
-	return ssb_gpio_in(&ssb_bcm47xx, 1 << gpio);
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		return ssb_gpio_in(&bcm47xx_bus.ssb, 1 << gpio);
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		return bcma_chipco_gpio_in(&bcm47xx_bus.bcma.bus.drv_cc,
+					   1 << gpio);
+#endif
+	}
+	return -EINVAL;
 }
 
 static inline void gpio_set_value(unsigned gpio, int value)
 {
-	ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
+			     value ? 1 << gpio : 0);
+		return;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+				     value ? 1 << gpio : 0);
+		return;
+#endif
+	}
 }
 
 static inline int gpio_direction_input(unsigned gpio)
 {
-	ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 0);
-	return 0;
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 0);
+		return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+				       0);
+		return 0;
+#endif
+	}
+	return -EINVAL;
 }
 
 static inline int gpio_direction_output(unsigned gpio, int value)
 {
-	/* first set the gpio out value */
-	ssb_gpio_out(&ssb_bcm47xx, 1 << gpio, value ? 1 << gpio : 0);
-	/* then set the gpio mode */
-	ssb_gpio_outen(&ssb_bcm47xx, 1 << gpio, 1 << gpio);
-	return 0;
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		/* first set the gpio out value */
+		ssb_gpio_out(&bcm47xx_bus.ssb, 1 << gpio,
+			     value ? 1 << gpio : 0);
+		/* then set the gpio mode */
+		ssb_gpio_outen(&bcm47xx_bus.ssb, 1 << gpio, 1 << gpio);
+		return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		/* first set the gpio out value */
+		bcma_chipco_gpio_out(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+				     value ? 1 << gpio : 0);
+		/* then set the gpio mode */
+		bcma_chipco_gpio_outen(&bcm47xx_bus.bcma.bus.drv_cc, 1 << gpio,
+				       1 << gpio);
+		return 0;
+#endif
+	}
+	return -EINVAL;
 }
 
 static inline int gpio_intmask(unsigned gpio, int value)
 {
-	ssb_gpio_intmask(&ssb_bcm47xx, 1 << gpio,
-			 value ? 1 << gpio : 0);
-	return 0;
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		ssb_gpio_intmask(&bcm47xx_bus.ssb, 1 << gpio,
+				 value ? 1 << gpio : 0);
+		return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		bcma_chipco_gpio_intmask(&bcm47xx_bus.bcma.bus.drv_cc,
+					 1 << gpio, value ? 1 << gpio : 0);
+		return 0;
+#endif
+	}
+	return -EINVAL;
 }
 
 static inline int gpio_polarity(unsigned gpio, int value)
 {
-	ssb_gpio_polarity(&ssb_bcm47xx, 1 << gpio,
-			  value ? 1 << gpio : 0);
-	return 0;
+	switch (bcm47xx_bus_type) {
+#ifdef CONFIG_BCM47XX_SSB
+	case BCM47XX_BUS_TYPE_SSB:
+		ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << gpio,
+				  value ? 1 << gpio : 0);
+		return 0;
+#endif
+#ifdef CONFIG_BCM47XX_BCMA
+	case BCM47XX_BUS_TYPE_BCMA:
+		bcma_chipco_gpio_polarity(&bcm47xx_bus.bcma.bus.drv_cc,
+					  1 << gpio, value ? 1 << gpio : 0);
+		return 0;
+#endif
+	}
+	return -EINVAL;
 }
 
 

+ 6 - 0
arch/mips/pci/pci-bcm47xx.c

@@ -25,6 +25,7 @@
 #include <linux/types.h>
 #include <linux/pci.h>
 #include <linux/ssb/ssb.h>
+#include <bcm47xx.h>
 
 int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 {
@@ -33,9 +34,13 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
 
 int pcibios_plat_dev_init(struct pci_dev *dev)
 {
+#ifdef CONFIG_BCM47XX_SSB
 	int res;
 	u8 slot, pin;
 
+	if (bcm47xx_bus_type !=  BCM47XX_BUS_TYPE_SSB)
+		return 0;
+
 	res = ssb_pcibios_plat_dev_init(dev);
 	if (res < 0) {
 		printk(KERN_ALERT "PCI: Failed to init device %s\n",
@@ -55,5 +60,6 @@ int pcibios_plat_dev_init(struct pci_dev *dev)
 	}
 
 	dev->irq = res;
+#endif
 	return 0;
 }

+ 1 - 1
arch/mips/txx9/generic/setup_tx4939.c

@@ -321,7 +321,7 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
 static u32 tx4939_get_eth_speed(struct net_device *dev)
 {
 	struct ethtool_cmd cmd;
-	if (dev_ethtool_get_settings(dev, &cmd))
+	if (__ethtool_get_settings(dev, &cmd))
 		return 100;	/* default 100Mbps */
 
 	return ethtool_cmd_speed(&cmd);

+ 2 - 0
arch/powerpc/Kconfig

@@ -656,6 +656,8 @@ config SBUS
 
 config FSL_SOC
 	bool
+	select HAVE_CAN_FLEXCAN if NET && CAN
+	select PPC_CLOCK if CAN_FLEXCAN
 
 config FSL_PCI
  	bool

+ 2 - 8
arch/powerpc/boot/dts/p1010rdb.dts

@@ -23,6 +23,8 @@
 		ethernet2 = &enet2;
 		pci0 = &pci0;
 		pci1 = &pci1;
+		can0 = &can0;
+		can1 = &can1;
 	};
 
 	memory {
@@ -169,14 +171,6 @@
 			};
 		};
 
-		can0@1c000 {
-			fsl,flexcan-clock-source = "platform";
-		};
-
-		can1@1d000 {
-			fsl,flexcan-clock-source = "platform";
-		};
-
 		usb@22000 {
 			phy_type = "utmi";
 		};

+ 4 - 6
arch/powerpc/boot/dts/p1010si.dtsi

@@ -140,20 +140,18 @@
 			interrupt-parent = <&mpic>;
 		};
 
-		can0@1c000 {
-			compatible = "fsl,flexcan-v1.0";
+		can0: can@1c000 {
+			compatible = "fsl,p1010-flexcan";
 			reg = <0x1c000 0x1000>;
 			interrupts = <48 0x2>;
 			interrupt-parent = <&mpic>;
-			fsl,flexcan-clock-divider = <2>;
 		};
 
-		can1@1d000 {
-			compatible = "fsl,flexcan-v1.0";
+		can1: can@1d000 {
+			compatible = "fsl,p1010-flexcan";
 			reg = <0x1d000 0x1000>;
 			interrupts = <61 0x2>;
 			interrupt-parent = <&mpic>;
-			fsl,flexcan-clock-divider = <2>;
 		};
 
 		L2: l2-cache-controller@20000 {

+ 6 - 5
arch/powerpc/configs/40x/acadia_defconfig

@@ -44,12 +44,13 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
 CONFIG_MII=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
-CONFIG_IBM_NEW_EMAC_DEBUG=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
+CONFIG_IBM_EMAC_DEBUG=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set

+ 3 - 2
arch/powerpc/configs/40x/ep405_defconfig

@@ -42,8 +42,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set

+ 3 - 2
arch/powerpc/configs/40x/hcu4_defconfig

@@ -43,8 +43,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set

+ 5 - 4
arch/powerpc/configs/40x/kilauea_defconfig

@@ -51,10 +51,11 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set

+ 5 - 4
arch/powerpc/configs/40x/makalu_defconfig

@@ -43,10 +43,11 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set

+ 3 - 2
arch/powerpc/configs/40x/walnut_defconfig

@@ -40,8 +40,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set

+ 5 - 4
arch/powerpc/configs/44x/arches_defconfig

@@ -44,10 +44,11 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set

+ 3 - 2
arch/powerpc/configs/44x/bamboo_defconfig

@@ -32,8 +32,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set

+ 5 - 4
arch/powerpc/configs/44x/bluestone_defconfig

@@ -38,10 +38,11 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
 CONFIG_SERIAL_8250_NR_UARTS=2

+ 5 - 4
arch/powerpc/configs/44x/canyonlands_defconfig

@@ -49,10 +49,11 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 # CONFIG_MISC_DEVICES is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set

+ 3 - 2
arch/powerpc/configs/44x/ebony_defconfig

@@ -40,8 +40,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set

+ 5 - 4
arch/powerpc/configs/44x/eiger_defconfig

@@ -55,10 +55,11 @@ CONFIG_FUSION=y
 CONFIG_FUSION_SAS=y
 CONFIG_I2O=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
 CONFIG_E1000E=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set

+ 3 - 2
arch/powerpc/configs/44x/icon_defconfig

@@ -56,8 +56,9 @@ CONFIG_FUSION_SAS=y
 CONFIG_FUSION_CTL=y
 CONFIG_FUSION_LOGGING=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_WLAN is not set

+ 3 - 2
arch/powerpc/configs/44x/katmai_defconfig

@@ -42,8 +42,9 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_MACINTOSH_DRIVERS=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set

+ 6 - 5
arch/powerpc/configs/44x/redwood_defconfig

@@ -53,11 +53,12 @@ CONFIG_FUSION=y
 CONFIG_FUSION_SAS=y
 CONFIG_I2O=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
-CONFIG_IBM_NEW_EMAC_RXB=256
-CONFIG_IBM_NEW_EMAC_TXB=256
-CONFIG_IBM_NEW_EMAC_DEBUG=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
+CONFIG_IBM_EMAC_RXB=256
+CONFIG_IBM_EMAC_TXB=256
+CONFIG_IBM_EMAC_DEBUG=y
 CONFIG_E1000E=y
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set

+ 3 - 2
arch/powerpc/configs/44x/sam440ep_defconfig

@@ -44,8 +44,9 @@ CONFIG_ATA=y
 # CONFIG_SATA_PMP is not set
 CONFIG_SATA_SIL=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 CONFIG_INPUT_FF_MEMLESS=m

+ 3 - 2
arch/powerpc/configs/44x/sequoia_defconfig

@@ -46,8 +46,9 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set

+ 3 - 2
arch/powerpc/configs/44x/taishan_defconfig

@@ -40,8 +40,9 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_MACINTOSH_DRIVERS=y
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 # CONFIG_SERIO is not set
 # CONFIG_VT is not set

+ 3 - 2
arch/powerpc/configs/44x/warp_defconfig

@@ -54,9 +54,10 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_SCSI_SPI_ATTRS=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
 CONFIG_MII=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_IBM_EMAC=y
 # CONFIG_NETDEV_1000 is not set
 # CONFIG_NETDEV_10000 is not set
 # CONFIG_INPUT is not set

+ 3 - 2
arch/powerpc/configs/ppc40x_defconfig

@@ -50,8 +50,9 @@ CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=35000
 CONFIG_XILINX_SYSACE=m
 CONFIG_NETDEVICES=y
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 CONFIG_SERIO=m
 # CONFIG_SERIO_I8042 is not set

+ 3 - 2
arch/powerpc/configs/ppc44x_defconfig

@@ -63,8 +63,9 @@ CONFIG_BLK_DEV_SD=m
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
 CONFIG_TUN=m
-CONFIG_NET_ETHERNET=y
-CONFIG_IBM_NEW_EMAC=y
+CONFIG_ETHERNET=y
+CONFIG_NET_VENDOR_IBM=y
+CONFIG_IBM_EMAC=y
 # CONFIG_INPUT is not set
 CONFIG_SERIO=m
 # CONFIG_SERIO_I8042 is not set

+ 6 - 6
arch/powerpc/platforms/40x/Kconfig

@@ -130,21 +130,21 @@ config 405GP
 	bool
 	select IBM405_ERR77
 	select IBM405_ERR51
-	select IBM_NEW_EMAC_ZMII
+	select IBM_EMAC_ZMII
 
 config 405EP
 	bool
 
 config 405EX
 	bool
-	select IBM_NEW_EMAC_EMAC4
-	select IBM_NEW_EMAC_RGMII
+	select IBM_EMAC_EMAC4
+	select IBM_EMAC_RGMII
 
 config 405EZ
 	bool
-	select IBM_NEW_EMAC_NO_FLOW_CTRL
-	select IBM_NEW_EMAC_MAL_CLR_ICINTSTAT
-	select IBM_NEW_EMAC_MAL_COMMON_ERR
+	select IBM_EMAC_NO_FLOW_CTRL
+	select IBM_EMAC_MAL_CLR_ICINTSTAT
+	select IBM_EMAC_MAL_COMMON_ERR
 
 config 405GPR
 	bool

+ 27 - 27
arch/powerpc/platforms/44x/Kconfig

@@ -23,7 +23,7 @@ config BLUESTONE
 	default n
 	select PPC44x_SIMPLE
 	select APM821xx
-	select IBM_NEW_EMAC_RGMII
+	select IBM_EMAC_RGMII
 	help
 	  This option enables support for the APM APM821xx Evaluation board.
 
@@ -122,8 +122,8 @@ config CANYONLANDS
 	select PPC4xx_PCI_EXPRESS
 	select PCI_MSI
 	select PPC4xx_MSI
-	select IBM_NEW_EMAC_RGMII
-	select IBM_NEW_EMAC_ZMII
+	select IBM_EMAC_RGMII
+	select IBM_EMAC_ZMII
 	help
 	  This option enables support for the AMCC PPC460EX evaluation board.
 
@@ -135,8 +135,8 @@ config GLACIER
 	select 460EX # Odd since it uses 460GT but the effects are the same
 	select PCI
 	select PPC4xx_PCI_EXPRESS
-	select IBM_NEW_EMAC_RGMII
-	select IBM_NEW_EMAC_ZMII
+	select IBM_EMAC_RGMII
+	select IBM_EMAC_ZMII
 	help
 	  This option enables support for the AMCC PPC460GT evaluation board.
 
@@ -161,7 +161,7 @@ config EIGER
 	select 460SX
 	select PCI
 	select PPC4xx_PCI_EXPRESS
-	select IBM_NEW_EMAC_RGMII
+	select IBM_EMAC_RGMII
 	help
 	  This option enables support for the AMCC PPC460SX evaluation board.
 
@@ -260,59 +260,59 @@ config 440EP
 	bool
 	select PPC_FPU
 	select IBM440EP_ERR42
-	select IBM_NEW_EMAC_ZMII
+	select IBM_EMAC_ZMII
 	select USB_ARCH_HAS_OHCI
 
 config 440EPX
 	bool
 	select PPC_FPU
-	select IBM_NEW_EMAC_EMAC4
-	select IBM_NEW_EMAC_RGMII
-	select IBM_NEW_EMAC_ZMII
+	select IBM_EMAC_EMAC4
+	select IBM_EMAC_RGMII
+	select IBM_EMAC_ZMII
 
 config 440GRX
 	bool
-	select IBM_NEW_EMAC_EMAC4
-	select IBM_NEW_EMAC_RGMII
-	select IBM_NEW_EMAC_ZMII
+	select IBM_EMAC_EMAC4
+	select IBM_EMAC_RGMII
+	select IBM_EMAC_ZMII
 
 config 440GP
 	bool
-	select IBM_NEW_EMAC_ZMII
+	select IBM_EMAC_ZMII
 
 config 440GX
 	bool
-	select IBM_NEW_EMAC_EMAC4
-	select IBM_NEW_EMAC_RGMII
-	select IBM_NEW_EMAC_ZMII #test only
-	select IBM_NEW_EMAC_TAH  #test only
+	select IBM_EMAC_EMAC4
+	select IBM_EMAC_RGMII
+	select IBM_EMAC_ZMII #test only
+	select IBM_EMAC_TAH  #test only
 
 config 440SP
 	bool
 
 config 440SPe
 	bool
-	select IBM_NEW_EMAC_EMAC4
+	select IBM_EMAC_EMAC4
 
 config 460EX
 	bool
 	select PPC_FPU
-	select IBM_NEW_EMAC_EMAC4
-	select IBM_NEW_EMAC_TAH
+	select IBM_EMAC_EMAC4
+	select IBM_EMAC_TAH
 
 config 460SX
 	bool
 	select PPC_FPU
-	select IBM_NEW_EMAC_EMAC4
-	select IBM_NEW_EMAC_RGMII
-	select IBM_NEW_EMAC_ZMII
-	select IBM_NEW_EMAC_TAH
+	select IBM_EMAC_EMAC4
+	select IBM_EMAC_RGMII
+	select IBM_EMAC_ZMII
+	select IBM_EMAC_TAH
 
 config APM821xx
 	bool
 	select PPC_FPU
-	select IBM_NEW_EMAC_EMAC4
-	select IBM_NEW_EMAC_TAH
+	select IBM_EMAC_EMAC4
+	select IBM_EMAC_TAH
 
 # 44x errata/workaround config symbols, selected by the CPU models above
 config IBM440EP_ERR42

+ 4 - 4
arch/powerpc/platforms/cell/Kconfig

@@ -17,10 +17,10 @@ config PPC_CELL_NATIVE
 	select PPC_CELL_COMMON
 	select MPIC
 	select PPC_IO_WORKAROUNDS
-	select IBM_NEW_EMAC_EMAC4
-	select IBM_NEW_EMAC_RGMII
-	select IBM_NEW_EMAC_ZMII #test only
-	select IBM_NEW_EMAC_TAH  #test only
+	select IBM_EMAC_EMAC4
+	select IBM_EMAC_RGMII
+	select IBM_EMAC_ZMII #test only
+	select IBM_EMAC_TAH  #test only
 	default n
 
 config PPC_IBM_CELL_BLADE

+ 75 - 3
arch/s390/include/asm/qdio.h

@@ -122,6 +122,40 @@ struct slibe {
 	u64 parms;
 };
 
+/**
+ * struct qaob - queue asynchronous operation block
+ * @res0: reserved parameters
+ * @res1: reserved parameter
+ * @res2: reserved parameter
+ * @res3: reserved parameter
+ * @aorc: asynchronous operation return code
+ * @flags: internal flags
+ * @cbtbs: control block type
+ * @sb_count: number of storage blocks
+ * @sba: storage block element addresses
+ * @dcount: size of storage block elements
+ * @user0: user defineable value
+ * @res4: reserved paramater
+ * @user1: user defineable value
+ * @user2: user defineable value
+ */
+struct qaob {
+	u64 res0[6];
+	u8 res1;
+	u8 res2;
+	u8 res3;
+	u8 aorc;
+	u8 flags;
+	u16 cbtbs;
+	u8 sb_count;
+	u64 sba[QDIO_MAX_ELEMENTS_PER_BUFFER];
+	u16 dcount[QDIO_MAX_ELEMENTS_PER_BUFFER];
+	u64 user0;
+	u64 res4[2];
+	u64 user1;
+	u64 user2;
+} __attribute__ ((packed, aligned(256)));
+
 /**
  * struct slib - storage list information block (SLIB)
  * @nsliba: next SLIB address (if any)
@@ -225,6 +259,41 @@ struct slsb {
 #define CHSC_AC2_DATA_DIV_AVAILABLE	0x0010
 #define CHSC_AC2_DATA_DIV_ENABLED	0x0002
 
+/**
+ * struct qdio_outbuf_state - SBAL related asynchronous operation information
+ *   (for communication with upper layer programs)
+ *   (only required for use with completion queues)
+ * @flags: flags indicating state of buffer
+ * @aob: pointer to QAOB used for the particular SBAL
+ * @user: pointer to upper layer program's state information related to SBAL
+ *        (stored in user1 data of QAOB)
+ */
+struct qdio_outbuf_state {
+	u8 flags;
+	struct qaob *aob;
+	void *user;
+};
+
+#define QDIO_OUTBUF_STATE_FLAG_NONE	0x00
+#define QDIO_OUTBUF_STATE_FLAG_PENDING	0x01
+
+#define CHSC_AC1_INITIATE_INPUTQ	0x80
+
+
+/* qdio adapter-characteristics-1 flag */
+#define AC1_SIGA_INPUT_NEEDED		0x40	/* process input queues */
+#define AC1_SIGA_OUTPUT_NEEDED		0x20	/* process output queues */
+#define AC1_SIGA_SYNC_NEEDED		0x10	/* ask hypervisor to sync */
+#define AC1_AUTOMATIC_SYNC_ON_THININT	0x08	/* set by hypervisor */
+#define AC1_AUTOMATIC_SYNC_ON_OUT_PCI	0x04	/* set by hypervisor */
+#define AC1_SC_QEBSM_AVAILABLE		0x02	/* available for subchannel */
+#define AC1_SC_QEBSM_ENABLED		0x01	/* enabled for subchannel */
+
+#define CHSC_AC2_DATA_DIV_AVAILABLE	0x0010
+#define CHSC_AC2_DATA_DIV_ENABLED	0x0002
+
+#define CHSC_AC3_FORMAT2_CQ_AVAILABLE	0x8000
+
 struct qdio_ssqd_desc {
 	u8 flags;
 	u8:8;
@@ -243,8 +312,7 @@ struct qdio_ssqd_desc {
 	u64 sch_token;
 	u8 mro;
 	u8 mri;
-	u8:8;
-	u8 sbalic;
+	u16 qdioac3;
 	u16:16;
 	u8:8;
 	u8 mmwc;
@@ -280,9 +348,11 @@ typedef void qdio_handler_t(struct ccw_device *, unsigned int, int,
  * @no_output_qs: number of output queues
  * @input_handler: handler to be called for input queues
  * @output_handler: handler to be called for output queues
+ * @queue_start_poll: polling handlers (one per input queue or NULL)
  * @int_parm: interruption parameter
  * @input_sbal_addr_array:  address of no_input_qs * 128 pointers
  * @output_sbal_addr_array: address of no_output_qs * 128 pointers
+ * @output_sbal_state_array: no_output_qs * 128 state info (for CQ or NULL)
  */
 struct qdio_initialize {
 	struct ccw_device *cdev;
@@ -297,11 +367,12 @@ struct qdio_initialize {
 	unsigned int no_output_qs;
 	qdio_handler_t *input_handler;
 	qdio_handler_t *output_handler;
-	void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
+	void (**queue_start_poll) (struct ccw_device *, int, unsigned long);
 	int scan_threshold;
 	unsigned long int_parm;
 	void **input_sbal_addr_array;
 	void **output_sbal_addr_array;
+	struct qdio_outbuf_state *output_sbal_state_array;
 };
 
 #define QDIO_STATE_INACTIVE		0x00000002 /* after qdio_cleanup */
@@ -316,6 +387,7 @@ struct qdio_initialize {
 extern int qdio_allocate(struct qdio_initialize *);
 extern int qdio_establish(struct qdio_initialize *);
 extern int qdio_activate(struct ccw_device *);
+extern void qdio_release_aob(struct qaob *);
 extern int do_QDIO(struct ccw_device *, unsigned int, int, unsigned int,
 		   unsigned int);
 extern int qdio_start_irq(struct ccw_device *, int);

+ 0 - 25
arch/sh/include/asm/sh_eth.h

@@ -1,25 +0,0 @@
-#ifndef __ASM_SH_ETH_H__
-#define __ASM_SH_ETH_H__
-
-#include <linux/phy.h>
-
-enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN};
-enum {
-	SH_ETH_REG_GIGABIT,
-	SH_ETH_REG_FAST_SH4,
-	SH_ETH_REG_FAST_SH3_SH2
-};
-
-struct sh_eth_plat_data {
-	int phy;
-	int edmac_endian;
-	int register_type;
-	phy_interface_t phy_interface;
-	void (*set_mdio_gate)(unsigned long addr);
-
-	unsigned char mac_addr[6];
-	unsigned no_ether_link:1;
-	unsigned ether_link_active_low:1;
-};
-
-#endif

+ 1 - 1
arch/um/drivers/net_kern.c

@@ -368,7 +368,7 @@ static const struct net_device_ops uml_netdev_ops = {
 	.ndo_open 		= uml_net_open,
 	.ndo_stop 		= uml_net_close,
 	.ndo_start_xmit 	= uml_net_start_xmit,
-	.ndo_set_multicast_list = uml_net_set_multicast_list,
+	.ndo_set_rx_mode	= uml_net_set_multicast_list,
 	.ndo_tx_timeout 	= uml_net_tx_timeout,
 	.ndo_set_mac_address	= eth_mac_addr,
 	.ndo_change_mtu 	= uml_net_change_mtu,

+ 1 - 1
arch/xtensa/platforms/iss/network.c

@@ -633,7 +633,7 @@ static const struct net_device_ops iss_netdev_ops = {
 	.ndo_set_mac_address	= iss_net_set_mac,
 	//.ndo_do_ioctl		= iss_net_ioctl,
 	.ndo_tx_timeout		= iss_net_tx_timeout,
-	.ndo_set_multicast_list = iss_net_set_multicast_list,
+	.ndo_set_rx_mode	= iss_net_set_multicast_list,
 };
 
 static int iss_net_configure(int index, char *init)

+ 3 - 2
drivers/atm/eni.c

@@ -1134,8 +1134,9 @@ DPRINTK("doing direct send\n"); /* @@@ well, this doesn't work anyway */
 				    skb_headlen(skb));
 			else
 				put_dma(tx->index,eni_dev->dma,&j,(unsigned long)
-				    skb_shinfo(skb)->frags[i].page + skb_shinfo(skb)->frags[i].page_offset,
-				    skb_shinfo(skb)->frags[i].size);
+				    skb_frag_page(&skb_shinfo(skb)->frags[i]) +
+					skb_shinfo(skb)->frags[i].page_offset,
+				    skb_frag_size(&skb_shinfo(skb)->frags[i]));
 	}
 	if (skb->len & 3)
 		put_dma(tx->index,eni_dev->dma,&j,zeroes,4-(skb->len & 3));

+ 145 - 120
drivers/atm/iphase.c

@@ -818,127 +818,152 @@ static void ia_hw_type(IADEV *iadev) {
 
 }
 
-static void IaFrontEndIntr(IADEV *iadev) {
-  volatile IA_SUNI *suni;
-  volatile ia_mb25_t *mb25;
-  volatile suni_pm7345_t *suni_pm7345;
-
-  if(iadev->phy_type & FE_25MBIT_PHY) {
-     mb25 = (ia_mb25_t*)iadev->phy;
-     iadev->carrier_detect =  Boolean(mb25->mb25_intr_status & MB25_IS_GSB);
-  } else if (iadev->phy_type & FE_DS3_PHY) {
-     suni_pm7345 = (suni_pm7345_t *)iadev->phy;
-     /* clear FRMR interrupts */
-     (void) suni_pm7345->suni_ds3_frm_intr_stat; 
-     iadev->carrier_detect =  
-           Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV));
-  } else if (iadev->phy_type & FE_E3_PHY ) {
-     suni_pm7345 = (suni_pm7345_t *)iadev->phy;
-     (void) suni_pm7345->suni_e3_frm_maint_intr_ind;
-     iadev->carrier_detect =
-           Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat&SUNI_E3_LOS));
-  }
-  else { 
-     suni = (IA_SUNI *)iadev->phy;
-     (void) suni->suni_rsop_status;
-     iadev->carrier_detect = Boolean(!(suni->suni_rsop_status & SUNI_LOSV));
-  }
-  if (iadev->carrier_detect)
-    printk("IA: SUNI carrier detected\n");
-  else
-    printk("IA: SUNI carrier lost signal\n"); 
-  return;
+static u32 ia_phy_read32(struct iadev_priv *ia, unsigned int reg)
+{
+	return readl(ia->phy + (reg >> 2));
+}
+
+static void ia_phy_write32(struct iadev_priv *ia, unsigned int reg, u32 val)
+{
+	writel(val, ia->phy + (reg >> 2));
+}
+
+static void ia_frontend_intr(struct iadev_priv *iadev)
+{
+	u32 status;
+
+	if (iadev->phy_type & FE_25MBIT_PHY) {
+		status = ia_phy_read32(iadev, MB25_INTR_STATUS);
+		iadev->carrier_detect = (status & MB25_IS_GSB) ? 1 : 0;
+	} else if (iadev->phy_type & FE_DS3_PHY) {
+		ia_phy_read32(iadev, SUNI_DS3_FRM_INTR_STAT);
+		status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT);
+		iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1;
+	} else if (iadev->phy_type & FE_E3_PHY) {
+		ia_phy_read32(iadev, SUNI_E3_FRM_MAINT_INTR_IND);
+		status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT);
+		iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1;
+	} else {
+		status = ia_phy_read32(iadev, SUNI_RSOP_STATUS);
+		iadev->carrier_detect = (status & SUNI_LOSV) ? 0 : 1;
+	}
+
+	printk(KERN_INFO "IA: SUNI carrier %s\n",
+		iadev->carrier_detect ? "detected" : "lost signal");
 }
 
-static void ia_mb25_init (IADEV *iadev)
+static void ia_mb25_init(struct iadev_priv *iadev)
 {
-   volatile ia_mb25_t  *mb25 = (ia_mb25_t*)iadev->phy;
 #if 0
    mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC | MB25_MC_ENABLED;
 #endif
-   mb25->mb25_master_ctrl = MB25_MC_DRIC | MB25_MC_DREC;
-   mb25->mb25_diag_control = 0;
-   /*
-    * Initialize carrier detect state
-    */
-   iadev->carrier_detect =  Boolean(mb25->mb25_intr_status & MB25_IS_GSB);
-   return;
-}                   
+	ia_phy_write32(iadev, MB25_MASTER_CTRL, MB25_MC_DRIC | MB25_MC_DREC);
+	ia_phy_write32(iadev, MB25_DIAG_CONTROL, 0);
+
+	iadev->carrier_detect =
+		(ia_phy_read32(iadev, MB25_INTR_STATUS) & MB25_IS_GSB) ? 1 : 0;
+}
 
-static void ia_suni_pm7345_init (IADEV *iadev)
+struct ia_reg {
+	u16 reg;
+	u16 val;
+};
+
+static void ia_phy_write(struct iadev_priv *iadev,
+			 const struct ia_reg *regs, int len)
 {
-   volatile suni_pm7345_t *suni_pm7345 = (suni_pm7345_t *)iadev->phy;
-   if (iadev->phy_type & FE_DS3_PHY)
-   {
-      iadev->carrier_detect = 
-          Boolean(!(suni_pm7345->suni_ds3_frm_stat & SUNI_DS3_LOSV)); 
-      suni_pm7345->suni_ds3_frm_intr_enbl = 0x17;
-      suni_pm7345->suni_ds3_frm_cfg = 1;
-      suni_pm7345->suni_ds3_tran_cfg = 1;
-      suni_pm7345->suni_config = 0;
-      suni_pm7345->suni_splr_cfg = 0;
-      suni_pm7345->suni_splt_cfg = 0;
-   }
-   else 
-   {
-      iadev->carrier_detect = 
-          Boolean(!(suni_pm7345->suni_e3_frm_fram_intr_ind_stat & SUNI_E3_LOS));
-      suni_pm7345->suni_e3_frm_fram_options = 0x4;
-      suni_pm7345->suni_e3_frm_maint_options = 0x20;
-      suni_pm7345->suni_e3_frm_fram_intr_enbl = 0x1d;
-      suni_pm7345->suni_e3_frm_maint_intr_enbl = 0x30;
-      suni_pm7345->suni_e3_tran_stat_diag_options = 0x0;
-      suni_pm7345->suni_e3_tran_fram_options = 0x1;
-      suni_pm7345->suni_config = SUNI_PM7345_E3ENBL;
-      suni_pm7345->suni_splr_cfg = 0x41;
-      suni_pm7345->suni_splt_cfg = 0x41;
-   } 
-   /*
-    * Enable RSOP loss of signal interrupt.
-    */
-   suni_pm7345->suni_intr_enbl = 0x28;
- 
-   /*
-    * Clear error counters
-    */
-   suni_pm7345->suni_id_reset = 0;
-
-   /*
-    * Clear "PMCTST" in master test register.
-    */
-   suni_pm7345->suni_master_test = 0;
-
-   suni_pm7345->suni_rxcp_ctrl = 0x2c;
-   suni_pm7345->suni_rxcp_fctrl = 0x81;
- 
-   suni_pm7345->suni_rxcp_idle_pat_h1 =
-   	suni_pm7345->suni_rxcp_idle_pat_h2 =
-   	suni_pm7345->suni_rxcp_idle_pat_h3 = 0;
-   suni_pm7345->suni_rxcp_idle_pat_h4 = 1;
- 
-   suni_pm7345->suni_rxcp_idle_mask_h1 = 0xff;
-   suni_pm7345->suni_rxcp_idle_mask_h2 = 0xff;
-   suni_pm7345->suni_rxcp_idle_mask_h3 = 0xff;
-   suni_pm7345->suni_rxcp_idle_mask_h4 = 0xfe;
- 
-   suni_pm7345->suni_rxcp_cell_pat_h1 =
-   	suni_pm7345->suni_rxcp_cell_pat_h2 =
-   	suni_pm7345->suni_rxcp_cell_pat_h3 = 0;
-   suni_pm7345->suni_rxcp_cell_pat_h4 = 1;
- 
-   suni_pm7345->suni_rxcp_cell_mask_h1 =
-   	suni_pm7345->suni_rxcp_cell_mask_h2 =
-   	suni_pm7345->suni_rxcp_cell_mask_h3 =
-   	suni_pm7345->suni_rxcp_cell_mask_h4 = 0xff;
- 
-   suni_pm7345->suni_txcp_ctrl = 0xa4;
-   suni_pm7345->suni_txcp_intr_en_sts = 0x10;
-   suni_pm7345->suni_txcp_idle_pat_h5 = 0x55;
- 
-   suni_pm7345->suni_config &= ~(SUNI_PM7345_LLB |
-                                 SUNI_PM7345_CLB |
-                                 SUNI_PM7345_DLB |
-                                  SUNI_PM7345_PLB);
+	while (len--) {
+		ia_phy_write32(iadev, regs->reg, regs->val);
+		regs++;
+	}
+}
+
+static void ia_suni_pm7345_init_ds3(struct iadev_priv *iadev)
+{
+	static const struct ia_reg suni_ds3_init [] = {
+		{ SUNI_DS3_FRM_INTR_ENBL,	0x17 },
+		{ SUNI_DS3_FRM_CFG,		0x01 },
+		{ SUNI_DS3_TRAN_CFG,		0x01 },
+		{ SUNI_CONFIG,			0 },
+		{ SUNI_SPLR_CFG,		0 },
+		{ SUNI_SPLT_CFG,		0 }
+	};
+	u32 status;
+
+	status = ia_phy_read32(iadev, SUNI_DS3_FRM_STAT);
+	iadev->carrier_detect = (status & SUNI_DS3_LOSV) ? 0 : 1;
+
+	ia_phy_write(iadev, suni_ds3_init, ARRAY_SIZE(suni_ds3_init));
+}
+
+static void ia_suni_pm7345_init_e3(struct iadev_priv *iadev)
+{
+	static const struct ia_reg suni_e3_init [] = {
+		{ SUNI_E3_FRM_FRAM_OPTIONS,		0x04 },
+		{ SUNI_E3_FRM_MAINT_OPTIONS,		0x20 },
+		{ SUNI_E3_FRM_FRAM_INTR_ENBL,		0x1d },
+		{ SUNI_E3_FRM_MAINT_INTR_ENBL,		0x30 },
+		{ SUNI_E3_TRAN_STAT_DIAG_OPTIONS,	0 },
+		{ SUNI_E3_TRAN_FRAM_OPTIONS,		0x01 },
+		{ SUNI_CONFIG,				SUNI_PM7345_E3ENBL },
+		{ SUNI_SPLR_CFG,			0x41 },
+		{ SUNI_SPLT_CFG,			0x41 }
+	};
+	u32 status;
+
+	status = ia_phy_read32(iadev, SUNI_E3_FRM_FRAM_INTR_IND_STAT);
+	iadev->carrier_detect = (status & SUNI_E3_LOS) ? 0 : 1;
+	ia_phy_write(iadev, suni_e3_init, ARRAY_SIZE(suni_e3_init));
+}
+
+static void ia_suni_pm7345_init(struct iadev_priv *iadev)
+{
+	static const struct ia_reg suni_init [] = {
+		/* Enable RSOP loss of signal interrupt. */
+		{ SUNI_INTR_ENBL,		0x28 },
+		/* Clear error counters. */
+		{ SUNI_ID_RESET,		0 },
+		/* Clear "PMCTST" in master test register. */
+		{ SUNI_MASTER_TEST,		0 },
+
+		{ SUNI_RXCP_CTRL,		0x2c },
+		{ SUNI_RXCP_FCTRL,		0x81 },
+
+		{ SUNI_RXCP_IDLE_PAT_H1,	0 },
+		{ SUNI_RXCP_IDLE_PAT_H2,	0 },
+		{ SUNI_RXCP_IDLE_PAT_H3,	0 },
+		{ SUNI_RXCP_IDLE_PAT_H4,	0x01 },
+
+		{ SUNI_RXCP_IDLE_MASK_H1,	0xff },
+		{ SUNI_RXCP_IDLE_MASK_H2,	0xff },
+		{ SUNI_RXCP_IDLE_MASK_H3,	0xff },
+		{ SUNI_RXCP_IDLE_MASK_H4,	0xfe },
+
+		{ SUNI_RXCP_CELL_PAT_H1,	0 },
+		{ SUNI_RXCP_CELL_PAT_H2,	0 },
+		{ SUNI_RXCP_CELL_PAT_H3,	0 },
+		{ SUNI_RXCP_CELL_PAT_H4,	0x01 },
+
+		{ SUNI_RXCP_CELL_MASK_H1,	0xff },
+		{ SUNI_RXCP_CELL_MASK_H2,	0xff },
+		{ SUNI_RXCP_CELL_MASK_H3,	0xff },
+		{ SUNI_RXCP_CELL_MASK_H4,	0xff },
+
+		{ SUNI_TXCP_CTRL,		0xa4 },
+		{ SUNI_TXCP_INTR_EN_STS,	0x10 },
+		{ SUNI_TXCP_IDLE_PAT_H5,	0x55 }
+	};
+
+	if (iadev->phy_type & FE_DS3_PHY)
+		ia_suni_pm7345_init_ds3(iadev);
+	else
+		ia_suni_pm7345_init_e3(iadev);
+
+	ia_phy_write(iadev, suni_init, ARRAY_SIZE(suni_init));
+
+	ia_phy_write32(iadev, SUNI_CONFIG, ia_phy_read32(iadev, SUNI_CONFIG) &
+		~(SUNI_PM7345_LLB | SUNI_PM7345_CLB |
+		  SUNI_PM7345_DLB | SUNI_PM7345_PLB));
 #ifdef __SNMP__
    suni_pm7345->suni_rxcp_intr_en_sts |= SUNI_OOCDE;
 #endif /* __SNMP__ */
@@ -1425,10 +1450,10 @@ static int rx_init(struct atm_dev *dev)
 	       iadev->dma + IPHASE5575_RX_LIST_ADDR);  
 	IF_INIT(printk("Tx Dle list addr: 0x%p value: 0x%0x\n",
                       iadev->dma+IPHASE5575_TX_LIST_ADDR,
-                      *(u32*)(iadev->dma+IPHASE5575_TX_LIST_ADDR));  
+                      readl(iadev->dma + IPHASE5575_TX_LIST_ADDR));
 	printk("Rx Dle list addr: 0x%p value: 0x%0x\n",
                       iadev->dma+IPHASE5575_RX_LIST_ADDR,
-                      *(u32*)(iadev->dma+IPHASE5575_RX_LIST_ADDR));)  
+                      readl(iadev->dma + IPHASE5575_RX_LIST_ADDR));)
   
 	writew(0xffff, iadev->reass_reg+REASS_MASK_REG);  
 	writew(0, iadev->reass_reg+MODE_REG);  
@@ -2208,7 +2233,7 @@ static irqreturn_t ia_int(int irq, void *dev_id)
 	if (status & STAT_DLERINT)  
 	{  
 	   /* Clear this bit by writing a 1 to it. */  
-	   *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLERINT;
+	   writel(STAT_DLERINT, iadev->reg + IPHASE5575_BUS_STATUS_REG);
 	   rx_dle_intr(dev);  
 	}  
 	if (status & STAT_SEGINT)  
@@ -2219,13 +2244,13 @@ static irqreturn_t ia_int(int irq, void *dev_id)
 	}  
 	if (status & STAT_DLETINT)  
 	{  
-	   *(u_int *)(iadev->reg+IPHASE5575_BUS_STATUS_REG) = STAT_DLETINT;  
+	   writel(STAT_DLETINT, iadev->reg + IPHASE5575_BUS_STATUS_REG);
 	   tx_dle_intr(dev);  
 	}  
 	if (status & (STAT_FEINT | STAT_ERRINT | STAT_MARKINT))  
 	{  
            if (status & STAT_FEINT) 
-               IaFrontEndIntr(iadev);
+               ia_frontend_intr(iadev);
 	}  
    }
    return IRQ_RETVAL(handled);
@@ -2556,7 +2581,7 @@ static int __devinit ia_start(struct atm_dev *dev)
 				goto err_free_rx;
 		}
 		/* Get iadev->carrier_detect status */
-		IaFrontEndIntr(iadev);
+		ia_frontend_intr(iadev);
 	}
 	return 0;
 
@@ -2827,7 +2852,7 @@ static int ia_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
 
          case 0xb:
 	    if (!capable(CAP_NET_ADMIN)) return -EPERM;
-            IaFrontEndIntr(iadev);
+            ia_frontend_intr(iadev);
             break;
          case 0xa:
 	    if (!capable(CAP_NET_ADMIN)) return -EPERM;

+ 192 - 203
drivers/atm/iphase.h

@@ -889,79 +889,71 @@ typedef struct ia_rtn_q {
 } IARTN_Q;
 
 #define SUNI_LOSV   	0x04
-typedef struct {
-        u32   suni_master_reset;      /* SUNI Master Reset and Identity     */
-        u32   suni_master_config;     /* SUNI Master Configuration          */
-        u32   suni_master_intr_stat;  /* SUNI Master Interrupt Status       */
-        u32   suni_reserved1;         /* Reserved                           */
-        u32   suni_master_clk_monitor;/* SUNI Master Clock Monitor          */
-        u32   suni_master_control;    /* SUNI Master Clock Monitor          */
-        u32   suni_reserved2[10];     /* Reserved                           */
-
-        u32   suni_rsop_control;      /* RSOP Control/Interrupt Enable      */
-        u32   suni_rsop_status;       /* RSOP Status/Interrupt States       */
-        u32   suni_rsop_section_bip8l;/* RSOP Section BIP-8 LSB             */
-        u32   suni_rsop_section_bip8m;/* RSOP Section BIP-8 MSB             */
-
-        u32   suni_tsop_control;      /* TSOP Control                       */
-        u32   suni_tsop_diag;         /* TSOP Disgnostics                   */
-        u32   suni_tsop_reserved[2];  /* TSOP Reserved                      */
-
-        u32   suni_rlop_cs;           /* RLOP Control/Status                */
-        u32   suni_rlop_intr;         /* RLOP Interrupt Enable/Status       */
-        u32   suni_rlop_line_bip24l;  /* RLOP Line BIP-24 LSB               */
-        u32   suni_rlop_line_bip24;   /* RLOP Line BIP-24                   */
-        u32   suni_rlop_line_bip24m;  /* RLOP Line BIP-24 MSB               */
-        u32   suni_rlop_line_febel;   /* RLOP Line FEBE LSB                 */
-        u32   suni_rlop_line_febe;    /* RLOP Line FEBE                     */
-        u32   suni_rlop_line_febem;   /* RLOP Line FEBE MSB                 */
-
-        u32   suni_tlop_control;      /* TLOP Control                       */
-        u32   suni_tlop_disg;         /* TLOP Disgnostics                   */
-        u32   suni_tlop_reserved[14]; /* TLOP Reserved                      */
-
-        u32   suni_rpop_cs;           /* RPOP Status/Control                */
-        u32   suni_rpop_intr;         /* RPOP Interrupt/Status              */
-        u32   suni_rpop_reserved;     /* RPOP Reserved                      */
-        u32   suni_rpop_intr_ena;     /* RPOP Interrupt Enable              */
-        u32   suni_rpop_reserved1[3]; /* RPOP Reserved                      */
-        u32   suni_rpop_path_sig;     /* RPOP Path Signal Label             */
-        u32   suni_rpop_bip8l;        /* RPOP Path BIP-8 LSB                */
-        u32   suni_rpop_bip8m;        /* RPOP Path BIP-8 MSB                */
-        u32   suni_rpop_febel;        /* RPOP Path FEBE LSB                 */
-        u32   suni_rpop_febem;        /* RPOP Path FEBE MSB                 */
-        u32   suni_rpop_reserved2[4]; /* RPOP Reserved                      */
-
-        u32   suni_tpop_cntrl_daig;   /* TPOP Control/Disgnostics           */
-        u32   suni_tpop_pointer_ctrl; /* TPOP Pointer Control               */
-        u32   suni_tpop_sourcer_ctrl; /* TPOP Source Control                */
-        u32   suni_tpop_reserved1[2]; /* TPOP Reserved                      */
-        u32   suni_tpop_arb_prtl;     /* TPOP Arbitrary Pointer LSB         */
-        u32   suni_tpop_arb_prtm;     /* TPOP Arbitrary Pointer MSB         */
-        u32   suni_tpop_reserved2;    /* TPOP Reserved                      */
-        u32   suni_tpop_path_sig;     /* TPOP Path Signal Lable             */
-        u32   suni_tpop_path_status;  /* TPOP Path Status                   */
-        u32   suni_tpop_reserved3[6]; /* TPOP Reserved                      */              
-
-        u32   suni_racp_cs;           /* RACP Control/Status                */
-        u32   suni_racp_intr;         /* RACP Interrupt Enable/Status       */
-        u32   suni_racp_hdr_pattern;  /* RACP Match Header Pattern          */
-        u32   suni_racp_hdr_mask;     /* RACP Match Header Mask             */
-        u32   suni_racp_corr_hcs;     /* RACP Correctable HCS Error Count   */
-        u32   suni_racp_uncorr_hcs;   /* RACP Uncorrectable HCS Error Count */
-        u32   suni_racp_reserved[10]; /* RACP Reserved                      */
-
-        u32   suni_tacp_control;      /* TACP Control                       */
-        u32   suni_tacp_idle_hdr_pat; /* TACP Idle Cell Header Pattern      */
-        u32   suni_tacp_idle_pay_pay; /* TACP Idle Cell Payld Octet Pattern */
-        u32   suni_tacp_reserved[5];  /* TACP Reserved                      */
-
-        u32   suni_reserved3[24];     /* Reserved                           */
-
-        u32   suni_master_test;       /* SUNI Master Test                   */
-        u32   suni_reserved_test;     /* SUNI Reserved for Test             */
-} IA_SUNI;
-
+enum ia_suni {
+	SUNI_MASTER_RESET	= 0x000, /* SUNI Master Reset and Identity   */
+	SUNI_MASTER_CONFIG	= 0x004, /* SUNI Master Configuration        */
+	SUNI_MASTER_INTR_STAT	= 0x008, /* SUNI Master Interrupt Status     */
+	SUNI_RESERVED1		= 0x00c, /* Reserved                         */
+	SUNI_MASTER_CLK_MONITOR	= 0x010, /* SUNI Master Clock Monitor        */
+	SUNI_MASTER_CONTROL	= 0x014, /* SUNI Master Clock Monitor        */
+					 /* Reserved (10)                    */
+	SUNI_RSOP_CONTROL	= 0x040, /* RSOP Control/Interrupt Enable    */
+	SUNI_RSOP_STATUS	= 0x044, /* RSOP Status/Interrupt States     */
+	SUNI_RSOP_SECTION_BIP8L	= 0x048, /* RSOP Section BIP-8 LSB           */
+	SUNI_RSOP_SECTION_BIP8M	= 0x04c, /* RSOP Section BIP-8 MSB           */
+
+	SUNI_TSOP_CONTROL	= 0x050, /* TSOP Control                     */
+	SUNI_TSOP_DIAG		= 0x054, /* TSOP Disgnostics                 */
+					 /* Reserved (2)                     */
+	SUNI_RLOP_CS		= 0x060, /* RLOP Control/Status              */
+	SUNI_RLOP_INTR		= 0x064, /* RLOP Interrupt Enable/Status     */
+	SUNI_RLOP_LINE_BIP24L	= 0x068, /* RLOP Line BIP-24 LSB             */
+	SUNI_RLOP_LINE_BIP24	= 0x06c, /* RLOP Line BIP-24                 */
+	SUNI_RLOP_LINE_BIP24M	= 0x070, /* RLOP Line BIP-24 MSB             */
+	SUNI_RLOP_LINE_FEBEL	= 0x074, /* RLOP Line FEBE LSB               */
+	SUNI_RLOP_LINE_FEBE	= 0x078, /* RLOP Line FEBE                   */
+	SUNI_RLOP_LINE_FEBEM	= 0x07c, /* RLOP Line FEBE MSB               */
+
+	SUNI_TLOP_CONTROL	= 0x080, /* TLOP Control                     */
+	SUNI_TLOP_DISG		= 0x084, /* TLOP Disgnostics                 */
+					 /* Reserved (14)                    */
+	SUNI_RPOP_CS		= 0x0c0, /* RPOP Status/Control              */
+	SUNI_RPOP_INTR		= 0x0c4, /* RPOP Interrupt/Status            */
+	SUNI_RPOP_RESERVED	= 0x0c8, /* RPOP Reserved                    */
+	SUNI_RPOP_INTR_ENA	= 0x0cc, /* RPOP Interrupt Enable            */
+					 /* Reserved (3)                     */
+	SUNI_RPOP_PATH_SIG	= 0x0dc, /* RPOP Path Signal Label           */
+	SUNI_RPOP_BIP8L		= 0x0e0, /* RPOP Path BIP-8 LSB              */
+	SUNI_RPOP_BIP8M		= 0x0e4, /* RPOP Path BIP-8 MSB              */
+	SUNI_RPOP_FEBEL		= 0x0e8, /* RPOP Path FEBE LSB               */
+	SUNI_RPOP_FEBEM		= 0x0ec, /* RPOP Path FEBE MSB               */
+					 /* Reserved (4)                     */
+	SUNI_TPOP_CNTRL_DAIG	= 0x100, /* TPOP Control/Disgnostics         */
+	SUNI_TPOP_POINTER_CTRL	= 0x104, /* TPOP Pointer Control             */
+	SUNI_TPOP_SOURCER_CTRL	= 0x108, /* TPOP Source Control              */
+					 /* Reserved (2)                     */
+	SUNI_TPOP_ARB_PRTL	= 0x114, /* TPOP Arbitrary Pointer LSB       */
+	SUNI_TPOP_ARB_PRTM	= 0x118, /* TPOP Arbitrary Pointer MSB       */
+	SUNI_TPOP_RESERVED2	= 0x11c, /* TPOP Reserved                    */
+	SUNI_TPOP_PATH_SIG	= 0x120, /* TPOP Path Signal Lable           */
+	SUNI_TPOP_PATH_STATUS	= 0x124, /* TPOP Path Status                 */
+					 /* Reserved (6)                     */
+	SUNI_RACP_CS		= 0x140, /* RACP Control/Status              */
+	SUNI_RACP_INTR		= 0x144, /* RACP Interrupt Enable/Status     */
+	SUNI_RACP_HDR_PATTERN	= 0x148, /* RACP Match Header Pattern        */
+	SUNI_RACP_HDR_MASK	= 0x14c, /* RACP Match Header Mask           */
+	SUNI_RACP_CORR_HCS	= 0x150, /* RACP Correctable HCS Error Count */
+	SUNI_RACP_UNCORR_HCS	= 0x154, /* RACP Uncorrectable HCS Err Count */
+					 /* Reserved (10)                    */
+	SUNI_TACP_CONTROL	= 0x180, /* TACP Control                     */
+	SUNI_TACP_IDLE_HDR_PAT	= 0x184, /* TACP Idle Cell Header Pattern    */
+	SUNI_TACP_IDLE_PAY_PAY	= 0x188, /* TACP Idle Cell Payld Octet Patrn */
+					 /* Reserved (5)                     */
+					 /* Reserved (24)                    */
+	/* FIXME: unused but name conflicts.
+	 * SUNI_MASTER_TEST	= 0x200,    SUNI Master Test                 */
+	SUNI_RESERVED_TEST	= 0x204  /* SUNI Reserved for Test           */
+};
 
 typedef struct _SUNI_STATS_
 {
@@ -993,13 +985,11 @@ typedef struct _SUNI_STATS_
    u32 racp_uchcs_count;            // uncorrectable HCS error count
 } IA_SUNI_STATS; 
 
-typedef struct iadev_t {  
+typedef struct iadev_priv {
 	/*-----base pointers into (i)chipSAR+ address space */   
-	u32 __iomem *phy;		/* base pointer into phy(SUNI) */  
-	u32 __iomem *dma;		/* base pointer into DMA control   
-						registers */  
-	u32 __iomem *reg;		/* base pointer to SAR registers  
-					   - Bus Interface Control Regs */  
+	u32 __iomem *phy;	/* Base pointer into phy (SUNI). */
+	u32 __iomem *dma;	/* Base pointer into DMA control registers. */
+	u32 __iomem *reg;	/* Base pointer to SAR registers. */
 	u32 __iomem *seg_reg;		/* base pointer to segmentation engine  
 						internal registers */  
 	u32 __iomem *reass_reg;		/* base pointer to reassemble engine  
@@ -1071,14 +1061,14 @@ typedef struct iadev_t {
 #define INPH_IA_VCC(v) ((struct ia_vcc *) (v)->dev_data)  
 
 /******************* IDT77105 25MB/s PHY DEFINE *****************************/
-typedef struct {
-	u_int	mb25_master_ctrl;	/* Master control		     */
-	u_int	mb25_intr_status;	/* Interrupt status		     */
-	u_int	mb25_diag_control;	/* Diagnostic control		     */
-	u_int	mb25_led_hec;		/* LED driver and HEC status/control */
-	u_int	mb25_low_byte_counter;	/* Low byte counter		     */
-	u_int	mb25_high_byte_counter;	/* High byte counter		     */
-} ia_mb25_t;
+enum ia_mb25 {
+	MB25_MASTER_CTRL	= 0x00, /* Master control		     */
+	MB25_INTR_STATUS	= 0x04,	/* Interrupt status		     */
+	MB25_DIAG_CONTROL	= 0x08,	/* Diagnostic control		     */
+	MB25_LED_HEC		= 0x0c,	/* LED driver and HEC status/control */
+	MB25_LOW_BYTE_COUNTER	= 0x10,
+	MB25_HIGH_BYTE_COUNTER	= 0x14
+};
 
 /*
  * Master Control
@@ -1127,122 +1117,121 @@ typedef struct {
 #define FE_E3_PHY       0x0090          /* E3 */
 		     
 /*********************** SUNI_PM7345 PHY DEFINE HERE *********************/
-typedef struct _suni_pm7345_t
-{
-    u_int suni_config;     /* SUNI Configuration */
-    u_int suni_intr_enbl;  /* SUNI Interrupt Enable */
-    u_int suni_intr_stat;  /* SUNI Interrupt Status */
-    u_int suni_control;    /* SUNI Control */
-    u_int suni_id_reset;   /* SUNI Reset and Identity */
-    u_int suni_data_link_ctrl;
-    u_int suni_rboc_conf_intr_enbl;
-    u_int suni_rboc_stat;
-    u_int suni_ds3_frm_cfg;
-    u_int suni_ds3_frm_intr_enbl;
-    u_int suni_ds3_frm_intr_stat;
-    u_int suni_ds3_frm_stat;
-    u_int suni_rfdl_cfg;
-    u_int suni_rfdl_enbl_stat;
-    u_int suni_rfdl_stat;
-    u_int suni_rfdl_data;
-    u_int suni_pmon_chng;
-    u_int suni_pmon_intr_enbl_stat;
-    u_int suni_reserved1[0x13-0x11];
-    u_int suni_pmon_lcv_evt_cnt_lsb;
-    u_int suni_pmon_lcv_evt_cnt_msb;
-    u_int suni_pmon_fbe_evt_cnt_lsb;
-    u_int suni_pmon_fbe_evt_cnt_msb;
-    u_int suni_pmon_sez_det_cnt_lsb;
-    u_int suni_pmon_sez_det_cnt_msb;
-    u_int suni_pmon_pe_evt_cnt_lsb;
-    u_int suni_pmon_pe_evt_cnt_msb;
-    u_int suni_pmon_ppe_evt_cnt_lsb;
-    u_int suni_pmon_ppe_evt_cnt_msb;
-    u_int suni_pmon_febe_evt_cnt_lsb;
-    u_int suni_pmon_febe_evt_cnt_msb;
-    u_int suni_ds3_tran_cfg;
-    u_int suni_ds3_tran_diag;
-    u_int suni_reserved2[0x23-0x21];
-    u_int suni_xfdl_cfg;
-    u_int suni_xfdl_intr_st;
-    u_int suni_xfdl_xmit_data;
-    u_int suni_xboc_code;
-    u_int suni_splr_cfg;
-    u_int suni_splr_intr_en;
-    u_int suni_splr_intr_st;
-    u_int suni_splr_status;
-    u_int suni_splt_cfg;
-    u_int suni_splt_cntl;
-    u_int suni_splt_diag_g1;
-    u_int suni_splt_f1;
-    u_int suni_cppm_loc_meters;
-    u_int suni_cppm_chng_of_cppm_perf_meter;
-    u_int suni_cppm_b1_err_cnt_lsb;
-    u_int suni_cppm_b1_err_cnt_msb;
-    u_int suni_cppm_framing_err_cnt_lsb;
-    u_int suni_cppm_framing_err_cnt_msb;
-    u_int suni_cppm_febe_cnt_lsb;
-    u_int suni_cppm_febe_cnt_msb;
-    u_int suni_cppm_hcs_err_cnt_lsb;
-    u_int suni_cppm_hcs_err_cnt_msb;
-    u_int suni_cppm_idle_un_cell_cnt_lsb;
-    u_int suni_cppm_idle_un_cell_cnt_msb;
-    u_int suni_cppm_rcv_cell_cnt_lsb;
-    u_int suni_cppm_rcv_cell_cnt_msb;
-    u_int suni_cppm_xmit_cell_cnt_lsb;
-    u_int suni_cppm_xmit_cell_cnt_msb;
-    u_int suni_rxcp_ctrl;
-    u_int suni_rxcp_fctrl;
-    u_int suni_rxcp_intr_en_sts;
-    u_int suni_rxcp_idle_pat_h1;
-    u_int suni_rxcp_idle_pat_h2;
-    u_int suni_rxcp_idle_pat_h3;
-    u_int suni_rxcp_idle_pat_h4;
-    u_int suni_rxcp_idle_mask_h1;
-    u_int suni_rxcp_idle_mask_h2;
-    u_int suni_rxcp_idle_mask_h3;
-    u_int suni_rxcp_idle_mask_h4;
-    u_int suni_rxcp_cell_pat_h1;
-    u_int suni_rxcp_cell_pat_h2;
-    u_int suni_rxcp_cell_pat_h3;
-    u_int suni_rxcp_cell_pat_h4;
-    u_int suni_rxcp_cell_mask_h1;
-    u_int suni_rxcp_cell_mask_h2;
-    u_int suni_rxcp_cell_mask_h3;
-    u_int suni_rxcp_cell_mask_h4;
-    u_int suni_rxcp_hcs_cs;
-    u_int suni_rxcp_lcd_cnt_threshold;
-    u_int suni_reserved3[0x57-0x54];
-    u_int suni_txcp_ctrl;
-    u_int suni_txcp_intr_en_sts;
-    u_int suni_txcp_idle_pat_h1;
-    u_int suni_txcp_idle_pat_h2;
-    u_int suni_txcp_idle_pat_h3;
-    u_int suni_txcp_idle_pat_h4;
-    u_int suni_txcp_idle_pat_h5;
-    u_int suni_txcp_idle_payload;
-    u_int suni_e3_frm_fram_options;
-    u_int suni_e3_frm_maint_options;
-    u_int suni_e3_frm_fram_intr_enbl;
-    u_int suni_e3_frm_fram_intr_ind_stat;
-    u_int suni_e3_frm_maint_intr_enbl;
-    u_int suni_e3_frm_maint_intr_ind;
-    u_int suni_e3_frm_maint_stat;
-    u_int suni_reserved4;
-    u_int suni_e3_tran_fram_options;
-    u_int suni_e3_tran_stat_diag_options;
-    u_int suni_e3_tran_bip_8_err_mask;
-    u_int suni_e3_tran_maint_adapt_options;
-    u_int suni_ttb_ctrl;
-    u_int suni_ttb_trail_trace_id_stat;
-    u_int suni_ttb_ind_addr;
-    u_int suni_ttb_ind_data;
-    u_int suni_ttb_exp_payload_type;
-    u_int suni_ttb_payload_type_ctrl_stat;
-    u_int suni_pad5[0x7f-0x71];
-    u_int suni_master_test;
-    u_int suni_pad6[0xff-0x80];
-}suni_pm7345_t;
+enum suni_pm7345 {
+	SUNI_CONFIG			= 0x000, /* SUNI Configuration */
+	SUNI_INTR_ENBL			= 0x004, /* SUNI Interrupt Enable */
+	SUNI_INTR_STAT			= 0x008, /* SUNI Interrupt Status */
+	SUNI_CONTROL			= 0x00c, /* SUNI Control */
+	SUNI_ID_RESET			= 0x010, /* SUNI Reset and Identity */
+	SUNI_DATA_LINK_CTRL		= 0x014,
+	SUNI_RBOC_CONF_INTR_ENBL	= 0x018,
+	SUNI_RBOC_STAT			= 0x01c,
+	SUNI_DS3_FRM_CFG		= 0x020,
+	SUNI_DS3_FRM_INTR_ENBL		= 0x024,
+	SUNI_DS3_FRM_INTR_STAT		= 0x028,
+	SUNI_DS3_FRM_STAT		= 0x02c,
+	SUNI_RFDL_CFG			= 0x030,
+	SUNI_RFDL_ENBL_STAT		= 0x034,
+	SUNI_RFDL_STAT			= 0x038,
+	SUNI_RFDL_DATA			= 0x03c,
+	SUNI_PMON_CHNG			= 0x040,
+	SUNI_PMON_INTR_ENBL_STAT	= 0x044,
+	/* SUNI_RESERVED1 (0x13 - 0x11) */
+	SUNI_PMON_LCV_EVT_CNT_LSB	= 0x050,
+	SUNI_PMON_LCV_EVT_CNT_MSB	= 0x054,
+	SUNI_PMON_FBE_EVT_CNT_LSB	= 0x058,
+	SUNI_PMON_FBE_EVT_CNT_MSB	= 0x05c,
+	SUNI_PMON_SEZ_DET_CNT_LSB	= 0x060,
+	SUNI_PMON_SEZ_DET_CNT_MSB	= 0x064,
+	SUNI_PMON_PE_EVT_CNT_LSB	= 0x068,
+	SUNI_PMON_PE_EVT_CNT_MSB	= 0x06c,
+	SUNI_PMON_PPE_EVT_CNT_LSB	= 0x070,
+	SUNI_PMON_PPE_EVT_CNT_MSB	= 0x074,
+	SUNI_PMON_FEBE_EVT_CNT_LSB	= 0x078,
+	SUNI_PMON_FEBE_EVT_CNT_MSB	= 0x07c,
+	SUNI_DS3_TRAN_CFG		= 0x080,
+	SUNI_DS3_TRAN_DIAG		= 0x084,
+	/* SUNI_RESERVED2 (0x23 - 0x21) */
+	SUNI_XFDL_CFG			= 0x090,
+	SUNI_XFDL_INTR_ST		= 0x094,
+	SUNI_XFDL_XMIT_DATA		= 0x098,
+	SUNI_XBOC_CODE			= 0x09c,
+	SUNI_SPLR_CFG			= 0x0a0,
+	SUNI_SPLR_INTR_EN		= 0x0a4,
+	SUNI_SPLR_INTR_ST		= 0x0a8,
+	SUNI_SPLR_STATUS		= 0x0ac,
+	SUNI_SPLT_CFG			= 0x0b0,
+	SUNI_SPLT_CNTL			= 0x0b4,
+	SUNI_SPLT_DIAG_G1		= 0x0b8,
+	SUNI_SPLT_F1			= 0x0bc,
+	SUNI_CPPM_LOC_METERS		= 0x0c0,
+	SUNI_CPPM_CHG_OF_CPPM_PERF_METR	= 0x0c4,
+	SUNI_CPPM_B1_ERR_CNT_LSB	= 0x0c8,
+	SUNI_CPPM_B1_ERR_CNT_MSB	= 0x0cc,
+	SUNI_CPPM_FRAMING_ERR_CNT_LSB	= 0x0d0,
+	SUNI_CPPM_FRAMING_ERR_CNT_MSB	= 0x0d4,
+	SUNI_CPPM_FEBE_CNT_LSB		= 0x0d8,
+	SUNI_CPPM_FEBE_CNT_MSB		= 0x0dc,
+	SUNI_CPPM_HCS_ERR_CNT_LSB	= 0x0e0,
+	SUNI_CPPM_HCS_ERR_CNT_MSB	= 0x0e4,
+	SUNI_CPPM_IDLE_UN_CELL_CNT_LSB	= 0x0e8,
+	SUNI_CPPM_IDLE_UN_CELL_CNT_MSB	= 0x0ec,
+	SUNI_CPPM_RCV_CELL_CNT_LSB	= 0x0f0,
+	SUNI_CPPM_RCV_CELL_CNT_MSB	= 0x0f4,
+	SUNI_CPPM_XMIT_CELL_CNT_LSB	= 0x0f8,
+	SUNI_CPPM_XMIT_CELL_CNT_MSB	= 0x0fc,
+	SUNI_RXCP_CTRL			= 0x100,
+	SUNI_RXCP_FCTRL			= 0x104,
+	SUNI_RXCP_INTR_EN_STS		= 0x108,
+	SUNI_RXCP_IDLE_PAT_H1		= 0x10c,
+	SUNI_RXCP_IDLE_PAT_H2		= 0x110,
+	SUNI_RXCP_IDLE_PAT_H3		= 0x114,
+	SUNI_RXCP_IDLE_PAT_H4		= 0x118,
+	SUNI_RXCP_IDLE_MASK_H1		= 0x11c,
+	SUNI_RXCP_IDLE_MASK_H2		= 0x120,
+	SUNI_RXCP_IDLE_MASK_H3		= 0x124,
+	SUNI_RXCP_IDLE_MASK_H4		= 0x128,
+	SUNI_RXCP_CELL_PAT_H1		= 0x12c,
+	SUNI_RXCP_CELL_PAT_H2		= 0x130,
+	SUNI_RXCP_CELL_PAT_H3		= 0x134,
+	SUNI_RXCP_CELL_PAT_H4		= 0x138,
+	SUNI_RXCP_CELL_MASK_H1		= 0x13c,
+	SUNI_RXCP_CELL_MASK_H2		= 0x140,
+	SUNI_RXCP_CELL_MASK_H3		= 0x144,
+	SUNI_RXCP_CELL_MASK_H4		= 0x148,
+	SUNI_RXCP_HCS_CS		= 0x14c,
+	SUNI_RXCP_LCD_CNT_THRESHOLD	= 0x150,
+	/* SUNI_RESERVED3 (0x57 - 0x54) */
+	SUNI_TXCP_CTRL			= 0x160,
+	SUNI_TXCP_INTR_EN_STS		= 0x164,
+	SUNI_TXCP_IDLE_PAT_H1		= 0x168,
+	SUNI_TXCP_IDLE_PAT_H2		= 0x16c,
+	SUNI_TXCP_IDLE_PAT_H3		= 0x170,
+	SUNI_TXCP_IDLE_PAT_H4		= 0x174,
+	SUNI_TXCP_IDLE_PAT_H5		= 0x178,
+	SUNI_TXCP_IDLE_PAYLOAD		= 0x17c,
+	SUNI_E3_FRM_FRAM_OPTIONS	= 0x180,
+	SUNI_E3_FRM_MAINT_OPTIONS	= 0x184,
+	SUNI_E3_FRM_FRAM_INTR_ENBL	= 0x188,
+	SUNI_E3_FRM_FRAM_INTR_IND_STAT	= 0x18c,
+	SUNI_E3_FRM_MAINT_INTR_ENBL	= 0x190,
+	SUNI_E3_FRM_MAINT_INTR_IND	= 0x194,
+	SUNI_E3_FRM_MAINT_STAT		= 0x198,
+	SUNI_RESERVED4			= 0x19c,
+	SUNI_E3_TRAN_FRAM_OPTIONS	= 0x1a0,
+	SUNI_E3_TRAN_STAT_DIAG_OPTIONS	= 0x1a4,
+	SUNI_E3_TRAN_BIP_8_ERR_MASK	= 0x1a8,
+	SUNI_E3_TRAN_MAINT_ADAPT_OPTS	= 0x1ac,
+	SUNI_TTB_CTRL			= 0x1b0,
+	SUNI_TTB_TRAIL_TRACE_ID_STAT	= 0x1b4,
+	SUNI_TTB_IND_ADDR		= 0x1b8,
+	SUNI_TTB_IND_DATA		= 0x1bc,
+	SUNI_TTB_EXP_PAYLOAD_TYPE	= 0x1c0,
+	SUNI_TTB_PAYLOAD_TYPE_CTRL_STAT	= 0x1c4,
+	/* SUNI_PAD5 (0x7f - 0x71) */
+	SUNI_MASTER_TEST		= 0x200,
+	/* SUNI_PAD6 (0xff - 0x80) */
+};
 
 #define SUNI_PM7345_T suni_pm7345_t
 #define SUNI_PM7345     0x20            /* Suni chip type */

+ 15 - 2
drivers/base/class.c

@@ -47,6 +47,18 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr,
 	return ret;
 }
 
+static const void *class_attr_namespace(struct kobject *kobj,
+					const struct attribute *attr)
+{
+	struct class_attribute *class_attr = to_class_attr(attr);
+	struct subsys_private *cp = to_subsys_private(kobj);
+	const void *ns = NULL;
+
+	if (class_attr->namespace)
+		ns = class_attr->namespace(cp->class, class_attr);
+	return ns;
+}
+
 static void class_release(struct kobject *kobj)
 {
 	struct subsys_private *cp = to_subsys_private(kobj);
@@ -72,8 +84,9 @@ static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject
 }
 
 static const struct sysfs_ops class_sysfs_ops = {
-	.show	= class_attr_show,
-	.store	= class_attr_store,
+	.show	   = class_attr_show,
+	.store	   = class_attr_store,
+	.namespace = class_attr_namespace,
 };
 
 static struct kobj_type class_ktype = {

+ 13 - 0
drivers/bcma/Kconfig

@@ -33,6 +33,19 @@ config BCMA_DRIVER_PCI_HOSTMODE
 	help
 	  PCI core hostmode operation (external PCI bus).
 
+config BCMA_HOST_SOC
+	bool
+	depends on BCMA_DRIVER_MIPS
+
+config BCMA_DRIVER_MIPS
+	bool "BCMA Broadcom MIPS core driver"
+	depends on BCMA && MIPS
+	help
+	  Driver for the Broadcom MIPS core attached to Broadcom specific
+	  Advanced Microcontroller Bus.
+
+	  If unsure, say N
+
 config BCMA_DEBUG
 	bool "BCMA debugging"
 	depends on BCMA

+ 2 - 0
drivers/bcma/Makefile

@@ -2,7 +2,9 @@ bcma-y					+= main.o scan.o core.o sprom.o
 bcma-y					+= driver_chipcommon.o driver_chipcommon_pmu.o
 bcma-y					+= driver_pci.o
 bcma-$(CONFIG_BCMA_DRIVER_PCI_HOSTMODE)	+= driver_pci_host.o
+bcma-$(CONFIG_BCMA_DRIVER_MIPS)		+= driver_mips.o
 bcma-$(CONFIG_BCMA_HOST_PCI)		+= host_pci.o
+bcma-$(CONFIG_BCMA_HOST_SOC)		+= host_soc.o
 obj-$(CONFIG_BCMA)			+= bcma.o
 
 ccflags-$(CONFIG_BCMA_DEBUG)		:= -DDEBUG

+ 16 - 0
drivers/bcma/bcma_private.h

@@ -15,13 +15,29 @@ struct bcma_bus;
 /* main.c */
 int bcma_bus_register(struct bcma_bus *bus);
 void bcma_bus_unregister(struct bcma_bus *bus);
+int __init bcma_bus_early_register(struct bcma_bus *bus,
+				   struct bcma_device *core_cc,
+				   struct bcma_device *core_mips);
 
 /* scan.c */
 int bcma_bus_scan(struct bcma_bus *bus);
+int __init bcma_bus_scan_early(struct bcma_bus *bus,
+			       struct bcma_device_id *match,
+			       struct bcma_device *core);
+void bcma_init_bus(struct bcma_bus *bus);
 
 /* sprom.c */
 int bcma_sprom_get(struct bcma_bus *bus);
 
+/* driver_chipcommon.c */
+#ifdef CONFIG_BCMA_DRIVER_MIPS
+void bcma_chipco_serial_init(struct bcma_drv_cc *cc);
+#endif /* CONFIG_BCMA_DRIVER_MIPS */
+
+/* driver_chipcommon_pmu.c */
+u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc);
+u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc);
+
 #ifdef CONFIG_BCMA_HOST_PCI
 /* host_pci.c */
 extern int __init bcma_host_pci_init(void);

+ 2 - 0
drivers/bcma/core.c

@@ -110,6 +110,8 @@ EXPORT_SYMBOL_GPL(bcma_core_pll_ctl);
 u32 bcma_core_dma_translation(struct bcma_device *core)
 {
 	switch (core->bus->hosttype) {
+	case BCMA_HOSTTYPE_SOC:
+		return 0;
 	case BCMA_HOSTTYPE_PCI:
 		if (bcma_aread32(core, BCMA_IOST) & BCMA_IOST_DMA64)
 			return BCMA_DMA_TRANSLATION_DMA64_CMT;

+ 53 - 0
drivers/bcma/driver_chipcommon.c

@@ -26,6 +26,9 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
 	u32 leddc_on = 10;
 	u32 leddc_off = 90;
 
+	if (cc->setup_done)
+		return;
+
 	if (cc->core->id.rev >= 11)
 		cc->status = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
 	cc->capabilities = bcma_cc_read32(cc, BCMA_CC_CAP);
@@ -52,6 +55,8 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc)
 			((leddc_on << BCMA_CC_GPIOTIMER_ONTIME_SHIFT) |
 			 (leddc_off << BCMA_CC_GPIOTIMER_OFFTIME_SHIFT)));
 	}
+
+	cc->setup_done = true;
 }
 
 /* Set chip watchdog reset timer to fire in 'ticks' backplane cycles */
@@ -101,3 +106,51 @@ u32 bcma_chipco_gpio_polarity(struct bcma_drv_cc *cc, u32 mask, u32 value)
 {
 	return bcma_cc_write32_masked(cc, BCMA_CC_GPIOPOL, mask, value);
 }
+
+#ifdef CONFIG_BCMA_DRIVER_MIPS
+void bcma_chipco_serial_init(struct bcma_drv_cc *cc)
+{
+	unsigned int irq;
+	u32 baud_base;
+	u32 i;
+	unsigned int ccrev = cc->core->id.rev;
+	struct bcma_serial_port *ports = cc->serial_ports;
+
+	if (ccrev >= 11 && ccrev != 15) {
+		/* Fixed ALP clock */
+		baud_base = bcma_pmu_alp_clock(cc);
+		if (ccrev >= 21) {
+			/* Turn off UART clock before switching clocksource. */
+			bcma_cc_write32(cc, BCMA_CC_CORECTL,
+				       bcma_cc_read32(cc, BCMA_CC_CORECTL)
+				       & ~BCMA_CC_CORECTL_UARTCLKEN);
+		}
+		/* Set the override bit so we don't divide it */
+		bcma_cc_write32(cc, BCMA_CC_CORECTL,
+			       bcma_cc_read32(cc, BCMA_CC_CORECTL)
+			       | BCMA_CC_CORECTL_UARTCLK0);
+		if (ccrev >= 21) {
+			/* Re-enable the UART clock. */
+			bcma_cc_write32(cc, BCMA_CC_CORECTL,
+				       bcma_cc_read32(cc, BCMA_CC_CORECTL)
+				       | BCMA_CC_CORECTL_UARTCLKEN);
+		}
+	} else {
+		pr_err("serial not supported on this device ccrev: 0x%x\n",
+		       ccrev);
+		return;
+	}
+
+	irq = bcma_core_mips_irq(cc->core);
+
+	/* Determine the registers of the UARTs */
+	cc->nr_serial_ports = (cc->capabilities & BCMA_CC_CAP_NRUART);
+	for (i = 0; i < cc->nr_serial_ports; i++) {
+		ports[i].regs = cc->core->io_addr + BCMA_CC_UART0_DATA +
+				(i * 256);
+		ports[i].irq = irq;
+		ports[i].baud_base = baud_base;
+		ports[i].reg_shift = 0;
+	}
+}
+#endif /* CONFIG_BCMA_DRIVER_MIPS */

+ 181 - 10
drivers/bcma/driver_chipcommon_pmu.c

@@ -11,20 +11,47 @@
 #include "bcma_private.h"
 #include <linux/bcma/bcma.h>
 
-static void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
-					u32 offset, u32 mask, u32 set)
+static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
 {
-	u32 value;
+	bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
+	bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
+	return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
+}
 
-	bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
+void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
+{
+	bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
+	bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
+	bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value);
+}
+EXPORT_SYMBOL_GPL(bcma_chipco_pll_write);
+
+void bcma_chipco_pll_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
+			     u32 set)
+{
+	bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
+	bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
+	bcma_cc_maskset32(cc, BCMA_CC_PLLCTL_DATA, mask, set);
+}
+EXPORT_SYMBOL_GPL(bcma_chipco_pll_maskset);
+
+void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc,
+				 u32 offset, u32 mask, u32 set)
+{
 	bcma_cc_write32(cc, BCMA_CC_CHIPCTL_ADDR, offset);
 	bcma_cc_read32(cc, BCMA_CC_CHIPCTL_ADDR);
-	value = bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
-	value &= mask;
-	value |= set;
-	bcma_cc_write32(cc, BCMA_CC_CHIPCTL_DATA, value);
-	bcma_cc_read32(cc, BCMA_CC_CHIPCTL_DATA);
+	bcma_cc_maskset32(cc, BCMA_CC_CHIPCTL_DATA, mask, set);
+}
+EXPORT_SYMBOL_GPL(bcma_chipco_chipctl_maskset);
+
+void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask,
+				u32 set)
+{
+	bcma_cc_write32(cc, BCMA_CC_REGCTL_ADDR, offset);
+	bcma_cc_read32(cc, BCMA_CC_REGCTL_ADDR);
+	bcma_cc_maskset32(cc, BCMA_CC_REGCTL_DATA, mask, set);
 }
+EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset);
 
 static void bcma_pmu_pll_init(struct bcma_drv_cc *cc)
 {
@@ -83,6 +110,24 @@ void bcma_pmu_swreg_init(struct bcma_drv_cc *cc)
 	}
 }
 
+/* Disable to allow reading SPROM. Don't know the adventages of enabling it. */
+void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable)
+{
+	struct bcma_bus *bus = cc->core->bus;
+	u32 val;
+
+	val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL);
+	if (enable) {
+		val |= BCMA_CHIPCTL_4331_EXTPA_EN;
+		if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11)
+			val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
+	} else {
+		val &= ~BCMA_CHIPCTL_4331_EXTPA_EN;
+		val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5;
+	}
+	bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val);
+}
+
 void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
 {
 	struct bcma_bus *bus = cc->core->bus;
@@ -92,7 +137,7 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
 		bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
 		break;
 	case 0x4331:
-		pr_err("Enabling Ext PA lines not implemented\n");
+		/* BCM4331 workaround is SPROM-related, we put it in sprom.c */
 		break;
 	case 43224:
 		if (bus->chipinfo.rev == 0) {
@@ -136,3 +181,129 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
 	bcma_pmu_swreg_init(cc);
 	bcma_pmu_workarounds(cc);
 }
+
+u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
+{
+	struct bcma_bus *bus = cc->core->bus;
+
+	switch (bus->chipinfo.id) {
+	case 0x4716:
+	case 0x4748:
+	case 47162:
+	case 0x4313:
+	case 0x5357:
+	case 0x4749:
+	case 53572:
+		/* always 20Mhz */
+		return 20000 * 1000;
+	case 0x5356:
+	case 0x5300:
+		/* always 25Mhz */
+		return 25000 * 1000;
+	default:
+		pr_warn("No ALP clock specified for %04X device, "
+			"pmu rev. %d, using default %d Hz\n",
+			bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_ALP_CLOCK);
+	}
+	return BCMA_CC_PMU_ALP_CLOCK;
+}
+
+/* Find the output of the "m" pll divider given pll controls that start with
+ * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
+ */
+static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
+{
+	u32 tmp, div, ndiv, p1, p2, fc;
+	struct bcma_bus *bus = cc->core->bus;
+
+	BUG_ON((pll0 & 3) || (pll0 > BCMA_CC_PMU4716_MAINPLL_PLL0));
+
+	BUG_ON(!m || m > 4);
+
+	if (bus->chipinfo.id == 0x5357 || bus->chipinfo.id == 0x4749) {
+		/* Detect failure in clock setting */
+		tmp = bcma_cc_read32(cc, BCMA_CC_CHIPSTAT);
+		if (tmp & 0x40000)
+			return 133 * 1000000;
+	}
+
+	tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_P1P2_OFF);
+	p1 = (tmp & BCMA_CC_PPL_P1_MASK) >> BCMA_CC_PPL_P1_SHIFT;
+	p2 = (tmp & BCMA_CC_PPL_P2_MASK) >> BCMA_CC_PPL_P2_SHIFT;
+
+	tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_M14_OFF);
+	div = (tmp >> ((m - 1) * BCMA_CC_PPL_MDIV_WIDTH)) &
+		BCMA_CC_PPL_MDIV_MASK;
+
+	tmp = bcma_chipco_pll_read(cc, pll0 + BCMA_CC_PPL_NM5_OFF);
+	ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
+
+	/* Do calculation in Mhz */
+	fc = bcma_pmu_alp_clock(cc) / 1000000;
+	fc = (p1 * ndiv * fc) / p2;
+
+	/* Return clock in Hertz */
+	return (fc / div) * 1000000;
+}
+
+/* query bus clock frequency for PMU-enabled chipcommon */
+u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
+{
+	struct bcma_bus *bus = cc->core->bus;
+
+	switch (bus->chipinfo.id) {
+	case 0x4716:
+	case 0x4748:
+	case 47162:
+		return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
+				      BCMA_CC_PMU5_MAINPLL_SSB);
+	case 0x5356:
+		return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
+				      BCMA_CC_PMU5_MAINPLL_SSB);
+	case 0x5357:
+	case 0x4749:
+		return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
+				      BCMA_CC_PMU5_MAINPLL_SSB);
+	case 0x5300:
+		return bcma_pmu_clock(cc, BCMA_CC_PMU4706_MAINPLL_PLL0,
+				      BCMA_CC_PMU5_MAINPLL_SSB);
+	case 53572:
+		return 75000000;
+	default:
+		pr_warn("No backplane clock specified for %04X device, "
+			"pmu rev. %d, using default %d Hz\n",
+			bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
+	}
+	return BCMA_CC_PMU_HT_CLOCK;
+}
+
+/* query cpu clock frequency for PMU-enabled chipcommon */
+u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
+{
+	struct bcma_bus *bus = cc->core->bus;
+
+	if (bus->chipinfo.id == 53572)
+		return 300000000;
+
+	if (cc->pmu.rev >= 5) {
+		u32 pll;
+		switch (bus->chipinfo.id) {
+		case 0x5356:
+			pll = BCMA_CC_PMU5356_MAINPLL_PLL0;
+			break;
+		case 0x5357:
+		case 0x4749:
+			pll = BCMA_CC_PMU5357_MAINPLL_PLL0;
+			break;
+		default:
+			pll = BCMA_CC_PMU4716_MAINPLL_PLL0;
+			break;
+		}
+
+		/* TODO: if (bus->chipinfo.id == 0x5300)
+		  return si_4706_pmu_clock(sih, osh, cc, PMU4706_MAINPLL_PLL0, PMU5_MAINPLL_CPU); */
+		return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
+	}
+
+	return bcma_pmu_get_clockcontrol(cc);
+}

+ 256 - 0
drivers/bcma/driver_mips.c

@@ -0,0 +1,256 @@
+/*
+ * Broadcom specific AMBA
+ * Broadcom MIPS32 74K core driver
+ *
+ * Copyright 2009, Broadcom Corporation
+ * Copyright 2006, 2007, Michael Buesch <mb@bu3sch.de>
+ * Copyright 2010, Bernhard Loos <bernhardloos@googlemail.com>
+ * Copyright 2011, Hauke Mehrtens <hauke@hauke-m.de>
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+
+#include <linux/bcma/bcma.h>
+
+#include <linux/serial.h>
+#include <linux/serial_core.h>
+#include <linux/serial_reg.h>
+#include <linux/time.h>
+
+/* The 47162a0 hangs when reading MIPS DMP registers registers */
+static inline bool bcma_core_mips_bcm47162a0_quirk(struct bcma_device *dev)
+{
+	return dev->bus->chipinfo.id == 47162 && dev->bus->chipinfo.rev == 0 &&
+	       dev->id.id == BCMA_CORE_MIPS_74K;
+}
+
+/* The 5357b0 hangs when reading USB20H DMP registers */
+static inline bool bcma_core_mips_bcm5357b0_quirk(struct bcma_device *dev)
+{
+	return (dev->bus->chipinfo.id == 0x5357 ||
+		dev->bus->chipinfo.id == 0x4749) &&
+	       dev->bus->chipinfo.pkg == 11 &&
+	       dev->id.id == BCMA_CORE_USB20_HOST;
+}
+
+static inline u32 mips_read32(struct bcma_drv_mips *mcore,
+			      u16 offset)
+{
+	return bcma_read32(mcore->core, offset);
+}
+
+static inline void mips_write32(struct bcma_drv_mips *mcore,
+				u16 offset,
+				u32 value)
+{
+	bcma_write32(mcore->core, offset, value);
+}
+
+static const u32 ipsflag_irq_mask[] = {
+	0,
+	BCMA_MIPS_IPSFLAG_IRQ1,
+	BCMA_MIPS_IPSFLAG_IRQ2,
+	BCMA_MIPS_IPSFLAG_IRQ3,
+	BCMA_MIPS_IPSFLAG_IRQ4,
+};
+
+static const u32 ipsflag_irq_shift[] = {
+	0,
+	BCMA_MIPS_IPSFLAG_IRQ1_SHIFT,
+	BCMA_MIPS_IPSFLAG_IRQ2_SHIFT,
+	BCMA_MIPS_IPSFLAG_IRQ3_SHIFT,
+	BCMA_MIPS_IPSFLAG_IRQ4_SHIFT,
+};
+
+static u32 bcma_core_mips_irqflag(struct bcma_device *dev)
+{
+	u32 flag;
+
+	if (bcma_core_mips_bcm47162a0_quirk(dev))
+		return dev->core_index;
+	if (bcma_core_mips_bcm5357b0_quirk(dev))
+		return dev->core_index;
+	flag = bcma_aread32(dev, BCMA_MIPS_OOBSELOUTA30);
+
+	return flag & 0x1F;
+}
+
+/* Get the MIPS IRQ assignment for a specified device.
+ * If unassigned, 0 is returned.
+ */
+unsigned int bcma_core_mips_irq(struct bcma_device *dev)
+{
+	struct bcma_device *mdev = dev->bus->drv_mips.core;
+	u32 irqflag;
+	unsigned int irq;
+
+	irqflag = bcma_core_mips_irqflag(dev);
+
+	for (irq = 1; irq <= 4; irq++)
+		if (bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq)) &
+		    (1 << irqflag))
+			return irq;
+
+	return 0;
+}
+EXPORT_SYMBOL(bcma_core_mips_irq);
+
+static void bcma_core_mips_set_irq(struct bcma_device *dev, unsigned int irq)
+{
+	unsigned int oldirq = bcma_core_mips_irq(dev);
+	struct bcma_bus *bus = dev->bus;
+	struct bcma_device *mdev = bus->drv_mips.core;
+	u32 irqflag;
+
+	irqflag = bcma_core_mips_irqflag(dev);
+	BUG_ON(oldirq == 6);
+
+	dev->irq = irq + 2;
+
+	/* clear the old irq */
+	if (oldirq == 0)
+		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
+			    bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) &
+			    ~(1 << irqflag));
+	else
+		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq), 0);
+
+	/* assign the new one */
+	if (irq == 0) {
+		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0),
+			    bcma_read32(mdev, BCMA_MIPS_MIPS74K_INTMASK(0)) |
+			    (1 << irqflag));
+	} else {
+		u32 oldirqflag = bcma_read32(mdev,
+					     BCMA_MIPS_MIPS74K_INTMASK(irq));
+		if (oldirqflag) {
+			struct bcma_device *core;
+
+			/* backplane irq line is in use, find out who uses
+			 * it and set user to irq 0
+			 */
+			list_for_each_entry_reverse(core, &bus->cores, list) {
+				if ((1 << bcma_core_mips_irqflag(core)) ==
+				    oldirqflag) {
+					bcma_core_mips_set_irq(core, 0);
+					break;
+				}
+			}
+		}
+		bcma_write32(mdev, BCMA_MIPS_MIPS74K_INTMASK(irq),
+			     1 << irqflag);
+	}
+
+	pr_info("set_irq: core 0x%04x, irq %d => %d\n",
+		dev->id.id, oldirq + 2, irq + 2);
+}
+
+static void bcma_core_mips_print_irq(struct bcma_device *dev, unsigned int irq)
+{
+	int i;
+	static const char *irq_name[] = {"2(S)", "3", "4", "5", "6", "D", "I"};
+	printk(KERN_INFO KBUILD_MODNAME ": core 0x%04x, irq :", dev->id.id);
+	for (i = 0; i <= 6; i++)
+		printk(" %s%s", irq_name[i], i == irq ? "*" : " ");
+	printk("\n");
+}
+
+static void bcma_core_mips_dump_irq(struct bcma_bus *bus)
+{
+	struct bcma_device *core;
+
+	list_for_each_entry_reverse(core, &bus->cores, list) {
+		bcma_core_mips_print_irq(core, bcma_core_mips_irq(core));
+	}
+}
+
+u32 bcma_cpu_clock(struct bcma_drv_mips *mcore)
+{
+	struct bcma_bus *bus = mcore->core->bus;
+
+	if (bus->drv_cc.capabilities & BCMA_CC_CAP_PMU)
+		return bcma_pmu_get_clockcpu(&bus->drv_cc);
+
+	pr_err("No PMU available, need this to get the cpu clock\n");
+	return 0;
+}
+EXPORT_SYMBOL(bcma_cpu_clock);
+
+static void bcma_core_mips_flash_detect(struct bcma_drv_mips *mcore)
+{
+	struct bcma_bus *bus = mcore->core->bus;
+
+	switch (bus->drv_cc.capabilities & BCMA_CC_CAP_FLASHT) {
+	case BCMA_CC_FLASHT_STSER:
+	case BCMA_CC_FLASHT_ATSER:
+		pr_err("Serial flash not supported.\n");
+		break;
+	case BCMA_CC_FLASHT_PARA:
+		pr_info("found parallel flash.\n");
+		bus->drv_cc.pflash.window = 0x1c000000;
+		bus->drv_cc.pflash.window_size = 0x02000000;
+
+		if ((bcma_read32(bus->drv_cc.core, BCMA_CC_FLASH_CFG) &
+		     BCMA_CC_FLASH_CFG_DS) == 0)
+			bus->drv_cc.pflash.buswidth = 1;
+		else
+			bus->drv_cc.pflash.buswidth = 2;
+		break;
+	default:
+		pr_err("flash not supported.\n");
+	}
+}
+
+void bcma_core_mips_init(struct bcma_drv_mips *mcore)
+{
+	struct bcma_bus *bus;
+	struct bcma_device *core;
+	bus = mcore->core->bus;
+
+	pr_info("Initializing MIPS core...\n");
+
+	if (!mcore->setup_done)
+		mcore->assigned_irqs = 1;
+
+	/* Assign IRQs to all cores on the bus */
+	list_for_each_entry_reverse(core, &bus->cores, list) {
+		int mips_irq;
+		if (core->irq)
+			continue;
+
+		mips_irq = bcma_core_mips_irq(core);
+		if (mips_irq > 4)
+			core->irq = 0;
+		else
+			core->irq = mips_irq + 2;
+		if (core->irq > 5)
+			continue;
+		switch (core->id.id) {
+		case BCMA_CORE_PCI:
+		case BCMA_CORE_PCIE:
+		case BCMA_CORE_ETHERNET:
+		case BCMA_CORE_ETHERNET_GBIT:
+		case BCMA_CORE_MAC_GBIT:
+		case BCMA_CORE_80211:
+		case BCMA_CORE_USB20_HOST:
+			/* These devices get their own IRQ line if available,
+			 * the rest goes on IRQ0
+			 */
+			if (mcore->assigned_irqs <= 4)
+				bcma_core_mips_set_irq(core,
+						       mcore->assigned_irqs++);
+			break;
+		}
+	}
+	pr_info("IRQ reconfiguration done\n");
+	bcma_core_mips_dump_irq(bus);
+
+	if (mcore->setup_done)
+		return;
+
+	bcma_chipco_serial_init(&bus->drv_cc);
+	bcma_core_mips_flash_detect(mcore);
+	mcore->setup_done = true;
+}

+ 14 - 2
drivers/bcma/driver_pci.c

@@ -173,7 +173,7 @@ static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
 		return false;
 
 #ifdef CONFIG_SSB_DRIVER_PCICORE
-	if (bus->sprom.boardflags_lo & SSB_PCICORE_BFL_NOPCI)
+	if (bus->sprom.boardflags_lo & SSB_BFL_NOPCI)
 		return false;
 #endif /* CONFIG_SSB_DRIVER_PCICORE */
 
@@ -189,6 +189,9 @@ static bool bcma_core_pci_is_in_hostmode(struct bcma_drv_pci *pc)
 
 void bcma_core_pci_init(struct bcma_drv_pci *pc)
 {
+	if (pc->setup_done)
+		return;
+
 	if (bcma_core_pci_is_in_hostmode(pc)) {
 #ifdef CONFIG_BCMA_DRIVER_PCI_HOSTMODE
 		bcma_core_pci_hostmode_init(pc);
@@ -198,6 +201,8 @@ void bcma_core_pci_init(struct bcma_drv_pci *pc)
 	} else {
 		bcma_core_pci_clientmode_init(pc);
 	}
+
+	pc->setup_done = true;
 }
 
 int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
@@ -205,7 +210,14 @@ int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
 {
 	struct pci_dev *pdev = pc->core->bus->host_pci;
 	u32 coremask, tmp;
-	int err;
+	int err = 0;
+
+	if (core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
+		/* This bcma device is not on a PCI host-bus. So the IRQs are
+		 * not routed through the PCI core.
+		 * So we must not enable routing through the PCI core. */
+		goto out;
+	}
 
 	err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
 	if (err)

+ 183 - 0
drivers/bcma/host_soc.c

@@ -0,0 +1,183 @@
+/*
+ * Broadcom specific AMBA
+ * System on Chip (SoC) Host
+ *
+ * Licensed under the GNU/GPL. See COPYING for details.
+ */
+
+#include "bcma_private.h"
+#include "scan.h"
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_soc.h>
+
+static u8 bcma_host_soc_read8(struct bcma_device *core, u16 offset)
+{
+	return readb(core->io_addr + offset);
+}
+
+static u16 bcma_host_soc_read16(struct bcma_device *core, u16 offset)
+{
+	return readw(core->io_addr + offset);
+}
+
+static u32 bcma_host_soc_read32(struct bcma_device *core, u16 offset)
+{
+	return readl(core->io_addr + offset);
+}
+
+static void bcma_host_soc_write8(struct bcma_device *core, u16 offset,
+				 u8 value)
+{
+	writeb(value, core->io_addr + offset);
+}
+
+static void bcma_host_soc_write16(struct bcma_device *core, u16 offset,
+				 u16 value)
+{
+	writew(value, core->io_addr + offset);
+}
+
+static void bcma_host_soc_write32(struct bcma_device *core, u16 offset,
+				 u32 value)
+{
+	writel(value, core->io_addr + offset);
+}
+
+#ifdef CONFIG_BCMA_BLOCKIO
+static void bcma_host_soc_block_read(struct bcma_device *core, void *buffer,
+				     size_t count, u16 offset, u8 reg_width)
+{
+	void __iomem *addr = core->io_addr + offset;
+
+	switch (reg_width) {
+	case sizeof(u8): {
+		u8 *buf = buffer;
+
+		while (count) {
+			*buf = __raw_readb(addr);
+			buf++;
+			count--;
+		}
+		break;
+	}
+	case sizeof(u16): {
+		__le16 *buf = buffer;
+
+		WARN_ON(count & 1);
+		while (count) {
+			*buf = (__force __le16)__raw_readw(addr);
+			buf++;
+			count -= 2;
+		}
+		break;
+	}
+	case sizeof(u32): {
+		__le32 *buf = buffer;
+
+		WARN_ON(count & 3);
+		while (count) {
+			*buf = (__force __le32)__raw_readl(addr);
+			buf++;
+			count -= 4;
+		}
+		break;
+	}
+	default:
+		WARN_ON(1);
+	}
+}
+
+static void bcma_host_soc_block_write(struct bcma_device *core,
+				      const void *buffer,
+				      size_t count, u16 offset, u8 reg_width)
+{
+	void __iomem *addr = core->io_addr + offset;
+
+	switch (reg_width) {
+	case sizeof(u8): {
+		const u8 *buf = buffer;
+
+		while (count) {
+			__raw_writeb(*buf, addr);
+			buf++;
+			count--;
+		}
+		break;
+	}
+	case sizeof(u16): {
+		const __le16 *buf = buffer;
+
+		WARN_ON(count & 1);
+		while (count) {
+			__raw_writew((__force u16)(*buf), addr);
+			buf++;
+			count -= 2;
+		}
+		break;
+	}
+	case sizeof(u32): {
+		const __le32 *buf = buffer;
+
+		WARN_ON(count & 3);
+		while (count) {
+			__raw_writel((__force u32)(*buf), addr);
+			buf++;
+			count -= 4;
+		}
+		break;
+	}
+	default:
+		WARN_ON(1);
+	}
+}
+#endif /* CONFIG_BCMA_BLOCKIO */
+
+static u32 bcma_host_soc_aread32(struct bcma_device *core, u16 offset)
+{
+	return readl(core->io_wrap + offset);
+}
+
+static void bcma_host_soc_awrite32(struct bcma_device *core, u16 offset,
+				  u32 value)
+{
+	writel(value, core->io_wrap + offset);
+}
+
+const struct bcma_host_ops bcma_host_soc_ops = {
+	.read8		= bcma_host_soc_read8,
+	.read16		= bcma_host_soc_read16,
+	.read32		= bcma_host_soc_read32,
+	.write8		= bcma_host_soc_write8,
+	.write16	= bcma_host_soc_write16,
+	.write32	= bcma_host_soc_write32,
+#ifdef CONFIG_BCMA_BLOCKIO
+	.block_read	= bcma_host_soc_block_read,
+	.block_write	= bcma_host_soc_block_write,
+#endif
+	.aread32	= bcma_host_soc_aread32,
+	.awrite32	= bcma_host_soc_awrite32,
+};
+
+int __init bcma_host_soc_register(struct bcma_soc *soc)
+{
+	struct bcma_bus *bus = &soc->bus;
+	int err;
+
+	/* iomap only first core. We have to read some register on this core
+	 * to scan the bus.
+	 */
+	bus->mmio = ioremap_nocache(BCMA_ADDR_BASE, BCMA_CORE_SIZE * 1);
+	if (!bus->mmio)
+		return -ENOMEM;
+
+	/* Host specific */
+	bus->hosttype = BCMA_HOSTTYPE_SOC;
+	bus->ops = &bcma_host_soc_ops;
+
+	/* Register */
+	err = bcma_bus_early_register(bus, &soc->core_cc, &soc->core_mips);
+	if (err)
+		iounmap(bus->mmio);
+
+	return err;
+}

+ 69 - 1
drivers/bcma/main.c

@@ -68,6 +68,10 @@ static struct bcma_device *bcma_find_core(struct bcma_bus *bus, u16 coreid)
 static void bcma_release_core_dev(struct device *dev)
 {
 	struct bcma_device *core = container_of(dev, struct bcma_device, dev);
+	if (core->io_addr)
+		iounmap(core->io_addr);
+	if (core->io_wrap)
+		iounmap(core->io_wrap);
 	kfree(core);
 }
 
@@ -82,6 +86,7 @@ static int bcma_register_cores(struct bcma_bus *bus)
 		case BCMA_CORE_CHIPCOMMON:
 		case BCMA_CORE_PCI:
 		case BCMA_CORE_PCIE:
+		case BCMA_CORE_MIPS_74K:
 			continue;
 		}
 
@@ -95,7 +100,10 @@ static int bcma_register_cores(struct bcma_bus *bus)
 			core->dma_dev = &bus->host_pci->dev;
 			core->irq = bus->host_pci->irq;
 			break;
-		case BCMA_HOSTTYPE_NONE:
+		case BCMA_HOSTTYPE_SOC:
+			core->dev.dma_mask = &core->dev.coherent_dma_mask;
+			core->dma_dev = &core->dev;
+			break;
 		case BCMA_HOSTTYPE_SDIO:
 			break;
 		}
@@ -142,6 +150,13 @@ int bcma_bus_register(struct bcma_bus *bus)
 		bcma_core_chipcommon_init(&bus->drv_cc);
 	}
 
+	/* Init MIPS core */
+	core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
+	if (core) {
+		bus->drv_mips.core = core;
+		bcma_core_mips_init(&bus->drv_mips);
+	}
+
 	/* Init PCIE core */
 	core = bcma_find_core(bus, BCMA_CORE_PCIE);
 	if (core) {
@@ -171,6 +186,59 @@ void bcma_bus_unregister(struct bcma_bus *bus)
 	bcma_unregister_cores(bus);
 }
 
+int __init bcma_bus_early_register(struct bcma_bus *bus,
+				   struct bcma_device *core_cc,
+				   struct bcma_device *core_mips)
+{
+	int err;
+	struct bcma_device *core;
+	struct bcma_device_id match;
+
+	bcma_init_bus(bus);
+
+	match.manuf = BCMA_MANUF_BCM;
+	match.id = BCMA_CORE_CHIPCOMMON;
+	match.class = BCMA_CL_SIM;
+	match.rev = BCMA_ANY_REV;
+
+	/* Scan for chip common core */
+	err = bcma_bus_scan_early(bus, &match, core_cc);
+	if (err) {
+		pr_err("Failed to scan for common core: %d\n", err);
+		return -1;
+	}
+
+	match.manuf = BCMA_MANUF_MIPS;
+	match.id = BCMA_CORE_MIPS_74K;
+	match.class = BCMA_CL_SIM;
+	match.rev = BCMA_ANY_REV;
+
+	/* Scan for mips core */
+	err = bcma_bus_scan_early(bus, &match, core_mips);
+	if (err) {
+		pr_err("Failed to scan for mips core: %d\n", err);
+		return -1;
+	}
+
+	/* Init CC core */
+	core = bcma_find_core(bus, BCMA_CORE_CHIPCOMMON);
+	if (core) {
+		bus->drv_cc.core = core;
+		bcma_core_chipcommon_init(&bus->drv_cc);
+	}
+
+	/* Init MIPS core */
+	core = bcma_find_core(bus, BCMA_CORE_MIPS_74K);
+	if (core) {
+		bus->drv_mips.core = core;
+		bcma_core_mips_init(&bus->drv_mips);
+	}
+
+	pr_info("Early bus registered\n");
+
+	return 0;
+}
+
 int __bcma_driver_register(struct bcma_driver *drv, struct module *owner)
 {
 	drv->drv.name = drv->name;

+ 237 - 111
drivers/bcma/scan.c

@@ -200,18 +200,162 @@ static s32 bcma_erom_get_addr_desc(struct bcma_bus *bus, u32 **eromptr,
 	return addrl;
 }
 
-int bcma_bus_scan(struct bcma_bus *bus)
+static struct bcma_device *bcma_find_core_by_index(struct bcma_bus *bus,
+						   u16 index)
 {
-	u32 erombase;
-	u32 __iomem *eromptr, *eromend;
+	struct bcma_device *core;
 
+	list_for_each_entry(core, &bus->cores, list) {
+		if (core->core_index == index)
+			return core;
+	}
+	return NULL;
+}
+
+static int bcma_get_next_core(struct bcma_bus *bus, u32 __iomem **eromptr,
+			      struct bcma_device_id *match, int core_num,
+			      struct bcma_device *core)
+{
+	s32 tmp;
+	u8 i, j;
 	s32 cia, cib;
 	u8 ports[2], wrappers[2];
 
+	/* get CIs */
+	cia = bcma_erom_get_ci(bus, eromptr);
+	if (cia < 0) {
+		bcma_erom_push_ent(eromptr);
+		if (bcma_erom_is_end(bus, eromptr))
+			return -ESPIPE;
+		return -EILSEQ;
+	}
+	cib = bcma_erom_get_ci(bus, eromptr);
+	if (cib < 0)
+		return -EILSEQ;
+
+	/* parse CIs */
+	core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
+	core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
+	core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
+	ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
+	ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
+	wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
+	wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
+	core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
+
+	if (((core->id.manuf == BCMA_MANUF_ARM) &&
+	     (core->id.id == 0xFFF)) ||
+	    (ports[1] == 0)) {
+		bcma_erom_skip_component(bus, eromptr);
+		return -ENXIO;
+	}
+
+	/* check if component is a core at all */
+	if (wrappers[0] + wrappers[1] == 0) {
+		/* we could save addrl of the router
+		if (cid == BCMA_CORE_OOB_ROUTER)
+		 */
+		bcma_erom_skip_component(bus, eromptr);
+		return -ENXIO;
+	}
+
+	if (bcma_erom_is_bridge(bus, eromptr)) {
+		bcma_erom_skip_component(bus, eromptr);
+		return -ENXIO;
+	}
+
+	if (bcma_find_core_by_index(bus, core_num)) {
+		bcma_erom_skip_component(bus, eromptr);
+		return -ENODEV;
+	}
+
+	if (match && ((match->manuf != BCMA_ANY_MANUF &&
+	      match->manuf != core->id.manuf) ||
+	     (match->id != BCMA_ANY_ID && match->id != core->id.id) ||
+	     (match->rev != BCMA_ANY_REV && match->rev != core->id.rev) ||
+	     (match->class != BCMA_ANY_CLASS && match->class != core->id.class)
+	    )) {
+		bcma_erom_skip_component(bus, eromptr);
+		return -ENODEV;
+	}
+
+	/* get & parse master ports */
+	for (i = 0; i < ports[0]; i++) {
+		s32 mst_port_d = bcma_erom_get_mst_port(bus, eromptr);
+		if (mst_port_d < 0)
+			return -EILSEQ;
+	}
+
+	/* get & parse slave ports */
+	for (i = 0; i < ports[1]; i++) {
+		for (j = 0; ; j++) {
+			tmp = bcma_erom_get_addr_desc(bus, eromptr,
+				SCAN_ADDR_TYPE_SLAVE, i);
+			if (tmp < 0) {
+				/* no more entries for port _i_ */
+				/* pr_debug("erom: slave port %d "
+				 * "has %d descriptors\n", i, j); */
+				break;
+			} else {
+				if (i == 0 && j == 0)
+					core->addr = tmp;
+			}
+		}
+	}
+
+	/* get & parse master wrappers */
+	for (i = 0; i < wrappers[0]; i++) {
+		for (j = 0; ; j++) {
+			tmp = bcma_erom_get_addr_desc(bus, eromptr,
+				SCAN_ADDR_TYPE_MWRAP, i);
+			if (tmp < 0) {
+				/* no more entries for port _i_ */
+				/* pr_debug("erom: master wrapper %d "
+				 * "has %d descriptors\n", i, j); */
+				break;
+			} else {
+				if (i == 0 && j == 0)
+					core->wrap = tmp;
+			}
+		}
+	}
+
+	/* get & parse slave wrappers */
+	for (i = 0; i < wrappers[1]; i++) {
+		u8 hack = (ports[1] == 1) ? 0 : 1;
+		for (j = 0; ; j++) {
+			tmp = bcma_erom_get_addr_desc(bus, eromptr,
+				SCAN_ADDR_TYPE_SWRAP, i + hack);
+			if (tmp < 0) {
+				/* no more entries for port _i_ */
+				/* pr_debug("erom: master wrapper %d "
+				 * has %d descriptors\n", i, j); */
+				break;
+			} else {
+				if (wrappers[0] == 0 && !i && !j)
+					core->wrap = tmp;
+			}
+		}
+	}
+	if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
+		core->io_addr = ioremap_nocache(core->addr, BCMA_CORE_SIZE);
+		if (!core->io_addr)
+			return -ENOMEM;
+		core->io_wrap = ioremap_nocache(core->wrap, BCMA_CORE_SIZE);
+		if (!core->io_wrap) {
+			iounmap(core->io_addr);
+			return -ENOMEM;
+		}
+	}
+	return 0;
+}
+
+void bcma_init_bus(struct bcma_bus *bus)
+{
 	s32 tmp;
-	u8 i, j;
 
-	int err;
+	if (bus->init_done)
+		return;
 
 	INIT_LIST_HEAD(&bus->cores);
 	bus->nr_cores = 0;
@@ -222,9 +366,27 @@ int bcma_bus_scan(struct bcma_bus *bus)
 	bus->chipinfo.id = (tmp & BCMA_CC_ID_ID) >> BCMA_CC_ID_ID_SHIFT;
 	bus->chipinfo.rev = (tmp & BCMA_CC_ID_REV) >> BCMA_CC_ID_REV_SHIFT;
 	bus->chipinfo.pkg = (tmp & BCMA_CC_ID_PKG) >> BCMA_CC_ID_PKG_SHIFT;
+	bus->init_done = true;
+}
+
+int bcma_bus_scan(struct bcma_bus *bus)
+{
+	u32 erombase;
+	u32 __iomem *eromptr, *eromend;
+
+	int err, core_num = 0;
+
+	bcma_init_bus(bus);
 
 	erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
-	eromptr = bus->mmio;
+	if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
+		eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
+		if (!eromptr)
+			return -ENOMEM;
+	} else {
+		eromptr = bus->mmio;
+	}
+
 	eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
 
 	bcma_scan_switch_core(bus, erombase);
@@ -236,125 +398,89 @@ int bcma_bus_scan(struct bcma_bus *bus)
 		INIT_LIST_HEAD(&core->list);
 		core->bus = bus;
 
-		/* get CIs */
-		cia = bcma_erom_get_ci(bus, &eromptr);
-		if (cia < 0) {
-			bcma_erom_push_ent(&eromptr);
-			if (bcma_erom_is_end(bus, &eromptr))
-				break;
-			err= -EILSEQ;
-			goto out;
-		}
-		cib = bcma_erom_get_ci(bus, &eromptr);
-		if (cib < 0) {
-			err= -EILSEQ;
-			goto out;
-		}
-
-		/* parse CIs */
-		core->id.class = (cia & SCAN_CIA_CLASS) >> SCAN_CIA_CLASS_SHIFT;
-		core->id.id = (cia & SCAN_CIA_ID) >> SCAN_CIA_ID_SHIFT;
-		core->id.manuf = (cia & SCAN_CIA_MANUF) >> SCAN_CIA_MANUF_SHIFT;
-		ports[0] = (cib & SCAN_CIB_NMP) >> SCAN_CIB_NMP_SHIFT;
-		ports[1] = (cib & SCAN_CIB_NSP) >> SCAN_CIB_NSP_SHIFT;
-		wrappers[0] = (cib & SCAN_CIB_NMW) >> SCAN_CIB_NMW_SHIFT;
-		wrappers[1] = (cib & SCAN_CIB_NSW) >> SCAN_CIB_NSW_SHIFT;
-		core->id.rev = (cib & SCAN_CIB_REV) >> SCAN_CIB_REV_SHIFT;
-
-		if (((core->id.manuf == BCMA_MANUF_ARM) &&
-		     (core->id.id == 0xFFF)) ||
-		    (ports[1] == 0)) {
-			bcma_erom_skip_component(bus, &eromptr);
+		err = bcma_get_next_core(bus, &eromptr, NULL, core_num, core);
+		if (err == -ENODEV) {
+			core_num++;
 			continue;
-		}
-
-		/* check if component is a core at all */
-		if (wrappers[0] + wrappers[1] == 0) {
-			/* we could save addrl of the router
-			if (cid == BCMA_CORE_OOB_ROUTER)
-			 */
-			bcma_erom_skip_component(bus, &eromptr);
+		} else if (err == -ENXIO)
 			continue;
-		}
+		else if (err == -ESPIPE)
+			break;
+		else if (err < 0)
+			return err;
 
-		if (bcma_erom_is_bridge(bus, &eromptr)) {
-			bcma_erom_skip_component(bus, &eromptr);
-			continue;
-		}
+		core->core_index = core_num++;
+		bus->nr_cores++;
 
-		/* get & parse master ports */
-		for (i = 0; i < ports[0]; i++) {
-			u32 mst_port_d = bcma_erom_get_mst_port(bus, &eromptr);
-			if (mst_port_d < 0) {
-				err= -EILSEQ;
-				goto out;
-			}
-		}
+		pr_info("Core %d found: %s "
+			"(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
+			core->core_index, bcma_device_name(&core->id),
+			core->id.manuf, core->id.id, core->id.rev,
+			core->id.class);
 
-		/* get & parse slave ports */
-		for (i = 0; i < ports[1]; i++) {
-			for (j = 0; ; j++) {
-				tmp = bcma_erom_get_addr_desc(bus, &eromptr,
-					SCAN_ADDR_TYPE_SLAVE, i);
-				if (tmp < 0) {
-					/* no more entries for port _i_ */
-					/* pr_debug("erom: slave port %d "
-					 * "has %d descriptors\n", i, j); */
-					break;
-				} else {
-					if (i == 0 && j == 0)
-						core->addr = tmp;
-				}
-			}
-		}
+		list_add(&core->list, &bus->cores);
+	}
 
-		/* get & parse master wrappers */
-		for (i = 0; i < wrappers[0]; i++) {
-			for (j = 0; ; j++) {
-				tmp = bcma_erom_get_addr_desc(bus, &eromptr,
-					SCAN_ADDR_TYPE_MWRAP, i);
-				if (tmp < 0) {
-					/* no more entries for port _i_ */
-					/* pr_debug("erom: master wrapper %d "
-					 * "has %d descriptors\n", i, j); */
-					break;
-				} else {
-					if (i == 0 && j == 0)
-						core->wrap = tmp;
-				}
-			}
-		}
+	if (bus->hosttype == BCMA_HOSTTYPE_SOC)
+		iounmap(eromptr);
 
-		/* get & parse slave wrappers */
-		for (i = 0; i < wrappers[1]; i++) {
-			u8 hack = (ports[1] == 1) ? 0 : 1;
-			for (j = 0; ; j++) {
-				tmp = bcma_erom_get_addr_desc(bus, &eromptr,
-					SCAN_ADDR_TYPE_SWRAP, i + hack);
-				if (tmp < 0) {
-					/* no more entries for port _i_ */
-					/* pr_debug("erom: master wrapper %d "
-					 * has %d descriptors\n", i, j); */
-					break;
-				} else {
-					if (wrappers[0] == 0 && !i && !j)
-						core->wrap = tmp;
-				}
-			}
-		}
+	return 0;
+}
+
+int __init bcma_bus_scan_early(struct bcma_bus *bus,
+			       struct bcma_device_id *match,
+			       struct bcma_device *core)
+{
+	u32 erombase;
+	u32 __iomem *eromptr, *eromend;
+
+	int err = -ENODEV;
+	int core_num = 0;
+
+	erombase = bcma_scan_read32(bus, 0, BCMA_CC_EROM);
+	if (bus->hosttype == BCMA_HOSTTYPE_SOC) {
+		eromptr = ioremap_nocache(erombase, BCMA_CORE_SIZE);
+		if (!eromptr)
+			return -ENOMEM;
+	} else {
+		eromptr = bus->mmio;
+	}
+
+	eromend = eromptr + BCMA_CORE_SIZE / sizeof(u32);
+
+	bcma_scan_switch_core(bus, erombase);
+
+	while (eromptr < eromend) {
+		memset(core, 0, sizeof(*core));
+		INIT_LIST_HEAD(&core->list);
+		core->bus = bus;
 
+		err = bcma_get_next_core(bus, &eromptr, match, core_num, core);
+		if (err == -ENODEV) {
+			core_num++;
+			continue;
+		} else if (err == -ENXIO)
+			continue;
+		else if (err == -ESPIPE)
+			break;
+		else if (err < 0)
+			return err;
+
+		core->core_index = core_num++;
+		bus->nr_cores++;
 		pr_info("Core %d found: %s "
 			"(manuf 0x%03X, id 0x%03X, rev 0x%02X, class 0x%X)\n",
-			bus->nr_cores, bcma_device_name(&core->id),
+			core->core_index, bcma_device_name(&core->id),
 			core->id.manuf, core->id.id, core->id.rev,
 			core->id.class);
 
-		core->core_index = bus->nr_cores++;
 		list_add(&core->list, &bus->cores);
-		continue;
-out:
-		return err;
+		err = 0;
+		break;
 	}
 
-	return 0;
+	if (bus->hosttype == BCMA_HOSTTYPE_SOC)
+		iounmap(eromptr);
+
+	return err;
 }

+ 15 - 0
drivers/bcma/sprom.c

@@ -133,6 +133,15 @@ static void bcma_sprom_extract_r8(struct bcma_bus *bus, const u16 *sprom)
 		v = sprom[SPOFF(SSB_SPROM8_IL0MAC) + i];
 		*(((__be16 *)bus->sprom.il0mac) + i) = cpu_to_be16(v);
 	}
+
+	bus->sprom.board_rev = sprom[SPOFF(SSB_SPROM8_BOARDREV)];
+
+	bus->sprom.boardflags_lo = sprom[SPOFF(SSB_SPROM8_BFLLO)];
+	bus->sprom.boardflags_hi = sprom[SPOFF(SSB_SPROM8_BFLHI)];
+	bus->sprom.boardflags2_lo = sprom[SPOFF(SSB_SPROM8_BFL2LO)];
+	bus->sprom.boardflags2_hi = sprom[SPOFF(SSB_SPROM8_BFL2HI)];
+
+	bus->sprom.country_code = sprom[SPOFF(SSB_SPROM8_CCODE)];
 }
 
 int bcma_sprom_get(struct bcma_bus *bus)
@@ -152,6 +161,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
 	if (!sprom)
 		return -ENOMEM;
 
+	if (bus->chipinfo.id == 0x4331)
+		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
+
 	/* Most cards have SPROM moved by additional offset 0x30 (48 dwords).
 	 * According to brcm80211 this applies to cards with PCIe rev >= 6
 	 * TODO: understand this condition and use it */
@@ -159,6 +171,9 @@ int bcma_sprom_get(struct bcma_bus *bus)
 		BCMA_CC_SPROM_PCIE6;
 	bcma_sprom_read(bus, offset, sprom);
 
+	if (bus->chipinfo.id == 0x4331)
+		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
+
 	err = bcma_sprom_valid(sprom);
 	if (err)
 		goto out;

+ 4 - 2
drivers/bluetooth/btusb.c

@@ -60,6 +60,9 @@ static struct usb_device_id btusb_table[] = {
 	/* Generic Bluetooth USB device */
 	{ USB_DEVICE_INFO(0xe0, 0x01, 0x01) },
 
+	/* Broadcom SoftSailing reporting vendor specific */
+	{ USB_DEVICE(0x05ac, 0x21e1) },
+
 	/* Apple MacBookPro 7,1 */
 	{ USB_DEVICE(0x05ac, 0x8213) },
 
@@ -708,8 +711,7 @@ static int btusb_send_frame(struct sk_buff *skb)
 		break;
 
 	case HCI_ACLDATA_PKT:
-		if (!data->bulk_tx_ep || (hdev->conn_hash.acl_num < 1 &&
-						hdev->conn_hash.le_num < 1))
+		if (!data->bulk_tx_ep)
 			return -ENODEV;
 
 		urb = usb_alloc_urb(0, GFP_ATOMIC);

+ 26 - 0
drivers/connector/cn_proc.c

@@ -205,6 +205,32 @@ void proc_ptrace_connector(struct task_struct *task, int ptrace_id)
 	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
 }
 
+void proc_comm_connector(struct task_struct *task)
+{
+	struct cn_msg *msg;
+	struct proc_event *ev;
+	struct timespec ts;
+	__u8 buffer[CN_PROC_MSG_SIZE];
+
+	if (atomic_read(&proc_event_num_listeners) < 1)
+		return;
+
+	msg = (struct cn_msg *)buffer;
+	ev = (struct proc_event *)msg->data;
+	get_seq(&msg->seq, &ev->cpu);
+	ktime_get_ts(&ts); /* get high res monotonic timestamp */
+	put_unaligned(timespec_to_ns(&ts), (__u64 *)&ev->timestamp_ns);
+	ev->what = PROC_EVENT_COMM;
+	ev->event_data.comm.process_pid  = task->pid;
+	ev->event_data.comm.process_tgid = task->tgid;
+	get_task_comm(ev->event_data.comm.comm, task);
+
+	memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id));
+	msg->ack = 0; /* not used */
+	msg->len = sizeof(*ev);
+	cn_netlink_send(msg, CN_IDX_PROC, GFP_KERNEL);
+}
+
 void proc_exit_connector(struct task_struct *task)
 {
 	struct cn_msg *msg;

+ 4 - 7
drivers/infiniband/hw/amso1100/c2.c

@@ -800,13 +800,10 @@ static int c2_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	/* Loop thru additional data fragments and queue them */
 	if (skb_shinfo(skb)->nr_frags) {
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-			maplen = frag->size;
-			mapaddr =
-			    pci_map_page(c2dev->pcidev, frag->page,
-					 frag->page_offset, maplen,
-					 PCI_DMA_TODEVICE);
-
+			const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+			maplen = skb_frag_size(frag);
+			mapaddr = skb_frag_dma_map(&c2dev->pcidev->dev, frag,
+						   0, maplen, DMA_TO_DEVICE);
 			elem = elem->next;
 			elem->skb = NULL;
 			elem->mapaddr = mapaddr;

+ 1 - 1
drivers/infiniband/hw/cxgb3/Makefile

@@ -1,4 +1,4 @@
-ccflags-y := -Idrivers/net/cxgb3
+ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb3
 
 obj-$(CONFIG_INFINIBAND_CXGB3) += iw_cxgb3.o
 

+ 1 - 1
drivers/infiniband/hw/cxgb4/Makefile

@@ -1,4 +1,4 @@
-ccflags-y := -Idrivers/net/cxgb4
+ccflags-y := -Idrivers/net/ethernet/chelsio/cxgb4
 
 obj-$(CONFIG_INFINIBAND_CXGB4) += iw_cxgb4.o
 

+ 2 - 1
drivers/infiniband/hw/mlx4/Kconfig

@@ -1,6 +1,7 @@
 config MLX4_INFINIBAND
 	tristate "Mellanox ConnectX HCA support"
-	depends on NETDEVICES && NETDEV_10000 && PCI
+	depends on NETDEVICES && ETHERNET && PCI
+	select NET_VENDOR_MELLANOX
 	select MLX4_CORE
 	---help---
 	  This driver provides low-level InfiniBand support for

+ 15 - 14
drivers/infiniband/hw/nes/nes_nic.c

@@ -441,13 +441,13 @@ static int nes_nic_send(struct sk_buff *skb, struct net_device *netdev)
 		nesnic->tx_skb[nesnic->sq_head] = skb;
 		for (skb_fragment_index = 0; skb_fragment_index < skb_shinfo(skb)->nr_frags;
 				skb_fragment_index++) {
-			bus_address = pci_map_page( nesdev->pcidev,
-					skb_shinfo(skb)->frags[skb_fragment_index].page,
-					skb_shinfo(skb)->frags[skb_fragment_index].page_offset,
-					skb_shinfo(skb)->frags[skb_fragment_index].size,
-					PCI_DMA_TODEVICE);
+			skb_frag_t *frag =
+				&skb_shinfo(skb)->frags[skb_fragment_index];
+			bus_address = skb_frag_dma_map(&nesdev->pcidev->dev,
+						       frag, 0, skb_frag_size(frag),
+						       DMA_TO_DEVICE);
 			wqe_fragment_length[wqe_fragment_index] =
-					cpu_to_le16(skb_shinfo(skb)->frags[skb_fragment_index].size);
+					cpu_to_le16(skb_frag_size(&skb_shinfo(skb)->frags[skb_fragment_index]));
 			set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX+(2*wqe_fragment_index),
 				bus_address);
 			wqe_fragment_index++;
@@ -561,11 +561,12 @@ tso_sq_no_longer_full:
 			/* Map all the buffers */
 			for (tso_frag_count=0; tso_frag_count < skb_shinfo(skb)->nr_frags;
 					tso_frag_count++) {
-				tso_bus_address[tso_frag_count] = pci_map_page( nesdev->pcidev,
-						skb_shinfo(skb)->frags[tso_frag_count].page,
-						skb_shinfo(skb)->frags[tso_frag_count].page_offset,
-						skb_shinfo(skb)->frags[tso_frag_count].size,
-						PCI_DMA_TODEVICE);
+				skb_frag_t *frag =
+					&skb_shinfo(skb)->frags[tso_frag_count];
+				tso_bus_address[tso_frag_count] =
+					skb_frag_dma_map(&nesdev->pcidev->dev,
+							 frag, 0, skb_frag_size(frag),
+							 DMA_TO_DEVICE);
 			}
 
 			tso_frag_index = 0;
@@ -636,11 +637,11 @@ tso_sq_no_longer_full:
 				}
 				while (wqe_fragment_index < 5) {
 					wqe_fragment_length[wqe_fragment_index] =
-							cpu_to_le16(skb_shinfo(skb)->frags[tso_frag_index].size);
+							cpu_to_le16(skb_frag_size(&skb_shinfo(skb)->frags[tso_frag_index]));
 					set_wqe_64bit_value(nic_sqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX+(2*wqe_fragment_index),
 						(u64)tso_bus_address[tso_frag_index]);
 					wqe_fragment_index++;
-					tso_wqe_length += skb_shinfo(skb)->frags[tso_frag_index++].size;
+					tso_wqe_length += skb_frag_size(&skb_shinfo(skb)->frags[tso_frag_index++]);
 					if (wqe_fragment_index < 5)
 						wqe_fragment_length[wqe_fragment_index] = 0;
 					if (tso_frag_index == tso_frag_count)
@@ -1638,7 +1639,7 @@ static const struct net_device_ops nes_netdev_ops = {
 	.ndo_get_stats		= nes_netdev_get_stats,
 	.ndo_tx_timeout		= nes_netdev_tx_timeout,
 	.ndo_set_mac_address	= nes_netdev_set_mac_address,
-	.ndo_set_multicast_list = nes_netdev_set_multicast_list,
+	.ndo_set_rx_mode	= nes_netdev_set_multicast_list,
 	.ndo_change_mtu		= nes_netdev_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,
 	.ndo_fix_features	= nes_fix_features,

+ 4 - 3
drivers/infiniband/ulp/ipoib/ipoib_cm.c

@@ -169,7 +169,7 @@ static struct sk_buff *ipoib_cm_alloc_rx_skb(struct net_device *dev,
 			goto partial_error;
 		skb_fill_page_desc(skb, i, page, 0, PAGE_SIZE);
 
-		mapping[i + 1] = ib_dma_map_page(priv->ca, skb_shinfo(skb)->frags[i].page,
+		mapping[i + 1] = ib_dma_map_page(priv->ca, page,
 						 0, PAGE_SIZE, DMA_FROM_DEVICE);
 		if (unlikely(ib_dma_mapping_error(priv->ca, mapping[i + 1])))
 			goto partial_error;
@@ -537,12 +537,13 @@ static void skb_put_frags(struct sk_buff *skb, unsigned int hdr_space,
 
 		if (length == 0) {
 			/* don't need this page */
-			skb_fill_page_desc(toskb, i, frag->page, 0, PAGE_SIZE);
+			skb_fill_page_desc(toskb, i, skb_frag_page(frag),
+					   0, PAGE_SIZE);
 			--skb_shinfo(skb)->nr_frags;
 		} else {
 			size = min(length, (unsigned) PAGE_SIZE);
 
-			frag->size = size;
+			skb_frag_size_set(frag, size);
 			skb->data_len += size;
 			skb->truesize += size;
 			skb->len += size;

+ 13 - 10
drivers/infiniband/ulp/ipoib/ipoib_ib.c

@@ -117,7 +117,7 @@ static void ipoib_ud_skb_put_frags(struct ipoib_dev_priv *priv,
 
 		size = length - IPOIB_UD_HEAD_SIZE;
 
-		frag->size     = size;
+		skb_frag_size_set(frag, size);
 		skb->data_len += size;
 		skb->truesize += size;
 	} else
@@ -182,7 +182,7 @@ static struct sk_buff *ipoib_alloc_rx_skb(struct net_device *dev, int id)
 			goto partial_error;
 		skb_fill_page_desc(skb, 0, page, 0, PAGE_SIZE);
 		mapping[1] =
-			ib_dma_map_page(priv->ca, skb_shinfo(skb)->frags[0].page,
+			ib_dma_map_page(priv->ca, page,
 					0, PAGE_SIZE, DMA_FROM_DEVICE);
 		if (unlikely(ib_dma_mapping_error(priv->ca, mapping[1])))
 			goto partial_error;
@@ -322,9 +322,10 @@ static int ipoib_dma_map_tx(struct ib_device *ca,
 		off = 0;
 
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) {
-		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-		mapping[i + off] = ib_dma_map_page(ca, frag->page,
-						 frag->page_offset, frag->size,
+		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+		mapping[i + off] = ib_dma_map_page(ca,
+						 skb_frag_page(frag),
+						 frag->page_offset, skb_frag_size(frag),
 						 DMA_TO_DEVICE);
 		if (unlikely(ib_dma_mapping_error(ca, mapping[i + off])))
 			goto partial_error;
@@ -333,8 +334,9 @@ static int ipoib_dma_map_tx(struct ib_device *ca,
 
 partial_error:
 	for (; i > 0; --i) {
-		skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
-		ib_dma_unmap_page(ca, mapping[i - !off], frag->size, DMA_TO_DEVICE);
+		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i - 1];
+
+		ib_dma_unmap_page(ca, mapping[i - !off], skb_frag_size(frag), DMA_TO_DEVICE);
 	}
 
 	if (off)
@@ -358,8 +360,9 @@ static void ipoib_dma_unmap_tx(struct ib_device *ca,
 		off = 0;
 
 	for (i = 0; i < skb_shinfo(skb)->nr_frags; ++i) {
-		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-		ib_dma_unmap_page(ca, mapping[i + off], frag->size,
+		const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+		ib_dma_unmap_page(ca, mapping[i + off], skb_frag_size(frag),
 				  DMA_TO_DEVICE);
 	}
 }
@@ -509,7 +512,7 @@ static inline int post_send(struct ipoib_dev_priv *priv,
 
 	for (i = 0; i < nr_frags; ++i) {
 		priv->tx_sge[i + off].addr = mapping[i + off];
-		priv->tx_sge[i + off].length = frags[i].size;
+		priv->tx_sge[i + off].length = skb_frag_size(&frags[i]);
 	}
 	priv->tx_wr.num_sge	     = nr_frags + off;
 	priv->tx_wr.wr_id 	     = wr_id;

+ 1 - 1
drivers/infiniband/ulp/ipoib/ipoib_main.c

@@ -998,7 +998,7 @@ static const struct net_device_ops ipoib_netdev_ops = {
 	.ndo_fix_features	 = ipoib_fix_features,
 	.ndo_start_xmit	 	 = ipoib_start_xmit,
 	.ndo_tx_timeout		 = ipoib_timeout,
-	.ndo_set_multicast_list	 = ipoib_set_mcast_list,
+	.ndo_set_rx_mode	 = ipoib_set_mcast_list,
 	.ndo_neigh_setup	 = ipoib_neigh_setup_dev,
 };
 

+ 1 - 1
drivers/media/dvb/dvb-core/dvb_net.c

@@ -1230,7 +1230,7 @@ static const struct net_device_ops dvb_netdev_ops = {
 	.ndo_open		= dvb_net_open,
 	.ndo_stop		= dvb_net_stop,
 	.ndo_start_xmit		= dvb_net_tx,
-	.ndo_set_multicast_list = dvb_net_set_multicast_list,
+	.ndo_set_rx_mode	= dvb_net_set_multicast_list,
 	.ndo_set_mac_address    = dvb_net_set_mac,
 	.ndo_change_mtu		= eth_change_mtu,
 	.ndo_validate_addr	= eth_validate_addr,

+ 0 - 896
drivers/net/3c501.c

@@ -1,896 +0,0 @@
-/* 3c501.c: A 3Com 3c501 Ethernet driver for Linux. */
-/*
-    Written 1992,1993,1994  Donald Becker
-
-    Copyright 1993 United States Government as represented by the
-    Director, National Security Agency.  This software may be used and
-    distributed according to the terms of the GNU General Public License,
-    incorporated herein by reference.
-
-    This is a device driver for the 3Com Etherlink 3c501.
-    Do not purchase this card, even as a joke.  It's performance is horrible,
-    and it breaks in many ways.
-
-    The original author may be reached as becker@scyld.com, or C/O
-	Scyld Computing Corporation
-	410 Severn Ave., Suite 210
-	Annapolis MD 21403
-
-    Fixed (again!) the missing interrupt locking on TX/RX shifting.
-	Alan Cox <alan@lxorguk.ukuu.org.uk>
-
-    Removed calls to init_etherdev since they are no longer needed, and
-    cleaned up modularization just a bit. The driver still allows only
-    the default address for cards when loaded as a module, but that's
-    really less braindead than anyone using a 3c501 board. :)
-		    19950208 (invid@msen.com)
-
-    Added traps for interrupts hitting the window as we clear and TX load
-    the board. Now getting 150K/second FTP with a 3c501 card. Still playing
-    with a TX-TX optimisation to see if we can touch 180-200K/second as seems
-    theoretically maximum.
-		19950402 Alan Cox <alan@lxorguk.ukuu.org.uk>
-
-    Cleaned up for 2.3.x because we broke SMP now.
-		20000208 Alan Cox <alan@lxorguk.ukuu.org.uk>
-
-    Check up pass for 2.5. Nothing significant changed
-		20021009 Alan Cox <alan@lxorguk.ukuu.org.uk>
-
-    Fixed zero fill corner case
-		20030104 Alan Cox <alan@lxorguk.ukuu.org.uk>
-
-
-   For the avoidance of doubt the "preferred form" of this code is one which
-   is in an open non patent encumbered format. Where cryptographic key signing
-   forms part of the process of creating an executable the information
-   including keys needed to generate an equivalently functional executable
-   are deemed to be part of the source code.
-
-*/
-
-
-/**
- * DOC: 3c501 Card Notes
- *
- *  Some notes on this thing if you have to hack it.  [Alan]
- *
- *  Some documentation is available from 3Com. Due to the boards age
- *  standard responses when you ask for this will range from 'be serious'
- *  to 'give it to a museum'. The documentation is incomplete and mostly
- *  of historical interest anyway.
- *
- *  The basic system is a single buffer which can be used to receive or
- *  transmit a packet. A third command mode exists when you are setting
- *  things up.
- *
- *  If it's transmitting it's not receiving and vice versa. In fact the
- *  time to get the board back into useful state after an operation is
- *  quite large.
- *
- *  The driver works by keeping the board in receive mode waiting for a
- *  packet to arrive. When one arrives it is copied out of the buffer
- *  and delivered to the kernel. The card is reloaded and off we go.
- *
- *  When transmitting lp->txing is set and the card is reset (from
- *  receive mode) [possibly losing a packet just received] to command
- *  mode. A packet is loaded and transmit mode triggered. The interrupt
- *  handler runs different code for transmit interrupts and can handle
- *  returning to receive mode or retransmissions (yes you have to help
- *  out with those too).
- *
- * DOC: Problems
- *
- *  There are a wide variety of undocumented error returns from the card
- *  and you basically have to kick the board and pray if they turn up. Most
- *  only occur under extreme load or if you do something the board doesn't
- *  like (eg touching a register at the wrong time).
- *
- *  The driver is less efficient than it could be. It switches through
- *  receive mode even if more transmits are queued. If this worries you buy
- *  a real Ethernet card.
- *
- *  The combination of slow receive restart and no real multicast
- *  filter makes the board unusable with a kernel compiled for IP
- *  multicasting in a real multicast environment. That's down to the board,
- *  but even with no multicast programs running a multicast IP kernel is
- *  in group 224.0.0.1 and you will therefore be listening to all multicasts.
- *  One nv conference running over that Ethernet and you can give up.
- *
- */
-
-#define DRV_NAME	"3c501"
-#define DRV_VERSION	"2002/10/09"
-
-
-static const char version[] =
-	DRV_NAME ".c: " DRV_VERSION " Alan Cox (alan@lxorguk.ukuu.org.uk).\n";
-
-/*
- *	Braindamage remaining:
- *	The 3c501 board.
- */
-
-#include <linux/module.h>
-
-#include <linux/kernel.h>
-#include <linux/fcntl.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-
-#include "3c501.h"
-
-/*
- *	The boilerplate probe code.
- */
-
-static int io = 0x280;
-static int irq = 5;
-static int mem_start;
-
-/**
- * el1_probe:		-	probe for a 3c501
- * @dev: The device structure passed in to probe.
- *
- * This can be called from two places. The network layer will probe using
- * a device structure passed in with the probe information completed. For a
- * modular driver we use #init_module to fill in our own structure and probe
- * for it.
- *
- * Returns 0 on success. ENXIO if asked not to probe and ENODEV if asked to
- * probe and failing to find anything.
- */
-
-struct net_device * __init el1_probe(int unit)
-{
-	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
-	static const unsigned ports[] = { 0x280, 0x300, 0};
-	const unsigned *port;
-	int err = 0;
-
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	if (unit >= 0) {
-		sprintf(dev->name, "eth%d", unit);
-		netdev_boot_setup_check(dev);
-		io = dev->base_addr;
-		irq = dev->irq;
-		mem_start = dev->mem_start & 7;
-	}
-
-	if (io > 0x1ff) {	/* Check a single specified location. */
-		err = el1_probe1(dev, io);
-	} else if (io != 0) {
-		err = -ENXIO;		/* Don't probe at all. */
-	} else {
-		for (port = ports; *port && el1_probe1(dev, *port); port++)
-			;
-		if (!*port)
-			err = -ENODEV;
-	}
-	if (err)
-		goto out;
-	err = register_netdev(dev);
-	if (err)
-		goto out1;
-	return dev;
-out1:
-	release_region(dev->base_addr, EL1_IO_EXTENT);
-out:
-	free_netdev(dev);
-	return ERR_PTR(err);
-}
-
-static const struct net_device_ops el_netdev_ops = {
-	.ndo_open		= el_open,
-	.ndo_stop		= el1_close,
-	.ndo_start_xmit 	= el_start_xmit,
-	.ndo_tx_timeout		= el_timeout,
-	.ndo_set_multicast_list = set_multicast_list,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-/**
- *	el1_probe1:
- *	@dev: The device structure to use
- *	@ioaddr: An I/O address to probe at.
- *
- *	The actual probe. This is iterated over by #el1_probe in order to
- *	check all the applicable device locations.
- *
- *	Returns 0 for a success, in which case the device is activated,
- *	EAGAIN if the IRQ is in use by another driver, and ENODEV if the
- *	board cannot be found.
- */
-
-static int __init el1_probe1(struct net_device *dev, int ioaddr)
-{
-	struct net_local *lp;
-	const char *mname;		/* Vendor name */
-	unsigned char station_addr[6];
-	int autoirq = 0;
-	int i;
-
-	/*
-	 *	Reserve I/O resource for exclusive use by this driver
-	 */
-
-	if (!request_region(ioaddr, EL1_IO_EXTENT, DRV_NAME))
-		return -ENODEV;
-
-	/*
-	 *	Read the station address PROM data from the special port.
-	 */
-
-	for (i = 0; i < 6; i++) {
-		outw(i, ioaddr + EL1_DATAPTR);
-		station_addr[i] = inb(ioaddr + EL1_SAPROM);
-	}
-	/*
-	 *	Check the first three octets of the S.A. for 3Com's prefix, or
-	 *	for the Sager NP943 prefix.
-	 */
-
-	if (station_addr[0] == 0x02 && station_addr[1] == 0x60 &&
-	    station_addr[2] == 0x8c)
-		mname = "3c501";
-	else if (station_addr[0] == 0x00 && station_addr[1] == 0x80 &&
-		 station_addr[2] == 0xC8)
-		mname = "NP943";
-	else {
-		release_region(ioaddr, EL1_IO_EXTENT);
-		return -ENODEV;
-	}
-
-	/*
-	 *	We auto-IRQ by shutting off the interrupt line and letting it
-	 *	float high.
-	 */
-
-	dev->irq = irq;
-
-	if (dev->irq < 2) {
-		unsigned long irq_mask;
-
-		irq_mask = probe_irq_on();
-		inb(RX_STATUS);		/* Clear pending interrupts. */
-		inb(TX_STATUS);
-		outb(AX_LOOP + 1, AX_CMD);
-
-		outb(0x00, AX_CMD);
-
-		mdelay(20);
-		autoirq = probe_irq_off(irq_mask);
-
-		if (autoirq == 0) {
-			pr_warning("%s probe at %#x failed to detect IRQ line.\n",
-				mname, ioaddr);
-			release_region(ioaddr, EL1_IO_EXTENT);
-			return -EAGAIN;
-		}
-	}
-
-	outb(AX_RESET+AX_LOOP, AX_CMD);			/* Loopback mode. */
-	dev->base_addr = ioaddr;
-	memcpy(dev->dev_addr, station_addr, ETH_ALEN);
-
-	if (mem_start & 0xf)
-		el_debug = mem_start & 0x7;
-	if (autoirq)
-		dev->irq = autoirq;
-
-	pr_info("%s: %s EtherLink at %#lx, using %sIRQ %d.\n",
-			dev->name, mname, dev->base_addr,
-			autoirq ? "auto":"assigned ", dev->irq);
-
-#ifdef CONFIG_IP_MULTICAST
-	pr_warning("WARNING: Use of the 3c501 in a multicast kernel is NOT recommended.\n");
-#endif
-
-	if (el_debug)
-		pr_debug("%s", version);
-
-	lp = netdev_priv(dev);
-	memset(lp, 0, sizeof(struct net_local));
-	spin_lock_init(&lp->lock);
-
-	/*
-	 *	The EL1-specific entries in the device structure.
-	 */
-
-	dev->netdev_ops = &el_netdev_ops;
-	dev->watchdog_timeo = HZ;
-	dev->ethtool_ops = &netdev_ethtool_ops;
-	return 0;
-}
-
-/**
- *	el1_open:
- *	@dev: device that is being opened
- *
- *	When an ifconfig is issued which changes the device flags to include
- *	IFF_UP this function is called. It is only called when the change
- *	occurs, not when the interface remains up. #el1_close will be called
- *	when it goes down.
- *
- *	Returns 0 for a successful open, or -EAGAIN if someone has run off
- *	with our interrupt line.
- */
-
-static int el_open(struct net_device *dev)
-{
-	int retval;
-	int ioaddr = dev->base_addr;
-	struct net_local *lp = netdev_priv(dev);
-	unsigned long flags;
-
-	if (el_debug > 2)
-		pr_debug("%s: Doing el_open()...\n", dev->name);
-
-	retval = request_irq(dev->irq, el_interrupt, 0, dev->name, dev);
-	if (retval)
-		return retval;
-
-	spin_lock_irqsave(&lp->lock, flags);
-	el_reset(dev);
-	spin_unlock_irqrestore(&lp->lock, flags);
-
-	lp->txing = 0;		/* Board in RX mode */
-	outb(AX_RX, AX_CMD);	/* Aux control, irq and receive enabled */
-	netif_start_queue(dev);
-	return 0;
-}
-
-/**
- * el_timeout:
- * @dev: The 3c501 card that has timed out
- *
- * Attempt to restart the board. This is basically a mixture of extreme
- * violence and prayer
- *
- */
-
-static void el_timeout(struct net_device *dev)
-{
-	struct net_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-
-	if (el_debug)
-		pr_debug("%s: transmit timed out, txsr %#2x axsr=%02x rxsr=%02x.\n",
-			dev->name, inb(TX_STATUS),
-			inb(AX_STATUS), inb(RX_STATUS));
-	dev->stats.tx_errors++;
-	outb(TX_NORM, TX_CMD);
-	outb(RX_NORM, RX_CMD);
-	outb(AX_OFF, AX_CMD);	/* Just trigger a false interrupt. */
-	outb(AX_RX, AX_CMD);	/* Aux control, irq and receive enabled */
-	lp->txing = 0;		/* Ripped back in to RX */
-	netif_wake_queue(dev);
-}
-
-
-/**
- * el_start_xmit:
- * @skb: The packet that is queued to be sent
- * @dev: The 3c501 card we want to throw it down
- *
- * Attempt to send a packet to a 3c501 card. There are some interesting
- * catches here because the 3c501 is an extremely old and therefore
- * stupid piece of technology.
- *
- * If we are handling an interrupt on the other CPU we cannot load a packet
- * as we may still be attempting to retrieve the last RX packet buffer.
- *
- * When a transmit times out we dump the card into control mode and just
- * start again. It happens enough that it isn't worth logging.
- *
- * We avoid holding the spin locks when doing the packet load to the board.
- * The device is very slow, and its DMA mode is even slower. If we held the
- * lock while loading 1500 bytes onto the controller we would drop a lot of
- * serial port characters. This requires we do extra locking, but we have
- * no real choice.
- */
-
-static netdev_tx_t el_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct net_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-	unsigned long flags;
-
-	/*
-	 *	Avoid incoming interrupts between us flipping txing and flipping
-	 *	mode as the driver assumes txing is a faithful indicator of card
-	 *	state
-	 */
-
-	spin_lock_irqsave(&lp->lock, flags);
-
-	/*
-	 *	Avoid timer-based retransmission conflicts.
-	 */
-
-	netif_stop_queue(dev);
-
-	do {
-		int len = skb->len;
-		int pad = 0;
-		int gp_start;
-		unsigned char *buf = skb->data;
-
-		if (len < ETH_ZLEN)
-			pad = ETH_ZLEN - len;
-
-		gp_start = 0x800 - (len + pad);
-
-		lp->tx_pkt_start = gp_start;
-		lp->collisions = 0;
-
-		dev->stats.tx_bytes += skb->len;
-
-		/*
-		 *	Command mode with status cleared should [in theory]
-		 *	mean no more interrupts can be pending on the card.
-		 */
-
-		outb_p(AX_SYS, AX_CMD);
-		inb_p(RX_STATUS);
-		inb_p(TX_STATUS);
-
-		lp->loading = 1;
-		lp->txing = 1;
-
-		/*
-		 *	Turn interrupts back on while we spend a pleasant
-		 *	afternoon loading bytes into the board
-		 */
-
-		spin_unlock_irqrestore(&lp->lock, flags);
-
-		/* Set rx packet area to 0. */
-		outw(0x00, RX_BUF_CLR);
-		/* aim - packet will be loaded into buffer start */
-		outw(gp_start, GP_LOW);
-		/* load buffer (usual thing each byte increments the pointer) */
-		outsb(DATAPORT, buf, len);
-		if (pad) {
-			while (pad--)		/* Zero fill buffer tail */
-				outb(0, DATAPORT);
-		}
-		/* the board reuses the same register */
-		outw(gp_start, GP_LOW);
-
-		if (lp->loading != 2) {
-			/* fire ... Trigger xmit.  */
-			outb(AX_XMIT, AX_CMD);
-			lp->loading = 0;
-			if (el_debug > 2)
-				pr_debug(" queued xmit.\n");
-			dev_kfree_skb(skb);
-			return NETDEV_TX_OK;
-		}
-		/* A receive upset our load, despite our best efforts */
-		if (el_debug > 2)
-			pr_debug("%s: burped during tx load.\n", dev->name);
-		spin_lock_irqsave(&lp->lock, flags);
-	} while (1);
-}
-
-/**
- * el_interrupt:
- * @irq: Interrupt number
- * @dev_id: The 3c501 that burped
- *
- * Handle the ether interface interrupts. The 3c501 needs a lot more
- * hand holding than most cards. In particular we get a transmit interrupt
- * with a collision error because the board firmware isn't capable of rewinding
- * its own transmit buffer pointers. It can however count to 16 for us.
- *
- * On the receive side the card is also very dumb. It has no buffering to
- * speak of. We simply pull the packet out of its PIO buffer (which is slow)
- * and queue it for the kernel. Then we reset the card for the next packet.
- *
- * We sometimes get surprise interrupts late both because the SMP IRQ delivery
- * is message passing and because the card sometimes seems to deliver late. I
- * think if it is part way through a receive and the mode is changed it carries
- * on receiving and sends us an interrupt. We have to band aid all these cases
- * to get a sensible 150kBytes/second performance. Even then you want a small
- * TCP window.
- */
-
-static irqreturn_t el_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct net_local *lp;
-	int ioaddr;
-	int axsr;			/* Aux. status reg. */
-
-	ioaddr = dev->base_addr;
-	lp = netdev_priv(dev);
-
-	spin_lock(&lp->lock);
-
-	/*
-	 *	What happened ?
-	 */
-
-	axsr = inb(AX_STATUS);
-
-	/*
-	 *	Log it
-	 */
-
-	if (el_debug > 3)
-		pr_debug("%s: el_interrupt() aux=%#02x\n", dev->name, axsr);
-
-	if (lp->loading == 1 && !lp->txing)
-		pr_warning("%s: Inconsistent state loading while not in tx\n",
-			dev->name);
-
-	if (lp->txing) {
-		/*
-		 *	Board in transmit mode. May be loading. If we are
-		 *	loading we shouldn't have got this.
-		 */
-		int txsr = inb(TX_STATUS);
-
-		if (lp->loading == 1) {
-			if (el_debug > 2)
-				pr_debug("%s: Interrupt while loading [txsr=%02x gp=%04x rp=%04x]\n",
-					dev->name, txsr, inw(GP_LOW), inw(RX_LOW));
-
-			/* Force a reload */
-			lp->loading = 2;
-			spin_unlock(&lp->lock);
-			goto out;
-		}
-		if (el_debug > 6)
-			pr_debug("%s: txsr=%02x gp=%04x rp=%04x\n", dev->name,
-					txsr, inw(GP_LOW), inw(RX_LOW));
-
-		if ((axsr & 0x80) && (txsr & TX_READY) == 0) {
-			/*
-			 *	FIXME: is there a logic to whether to keep
-			 *	on trying or reset immediately ?
-			 */
-			if (el_debug > 1)
-				pr_debug("%s: Unusual interrupt during Tx, txsr=%02x axsr=%02x gp=%03x rp=%03x.\n",
-					dev->name, txsr, axsr,
-					inw(ioaddr + EL1_DATAPTR),
-					inw(ioaddr + EL1_RXPTR));
-			lp->txing = 0;
-			netif_wake_queue(dev);
-		} else if (txsr & TX_16COLLISIONS) {
-			/*
-			 *	Timed out
-			 */
-			if (el_debug)
-				pr_debug("%s: Transmit failed 16 times, Ethernet jammed?\n", dev->name);
-			outb(AX_SYS, AX_CMD);
-			lp->txing = 0;
-			dev->stats.tx_aborted_errors++;
-			netif_wake_queue(dev);
-		} else if (txsr & TX_COLLISION) {
-			/*
-			 *	Retrigger xmit.
-			 */
-
-			if (el_debug > 6)
-				pr_debug("%s: retransmitting after a collision.\n", dev->name);
-			/*
-			 *	Poor little chip can't reset its own start
-			 *	pointer
-			 */
-
-			outb(AX_SYS, AX_CMD);
-			outw(lp->tx_pkt_start, GP_LOW);
-			outb(AX_XMIT, AX_CMD);
-			dev->stats.collisions++;
-			spin_unlock(&lp->lock);
-			goto out;
-		} else {
-			/*
-			 *	It worked.. we will now fall through and receive
-			 */
-			dev->stats.tx_packets++;
-			if (el_debug > 6)
-				pr_debug("%s: Tx succeeded %s\n", dev->name,
-					(txsr & TX_RDY) ? "." : "but tx is busy!");
-			/*
-			 *	This is safe the interrupt is atomic WRT itself.
-			 */
-			lp->txing = 0;
-			/* In case more to transmit */
-			netif_wake_queue(dev);
-		}
-	} else {
-		/*
-		 *	In receive mode.
-		 */
-
-		int rxsr = inb(RX_STATUS);
-		if (el_debug > 5)
-			pr_debug("%s: rxsr=%02x txsr=%02x rp=%04x\n",
-				dev->name, rxsr, inb(TX_STATUS), inw(RX_LOW));
-		/*
-		 *	Just reading rx_status fixes most errors.
-		 */
-		if (rxsr & RX_MISSED)
-			dev->stats.rx_missed_errors++;
-		else if (rxsr & RX_RUNT) {
-			/* Handled to avoid board lock-up. */
-			dev->stats.rx_length_errors++;
-			if (el_debug > 5)
-				pr_debug("%s: runt.\n", dev->name);
-		} else if (rxsr & RX_GOOD) {
-			/*
-			 *	Receive worked.
-			 */
-			el_receive(dev);
-		} else {
-			/*
-			 *	Nothing?  Something is broken!
-			 */
-			if (el_debug > 2)
-				pr_debug("%s: No packet seen, rxsr=%02x **resetting 3c501***\n",
-					dev->name, rxsr);
-			el_reset(dev);
-		}
-	}
-
-	/*
-	 *	Move into receive mode
-	 */
-
-	outb(AX_RX, AX_CMD);
-	outw(0x00, RX_BUF_CLR);
-	inb(RX_STATUS);		/* Be certain that interrupts are cleared. */
-	inb(TX_STATUS);
-	spin_unlock(&lp->lock);
-out:
-	return IRQ_HANDLED;
-}
-
-
-/**
- * el_receive:
- * @dev: Device to pull the packets from
- *
- * We have a good packet. Well, not really "good", just mostly not broken.
- * We must check everything to see if it is good. In particular we occasionally
- * get wild packet sizes from the card. If the packet seems sane we PIO it
- * off the card and queue it for the protocol layers.
- */
-
-static void el_receive(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-	int pkt_len;
-	struct sk_buff *skb;
-
-	pkt_len = inw(RX_LOW);
-
-	if (el_debug > 4)
-		pr_debug(" el_receive %d.\n", pkt_len);
-
-	if (pkt_len < 60 || pkt_len > 1536) {
-		if (el_debug)
-			pr_debug("%s: bogus packet, length=%d\n",
-						dev->name, pkt_len);
-		dev->stats.rx_over_errors++;
-		return;
-	}
-
-	/*
-	 *	Command mode so we can empty the buffer
-	 */
-
-	outb(AX_SYS, AX_CMD);
-	skb = dev_alloc_skb(pkt_len+2);
-
-	/*
-	 *	Start of frame
-	 */
-
-	outw(0x00, GP_LOW);
-	if (skb == NULL) {
-		pr_info("%s: Memory squeeze, dropping packet.\n", dev->name);
-		dev->stats.rx_dropped++;
-		return;
-	} else {
-		skb_reserve(skb, 2);	/* Force 16 byte alignment */
-		/*
-		 *	The read increments through the bytes. The interrupt
-		 *	handler will fix the pointer when it returns to
-		 *	receive mode.
-		 */
-		insb(DATAPORT, skb_put(skb, pkt_len), pkt_len);
-		skb->protocol = eth_type_trans(skb, dev);
-		netif_rx(skb);
-		dev->stats.rx_packets++;
-		dev->stats.rx_bytes += pkt_len;
-	}
-}
-
-/**
- * el_reset: Reset a 3c501 card
- * @dev: The 3c501 card about to get zapped
- *
- * Even resetting a 3c501 isn't simple. When you activate reset it loses all
- * its configuration. You must hold the lock when doing this. The function
- * cannot take the lock itself as it is callable from the irq handler.
- */
-
-static void  el_reset(struct net_device *dev)
-{
-	struct net_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-
-	if (el_debug > 2)
-		pr_info("3c501 reset...\n");
-	outb(AX_RESET, AX_CMD);		/* Reset the chip */
-	/* Aux control, irq and loopback enabled */
-	outb(AX_LOOP, AX_CMD);
-	{
-		int i;
-		for (i = 0; i < 6; i++)	/* Set the station address. */
-			outb(dev->dev_addr[i], ioaddr + i);
-	}
-
-	outw(0, RX_BUF_CLR);		/* Set rx packet area to 0. */
-	outb(TX_NORM, TX_CMD);		/* tx irq on done, collision */
-	outb(RX_NORM, RX_CMD);		/* Set Rx commands. */
-	inb(RX_STATUS);			/* Clear status. */
-	inb(TX_STATUS);
-	lp->txing = 0;
-}
-
-/**
- * el1_close:
- * @dev: 3c501 card to shut down
- *
- * Close a 3c501 card. The IFF_UP flag has been cleared by the user via
- * the SIOCSIFFLAGS ioctl. We stop any further transmissions being queued,
- * and then disable the interrupts. Finally we reset the chip. The effects
- * of the rest will be cleaned up by #el1_open. Always returns 0 indicating
- * a success.
- */
-
-static int el1_close(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-
-	if (el_debug > 2)
-		pr_info("%s: Shutting down Ethernet card at %#x.\n",
-						dev->name, ioaddr);
-
-	netif_stop_queue(dev);
-
-	/*
-	 *	Free and disable the IRQ.
-	 */
-
-	free_irq(dev->irq, dev);
-	outb(AX_RESET, AX_CMD);		/* Reset the chip */
-
-	return 0;
-}
-
-/**
- * set_multicast_list:
- * @dev: The device to adjust
- *
- * Set or clear the multicast filter for this adaptor to use the best-effort
- * filtering supported. The 3c501 supports only three modes of filtering.
- * It always receives broadcasts and packets for itself. You can choose to
- * optionally receive all packets, or all multicast packets on top of this.
- */
-
-static void set_multicast_list(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-
-	if (dev->flags & IFF_PROMISC) {
-		outb(RX_PROM, RX_CMD);
-		inb(RX_STATUS);
-	} else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
-		/* Multicast or all multicast is the same */
-		outb(RX_MULT, RX_CMD);
-		inb(RX_STATUS);		/* Clear status. */
-	} else {
-		outb(RX_NORM, RX_CMD);
-		inb(RX_STATUS);
-	}
-}
-
-
-static void netdev_get_drvinfo(struct net_device *dev,
-			       struct ethtool_drvinfo *info)
-{
-	strcpy(info->driver, DRV_NAME);
-	strcpy(info->version, DRV_VERSION);
-	sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
-	return debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
-	debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
-	.get_drvinfo		= netdev_get_drvinfo,
-	.get_msglevel		= netdev_get_msglevel,
-	.set_msglevel		= netdev_set_msglevel,
-};
-
-#ifdef MODULE
-
-static struct net_device *dev_3c501;
-
-module_param(io, int, 0);
-module_param(irq, int, 0);
-MODULE_PARM_DESC(io, "EtherLink I/O base address");
-MODULE_PARM_DESC(irq, "EtherLink IRQ number");
-
-/**
- * init_module:
- *
- * When the driver is loaded as a module this function is called. We fake up
- * a device structure with the base I/O and interrupt set as if it were being
- * called from Space.c. This minimises the extra code that would otherwise
- * be required.
- *
- * Returns 0 for success or -EIO if a card is not found. Returning an error
- * here also causes the module to be unloaded
- */
-
-int __init init_module(void)
-{
-	dev_3c501 = el1_probe(-1);
-	if (IS_ERR(dev_3c501))
-		return PTR_ERR(dev_3c501);
-	return 0;
-}
-
-/**
- * cleanup_module:
- *
- * The module is being unloaded. We unhook our network device from the system
- * and then free up the resources we took when the card was found.
- */
-
-void __exit cleanup_module(void)
-{
-	struct net_device *dev = dev_3c501;
-	unregister_netdev(dev);
-	release_region(dev->base_addr, EL1_IO_EXTENT);
-	free_netdev(dev);
-}
-
-#endif /* MODULE */
-
-MODULE_AUTHOR("Donald Becker, Alan Cox");
-MODULE_DESCRIPTION("Support for the ancient 3Com 3c501 ethernet card");
-MODULE_LICENSE("GPL");
-

+ 0 - 778
drivers/net/3c503.c

@@ -1,778 +0,0 @@
-/* 3c503.c: A shared-memory NS8390 ethernet driver for linux. */
-/*
-    Written 1992-94 by Donald Becker.
-
-    Copyright 1993 United States Government as represented by the
-    Director, National Security Agency.  This software may be used and
-    distributed according to the terms of the GNU General Public License,
-    incorporated herein by reference.
-
-    The author may be reached as becker@scyld.com, or C/O
-	Scyld Computing Corporation
-	410 Severn Ave., Suite 210
-	Annapolis MD 21403
-
-
-    This driver should work with the 3c503 and 3c503/16.  It should be used
-    in shared memory mode for best performance, although it may also work
-    in programmed-I/O mode.
-
-    Sources:
-    EtherLink II Technical Reference Manual,
-    EtherLink II/16 Technical Reference Manual Supplement,
-    3Com Corporation, 5400 Bayfront Plaza, Santa Clara CA 95052-8145
-
-    The Crynwr 3c503 packet driver.
-
-    Changelog:
-
-    Paul Gortmaker	: add support for the 2nd 8kB of RAM on 16 bit cards.
-    Paul Gortmaker	: multiple card support for module users.
-    rjohnson@analogic.com : Fix up PIO interface for efficient operation.
-    Jeff Garzik		: ethtool support
-
-*/
-
-#define DRV_NAME	"3c503"
-#define DRV_VERSION	"1.10a"
-#define DRV_RELDATE	"11/17/2001"
-
-
-static const char version[] =
-    DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE "  Donald Becker (becker@scyld.com)\n";
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/ethtool.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/byteorder.h>
-
-#include "8390.h"
-#include "3c503.h"
-#define WRD_COUNT 4
-
-static int el2_pio_probe(struct net_device *dev);
-static int el2_probe1(struct net_device *dev, int ioaddr);
-
-/* A zero-terminated list of I/O addresses to be probed in PIO mode. */
-static unsigned int netcard_portlist[] __initdata =
-	{ 0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0};
-
-#define EL2_IO_EXTENT	16
-
-static int el2_open(struct net_device *dev);
-static int el2_close(struct net_device *dev);
-static void el2_reset_8390(struct net_device *dev);
-static void el2_init_card(struct net_device *dev);
-static void el2_block_output(struct net_device *dev, int count,
-			     const unsigned char *buf, int start_page);
-static void el2_block_input(struct net_device *dev, int count, struct sk_buff *skb,
-			   int ring_offset);
-static void el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
-			 int ring_page);
-static const struct ethtool_ops netdev_ethtool_ops;
-
-
-/* This routine probes for a memory-mapped 3c503 board by looking for
-   the "location register" at the end of the jumpered boot PROM space.
-   This works even if a PROM isn't there.
-
-   If the ethercard isn't found there is an optional probe for
-   ethercard jumpered to programmed-I/O mode.
-   */
-static int __init do_el2_probe(struct net_device *dev)
-{
-    int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
-    int base_addr = dev->base_addr;
-    int irq = dev->irq;
-
-    if (base_addr > 0x1ff)	/* Check a single specified location. */
-	return el2_probe1(dev, base_addr);
-    else if (base_addr != 0)		/* Don't probe at all. */
-	return -ENXIO;
-
-    for (addr = addrs; *addr; addr++) {
-	void __iomem *p = ioremap(*addr, 1);
-	unsigned base_bits;
-	int i;
-
-	if (!p)
-		continue;
-	base_bits = readb(p);
-	iounmap(p);
-	i = ffs(base_bits) - 1;
-	if (i == -1 || base_bits != (1 << i))
-	    continue;
-	if (el2_probe1(dev, netcard_portlist[i]) == 0)
-	    return 0;
-	dev->irq = irq;
-    }
-#if ! defined(no_probe_nonshared_memory)
-    return el2_pio_probe(dev);
-#else
-    return -ENODEV;
-#endif
-}
-
-/*  Try all of the locations that aren't obviously empty.  This touches
-    a lot of locations, and is much riskier than the code above. */
-static int __init
-el2_pio_probe(struct net_device *dev)
-{
-    int i;
-    int base_addr = dev->base_addr;
-    int irq = dev->irq;
-
-    if (base_addr > 0x1ff)	/* Check a single specified location. */
-	return el2_probe1(dev, base_addr);
-    else if (base_addr != 0)	/* Don't probe at all. */
-	return -ENXIO;
-
-    for (i = 0; netcard_portlist[i]; i++) {
-	if (el2_probe1(dev, netcard_portlist[i]) == 0)
-	    return 0;
-	dev->irq = irq;
-    }
-
-    return -ENODEV;
-}
-
-#ifndef MODULE
-struct net_device * __init el2_probe(int unit)
-{
-	struct net_device *dev = alloc_eip_netdev();
-	int err;
-
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	sprintf(dev->name, "eth%d", unit);
-	netdev_boot_setup_check(dev);
-
-	err = do_el2_probe(dev);
-	if (err)
-		goto out;
-	return dev;
-out:
-	free_netdev(dev);
-	return ERR_PTR(err);
-}
-#endif
-
-static const struct net_device_ops el2_netdev_ops = {
-	.ndo_open		= el2_open,
-	.ndo_stop		= el2_close,
-
-	.ndo_start_xmit		= eip_start_xmit,
-	.ndo_tx_timeout		= eip_tx_timeout,
-	.ndo_get_stats		= eip_get_stats,
-	.ndo_set_multicast_list = eip_set_multicast_list,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_change_mtu		= eth_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller 	= eip_poll,
-#endif
-};
-
-/* Probe for the Etherlink II card at I/O port base IOADDR,
-   returning non-zero on success.  If found, set the station
-   address and memory parameters in DEVICE. */
-static int __init
-el2_probe1(struct net_device *dev, int ioaddr)
-{
-    int i, iobase_reg, membase_reg, saved_406, wordlength, retval;
-    static unsigned version_printed;
-    unsigned long vendor_id;
-
-    if (!request_region(ioaddr, EL2_IO_EXTENT, DRV_NAME))
-	return -EBUSY;
-
-    if (!request_region(ioaddr + 0x400, 8, DRV_NAME)) {
-	retval = -EBUSY;
-	goto out;
-    }
-
-    /* Reset and/or avoid any lurking NE2000 */
-    if (inb(ioaddr + 0x408) == 0xff) {
-    	mdelay(1);
-	retval = -ENODEV;
-	goto out1;
-    }
-
-    /* We verify that it's a 3C503 board by checking the first three octets
-       of its ethernet address. */
-    iobase_reg = inb(ioaddr+0x403);
-    membase_reg = inb(ioaddr+0x404);
-    /* ASIC location registers should be 0 or have only a single bit set. */
-    if ((iobase_reg  & (iobase_reg - 1)) ||
-	(membase_reg & (membase_reg - 1))) {
-	retval = -ENODEV;
-	goto out1;
-    }
-    saved_406 = inb_p(ioaddr + 0x406);
-    outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */
-    outb_p(ECNTRL_THIN, ioaddr + 0x406);
-    /* Map the station addr PROM into the lower I/O ports. We now check
-       for both the old and new 3Com prefix */
-    outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406);
-    vendor_id = inb(ioaddr)*0x10000 + inb(ioaddr + 1)*0x100 + inb(ioaddr + 2);
-    if ((vendor_id != OLD_3COM_ID) && (vendor_id != NEW_3COM_ID)) {
-	/* Restore the register we frobbed. */
-	outb(saved_406, ioaddr + 0x406);
-	retval = -ENODEV;
-	goto out1;
-    }
-
-    if (ei_debug  &&  version_printed++ == 0)
-	pr_debug("%s", version);
-
-    dev->base_addr = ioaddr;
-
-    pr_info("%s: 3c503 at i/o base %#3x, node ", dev->name, ioaddr);
-
-    /* Retrieve and print the ethernet address. */
-    for (i = 0; i < 6; i++)
-	dev->dev_addr[i] = inb(ioaddr + i);
-    pr_cont("%pM", dev->dev_addr);
-
-    /* Map the 8390 back into the window. */
-    outb(ECNTRL_THIN, ioaddr + 0x406);
-
-    /* Check for EL2/16 as described in tech. man. */
-    outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
-    outb_p(0, ioaddr + EN0_DCFG);
-    outb_p(E8390_PAGE2, ioaddr + E8390_CMD);
-    wordlength = inb_p(ioaddr + EN0_DCFG) & ENDCFG_WTS;
-    outb_p(E8390_PAGE0, ioaddr + E8390_CMD);
-
-    /* Probe for, turn on and clear the board's shared memory. */
-    if (ei_debug > 2)
-	pr_cont(" memory jumpers %2.2x ", membase_reg);
-    outb(EGACFR_NORM, ioaddr + 0x405);	/* Enable RAM */
-
-    /* This should be probed for (or set via an ioctl()) at run-time.
-       Right now we use a sleazy hack to pass in the interface number
-       at boot-time via the low bits of the mem_end field.  That value is
-       unused, and the low bits would be discarded even if it was used. */
-#if defined(EI8390_THICK) || defined(EL2_AUI)
-    ei_status.interface_num = 1;
-#else
-    ei_status.interface_num = dev->mem_end & 0xf;
-#endif
-    pr_cont(", using %sternal xcvr.\n", ei_status.interface_num == 0 ? "in" : "ex");
-
-    if ((membase_reg & 0xf0) == 0) {
-	dev->mem_start = 0;
-	ei_status.name = "3c503-PIO";
-	ei_status.mem = NULL;
-    } else {
-	dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
-	    ((membase_reg & 0xA0) ? 0x4000 : 0);
-#define EL2_MEMSIZE (EL2_MB1_STOP_PG - EL2_MB1_START_PG)*256
-	ei_status.mem = ioremap(dev->mem_start, EL2_MEMSIZE);
-
-#ifdef EL2MEMTEST
-	/* This has never found an error, but someone might care.
-	   Note that it only tests the 2nd 8kB on 16kB 3c503/16
-	   cards between card addr. 0x2000 and 0x3fff. */
-	{			/* Check the card's memory. */
-	    void __iomem *mem_base = ei_status.mem;
-	    unsigned int test_val = 0xbbadf00d;
-	    writel(0xba5eba5e, mem_base);
-	    for (i = sizeof(test_val); i < EL2_MEMSIZE; i+=sizeof(test_val)) {
-		writel(test_val, mem_base + i);
-		if (readl(mem_base) != 0xba5eba5e ||
-		    readl(mem_base + i) != test_val) {
-		    pr_warning("3c503: memory failure or memory address conflict.\n");
-		    dev->mem_start = 0;
-		    ei_status.name = "3c503-PIO";
-		    iounmap(mem_base);
-		    ei_status.mem = NULL;
-		    break;
-		}
-		test_val += 0x55555555;
-		writel(0, mem_base + i);
-	    }
-	}
-#endif  /* EL2MEMTEST */
-
-	if (dev->mem_start)
-		dev->mem_end = dev->mem_start + EL2_MEMSIZE;
-
-	if (wordlength) {	/* No Tx pages to skip over to get to Rx */
-		ei_status.priv = 0;
-		ei_status.name = "3c503/16";
-	} else {
-		ei_status.priv = TX_PAGES * 256;
-		ei_status.name = "3c503";
-	}
-    }
-
-    /*
-	Divide up the memory on the card. This is the same regardless of
-	whether shared-mem or PIO is used. For 16 bit cards (16kB RAM),
-	we use the entire 8k of bank1 for an Rx ring. We only use 3k
-	of the bank0 for 2 full size Tx packet slots. For 8 bit cards,
-	(8kB RAM) we use 3kB of bank1 for two Tx slots, and the remaining
-	5kB for an Rx ring.  */
-
-    if (wordlength) {
-	ei_status.tx_start_page = EL2_MB0_START_PG;
-	ei_status.rx_start_page = EL2_MB1_START_PG;
-    } else {
-	ei_status.tx_start_page = EL2_MB1_START_PG;
-	ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
-    }
-
-    /* Finish setting the board's parameters. */
-    ei_status.stop_page = EL2_MB1_STOP_PG;
-    ei_status.word16 = wordlength;
-    ei_status.reset_8390 = el2_reset_8390;
-    ei_status.get_8390_hdr = el2_get_8390_hdr;
-    ei_status.block_input = el2_block_input;
-    ei_status.block_output = el2_block_output;
-
-    if (dev->irq == 2)
-	dev->irq = 9;
-    else if (dev->irq > 5 && dev->irq != 9) {
-	pr_warning("3c503: configured interrupt %d invalid, will use autoIRQ.\n",
-	       dev->irq);
-	dev->irq = 0;
-    }
-
-    ei_status.saved_irq = dev->irq;
-
-    dev->netdev_ops = &el2_netdev_ops;
-    dev->ethtool_ops = &netdev_ethtool_ops;
-
-    retval = register_netdev(dev);
-    if (retval)
-	goto out1;
-
-    if (dev->mem_start)
-	pr_info("%s: %s - %dkB RAM, 8kB shared mem window at %#6lx-%#6lx.\n",
-		dev->name, ei_status.name, (wordlength+1)<<3,
-		dev->mem_start, dev->mem_end-1);
-
-    else
-    {
-	ei_status.tx_start_page = EL2_MB1_START_PG;
-	ei_status.rx_start_page = EL2_MB1_START_PG + TX_PAGES;
-	pr_info("%s: %s, %dkB RAM, using programmed I/O (REJUMPER for SHARED MEMORY).\n",
-	       dev->name, ei_status.name, (wordlength+1)<<3);
-    }
-    release_region(ioaddr + 0x400, 8);
-    return 0;
-out1:
-    release_region(ioaddr + 0x400, 8);
-out:
-    release_region(ioaddr, EL2_IO_EXTENT);
-    return retval;
-}
-
-static irqreturn_t el2_probe_interrupt(int irq, void *seen)
-{
-	*(bool *)seen = true;
-	return IRQ_HANDLED;
-}
-
-static int
-el2_open(struct net_device *dev)
-{
-    int retval;
-
-    if (dev->irq < 2) {
-	static const int irqlist[] = {5, 9, 3, 4, 0};
-	const int *irqp = irqlist;
-
-	outb(EGACFR_NORM, E33G_GACFR);	/* Enable RAM and interrupts. */
-	do {
-		bool seen;
-
-		retval = request_irq(*irqp, el2_probe_interrupt, 0,
-				     dev->name, &seen);
-		if (retval == -EBUSY)
-			continue;
-		if (retval < 0)
-			goto err_disable;
-
-		/* Twinkle the interrupt, and check if it's seen. */
-		seen = false;
-		smp_wmb();
-		outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
-		outb_p(0x00, E33G_IDCFR);
-		msleep(1);
-		free_irq(*irqp, &seen);
-		if (!seen)
-			continue;
-
-		retval = request_irq(dev->irq = *irqp, eip_interrupt, 0,
-				     dev->name, dev);
-		if (retval == -EBUSY)
-			continue;
-		if (retval < 0)
-			goto err_disable;
-		break;
-	} while (*++irqp);
-
-	if (*irqp == 0) {
-	err_disable:
-	    outb(EGACFR_IRQOFF, E33G_GACFR);	/* disable interrupts. */
-	    return -EAGAIN;
-	}
-    } else {
-	if ((retval = request_irq(dev->irq, eip_interrupt, 0, dev->name, dev))) {
-	    return retval;
-	}
-    }
-
-    el2_init_card(dev);
-    eip_open(dev);
-    return 0;
-}
-
-static int
-el2_close(struct net_device *dev)
-{
-    free_irq(dev->irq, dev);
-    dev->irq = ei_status.saved_irq;
-    outb(EGACFR_IRQOFF, E33G_GACFR);	/* disable interrupts. */
-
-    eip_close(dev);
-    return 0;
-}
-
-/* This is called whenever we have a unrecoverable failure:
-       transmit timeout
-       Bad ring buffer packet header
- */
-static void
-el2_reset_8390(struct net_device *dev)
-{
-    if (ei_debug > 1) {
-	pr_debug("%s: Resetting the 3c503 board...", dev->name);
-	pr_cont(" %#lx=%#02x %#lx=%#02x %#lx=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
-	       E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
-    }
-    outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
-    ei_status.txing = 0;
-    outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-    el2_init_card(dev);
-    if (ei_debug > 1)
-	pr_cont("done\n");
-}
-
-/* Initialize the 3c503 GA registers after a reset. */
-static void
-el2_init_card(struct net_device *dev)
-{
-    /* Unmap the station PROM and select the DIX or BNC connector. */
-    outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-
-    /* Set ASIC copy of rx's first and last+1 buffer pages */
-    /* These must be the same as in the 8390. */
-    outb(ei_status.rx_start_page, E33G_STARTPG);
-    outb(ei_status.stop_page,  E33G_STOPPG);
-
-    /* Point the vector pointer registers somewhere ?harmless?. */
-    outb(0xff, E33G_VP2);	/* Point at the ROM restart location 0xffff0 */
-    outb(0xff, E33G_VP1);
-    outb(0x00, E33G_VP0);
-    /* Turn off all interrupts until we're opened. */
-    outb_p(0x00,  dev->base_addr + EN0_IMR);
-    /* Enable IRQs iff started. */
-    outb(EGACFR_NORM, E33G_GACFR);
-
-    /* Set the interrupt line. */
-    outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR);
-    outb_p((WRD_COUNT << 1), E33G_DRQCNT);	/* Set burst size to 8 */
-    outb_p(0x20, E33G_DMAAH);	/* Put a valid addr in the GA DMA */
-    outb_p(0x00, E33G_DMAAL);
-    return;			/* We always succeed */
-}
-
-/*
- * Either use the shared memory (if enabled on the board) or put the packet
- * out through the ASIC FIFO.
- */
-static void
-el2_block_output(struct net_device *dev, int count,
-		 const unsigned char *buf, int start_page)
-{
-    unsigned short int *wrd;
-    int boguscount;		/* timeout counter */
-    unsigned short word;	/* temporary for better machine code */
-    void __iomem *base = ei_status.mem;
-
-    if (ei_status.word16)      /* Tx packets go into bank 0 on EL2/16 card */
-	outb(EGACFR_RSEL|EGACFR_TCM, E33G_GACFR);
-    else
-	outb(EGACFR_NORM, E33G_GACFR);
-
-    if (base) {	/* Shared memory transfer */
-	memcpy_toio(base + ((start_page - ei_status.tx_start_page) << 8),
-			buf, count);
-	outb(EGACFR_NORM, E33G_GACFR);	/* Back to bank1 in case on bank0 */
-	return;
-    }
-
-/*
- *  No shared memory, put the packet out the other way.
- *  Set up then start the internal memory transfer to Tx Start Page
- */
-
-    word = (unsigned short)start_page;
-    outb(word&0xFF, E33G_DMAAH);
-    outb(word>>8, E33G_DMAAL);
-
-    outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
-	   | ECNTRL_START, E33G_CNTRL);
-
-/*
- *  Here I am going to write data to the FIFO as quickly as possible.
- *  Note that E33G_FIFOH is defined incorrectly. It is really
- *  E33G_FIFOL, the lowest port address for both the byte and
- *  word write. Variable 'count' is NOT checked. Caller must supply a
- *  valid count. Note that I may write a harmless extra byte to the
- *  8390 if the byte-count was not even.
- */
-    wrd = (unsigned short int *) buf;
-    count  = (count + 1) >> 1;
-    for(;;)
-    {
-        boguscount = 0x1000;
-        while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
-        {
-            if(!boguscount--)
-            {
-                pr_notice("%s: FIFO blocked in el2_block_output.\n", dev->name);
-                el2_reset_8390(dev);
-                goto blocked;
-            }
-        }
-        if(count > WRD_COUNT)
-        {
-            outsw(E33G_FIFOH, wrd, WRD_COUNT);
-            wrd   += WRD_COUNT;
-            count -= WRD_COUNT;
-        }
-        else
-        {
-            outsw(E33G_FIFOH, wrd, count);
-            break;
-        }
-    }
-    blocked:;
-    outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-}
-
-/* Read the 4 byte, page aligned 8390 specific header. */
-static void
-el2_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
-{
-    int boguscount;
-    void __iomem *base = ei_status.mem;
-    unsigned short word;
-
-    if (base) {       /* Use the shared memory. */
-	void __iomem *hdr_start = base + ((ring_page - EL2_MB1_START_PG)<<8);
-	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
-	hdr->count = le16_to_cpu(hdr->count);
-	return;
-    }
-
-/*
- *  No shared memory, use programmed I/O.
- */
-
-    word = (unsigned short)ring_page;
-    outb(word&0xFF, E33G_DMAAH);
-    outb(word>>8, E33G_DMAAL);
-
-    outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
-	   | ECNTRL_START, E33G_CNTRL);
-    boguscount = 0x1000;
-    while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
-    {
-        if(!boguscount--)
-        {
-            pr_notice("%s: FIFO blocked in el2_get_8390_hdr.\n", dev->name);
-            memset(hdr, 0x00, sizeof(struct e8390_pkt_hdr));
-            el2_reset_8390(dev);
-            goto blocked;
-        }
-    }
-    insw(E33G_FIFOH, hdr, (sizeof(struct e8390_pkt_hdr))>> 1);
-    blocked:;
-    outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-}
-
-
-static void
-el2_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
-{
-    int boguscount = 0;
-    void __iomem *base = ei_status.mem;
-    unsigned short int *buf;
-    unsigned short word;
-
-    /* Maybe enable shared memory just be to be safe... nahh.*/
-    if (base) {	/* Use the shared memory. */
-	ring_offset -= (EL2_MB1_START_PG<<8);
-	if (ring_offset + count > EL2_MEMSIZE) {
-	    /* We must wrap the input move. */
-	    int semi_count = EL2_MEMSIZE - ring_offset;
-	    memcpy_fromio(skb->data, base + ring_offset, semi_count);
-	    count -= semi_count;
-	    memcpy_fromio(skb->data + semi_count, base + ei_status.priv, count);
-	} else {
-		memcpy_fromio(skb->data, base + ring_offset, count);
-	}
-	return;
-    }
-
-/*
- *  No shared memory, use programmed I/O.
- */
-    word = (unsigned short) ring_offset;
-    outb(word>>8, E33G_DMAAH);
-    outb(word&0xFF, E33G_DMAAL);
-
-    outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
-	   | ECNTRL_START, E33G_CNTRL);
-
-/*
- *  Here I also try to get data as fast as possible. I am betting that I
- *  can read one extra byte without clobbering anything in the kernel because
- *  this would only occur on an odd byte-count and allocation of skb->data
- *  is word-aligned. Variable 'count' is NOT checked. Caller must check
- *  for a valid count.
- *  [This is currently quite safe.... but if one day the 3c503 explodes
- *   you know where to come looking ;)]
- */
-
-    buf =  (unsigned short int *) skb->data;
-    count =  (count + 1) >> 1;
-    for(;;)
-    {
-        boguscount = 0x1000;
-        while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
-        {
-            if(!boguscount--)
-            {
-                pr_notice("%s: FIFO blocked in el2_block_input.\n", dev->name);
-                el2_reset_8390(dev);
-                goto blocked;
-            }
-        }
-        if(count > WRD_COUNT)
-        {
-            insw(E33G_FIFOH, buf, WRD_COUNT);
-            buf   += WRD_COUNT;
-            count -= WRD_COUNT;
-        }
-        else
-        {
-            insw(E33G_FIFOH, buf, count);
-            break;
-        }
-    }
-    blocked:;
-    outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
-}
-
-
-static void netdev_get_drvinfo(struct net_device *dev,
-			       struct ethtool_drvinfo *info)
-{
-	strcpy(info->driver, DRV_NAME);
-	strcpy(info->version, DRV_VERSION);
-	sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
-	.get_drvinfo		= netdev_get_drvinfo,
-};
-
-#ifdef MODULE
-#define MAX_EL2_CARDS	4	/* Max number of EL2 cards per module */
-
-static struct net_device *dev_el2[MAX_EL2_CARDS];
-static int io[MAX_EL2_CARDS];
-static int irq[MAX_EL2_CARDS];
-static int xcvr[MAX_EL2_CARDS];	/* choose int. or ext. xcvr */
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(xcvr, int, NULL, 0);
-MODULE_PARM_DESC(io, "I/O base address(es)");
-MODULE_PARM_DESC(irq, "IRQ number(s) (assigned)");
-MODULE_PARM_DESC(xcvr, "transceiver(s) (0=internal, 1=external)");
-MODULE_DESCRIPTION("3Com ISA EtherLink II, II/16 (3c503, 3c503/16) driver");
-MODULE_LICENSE("GPL");
-
-/* This is set up so that only a single autoprobe takes place per call.
-ISA device autoprobes on a running machine are not recommended. */
-int __init
-init_module(void)
-{
-	struct net_device *dev;
-	int this_dev, found = 0;
-
-	for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
-		if (io[this_dev] == 0)  {
-			if (this_dev != 0) break; /* only autoprobe 1st one */
-			pr_notice("3c503.c: Presently autoprobing (not recommended) for a single card.\n");
-		}
-		dev = alloc_eip_netdev();
-		if (!dev)
-			break;
-		dev->irq = irq[this_dev];
-		dev->base_addr = io[this_dev];
-		dev->mem_end = xcvr[this_dev];	/* low 4bits = xcvr sel. */
-		if (do_el2_probe(dev) == 0) {
-			dev_el2[found++] = dev;
-			continue;
-		}
-		free_netdev(dev);
-		pr_warning("3c503.c: No 3c503 card found (i/o = 0x%x).\n", io[this_dev]);
-		break;
-	}
-	if (found)
-		return 0;
-	return -ENXIO;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
-	/* NB: el2_close() handles free_irq */
-	release_region(dev->base_addr, EL2_IO_EXTENT);
-	if (ei_status.mem)
-		iounmap(ei_status.mem);
-}
-
-void __exit
-cleanup_module(void)
-{
-	int this_dev;
-
-	for (this_dev = 0; this_dev < MAX_EL2_CARDS; this_dev++) {
-		struct net_device *dev = dev_el2[this_dev];
-		if (dev) {
-			unregister_netdev(dev);
-			cleanup_card(dev);
-			free_netdev(dev);
-		}
-	}
-}
-#endif /* MODULE */

+ 0 - 1673
drivers/net/3c505.c

@@ -1,1673 +0,0 @@
-/*
- * Linux Ethernet device driver for the 3Com Etherlink Plus (3C505)
- *      By Craig Southeren, Juha Laiho and Philip Blundell
- *
- * 3c505.c      This module implements an interface to the 3Com
- *              Etherlink Plus (3c505) Ethernet card. Linux device
- *              driver interface reverse engineered from the Linux 3C509
- *              device drivers. Some 3C505 information gleaned from
- *              the Crynwr packet driver. Still this driver would not
- *              be here without 3C505 technical reference provided by
- *              3Com.
- *
- * $Id: 3c505.c,v 1.10 1996/04/16 13:06:27 phil Exp $
- *
- * Authors:     Linux 3c505 device driver by
- *                      Craig Southeren, <craigs@ineluki.apana.org.au>
- *              Final debugging by
- *                      Andrew Tridgell, <tridge@nimbus.anu.edu.au>
- *              Auto irq/address, tuning, cleanup and v1.1.4+ kernel mods by
- *                      Juha Laiho, <jlaiho@ichaos.nullnet.fi>
- *              Linux 3C509 driver by
- *                      Donald Becker, <becker@super.org>
- *			(Now at <becker@scyld.com>)
- *              Crynwr packet driver by
- *                      Krishnan Gopalan and Gregg Stefancik,
- *                      Clemson University Engineering Computer Operations.
- *                      Portions of the code have been adapted from the 3c505
- *                         driver for NCSA Telnet by Bruce Orchard and later
- *                         modified by Warren Van Houten and krus@diku.dk.
- *              3C505 technical information provided by
- *                      Terry Murphy, of 3Com Network Adapter Division
- *              Linux 1.3.0 changes by
- *                      Alan Cox <Alan.Cox@linux.org>
- *              More debugging, DMA support, currently maintained by
- *                      Philip Blundell <philb@gnu.org>
- *              Multicard/soft configurable dma channel/rev 2 hardware support
- *                      by Christopher Collins <ccollins@pcug.org.au>
- *		Ethtool support (jgarzik), 11/17/2001
- */
-
-#define DRV_NAME	"3c505"
-#define DRV_VERSION	"1.10a"
-
-
-/* Theory of operation:
- *
- * The 3c505 is quite an intelligent board.  All communication with it is done
- * by means of Primary Command Blocks (PCBs); these are transferred using PIO
- * through the command register.  The card has 256k of on-board RAM, which is
- * used to buffer received packets.  It might seem at first that more buffers
- * are better, but in fact this isn't true.  From my tests, it seems that
- * more than about 10 buffers are unnecessary, and there is a noticeable
- * performance hit in having more active on the card.  So the majority of the
- * card's memory isn't, in fact, used.  Sadly, the card only has one transmit
- * buffer and, short of loading our own firmware into it (which is what some
- * drivers resort to) there's nothing we can do about this.
- *
- * We keep up to 4 "receive packet" commands active on the board at a time.
- * When a packet comes in, so long as there is a receive command active, the
- * board will send us a "packet received" PCB and then add the data for that
- * packet to the DMA queue.  If a DMA transfer is not already in progress, we
- * set one up to start uploading the data.  We have to maintain a list of
- * backlogged receive packets, because the card may decide to tell us about
- * a newly-arrived packet at any time, and we may not be able to start a DMA
- * transfer immediately (ie one may already be going on).  We can't NAK the
- * PCB, because then it would throw the packet away.
- *
- * Trying to send a PCB to the card at the wrong moment seems to have bad
- * effects.  If we send it a transmit PCB while a receive DMA is happening,
- * it will just NAK the PCB and so we will have wasted our time.  Worse, it
- * sometimes seems to interrupt the transfer.  The majority of the low-level
- * code is protected by one huge semaphore -- "busy" -- which is set whenever
- * it probably isn't safe to do anything to the card.  The receive routine
- * must gain a lock on "busy" before it can start a DMA transfer, and the
- * transmit routine must gain a lock before it sends the first PCB to the card.
- * The send_pcb() routine also has an internal semaphore to protect it against
- * being re-entered (which would be disastrous) -- this is needed because
- * several things can happen asynchronously (re-priming the receiver and
- * asking the card for statistics, for example).  send_pcb() will also refuse
- * to talk to the card at all if a DMA upload is happening.  The higher-level
- * networking code will reschedule a later retry if some part of the driver
- * is blocked.  In practice, this doesn't seem to happen very often.
- */
-
-/* This driver may now work with revision 2.x hardware, since all the read
- * operations on the HCR have been removed (we now keep our own softcopy).
- * But I don't have an old card to test it on.
- *
- * This has had the bad effect that the autoprobe routine is now a bit
- * less friendly to other devices.  However, it was never very good.
- * before, so I doubt it will hurt anybody.
- */
-
-/* The driver is a mess.  I took Craig's and Juha's code, and hacked it firstly
- * to make it more reliable, and secondly to add DMA mode.  Many things could
- * probably be done better; the concurrency protection is particularly awful.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/ioport.h>
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/delay.h>
-#include <linux/bitops.h>
-#include <linux/gfp.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-
-#include "3c505.h"
-
-/*********************************************************
- *
- *  define debug messages here as common strings to reduce space
- *
- *********************************************************/
-
-#define filename __FILE__
-
-#define timeout_msg "*** timeout at %s:%s (line %d) ***\n"
-#define TIMEOUT_MSG(lineno) \
-	pr_notice(timeout_msg, filename, __func__, (lineno))
-
-#define invalid_pcb_msg "*** invalid pcb length %d at %s:%s (line %d) ***\n"
-#define INVALID_PCB_MSG(len) \
-	pr_notice(invalid_pcb_msg, (len), filename, __func__, __LINE__)
-
-#define search_msg "%s: Looking for 3c505 adapter at address %#x..."
-
-#define stilllooking_msg "still looking..."
-
-#define found_msg "found.\n"
-
-#define notfound_msg "not found (reason = %d)\n"
-
-#define couldnot_msg "%s: 3c505 not found\n"
-
-/*********************************************************
- *
- *  various other debug stuff
- *
- *********************************************************/
-
-#ifdef ELP_DEBUG
-static int elp_debug = ELP_DEBUG;
-#else
-static int elp_debug;
-#endif
-#define debug elp_debug
-
-/*
- *  0 = no messages (well, some)
- *  1 = messages when high level commands performed
- *  2 = messages when low level commands performed
- *  3 = messages when interrupts received
- */
-
-/*****************************************************************
- *
- * List of I/O-addresses we try to auto-sense
- * Last element MUST BE 0!
- *****************************************************************/
-
-static int addr_list[] __initdata = {0x300, 0x280, 0x310, 0};
-
-/* Dma Memory related stuff */
-
-static unsigned long dma_mem_alloc(int size)
-{
-	int order = get_order(size);
-	return __get_dma_pages(GFP_KERNEL, order);
-}
-
-
-/*****************************************************************
- *
- * Functions for I/O (note the inline !)
- *
- *****************************************************************/
-
-static inline unsigned char inb_status(unsigned int base_addr)
-{
-	return inb(base_addr + PORT_STATUS);
-}
-
-static inline int inb_command(unsigned int base_addr)
-{
-	return inb(base_addr + PORT_COMMAND);
-}
-
-static inline void outb_control(unsigned char val, struct net_device *dev)
-{
-	outb(val, dev->base_addr + PORT_CONTROL);
-	((elp_device *)(netdev_priv(dev)))->hcr_val = val;
-}
-
-#define HCR_VAL(x)   (((elp_device *)(netdev_priv(x)))->hcr_val)
-
-static inline void outb_command(unsigned char val, unsigned int base_addr)
-{
-	outb(val, base_addr + PORT_COMMAND);
-}
-
-static inline unsigned int backlog_next(unsigned int n)
-{
-	return (n + 1) % BACKLOG_SIZE;
-}
-
-/*****************************************************************
- *
- *  useful functions for accessing the adapter
- *
- *****************************************************************/
-
-/*
- * use this routine when accessing the ASF bits as they are
- * changed asynchronously by the adapter
- */
-
-/* get adapter PCB status */
-#define	GET_ASF(addr) \
-	(get_status(addr)&ASF_PCB_MASK)
-
-static inline int get_status(unsigned int base_addr)
-{
-	unsigned long timeout = jiffies + 10*HZ/100;
-	register int stat1;
-	do {
-		stat1 = inb_status(base_addr);
-	} while (stat1 != inb_status(base_addr) && time_before(jiffies, timeout));
-	if (time_after_eq(jiffies, timeout))
-		TIMEOUT_MSG(__LINE__);
-	return stat1;
-}
-
-static inline void set_hsf(struct net_device *dev, int hsf)
-{
-	elp_device *adapter = netdev_priv(dev);
-	unsigned long flags;
-
-	spin_lock_irqsave(&adapter->lock, flags);
-	outb_control((HCR_VAL(dev) & ~HSF_PCB_MASK) | hsf, dev);
-	spin_unlock_irqrestore(&adapter->lock, flags);
-}
-
-static bool start_receive(struct net_device *, pcb_struct *);
-
-static inline void adapter_reset(struct net_device *dev)
-{
-	unsigned long timeout;
-	elp_device *adapter = netdev_priv(dev);
-	unsigned char orig_hcr = adapter->hcr_val;
-
-	outb_control(0, dev);
-
-	if (inb_status(dev->base_addr) & ACRF) {
-		do {
-			inb_command(dev->base_addr);
-			timeout = jiffies + 2*HZ/100;
-			while (time_before_eq(jiffies, timeout) && !(inb_status(dev->base_addr) & ACRF));
-		} while (inb_status(dev->base_addr) & ACRF);
-		set_hsf(dev, HSF_PCB_NAK);
-	}
-	outb_control(adapter->hcr_val | ATTN | DIR, dev);
-	mdelay(10);
-	outb_control(adapter->hcr_val & ~ATTN, dev);
-	mdelay(10);
-	outb_control(adapter->hcr_val | FLSH, dev);
-	mdelay(10);
-	outb_control(adapter->hcr_val & ~FLSH, dev);
-	mdelay(10);
-
-	outb_control(orig_hcr, dev);
-	if (!start_receive(dev, &adapter->tx_pcb))
-		pr_err("%s: start receive command failed\n", dev->name);
-}
-
-/* Check to make sure that a DMA transfer hasn't timed out.  This should
- * never happen in theory, but seems to occur occasionally if the card gets
- * prodded at the wrong time.
- */
-static inline void check_3c505_dma(struct net_device *dev)
-{
-	elp_device *adapter = netdev_priv(dev);
-	if (adapter->dmaing && time_after(jiffies, adapter->current_dma.start_time + 10)) {
-		unsigned long flags, f;
-		pr_err("%s: DMA %s timed out, %d bytes left\n", dev->name,
-			adapter->current_dma.direction ? "download" : "upload",
-			get_dma_residue(dev->dma));
-		spin_lock_irqsave(&adapter->lock, flags);
-		adapter->dmaing = 0;
-		adapter->busy = 0;
-
-		f=claim_dma_lock();
-		disable_dma(dev->dma);
-		release_dma_lock(f);
-
-		if (adapter->rx_active)
-			adapter->rx_active--;
-		outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
-		spin_unlock_irqrestore(&adapter->lock, flags);
-	}
-}
-
-/* Primitive functions used by send_pcb() */
-static inline bool send_pcb_slow(unsigned int base_addr, unsigned char byte)
-{
-	unsigned long timeout;
-	outb_command(byte, base_addr);
-	for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) {
-		if (inb_status(base_addr) & HCRE)
-			return false;
-	}
-	pr_warning("3c505: send_pcb_slow timed out\n");
-	return true;
-}
-
-static inline bool send_pcb_fast(unsigned int base_addr, unsigned char byte)
-{
-	unsigned int timeout;
-	outb_command(byte, base_addr);
-	for (timeout = 0; timeout < 40000; timeout++) {
-		if (inb_status(base_addr) & HCRE)
-			return false;
-	}
-	pr_warning("3c505: send_pcb_fast timed out\n");
-	return true;
-}
-
-/* Check to see if the receiver needs restarting, and kick it if so */
-static inline void prime_rx(struct net_device *dev)
-{
-	elp_device *adapter = netdev_priv(dev);
-	while (adapter->rx_active < ELP_RX_PCBS && netif_running(dev)) {
-		if (!start_receive(dev, &adapter->itx_pcb))
-			break;
-	}
-}
-
-/*****************************************************************
- *
- * send_pcb
- *   Send a PCB to the adapter.
- *
- *	output byte to command reg  --<--+
- *	wait until HCRE is non zero      |
- *	loop until all bytes sent   -->--+
- *	set HSF1 and HSF2 to 1
- *	output pcb length
- *	wait until ASF give ACK or NAK
- *	set HSF1 and HSF2 to 0
- *
- *****************************************************************/
-
-/* This can be quite slow -- the adapter is allowed to take up to 40ms
- * to respond to the initial interrupt.
- *
- * We run initially with interrupts turned on, but with a semaphore set
- * so that nobody tries to re-enter this code.  Once the first byte has
- * gone through, we turn interrupts off and then send the others (the
- * timeout is reduced to 500us).
- */
-
-static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
-{
-	int i;
-	unsigned long timeout;
-	elp_device *adapter = netdev_priv(dev);
-	unsigned long flags;
-
-	check_3c505_dma(dev);
-
-	if (adapter->dmaing && adapter->current_dma.direction == 0)
-		return false;
-
-	/* Avoid contention */
-	if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
-		if (elp_debug >= 3) {
-			pr_debug("%s: send_pcb entered while threaded\n", dev->name);
-		}
-		return false;
-	}
-	/*
-	 * load each byte into the command register and
-	 * wait for the HCRE bit to indicate the adapter
-	 * had read the byte
-	 */
-	set_hsf(dev, 0);
-
-	if (send_pcb_slow(dev->base_addr, pcb->command))
-		goto abort;
-
-	spin_lock_irqsave(&adapter->lock, flags);
-
-	if (send_pcb_fast(dev->base_addr, pcb->length))
-		goto sti_abort;
-
-	for (i = 0; i < pcb->length; i++) {
-		if (send_pcb_fast(dev->base_addr, pcb->data.raw[i]))
-			goto sti_abort;
-	}
-
-	outb_control(adapter->hcr_val | 3, dev);	/* signal end of PCB */
-	outb_command(2 + pcb->length, dev->base_addr);
-
-	/* now wait for the acknowledgement */
-	spin_unlock_irqrestore(&adapter->lock, flags);
-
-	for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) {
-		switch (GET_ASF(dev->base_addr)) {
-		case ASF_PCB_ACK:
-			adapter->send_pcb_semaphore = 0;
-			return true;
-
-		case ASF_PCB_NAK:
-#ifdef ELP_DEBUG
-			pr_debug("%s: send_pcb got NAK\n", dev->name);
-#endif
-			goto abort;
-		}
-	}
-
-	if (elp_debug >= 1)
-		pr_debug("%s: timeout waiting for PCB acknowledge (status %02x)\n",
-			dev->name, inb_status(dev->base_addr));
-	goto abort;
-
-      sti_abort:
-	spin_unlock_irqrestore(&adapter->lock, flags);
-      abort:
-	adapter->send_pcb_semaphore = 0;
-	return false;
-}
-
-
-/*****************************************************************
- *
- * receive_pcb
- *   Read a PCB from the adapter
- *
- *	wait for ACRF to be non-zero        ---<---+
- *	input a byte                               |
- *	if ASF1 and ASF2 were not both one         |
- *		before byte was read, loop      --->---+
- *	set HSF1 and HSF2 for ack
- *
- *****************************************************************/
-
-static bool receive_pcb(struct net_device *dev, pcb_struct * pcb)
-{
-	int i, j;
-	int total_length;
-	int stat;
-	unsigned long timeout;
-	unsigned long flags;
-
-	elp_device *adapter = netdev_priv(dev);
-
-	set_hsf(dev, 0);
-
-	/* get the command code */
-	timeout = jiffies + 2*HZ/100;
-	while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
-	if (time_after_eq(jiffies, timeout)) {
-		TIMEOUT_MSG(__LINE__);
-		return false;
-	}
-	pcb->command = inb_command(dev->base_addr);
-
-	/* read the data length */
-	timeout = jiffies + 3*HZ/100;
-	while (((stat = get_status(dev->base_addr)) & ACRF) == 0 && time_before(jiffies, timeout));
-	if (time_after_eq(jiffies, timeout)) {
-		TIMEOUT_MSG(__LINE__);
-		pr_info("%s: status %02x\n", dev->name, stat);
-		return false;
-	}
-	pcb->length = inb_command(dev->base_addr);
-
-	if (pcb->length > MAX_PCB_DATA) {
-		INVALID_PCB_MSG(pcb->length);
-		adapter_reset(dev);
-		return false;
-	}
-	/* read the data */
-	spin_lock_irqsave(&adapter->lock, flags);
-	for (i = 0; i < MAX_PCB_DATA; i++) {
-		for (j = 0; j < 20000; j++) {
-			stat = get_status(dev->base_addr);
-			if (stat & ACRF)
-				break;
-		}
-		pcb->data.raw[i] = inb_command(dev->base_addr);
-		if ((stat & ASF_PCB_MASK) == ASF_PCB_END || j >= 20000)
-			break;
-	}
-	spin_unlock_irqrestore(&adapter->lock, flags);
-	if (i >= MAX_PCB_DATA) {
-		INVALID_PCB_MSG(i);
-		return false;
-	}
-	if (j >= 20000) {
-		TIMEOUT_MSG(__LINE__);
-		return false;
-	}
-	/* the last "data" byte was really the length! */
-	total_length = pcb->data.raw[i];
-
-	/* safety check total length vs data length */
-	if (total_length != (pcb->length + 2)) {
-		if (elp_debug >= 2)
-			pr_warning("%s: mangled PCB received\n", dev->name);
-		set_hsf(dev, HSF_PCB_NAK);
-		return false;
-	}
-
-	if (pcb->command == CMD_RECEIVE_PACKET_COMPLETE) {
-		if (test_and_set_bit(0, (void *) &adapter->busy)) {
-			if (backlog_next(adapter->rx_backlog.in) == adapter->rx_backlog.out) {
-				set_hsf(dev, HSF_PCB_NAK);
-				pr_warning("%s: PCB rejected, transfer in progress and backlog full\n", dev->name);
-				pcb->command = 0;
-				return true;
-			} else {
-				pcb->command = 0xff;
-			}
-		}
-	}
-	set_hsf(dev, HSF_PCB_ACK);
-	return true;
-}
-
-/******************************************************
- *
- *  queue a receive command on the adapter so we will get an
- *  interrupt when a packet is received.
- *
- ******************************************************/
-
-static bool start_receive(struct net_device *dev, pcb_struct * tx_pcb)
-{
-	bool status;
-	elp_device *adapter = netdev_priv(dev);
-
-	if (elp_debug >= 3)
-		pr_debug("%s: restarting receiver\n", dev->name);
-	tx_pcb->command = CMD_RECEIVE_PACKET;
-	tx_pcb->length = sizeof(struct Rcv_pkt);
-	tx_pcb->data.rcv_pkt.buf_seg
-	    = tx_pcb->data.rcv_pkt.buf_ofs = 0;		/* Unused */
-	tx_pcb->data.rcv_pkt.buf_len = 1600;
-	tx_pcb->data.rcv_pkt.timeout = 0;	/* set timeout to zero */
-	status = send_pcb(dev, tx_pcb);
-	if (status)
-		adapter->rx_active++;
-	return status;
-}
-
-/******************************************************
- *
- * extract a packet from the adapter
- * this routine is only called from within the interrupt
- * service routine, so no cli/sti calls are needed
- * note that the length is always assumed to be even
- *
- ******************************************************/
-
-static void receive_packet(struct net_device *dev, int len)
-{
-	int rlen;
-	elp_device *adapter = netdev_priv(dev);
-	void *target;
-	struct sk_buff *skb;
-	unsigned long flags;
-
-	rlen = (len + 1) & ~1;
-	skb = dev_alloc_skb(rlen + 2);
-
-	if (!skb) {
-		pr_warning("%s: memory squeeze, dropping packet\n", dev->name);
-		target = adapter->dma_buffer;
-		adapter->current_dma.target = NULL;
-		/* FIXME: stats */
-		return;
-	}
-
-	skb_reserve(skb, 2);
-	target = skb_put(skb, rlen);
-	if ((unsigned long)(target + rlen) >= MAX_DMA_ADDRESS) {
-		adapter->current_dma.target = target;
-		target = adapter->dma_buffer;
-	} else {
-		adapter->current_dma.target = NULL;
-	}
-
-	/* if this happens, we die */
-	if (test_and_set_bit(0, (void *) &adapter->dmaing))
-		pr_err("%s: rx blocked, DMA in progress, dir %d\n",
-			dev->name, adapter->current_dma.direction);
-
-	adapter->current_dma.direction = 0;
-	adapter->current_dma.length = rlen;
-	adapter->current_dma.skb = skb;
-	adapter->current_dma.start_time = jiffies;
-
-	outb_control(adapter->hcr_val | DIR | TCEN | DMAE, dev);
-
-	flags=claim_dma_lock();
-	disable_dma(dev->dma);
-	clear_dma_ff(dev->dma);
-	set_dma_mode(dev->dma, 0x04);	/* dma read */
-	set_dma_addr(dev->dma, isa_virt_to_bus(target));
-	set_dma_count(dev->dma, rlen);
-	enable_dma(dev->dma);
-	release_dma_lock(flags);
-
-	if (elp_debug >= 3) {
-		pr_debug("%s: rx DMA transfer started\n", dev->name);
-	}
-
-	if (adapter->rx_active)
-		adapter->rx_active--;
-
-	if (!adapter->busy)
-		pr_warning("%s: receive_packet called, busy not set.\n", dev->name);
-}
-
-/******************************************************
- *
- * interrupt handler
- *
- ******************************************************/
-
-static irqreturn_t elp_interrupt(int irq, void *dev_id)
-{
-	int len;
-	int dlen;
-	int icount = 0;
-	struct net_device *dev = dev_id;
-	elp_device *adapter = netdev_priv(dev);
-	unsigned long timeout;
-
-	spin_lock(&adapter->lock);
-
-	do {
-		/*
-		 * has a DMA transfer finished?
-		 */
-		if (inb_status(dev->base_addr) & DONE) {
-			if (!adapter->dmaing)
-				pr_warning("%s: phantom DMA completed\n", dev->name);
-
-			if (elp_debug >= 3)
-				pr_debug("%s: %s DMA complete, status %02x\n", dev->name,
-					adapter->current_dma.direction ? "tx" : "rx",
-					inb_status(dev->base_addr));
-
-			outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
-			if (adapter->current_dma.direction) {
-				dev_kfree_skb_irq(adapter->current_dma.skb);
-			} else {
-				struct sk_buff *skb = adapter->current_dma.skb;
-				if (skb) {
-					if (adapter->current_dma.target) {
-				  	/* have already done the skb_put() */
-				  	memcpy(adapter->current_dma.target, adapter->dma_buffer, adapter->current_dma.length);
-					}
-					skb->protocol = eth_type_trans(skb,dev);
-					dev->stats.rx_bytes += skb->len;
-					netif_rx(skb);
-				}
-			}
-			adapter->dmaing = 0;
-			if (adapter->rx_backlog.in != adapter->rx_backlog.out) {
-				int t = adapter->rx_backlog.length[adapter->rx_backlog.out];
-				adapter->rx_backlog.out = backlog_next(adapter->rx_backlog.out);
-				if (elp_debug >= 2)
-					pr_debug("%s: receiving backlogged packet (%d)\n", dev->name, t);
-				receive_packet(dev, t);
-			} else {
-				adapter->busy = 0;
-			}
-		} else {
-			/* has one timed out? */
-			check_3c505_dma(dev);
-		}
-
-		/*
-		 * receive a PCB from the adapter
-		 */
-		timeout = jiffies + 3*HZ/100;
-		while ((inb_status(dev->base_addr) & ACRF) != 0 && time_before(jiffies, timeout)) {
-			if (receive_pcb(dev, &adapter->irx_pcb)) {
-				switch (adapter->irx_pcb.command)
-				{
-				case 0:
-					break;
-					/*
-					 * received a packet - this must be handled fast
-					 */
-				case 0xff:
-				case CMD_RECEIVE_PACKET_COMPLETE:
-					/* if the device isn't open, don't pass packets up the stack */
-					if (!netif_running(dev))
-						break;
-					len = adapter->irx_pcb.data.rcv_resp.pkt_len;
-					dlen = adapter->irx_pcb.data.rcv_resp.buf_len;
-					if (adapter->irx_pcb.data.rcv_resp.timeout != 0) {
-						pr_err("%s: interrupt - packet not received correctly\n", dev->name);
-					} else {
-						if (elp_debug >= 3) {
-							pr_debug("%s: interrupt - packet received of length %i (%i)\n",
-								dev->name, len, dlen);
-						}
-						if (adapter->irx_pcb.command == 0xff) {
-							if (elp_debug >= 2)
-								pr_debug("%s: adding packet to backlog (len = %d)\n",
-									dev->name, dlen);
-							adapter->rx_backlog.length[adapter->rx_backlog.in] = dlen;
-							adapter->rx_backlog.in = backlog_next(adapter->rx_backlog.in);
-						} else {
-							receive_packet(dev, dlen);
-						}
-						if (elp_debug >= 3)
-							pr_debug("%s: packet received\n", dev->name);
-					}
-					break;
-
-					/*
-					 * 82586 configured correctly
-					 */
-				case CMD_CONFIGURE_82586_RESPONSE:
-					adapter->got[CMD_CONFIGURE_82586] = 1;
-					if (elp_debug >= 3)
-						pr_debug("%s: interrupt - configure response received\n", dev->name);
-					break;
-
-					/*
-					 * Adapter memory configuration
-					 */
-				case CMD_CONFIGURE_ADAPTER_RESPONSE:
-					adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 1;
-					if (elp_debug >= 3)
-						pr_debug("%s: Adapter memory configuration %s.\n", dev->name,
-						       adapter->irx_pcb.data.failed ? "failed" : "succeeded");
-					break;
-
-					/*
-					 * Multicast list loading
-					 */
-				case CMD_LOAD_MULTICAST_RESPONSE:
-					adapter->got[CMD_LOAD_MULTICAST_LIST] = 1;
-					if (elp_debug >= 3)
-						pr_debug("%s: Multicast address list loading %s.\n", dev->name,
-						       adapter->irx_pcb.data.failed ? "failed" : "succeeded");
-					break;
-
-					/*
-					 * Station address setting
-					 */
-				case CMD_SET_ADDRESS_RESPONSE:
-					adapter->got[CMD_SET_STATION_ADDRESS] = 1;
-					if (elp_debug >= 3)
-						pr_debug("%s: Ethernet address setting %s.\n", dev->name,
-						       adapter->irx_pcb.data.failed ? "failed" : "succeeded");
-					break;
-
-
-					/*
-					 * received board statistics
-					 */
-				case CMD_NETWORK_STATISTICS_RESPONSE:
-					dev->stats.rx_packets += adapter->irx_pcb.data.netstat.tot_recv;
-					dev->stats.tx_packets += adapter->irx_pcb.data.netstat.tot_xmit;
-					dev->stats.rx_crc_errors += adapter->irx_pcb.data.netstat.err_CRC;
-					dev->stats.rx_frame_errors += adapter->irx_pcb.data.netstat.err_align;
-					dev->stats.rx_fifo_errors += adapter->irx_pcb.data.netstat.err_ovrrun;
-					dev->stats.rx_over_errors += adapter->irx_pcb.data.netstat.err_res;
-					adapter->got[CMD_NETWORK_STATISTICS] = 1;
-					if (elp_debug >= 3)
-						pr_debug("%s: interrupt - statistics response received\n", dev->name);
-					break;
-
-					/*
-					 * sent a packet
-					 */
-				case CMD_TRANSMIT_PACKET_COMPLETE:
-					if (elp_debug >= 3)
-						pr_debug("%s: interrupt - packet sent\n", dev->name);
-					if (!netif_running(dev))
-						break;
-					switch (adapter->irx_pcb.data.xmit_resp.c_stat) {
-					case 0xffff:
-						dev->stats.tx_aborted_errors++;
-						pr_info("%s: transmit timed out, network cable problem?\n", dev->name);
-						break;
-					case 0xfffe:
-						dev->stats.tx_fifo_errors++;
-						pr_info("%s: transmit timed out, FIFO underrun\n", dev->name);
-						break;
-					}
-					netif_wake_queue(dev);
-					break;
-
-					/*
-					 * some unknown PCB
-					 */
-				default:
-					pr_debug("%s: unknown PCB received - %2.2x\n",
-						dev->name, adapter->irx_pcb.command);
-					break;
-				}
-			} else {
-				pr_warning("%s: failed to read PCB on interrupt\n", dev->name);
-				adapter_reset(dev);
-			}
-		}
-
-	} while (icount++ < 5 && (inb_status(dev->base_addr) & (ACRF | DONE)));
-
-	prime_rx(dev);
-
-	/*
-	 * indicate no longer in interrupt routine
-	 */
-	spin_unlock(&adapter->lock);
-	return IRQ_HANDLED;
-}
-
-
-/******************************************************
- *
- * open the board
- *
- ******************************************************/
-
-static int elp_open(struct net_device *dev)
-{
-	elp_device *adapter = netdev_priv(dev);
-	int retval;
-
-	if (elp_debug >= 3)
-		pr_debug("%s: request to open device\n", dev->name);
-
-	/*
-	 * make sure we actually found the device
-	 */
-	if (adapter == NULL) {
-		pr_err("%s: Opening a non-existent physical device\n", dev->name);
-		return -EAGAIN;
-	}
-	/*
-	 * disable interrupts on the board
-	 */
-	outb_control(0, dev);
-
-	/*
-	 * clear any pending interrupts
-	 */
-	inb_command(dev->base_addr);
-	adapter_reset(dev);
-
-	/*
-	 * no receive PCBs active
-	 */
-	adapter->rx_active = 0;
-
-	adapter->busy = 0;
-	adapter->send_pcb_semaphore = 0;
-	adapter->rx_backlog.in = 0;
-	adapter->rx_backlog.out = 0;
-
-	spin_lock_init(&adapter->lock);
-
-	/*
-	 * install our interrupt service routine
-	 */
-	if ((retval = request_irq(dev->irq, elp_interrupt, 0, dev->name, dev))) {
-		pr_err("%s: could not allocate IRQ%d\n", dev->name, dev->irq);
-		return retval;
-	}
-	if ((retval = request_dma(dev->dma, dev->name))) {
-		free_irq(dev->irq, dev);
-		pr_err("%s: could not allocate DMA%d channel\n", dev->name, dev->dma);
-		return retval;
-	}
-	adapter->dma_buffer = (void *) dma_mem_alloc(DMA_BUFFER_SIZE);
-	if (!adapter->dma_buffer) {
-		pr_err("%s: could not allocate DMA buffer\n", dev->name);
-		free_dma(dev->dma);
-		free_irq(dev->irq, dev);
-		return -ENOMEM;
-	}
-	adapter->dmaing = 0;
-
-	/*
-	 * enable interrupts on the board
-	 */
-	outb_control(CMDE, dev);
-
-	/*
-	 * configure adapter memory: we need 10 multicast addresses, default==0
-	 */
-	if (elp_debug >= 3)
-		pr_debug("%s: sending 3c505 memory configuration command\n", dev->name);
-	adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
-	adapter->tx_pcb.data.memconf.cmd_q = 10;
-	adapter->tx_pcb.data.memconf.rcv_q = 20;
-	adapter->tx_pcb.data.memconf.mcast = 10;
-	adapter->tx_pcb.data.memconf.frame = 20;
-	adapter->tx_pcb.data.memconf.rcv_b = 20;
-	adapter->tx_pcb.data.memconf.progs = 0;
-	adapter->tx_pcb.length = sizeof(struct Memconf);
-	adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] = 0;
-	if (!send_pcb(dev, &adapter->tx_pcb))
-		pr_err("%s: couldn't send memory configuration command\n", dev->name);
-	else {
-		unsigned long timeout = jiffies + TIMEOUT;
-		while (adapter->got[CMD_CONFIGURE_ADAPTER_MEMORY] == 0 && time_before(jiffies, timeout));
-		if (time_after_eq(jiffies, timeout))
-			TIMEOUT_MSG(__LINE__);
-	}
-
-
-	/*
-	 * configure adapter to receive broadcast messages and wait for response
-	 */
-	if (elp_debug >= 3)
-		pr_debug("%s: sending 82586 configure command\n", dev->name);
-	adapter->tx_pcb.command = CMD_CONFIGURE_82586;
-	adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
-	adapter->tx_pcb.length = 2;
-	adapter->got[CMD_CONFIGURE_82586] = 0;
-	if (!send_pcb(dev, &adapter->tx_pcb))
-		pr_err("%s: couldn't send 82586 configure command\n", dev->name);
-	else {
-		unsigned long timeout = jiffies + TIMEOUT;
-		while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
-		if (time_after_eq(jiffies, timeout))
-			TIMEOUT_MSG(__LINE__);
-	}
-
-	/* enable burst-mode DMA */
-	/* outb(0x1, dev->base_addr + PORT_AUXDMA); */
-
-	/*
-	 * queue receive commands to provide buffering
-	 */
-	prime_rx(dev);
-	if (elp_debug >= 3)
-		pr_debug("%s: %d receive PCBs active\n", dev->name, adapter->rx_active);
-
-	/*
-	 * device is now officially open!
-	 */
-
-	netif_start_queue(dev);
-	return 0;
-}
-
-
-/******************************************************
- *
- * send a packet to the adapter
- *
- ******************************************************/
-
-static netdev_tx_t send_packet(struct net_device *dev, struct sk_buff *skb)
-{
-	elp_device *adapter = netdev_priv(dev);
-	unsigned long target;
-	unsigned long flags;
-
-	/*
-	 * make sure the length is even and no shorter than 60 bytes
-	 */
-	unsigned int nlen = (((skb->len < 60) ? 60 : skb->len) + 1) & (~1);
-
-	if (test_and_set_bit(0, (void *) &adapter->busy)) {
-		if (elp_debug >= 2)
-			pr_debug("%s: transmit blocked\n", dev->name);
-		return false;
-	}
-
-	dev->stats.tx_bytes += nlen;
-
-	/*
-	 * send the adapter a transmit packet command. Ignore segment and offset
-	 * and make sure the length is even
-	 */
-	adapter->tx_pcb.command = CMD_TRANSMIT_PACKET;
-	adapter->tx_pcb.length = sizeof(struct Xmit_pkt);
-	adapter->tx_pcb.data.xmit_pkt.buf_ofs
-	    = adapter->tx_pcb.data.xmit_pkt.buf_seg = 0;	/* Unused */
-	adapter->tx_pcb.data.xmit_pkt.pkt_len = nlen;
-
-	if (!send_pcb(dev, &adapter->tx_pcb)) {
-		adapter->busy = 0;
-		return false;
-	}
-	/* if this happens, we die */
-	if (test_and_set_bit(0, (void *) &adapter->dmaing))
-		pr_debug("%s: tx: DMA %d in progress\n", dev->name, adapter->current_dma.direction);
-
-	adapter->current_dma.direction = 1;
-	adapter->current_dma.start_time = jiffies;
-
-	if ((unsigned long)(skb->data + nlen) >= MAX_DMA_ADDRESS || nlen != skb->len) {
-		skb_copy_from_linear_data(skb, adapter->dma_buffer, nlen);
-		memset(adapter->dma_buffer+skb->len, 0, nlen-skb->len);
-		target = isa_virt_to_bus(adapter->dma_buffer);
-	}
-	else {
-		target = isa_virt_to_bus(skb->data);
-	}
-	adapter->current_dma.skb = skb;
-
-	flags=claim_dma_lock();
-	disable_dma(dev->dma);
-	clear_dma_ff(dev->dma);
-	set_dma_mode(dev->dma, 0x48);	/* dma memory -> io */
-	set_dma_addr(dev->dma, target);
-	set_dma_count(dev->dma, nlen);
-	outb_control(adapter->hcr_val | DMAE | TCEN, dev);
-	enable_dma(dev->dma);
-	release_dma_lock(flags);
-
-	if (elp_debug >= 3)
-		pr_debug("%s: DMA transfer started\n", dev->name);
-
-	return true;
-}
-
-/*
- *	The upper layer thinks we timed out
- */
-
-static void elp_timeout(struct net_device *dev)
-{
-	int stat;
-
-	stat = inb_status(dev->base_addr);
-	pr_warning("%s: transmit timed out, lost %s?\n", dev->name,
-		   (stat & ACRF) ? "interrupt" : "command");
-	if (elp_debug >= 1)
-		pr_debug("%s: status %#02x\n", dev->name, stat);
-	dev->trans_start = jiffies; /* prevent tx timeout */
-	dev->stats.tx_dropped++;
-	netif_wake_queue(dev);
-}
-
-/******************************************************
- *
- * start the transmitter
- *    return 0 if sent OK, else return 1
- *
- ******************************************************/
-
-static netdev_tx_t elp_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	unsigned long flags;
-	elp_device *adapter = netdev_priv(dev);
-
-	spin_lock_irqsave(&adapter->lock, flags);
-	check_3c505_dma(dev);
-
-	if (elp_debug >= 3)
-		pr_debug("%s: request to send packet of length %d\n", dev->name, (int) skb->len);
-
-	netif_stop_queue(dev);
-
-	/*
-	 * send the packet at skb->data for skb->len
-	 */
-	if (!send_packet(dev, skb)) {
-		if (elp_debug >= 2) {
-			pr_debug("%s: failed to transmit packet\n", dev->name);
-		}
-		spin_unlock_irqrestore(&adapter->lock, flags);
-		return NETDEV_TX_BUSY;
-	}
-	if (elp_debug >= 3)
-		pr_debug("%s: packet of length %d sent\n", dev->name, (int) skb->len);
-
-	prime_rx(dev);
-	spin_unlock_irqrestore(&adapter->lock, flags);
-	netif_start_queue(dev);
-	return NETDEV_TX_OK;
-}
-
-/******************************************************
- *
- * return statistics on the board
- *
- ******************************************************/
-
-static struct net_device_stats *elp_get_stats(struct net_device *dev)
-{
-	elp_device *adapter = netdev_priv(dev);
-
-	if (elp_debug >= 3)
-		pr_debug("%s: request for stats\n", dev->name);
-
-	/* If the device is closed, just return the latest stats we have,
-	   - we cannot ask from the adapter without interrupts */
-	if (!netif_running(dev))
-		return &dev->stats;
-
-	/* send a get statistics command to the board */
-	adapter->tx_pcb.command = CMD_NETWORK_STATISTICS;
-	adapter->tx_pcb.length = 0;
-	adapter->got[CMD_NETWORK_STATISTICS] = 0;
-	if (!send_pcb(dev, &adapter->tx_pcb))
-		pr_err("%s: couldn't send get statistics command\n", dev->name);
-	else {
-		unsigned long timeout = jiffies + TIMEOUT;
-		while (adapter->got[CMD_NETWORK_STATISTICS] == 0 && time_before(jiffies, timeout));
-		if (time_after_eq(jiffies, timeout)) {
-			TIMEOUT_MSG(__LINE__);
-			return &dev->stats;
-		}
-	}
-
-	/* statistics are now up to date */
-	return &dev->stats;
-}
-
-
-static void netdev_get_drvinfo(struct net_device *dev,
-			       struct ethtool_drvinfo *info)
-{
-	strcpy(info->driver, DRV_NAME);
-	strcpy(info->version, DRV_VERSION);
-	sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
-	return debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
-	debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
-	.get_drvinfo		= netdev_get_drvinfo,
-	.get_msglevel		= netdev_get_msglevel,
-	.set_msglevel		= netdev_set_msglevel,
-};
-
-/******************************************************
- *
- * close the board
- *
- ******************************************************/
-
-static int elp_close(struct net_device *dev)
-{
-	elp_device *adapter = netdev_priv(dev);
-
-	if (elp_debug >= 3)
-		pr_debug("%s: request to close device\n", dev->name);
-
-	netif_stop_queue(dev);
-
-	/* Someone may request the device statistic information even when
-	 * the interface is closed. The following will update the statistics
-	 * structure in the driver, so we'll be able to give current statistics.
-	 */
-	(void) elp_get_stats(dev);
-
-	/*
-	 * disable interrupts on the board
-	 */
-	outb_control(0, dev);
-
-	/*
-	 * release the IRQ
-	 */
-	free_irq(dev->irq, dev);
-
-	free_dma(dev->dma);
-	free_pages((unsigned long) adapter->dma_buffer, get_order(DMA_BUFFER_SIZE));
-
-	return 0;
-}
-
-
-/************************************************************
- *
- * Set multicast list
- * num_addrs==0: clear mc_list
- * num_addrs==-1: set promiscuous mode
- * num_addrs>0: set mc_list
- *
- ************************************************************/
-
-static void elp_set_mc_list(struct net_device *dev)
-{
-	elp_device *adapter = netdev_priv(dev);
-	struct netdev_hw_addr *ha;
-	int i;
-	unsigned long flags;
-
-	if (elp_debug >= 3)
-		pr_debug("%s: request to set multicast list\n", dev->name);
-
-	spin_lock_irqsave(&adapter->lock, flags);
-
-	if (!(dev->flags & (IFF_PROMISC | IFF_ALLMULTI))) {
-		/* send a "load multicast list" command to the board, max 10 addrs/cmd */
-		/* if num_addrs==0 the list will be cleared */
-		adapter->tx_pcb.command = CMD_LOAD_MULTICAST_LIST;
-		adapter->tx_pcb.length = 6 * netdev_mc_count(dev);
-		i = 0;
-		netdev_for_each_mc_addr(ha, dev)
-			memcpy(adapter->tx_pcb.data.multicast[i++],
-			       ha->addr, 6);
-		adapter->got[CMD_LOAD_MULTICAST_LIST] = 0;
-		if (!send_pcb(dev, &adapter->tx_pcb))
-			pr_err("%s: couldn't send set_multicast command\n", dev->name);
-		else {
-			unsigned long timeout = jiffies + TIMEOUT;
-			while (adapter->got[CMD_LOAD_MULTICAST_LIST] == 0 && time_before(jiffies, timeout));
-			if (time_after_eq(jiffies, timeout)) {
-				TIMEOUT_MSG(__LINE__);
-			}
-		}
-		if (!netdev_mc_empty(dev))
-			adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD | RECV_MULTI;
-		else		/* num_addrs == 0 */
-			adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_BROAD;
-	} else
-		adapter->tx_pcb.data.configure = NO_LOOPBACK | RECV_PROMISC;
-	/*
-	 * configure adapter to receive messages (as specified above)
-	 * and wait for response
-	 */
-	if (elp_debug >= 3)
-		pr_debug("%s: sending 82586 configure command\n", dev->name);
-	adapter->tx_pcb.command = CMD_CONFIGURE_82586;
-	adapter->tx_pcb.length = 2;
-	adapter->got[CMD_CONFIGURE_82586] = 0;
-	if (!send_pcb(dev, &adapter->tx_pcb))
-	{
-		spin_unlock_irqrestore(&adapter->lock, flags);
-		pr_err("%s: couldn't send 82586 configure command\n", dev->name);
-	}
-	else {
-		unsigned long timeout = jiffies + TIMEOUT;
-		spin_unlock_irqrestore(&adapter->lock, flags);
-		while (adapter->got[CMD_CONFIGURE_82586] == 0 && time_before(jiffies, timeout));
-		if (time_after_eq(jiffies, timeout))
-			TIMEOUT_MSG(__LINE__);
-	}
-}
-
-/************************************************************
- *
- * A couple of tests to see if there's 3C505 or not
- * Called only by elp_autodetect
- ************************************************************/
-
-static int __init elp_sense(struct net_device *dev)
-{
-	int addr = dev->base_addr;
-	const char *name = dev->name;
-	byte orig_HSR;
-
-	if (!request_region(addr, ELP_IO_EXTENT, "3c505"))
-		return -ENODEV;
-
-	orig_HSR = inb_status(addr);
-
-	if (elp_debug > 0)
-		pr_debug(search_msg, name, addr);
-
-	if (orig_HSR == 0xff) {
-		if (elp_debug > 0)
-			pr_cont(notfound_msg, 1);
-		goto out;
-	}
-
-	/* Wait for a while; the adapter may still be booting up */
-	if (elp_debug > 0)
-		pr_cont(stilllooking_msg);
-
-	if (orig_HSR & DIR) {
-		/* If HCR.DIR is up, we pull it down. HSR.DIR should follow. */
-		outb(0, dev->base_addr + PORT_CONTROL);
-		msleep(300);
-		if (inb_status(addr) & DIR) {
-			if (elp_debug > 0)
-				pr_cont(notfound_msg, 2);
-			goto out;
-		}
-	} else {
-		/* If HCR.DIR is down, we pull it up. HSR.DIR should follow. */
-		outb(DIR, dev->base_addr + PORT_CONTROL);
-		msleep(300);
-		if (!(inb_status(addr) & DIR)) {
-			if (elp_debug > 0)
-				pr_cont(notfound_msg, 3);
-			goto out;
-		}
-	}
-	/*
-	 * It certainly looks like a 3c505.
-	 */
-	if (elp_debug > 0)
-		pr_cont(found_msg);
-
-	return 0;
-out:
-	release_region(addr, ELP_IO_EXTENT);
-	return -ENODEV;
-}
-
-/*************************************************************
- *
- * Search through addr_list[] and try to find a 3C505
- * Called only by eplus_probe
- *************************************************************/
-
-static int __init elp_autodetect(struct net_device *dev)
-{
-	int idx = 0;
-
-	/* if base address set, then only check that address
-	   otherwise, run through the table */
-	if (dev->base_addr != 0) {	/* dev->base_addr == 0 ==> plain autodetect */
-		if (elp_sense(dev) == 0)
-			return dev->base_addr;
-	} else
-		while ((dev->base_addr = addr_list[idx++])) {
-			if (elp_sense(dev) == 0)
-				return dev->base_addr;
-		}
-
-	/* could not find an adapter */
-	if (elp_debug > 0)
-		pr_debug(couldnot_msg, dev->name);
-
-	return 0;		/* Because of this, the layer above will return -ENODEV */
-}
-
-static const struct net_device_ops elp_netdev_ops = {
-	.ndo_open		= elp_open,
-	.ndo_stop		= elp_close,
-	.ndo_get_stats 		= elp_get_stats,
-	.ndo_start_xmit		= elp_start_xmit,
-	.ndo_tx_timeout 	= elp_timeout,
-	.ndo_set_multicast_list = elp_set_mc_list,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-/******************************************************
- *
- * probe for an Etherlink Plus board at the specified address
- *
- ******************************************************/
-
-/* There are three situations we need to be able to detect here:
-
- *  a) the card is idle
- *  b) the card is still booting up
- *  c) the card is stuck in a strange state (some DOS drivers do this)
- *
- * In case (a), all is well.  In case (b), we wait 10 seconds to see if the
- * card finishes booting, and carry on if so.  In case (c), we do a hard reset,
- * loop round, and hope for the best.
- *
- * This is all very unpleasant, but hopefully avoids the problems with the old
- * probe code (which had a 15-second delay if the card was idle, and didn't
- * work at all if it was in a weird state).
- */
-
-static int __init elplus_setup(struct net_device *dev)
-{
-	elp_device *adapter = netdev_priv(dev);
-	int i, tries, tries1, okay;
-	unsigned long timeout;
-	unsigned long cookie = 0;
-	int err = -ENODEV;
-
-	/*
-	 *  setup adapter structure
-	 */
-
-	dev->base_addr = elp_autodetect(dev);
-	if (!dev->base_addr)
-		return -ENODEV;
-
-	adapter->send_pcb_semaphore = 0;
-
-	for (tries1 = 0; tries1 < 3; tries1++) {
-		outb_control((adapter->hcr_val | CMDE) & ~DIR, dev);
-		/* First try to write just one byte, to see if the card is
-		 * responding at all normally.
-		 */
-		timeout = jiffies + 5*HZ/100;
-		okay = 0;
-		while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE));
-		if ((inb_status(dev->base_addr) & HCRE)) {
-			outb_command(0, dev->base_addr);	/* send a spurious byte */
-			timeout = jiffies + 5*HZ/100;
-			while (time_before(jiffies, timeout) && !(inb_status(dev->base_addr) & HCRE));
-			if (inb_status(dev->base_addr) & HCRE)
-				okay = 1;
-		}
-		if (!okay) {
-			/* Nope, it's ignoring the command register.  This means that
-			 * either it's still booting up, or it's died.
-			 */
-			pr_err("%s: command register wouldn't drain, ", dev->name);
-			if ((inb_status(dev->base_addr) & 7) == 3) {
-				/* If the adapter status is 3, it *could* still be booting.
-				 * Give it the benefit of the doubt for 10 seconds.
-				 */
-				pr_cont("assuming 3c505 still starting\n");
-				timeout = jiffies + 10*HZ;
-				while (time_before(jiffies, timeout) && (inb_status(dev->base_addr) & 7));
-				if (inb_status(dev->base_addr) & 7) {
-					pr_err("%s: 3c505 failed to start\n", dev->name);
-				} else {
-					okay = 1;  /* It started */
-				}
-			} else {
-				/* Otherwise, it must just be in a strange
-				 * state.  We probably need to kick it.
-				 */
-				pr_cont("3c505 is sulking\n");
-			}
-		}
-		for (tries = 0; tries < 5 && okay; tries++) {
-
-			/*
-			 * Try to set the Ethernet address, to make sure that the board
-			 * is working.
-			 */
-			adapter->tx_pcb.command = CMD_STATION_ADDRESS;
-			adapter->tx_pcb.length = 0;
-			cookie = probe_irq_on();
-			if (!send_pcb(dev, &adapter->tx_pcb)) {
-				pr_err("%s: could not send first PCB\n", dev->name);
-				probe_irq_off(cookie);
-				continue;
-			}
-			if (!receive_pcb(dev, &adapter->rx_pcb)) {
-				pr_err("%s: could not read first PCB\n", dev->name);
-				probe_irq_off(cookie);
-				continue;
-			}
-			if ((adapter->rx_pcb.command != CMD_ADDRESS_RESPONSE) ||
-			    (adapter->rx_pcb.length != 6)) {
-				pr_err("%s: first PCB wrong (%d, %d)\n", dev->name,
-					adapter->rx_pcb.command, adapter->rx_pcb.length);
-				probe_irq_off(cookie);
-				continue;
-			}
-			goto okay;
-		}
-		/* It's broken.  Do a hard reset to re-initialise the board,
-		 * and try again.
-		 */
-		pr_info("%s: resetting adapter\n", dev->name);
-		outb_control(adapter->hcr_val | FLSH | ATTN, dev);
-		outb_control(adapter->hcr_val & ~(FLSH | ATTN), dev);
-	}
-	pr_err("%s: failed to initialise 3c505\n", dev->name);
-	goto out;
-
-      okay:
-	if (dev->irq) {		/* Is there a preset IRQ? */
-		int rpt = probe_irq_off(cookie);
-		if (dev->irq != rpt) {
-			pr_warning("%s: warning, irq %d configured but %d detected\n", dev->name, dev->irq, rpt);
-		}
-		/* if dev->irq == probe_irq_off(cookie), all is well */
-	} else		       /* No preset IRQ; just use what we can detect */
-		dev->irq = probe_irq_off(cookie);
-	switch (dev->irq) {    /* Legal, sane? */
-	case 0:
-		pr_err("%s: IRQ probe failed: check 3c505 jumpers.\n",
-		       dev->name);
-		goto out;
-	case 1:
-	case 6:
-	case 8:
-	case 13:
-		pr_err("%s: Impossible IRQ %d reported by probe_irq_off().\n",
-		       dev->name, dev->irq);
-		       goto out;
-	}
-	/*
-	 *  Now we have the IRQ number so we can disable the interrupts from
-	 *  the board until the board is opened.
-	 */
-	outb_control(adapter->hcr_val & ~CMDE, dev);
-
-	/*
-	 * copy Ethernet address into structure
-	 */
-	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = adapter->rx_pcb.data.eth_addr[i];
-
-	/* find a DMA channel */
-	if (!dev->dma) {
-		if (dev->mem_start) {
-			dev->dma = dev->mem_start & 7;
-		}
-		else {
-			pr_warning("%s: warning, DMA channel not specified, using default\n", dev->name);
-			dev->dma = ELP_DMA;
-		}
-	}
-
-	/*
-	 * print remainder of startup message
-	 */
-	pr_info("%s: 3c505 at %#lx, irq %d, dma %d, addr %pM, ",
-		dev->name, dev->base_addr, dev->irq, dev->dma, dev->dev_addr);
-	/*
-	 * read more information from the adapter
-	 */
-
-	adapter->tx_pcb.command = CMD_ADAPTER_INFO;
-	adapter->tx_pcb.length = 0;
-	if (!send_pcb(dev, &adapter->tx_pcb) ||
-	    !receive_pcb(dev, &adapter->rx_pcb) ||
-	    (adapter->rx_pcb.command != CMD_ADAPTER_INFO_RESPONSE) ||
-	    (adapter->rx_pcb.length != 10)) {
-		pr_cont("not responding to second PCB\n");
-	}
-	pr_cont("rev %d.%d, %dk\n", adapter->rx_pcb.data.info.major_vers,
-		adapter->rx_pcb.data.info.minor_vers, adapter->rx_pcb.data.info.RAM_sz);
-
-	/*
-	 * reconfigure the adapter memory to better suit our purposes
-	 */
-	adapter->tx_pcb.command = CMD_CONFIGURE_ADAPTER_MEMORY;
-	adapter->tx_pcb.length = 12;
-	adapter->tx_pcb.data.memconf.cmd_q = 8;
-	adapter->tx_pcb.data.memconf.rcv_q = 8;
-	adapter->tx_pcb.data.memconf.mcast = 10;
-	adapter->tx_pcb.data.memconf.frame = 10;
-	adapter->tx_pcb.data.memconf.rcv_b = 10;
-	adapter->tx_pcb.data.memconf.progs = 0;
-	if (!send_pcb(dev, &adapter->tx_pcb) ||
-	    !receive_pcb(dev, &adapter->rx_pcb) ||
-	    (adapter->rx_pcb.command != CMD_CONFIGURE_ADAPTER_RESPONSE) ||
-	    (adapter->rx_pcb.length != 2)) {
-		pr_err("%s: could not configure adapter memory\n", dev->name);
-	}
-	if (adapter->rx_pcb.data.configure) {
-		pr_err("%s: adapter configuration failed\n", dev->name);
-	}
-
-	dev->netdev_ops = &elp_netdev_ops;
-	dev->watchdog_timeo = 10*HZ;
-	dev->ethtool_ops = &netdev_ethtool_ops;		/* local */
-
-	dev->mem_start = dev->mem_end = 0;
-
-	err = register_netdev(dev);
-	if (err)
-		goto out;
-
-	return 0;
-out:
-	release_region(dev->base_addr, ELP_IO_EXTENT);
-	return err;
-}
-
-#ifndef MODULE
-struct net_device * __init elplus_probe(int unit)
-{
-	struct net_device *dev = alloc_etherdev(sizeof(elp_device));
-	int err;
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	sprintf(dev->name, "eth%d", unit);
-	netdev_boot_setup_check(dev);
-
-	err = elplus_setup(dev);
-	if (err) {
-		free_netdev(dev);
-		return ERR_PTR(err);
-	}
-	return dev;
-}
-
-#else
-static struct net_device *dev_3c505[ELP_MAX_CARDS];
-static int io[ELP_MAX_CARDS];
-static int irq[ELP_MAX_CARDS];
-static int dma[ELP_MAX_CARDS];
-module_param_array(io, int, NULL, 0);
-module_param_array(irq, int, NULL, 0);
-module_param_array(dma, int, NULL, 0);
-MODULE_PARM_DESC(io, "EtherLink Plus I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherLink Plus IRQ number(s) (assigned)");
-MODULE_PARM_DESC(dma, "EtherLink Plus DMA channel(s)");
-
-int __init init_module(void)
-{
-	int this_dev, found = 0;
-
-	for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
-		struct net_device *dev = alloc_etherdev(sizeof(elp_device));
-		if (!dev)
-			break;
-
-		dev->irq = irq[this_dev];
-		dev->base_addr = io[this_dev];
-		if (dma[this_dev]) {
-			dev->dma = dma[this_dev];
-		} else {
-			dev->dma = ELP_DMA;
-			pr_warning("3c505.c: warning, using default DMA channel,\n");
-		}
-		if (io[this_dev] == 0) {
-			if (this_dev) {
-				free_netdev(dev);
-				break;
-			}
-			pr_notice("3c505.c: module autoprobe not recommended, give io=xx.\n");
-		}
-		if (elplus_setup(dev) != 0) {
-			pr_warning("3c505.c: Failed to register card at 0x%x.\n", io[this_dev]);
-			free_netdev(dev);
-			break;
-		}
-		dev_3c505[this_dev] = dev;
-		found++;
-	}
-	if (!found)
-		return -ENODEV;
-	return 0;
-}
-
-void __exit cleanup_module(void)
-{
-	int this_dev;
-
-	for (this_dev = 0; this_dev < ELP_MAX_CARDS; this_dev++) {
-		struct net_device *dev = dev_3c505[this_dev];
-		if (dev) {
-			unregister_netdev(dev);
-			release_region(dev->base_addr, ELP_IO_EXTENT);
-			free_netdev(dev);
-		}
-	}
-}
-
-#endif				/* MODULE */
-MODULE_LICENSE("GPL");

+ 0 - 1594
drivers/net/3c509.c

@@ -1,1594 +0,0 @@
-/* 3c509.c: A 3c509 EtherLink3 ethernet driver for linux. */
-/*
-	Written 1993-2000 by Donald Becker.
-
-	Copyright 1994-2000 by Donald Becker.
-	Copyright 1993 United States Government as represented by the
-	Director, National Security Agency.	 This software may be used and
-	distributed according to the terms of the GNU General Public License,
-	incorporated herein by reference.
-
-	This driver is for the 3Com EtherLinkIII series.
-
-	The author may be reached as becker@scyld.com, or C/O
-	Scyld Computing Corporation
-	410 Severn Ave., Suite 210
-	Annapolis MD 21403
-
-	Known limitations:
-	Because of the way 3c509 ISA detection works it's difficult to predict
-	a priori which of several ISA-mode cards will be detected first.
-
-	This driver does not use predictive interrupt mode, resulting in higher
-	packet latency but lower overhead.  If interrupts are disabled for an
-	unusually long time it could also result in missed packets, but in
-	practice this rarely happens.
-
-
-	FIXES:
-		Alan Cox:       Removed the 'Unexpected interrupt' bug.
-		Michael Meskes:	Upgraded to Donald Becker's version 1.07.
-		Alan Cox:	Increased the eeprom delay. Regardless of
-				what the docs say some people definitely
-				get problems with lower (but in card spec)
-				delays
-		v1.10 4/21/97 Fixed module code so that multiple cards may be detected,
-				other cleanups.  -djb
-		Andrea Arcangeli:	Upgraded to Donald Becker's version 1.12.
-		Rick Payne:	Fixed SMP race condition
-		v1.13 9/8/97 Made 'max_interrupt_work' an insmod-settable variable -djb
-		v1.14 10/15/97 Avoided waiting..discard message for fast machines -djb
-		v1.15 1/31/98 Faster recovery for Tx errors. -djb
-		v1.16 2/3/98 Different ID port handling to avoid sound cards. -djb
-		v1.18 12Mar2001 Andrew Morton
-			- Avoid bogus detect of 3c590's (Andrzej Krzysztofowicz)
-			- Reviewed against 1.18 from scyld.com
-		v1.18a 17Nov2001 Jeff Garzik <jgarzik@pobox.com>
-			- ethtool support
-		v1.18b 1Mar2002 Zwane Mwaikambo <zwane@commfireservices.com>
-			- Power Management support
-		v1.18c 1Mar2002 David Ruggiero <jdr@farfalle.com>
-			- Full duplex support
-		v1.19  16Oct2002 Zwane Mwaikambo <zwane@linuxpower.ca>
-			- Additional ethtool features
-		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.
-		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.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)
-
-#include <linux/module.h>
-#include <linux/mca.h>
-#include <linux/isa.h>
-#include <linux/pnp.h>
-#include <linux/string.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/pm.h>
-#include <linux/skbuff.h>
-#include <linux/delay.h>	/* for udelay() */
-#include <linux/spinlock.h>
-#include <linux/ethtool.h>
-#include <linux/device.h>
-#include <linux/eisa.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-
-static char version[] __devinitdata = DRV_NAME ".c:" DRV_VERSION " " DRV_RELDATE " becker@scyld.com\n";
-
-#ifdef EL3_DEBUG
-static int el3_debug = EL3_DEBUG;
-#else
-static int el3_debug = 2;
-#endif
-
-/* Used to do a global count of all the cards in the system.  Must be
- * 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
-   anyway if you want to understand driver details. */
-/* Offsets from base I/O address. */
-#define EL3_DATA 0x00
-#define EL3_CMD 0x0e
-#define EL3_STATUS 0x0e
-#define	EEPROM_READ 0x80
-
-#define EL3_IO_EXTENT	16
-
-#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
-
-
-/* The top five bits written to EL3_CMD are a command, the lower
-   11 bits are the parameter, if applicable. */
-enum c509cmd {
-	TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
-	RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
-	TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
-	FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
-	SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
-	SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
-	StatsDisable = 22<<11, StopCoax = 23<<11, PowerUp = 27<<11,
-	PowerDown = 28<<11, PowerAuto = 29<<11};
-
-enum c509status {
-	IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
-	TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
-	IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000, };
-
-/* The SetRxFilter command accepts the following classes: */
-enum RxFilter {
-	RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
-
-/* Register window 1 offsets, the window used in normal operation. */
-#define TX_FIFO		0x00
-#define RX_FIFO		0x00
-#define RX_STATUS 	0x08
-#define TX_STATUS 	0x0B
-#define TX_FREE		0x0C		/* Remaining free bytes in Tx buffer. */
-
-#define WN0_CONF_CTRL	0x04		/* Window 0: Configuration control register */
-#define WN0_ADDR_CONF	0x06		/* Window 0: Address configuration register */
-#define WN0_IRQ		0x08		/* Window 0: Set IRQ line in bits 12-15. */
-#define WN4_MEDIA	0x0A		/* Window 4: Various transcvr/media bits. */
-#define	MEDIA_TP	0x00C0		/* Enable link beat and jabber for 10baseT. */
-#define WN4_NETDIAG	0x06		/* Window 4: Net diagnostic */
-#define FD_ENABLE	0x8000		/* Enable full-duplex ("external loopback") */
-
-/*
- * Must be a power of two (we use a binary and in the
- * circular queue)
- */
-#define SKB_QUEUE_SIZE	64
-
-enum el3_cardtype { EL3_ISA, EL3_PNP, EL3_MCA, EL3_EISA };
-
-struct el3_private {
-	spinlock_t lock;
-	/* skb send-queue */
-	int head, size;
-	struct sk_buff *queue[SKB_QUEUE_SIZE];
-	enum el3_cardtype type;
-};
-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 __devinit 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);
-static netdev_tx_t el3_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t el3_interrupt(int irq, void *dev_id);
-static void update_stats(struct net_device *dev);
-static struct net_device_stats *el3_get_stats(struct net_device *dev);
-static int el3_rx(struct net_device *dev);
-static int el3_close(struct net_device *dev);
-static void set_multicast_list(struct net_device *dev);
-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 CONFIG_PM
-static int el3_suspend(struct device *, pm_message_t);
-static int el3_resume(struct device *);
-#else
-#define el3_suspend NULL
-#define el3_resume NULL
-#endif
-
-
-/* generic device remove for all device types */
-static int el3_device_remove (struct device *device);
-#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)
-					pr_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;
-	__be16 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[] = {
-		{ "TCM5090" },
-		{ "TCM5091" },
-		{ "TCM5092" },
-		{ "TCM5093" },
-		{ "TCM5094" },
-		{ "TCM5095" },
-		{ "TCM5098" },
-		{ "" }
-};
-MODULE_DEVICE_TABLE(eisa, el3_eisa_ids);
-
-static int el3_eisa_probe (struct device *device);
-
-static struct eisa_driver el3_eisa_driver = {
-		.id_table = el3_eisa_ids,
-		.driver   = {
-				.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
-static int el3_mca_probe(struct device *dev);
-
-static short el3_mca_adapter_ids[] __initdata = {
-		0x627c,
-		0x627d,
-		0x62db,
-		0x62f6,
-		0x62f7,
-		0x0000
-};
-
-static char *el3_mca_adapter_names[] __initdata = {
-		"3Com 3c529 EtherLink III (10base2)",
-		"3Com 3c529 EtherLink III (10baseT)",
-		"3Com 3c529 EtherLink III (test mode)",
-		"3Com 3c529 EtherLink III (TP or coax)",
-		"3Com 3c529 EtherLink III (TP)",
-		NULL
-};
-
-static struct mca_driver el3_mca_driver = {
-		.id_table = el3_mca_adapter_ids,
-		.driver = {
-				.name = "3c529",
-				.bus = &mca_bus_type,
-				.probe = el3_mca_probe,
-				.remove = __devexit_p(el3_device_remove),
-				.suspend = el3_suspend,
-				.resume  = el3_resume,
-		},
-};
-static int mca_registered;
-#endif /* CONFIG_MCA */
-
-static const struct net_device_ops netdev_ops = {
-	.ndo_open 		= el3_open,
-	.ndo_stop	 	= el3_close,
-	.ndo_start_xmit 	= el3_start_xmit,
-	.ndo_get_stats 		= el3_get_stats,
-	.ndo_set_multicast_list = set_multicast_list,
-	.ndo_tx_timeout 	= el3_tx_timeout,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= el3_poll_controller,
-#endif
-};
-
-static int __devinit el3_common_init(struct net_device *dev)
-{
-	struct el3_private *lp = netdev_priv(dev);
-	int err;
-	const char *if_names[] = {"10baseT", "AUI", "undefined", "BNC"};
-
-	spin_lock_init(&lp->lock);
-
-	if (dev->mem_start & 0x05) { /* xcvr codes 1/3/4/12 */
-		dev->if_port = (dev->mem_start & 0x0f);
-	} else { /* xcvr codes 0/8 */
-		/* use eeprom value, but save user's full-duplex selection */
-		dev->if_port |= (dev->mem_start & 0x08);
-	}
-
-	/* The EL3-specific entries in the device structure. */
-	dev->netdev_ops = &netdev_ops;
-	dev->watchdog_timeo = TX_TIMEOUT;
-	SET_ETHTOOL_OPS(dev, &ethtool_ops);
-
-	err = register_netdev(dev);
-	if (err) {
-		pr_err("Failed to register 3c5x9 at %#3.3lx, IRQ %d.\n",
-			dev->base_addr, dev->irq);
-		release_region(dev->base_addr, EL3_IO_EXTENT);
-		return err;
-	}
-
-	pr_info("%s: 3c5x9 found at %#3.3lx, %s port, address %pM, IRQ %d.\n",
-	       dev->name, dev->base_addr, if_names[(dev->if_port & 0x03)],
-	       dev->dev_addr, dev->irq);
-
-	if (el3_debug > 0)
-		pr_info("%s", version);
-	return 0;
-
-}
-
-static void el3_common_remove (struct net_device *dev)
-{
-	unregister_netdev (dev);
-	release_region(dev->base_addr, EL3_IO_EXTENT);
-	free_netdev (dev);
-}
-
-#ifdef CONFIG_MCA
-static int __init el3_mca_probe(struct device *device)
-{
-	/* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch,
-	 * heavily modified by Chris Beauregard
-	 * (cpbeaure@csclub.uwaterloo.ca) to support standard MCA
-	 * probing.
-	 *
-	 * redone for multi-card detection by ZP Gu (zpg@castle.net)
-	 * now works as a module */
-
-	short i;
-	int ioaddr, irq, if_port;
-	__be16 phys_addr[3];
-	struct net_device *dev = NULL;
-	u_char pos4, pos5;
-	struct mca_device *mdev = to_mca_device(device);
-	int slot = mdev->slot;
-	int err;
-
-	pos4 = mca_device_read_stored_pos(mdev, 4);
-	pos5 = mca_device_read_stored_pos(mdev, 5);
-
-	ioaddr = ((short)((pos4&0xfc)|0x02)) << 8;
-	irq = pos5 & 0x0f;
-
-
-	pr_info("3c529: found %s at slot %d\n",
-		el3_mca_adapter_names[mdev->index], slot + 1);
-
-	/* claim the slot */
-	strncpy(mdev->name, el3_mca_adapter_names[mdev->index],
-			sizeof(mdev->name));
-	mca_device_set_claim(mdev, 1);
-
-	if_port = pos4 & 0x03;
-
-	irq = mca_device_transform_irq(mdev, irq);
-	ioaddr = mca_device_transform_ioport(mdev, ioaddr);
-	if (el3_debug > 2) {
-		pr_debug("3c529: irq %d  ioaddr 0x%x  ifport %d\n", irq, ioaddr, if_port);
-	}
-	EL3WINDOW(0);
-	for (i = 0; i < 3; i++)
-		phys_addr[i] = htons(read_eeprom(ioaddr, i));
-
-	dev = alloc_etherdev(sizeof (struct el3_private));
-	if (dev == NULL) {
-		release_region(ioaddr, EL3_IO_EXTENT);
-		return -ENOMEM;
-	}
-
-	netdev_boot_setup_check(dev);
-
-	el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_MCA);
-	dev_set_drvdata(device, dev);
-	err = el3_common_init(dev);
-
-	if (err) {
-		dev_set_drvdata(device, NULL);
-		free_netdev(dev);
-		return -ENOMEM;
-	}
-
-	el3_devs[el3_cards++] = dev;
-	return 0;
-}
-
-#endif /* CONFIG_MCA */
-
-#ifdef CONFIG_EISA
-static int __init el3_eisa_probe (struct device *device)
-{
-	short i;
-	int ioaddr, irq, if_port;
-	__be16 phys_addr[3];
-	struct net_device *dev = NULL;
-	struct eisa_device *edev;
-	int err;
-
-	/* Yeepee, The driver framework is calling us ! */
-	edev = to_eisa_device (device);
-	ioaddr = edev->base_addr;
-
-	if (!request_region(ioaddr, EL3_IO_EXTENT, "3c579-eisa"))
-		return -EBUSY;
-
-	/* Change the register set to the configuration window 0. */
-	outw(SelectWindow | 0, ioaddr + 0xC80 + EL3_CMD);
-
-	irq = inw(ioaddr + WN0_IRQ) >> 12;
-	if_port = inw(ioaddr + 6)>>14;
-	for (i = 0; i < 3; i++)
-		phys_addr[i] = htons(read_eeprom(ioaddr, i));
-
-	/* Restore the "Product ID" to the EEPROM read register. */
-	read_eeprom(ioaddr, 3);
-
-	dev = alloc_etherdev(sizeof (struct el3_private));
-	if (dev == NULL) {
-		release_region(ioaddr, EL3_IO_EXTENT);
-		return -ENOMEM;
-	}
-
-	netdev_boot_setup_check(dev);
-
-	el3_dev_fill(dev, phys_addr, ioaddr, irq, if_port, EL3_EISA);
-	eisa_set_drvdata (edev, dev);
-	err = el3_common_init(dev);
-
-	if (err) {
-		eisa_set_drvdata (edev, NULL);
-		free_netdev(dev);
-		return err;
-	}
-
-	el3_devs[el3_cards++] = dev;
-	return 0;
-}
-#endif
-
-/* This remove works for all device types.
- *
- * The net dev must be stored in the driver data field */
-static int __devexit el3_device_remove (struct device *device)
-{
-	struct net_device *dev;
-
-	dev = dev_get_drvdata(device);
-
-	el3_common_remove (dev);
-	return 0;
-}
-
-/* Read a word from the EEPROM using the regular EEPROM access register.
-   Assume that we are in register window zero.
- */
-static ushort read_eeprom(int ioaddr, int index)
-{
-	outw(EEPROM_READ + index, ioaddr + 10);
-	/* Pause for at least 162 us. for the read to take place.
-	   Some chips seem to require much longer */
-	mdelay(2);
-	return inw(ioaddr + 12);
-}
-
-/* Read a word from the EEPROM when in the ISA ID probe state. */
-static ushort id_read_eeprom(int index)
-{
-	int bit, word = 0;
-
-	/* Issue read command, and pause for at least 162 us. for it to complete.
-	   Assume extra-fast 16Mhz bus. */
-	outb(EEPROM_READ + index, id_port);
-
-	/* Pause for at least 162 us. for the read to take place. */
-	/* Some chips seem to require much longer */
-	mdelay(4);
-
-	for (bit = 15; bit >= 0; bit--)
-		word = (word << 1) + (inb(id_port) & 0x01);
-
-	if (el3_debug > 3)
-		pr_debug("  3c509 EEPROM word %d %#4.4x.\n", index, word);
-
-	return word;
-}
-
-
-static int
-el3_open(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-	int i;
-
-	outw(TxReset, ioaddr + EL3_CMD);
-	outw(RxReset, ioaddr + EL3_CMD);
-	outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
-
-	i = request_irq(dev->irq, el3_interrupt, 0, dev->name, dev);
-	if (i)
-		return i;
-
-	EL3WINDOW(0);
-	if (el3_debug > 3)
-		pr_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)
-		pr_debug("%s: Opened 3c509  IRQ %d  status %4.4x.\n",
-			   dev->name, dev->irq, inw(ioaddr + EL3_STATUS));
-
-	return 0;
-}
-
-static void
-el3_tx_timeout (struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-
-	/* Transmitter timeout, serious problems. */
-	pr_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));
-	dev->stats.tx_errors++;
-	dev->trans_start = jiffies; /* prevent tx timeout */
-	/* Issue TX_RESET and TX_START commands. */
-	outw(TxReset, ioaddr + EL3_CMD);
-	outw(TxEnable, ioaddr + EL3_CMD);
-	netif_wake_queue(dev);
-}
-
-
-static netdev_tx_t
-el3_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct el3_private *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-	unsigned long flags;
-
-	netif_stop_queue (dev);
-
-	dev->stats.tx_bytes += skb->len;
-
-	if (el3_debug > 4) {
-		pr_debug("%s: el3_start_xmit(length = %u) called, status %4.4x.\n",
-			   dev->name, skb->len, inw(ioaddr + EL3_STATUS));
-	}
-#if 0
-#ifndef final_version
-	{	/* Error-checking code, delete someday. */
-		ushort status = inw(ioaddr + EL3_STATUS);
-		if (status & 0x0001 && 		/* IRQ line active, missed one. */
-		    inw(ioaddr + EL3_STATUS) & 1) { 			/* Make sure. */
-			pr_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));
-			/* Fake interrupt trigger by masking, acknowledge interrupts. */
-			outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
-			outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
-				 ioaddr + EL3_CMD);
-			outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
-		}
-	}
-#endif
-#endif
-	/*
-	 *	We lock the driver against other processors. Note
-	 *	we don't need to lock versus the IRQ as we suspended
-	 *	that. This means that we lose the ability to take
-	 *	an RX during a TX upload. That sucks a bit with SMP
-	 *	on an original 3c509 (2K buffer)
-	 *
-	 *	Using disable_irq stops us crapping on other
-	 *	time sensitive devices.
-	 */
-
-	spin_lock_irqsave(&lp->lock, flags);
-
-	/* Put out the doubleword header... */
-	outw(skb->len, ioaddr + TX_FIFO);
-	outw(0x00, ioaddr + TX_FIFO);
-	/* ... and the packet rounded to a doubleword. */
-	outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
-
-	if (inw(ioaddr + TX_FREE) > 1536)
-		netif_start_queue(dev);
-	else
-		/* Interrupt us when the FIFO has room for max-sized packet. */
-		outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
-
-	spin_unlock_irqrestore(&lp->lock, flags);
-
-	dev_kfree_skb (skb);
-
-	/* Clear the Tx status stack. */
-	{
-		short tx_status;
-		int i = 4;
-
-		while (--i > 0	&&	(tx_status = inb(ioaddr + TX_STATUS)) > 0) {
-			if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
-			if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
-			if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
-			outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
-		}
-	}
-	return NETDEV_TX_OK;
-}
-
-/* The EL3 interrupt handler. */
-static irqreturn_t
-el3_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct el3_private *lp;
-	int ioaddr, status;
-	int i = max_interrupt_work;
-
-	lp = netdev_priv(dev);
-	spin_lock(&lp->lock);
-
-	ioaddr = dev->base_addr;
-
-	if (el3_debug > 4) {
-		status = inw(ioaddr + EL3_STATUS);
-		pr_debug("%s: interrupt, status %4.4x.\n", dev->name, status);
-	}
-
-	while ((status = inw(ioaddr + EL3_STATUS)) &
-		   (IntLatch | RxComplete | StatsFull)) {
-
-		if (status & RxComplete)
-			el3_rx(dev);
-
-		if (status & TxAvailable) {
-			if (el3_debug > 5)
-				pr_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);
-		}
-		if (status & (AdapterFailure | RxEarly | StatsFull | TxComplete)) {
-			/* Handle all uncommon interrupts. */
-			if (status & StatsFull)				/* Empty statistics. */
-				update_stats(dev);
-			if (status & RxEarly) {				/* Rx early is unused. */
-				el3_rx(dev);
-				outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
-			}
-			if (status & TxComplete) {			/* Really Tx error. */
-				short tx_status;
-				int i = 4;
-
-				while (--i>0 && (tx_status = inb(ioaddr + TX_STATUS)) > 0) {
-					if (tx_status & 0x38) dev->stats.tx_aborted_errors++;
-					if (tx_status & 0x30) outw(TxReset, ioaddr + EL3_CMD);
-					if (tx_status & 0x3C) outw(TxEnable, ioaddr + EL3_CMD);
-					outb(0x00, ioaddr + TX_STATUS); /* Pop the status stack. */
-				}
-			}
-			if (status & AdapterFailure) {
-				/* Adapter failure requires Rx reset and reinit. */
-				outw(RxReset, ioaddr + EL3_CMD);
-				/* Set the Rx filter to the current state. */
-				outw(SetRxFilter | RxStation | RxBroadcast
-					 | (dev->flags & IFF_ALLMULTI ? RxMulticast : 0)
-					 | (dev->flags & IFF_PROMISC ? RxProm : 0),
-					 ioaddr + EL3_CMD);
-				outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
-				outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD);
-			}
-		}
-
-		if (--i < 0) {
-			pr_err("%s: Infinite loop in interrupt, status %4.4x.\n",
-				   dev->name, status);
-			/* Clear all interrupts. */
-			outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
-			break;
-		}
-		/* Acknowledge the IRQ. */
-		outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD); /* Ack IRQ */
-	}
-
-	if (el3_debug > 4) {
-		pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name,
-			   inw(ioaddr + EL3_STATUS));
-	}
-	spin_unlock(&lp->lock);
-	return IRQ_HANDLED;
-}
-
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling receive - used by netconsole and other diagnostic tools
- * to allow network i/o with interrupts disabled.
- */
-static void el3_poll_controller(struct net_device *dev)
-{
-	disable_irq(dev->irq);
-	el3_interrupt(dev->irq, dev);
-	enable_irq(dev->irq);
-}
-#endif
-
-static struct net_device_stats *
-el3_get_stats(struct net_device *dev)
-{
-	struct el3_private *lp = netdev_priv(dev);
-	unsigned long flags;
-
-	/*
-	 *	This is fast enough not to bother with disable IRQ
-	 *	stuff.
-	 */
-
-	spin_lock_irqsave(&lp->lock, flags);
-	update_stats(dev);
-	spin_unlock_irqrestore(&lp->lock, flags);
-	return &dev->stats;
-}
-
-/*  Update statistics.  We change to register window 6, so this should be run
-	single-threaded if the device is active. This is expected to be a rare
-	operation, and it's simpler for the rest of the driver to assume that
-	window 1 is always valid rather than use a special window-state variable.
-	*/
-static void update_stats(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-
-	if (el3_debug > 5)
-		pr_debug("   Updating the statistics.\n");
-	/* Turn off statistics updates while reading. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
-	/* Switch to the stats window, and read everything. */
-	EL3WINDOW(6);
-	dev->stats.tx_carrier_errors 	+= inb(ioaddr + 0);
-	dev->stats.tx_heartbeat_errors	+= inb(ioaddr + 1);
-	/* Multiple collisions. */	   inb(ioaddr + 2);
-	dev->stats.collisions		+= inb(ioaddr + 3);
-	dev->stats.tx_window_errors	+= inb(ioaddr + 4);
-	dev->stats.rx_fifo_errors	+= inb(ioaddr + 5);
-	dev->stats.tx_packets		+= inb(ioaddr + 6);
-	/* Rx packets	*/		   inb(ioaddr + 7);
-	/* Tx deferrals */		   inb(ioaddr + 8);
-	inw(ioaddr + 10);	/* Total Rx and Tx octets. */
-	inw(ioaddr + 12);
-
-	/* Back to window 1, and turn statistics back on. */
-	EL3WINDOW(1);
-	outw(StatsEnable, ioaddr + EL3_CMD);
-}
-
-static int
-el3_rx(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-	short rx_status;
-
-	if (el3_debug > 5)
-		pr_debug("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
-			   inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
-	while ((rx_status = inw(ioaddr + RX_STATUS)) > 0) {
-		if (rx_status & 0x4000) { /* Error, update stats. */
-			short error = rx_status & 0x3800;
-
-			outw(RxDiscard, ioaddr + EL3_CMD);
-			dev->stats.rx_errors++;
-			switch (error) {
-			case 0x0000:		dev->stats.rx_over_errors++; break;
-			case 0x0800:		dev->stats.rx_length_errors++; break;
-			case 0x1000:		dev->stats.rx_frame_errors++; break;
-			case 0x1800:		dev->stats.rx_length_errors++; break;
-			case 0x2000:		dev->stats.rx_frame_errors++; break;
-			case 0x2800:		dev->stats.rx_crc_errors++; break;
-			}
-		} else {
-			short pkt_len = rx_status & 0x7ff;
-			struct sk_buff *skb;
-
-			skb = dev_alloc_skb(pkt_len+5);
-			if (el3_debug > 4)
-				pr_debug("Receiving packet size %d status %4.4x.\n",
-					   pkt_len, rx_status);
-			if (skb != NULL) {
-				skb_reserve(skb, 2);     /* Align IP on 16 byte */
-
-				/* 'skb->data' points to the start of sk_buff data area. */
-				insl(ioaddr + RX_FIFO, skb_put(skb,pkt_len),
-					 (pkt_len + 3) >> 2);
-
-				outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
-				skb->protocol = eth_type_trans(skb,dev);
-				netif_rx(skb);
-				dev->stats.rx_bytes += pkt_len;
-				dev->stats.rx_packets++;
-				continue;
-			}
-			outw(RxDiscard, ioaddr + EL3_CMD);
-			dev->stats.rx_dropped++;
-			if (el3_debug)
-				pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n",
-					   dev->name, pkt_len);
-		}
-		inw(ioaddr + EL3_STATUS); 				/* Delay. */
-		while (inw(ioaddr + EL3_STATUS) & 0x1000)
-			pr_debug("	Waiting for 3c509 to discard packet, status %x.\n",
-				   inw(ioaddr + EL3_STATUS) );
-	}
-
-	return 0;
-}
-
-/*
- *     Set or clear the multicast filter for this adaptor.
- */
-static void
-set_multicast_list(struct net_device *dev)
-{
-	unsigned long flags;
-	struct el3_private *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-	int mc_count = netdev_mc_count(dev);
-
-	if (el3_debug > 1) {
-		static int old;
-		if (old != mc_count) {
-			old = mc_count;
-			pr_debug("%s: Setting Rx mode to %d addresses.\n",
-				 dev->name, mc_count);
-		}
-	}
-	spin_lock_irqsave(&lp->lock, flags);
-	if (dev->flags&IFF_PROMISC) {
-		outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm,
-			 ioaddr + EL3_CMD);
-	}
-	else if (mc_count || (dev->flags&IFF_ALLMULTI)) {
-		outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast, ioaddr + EL3_CMD);
-	}
-	else
-		outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
-	spin_unlock_irqrestore(&lp->lock, flags);
-}
-
-static int
-el3_close(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-	struct el3_private *lp = netdev_priv(dev);
-
-	if (el3_debug > 2)
-		pr_debug("%s: Shutting down ethercard.\n", dev->name);
-
-	el3_down(dev);
-
-	free_irq(dev->irq, dev);
-	/* Switching back to window 0 disables the IRQ. */
-	EL3WINDOW(0);
-	if (lp->type != EL3_EISA) {
-		/* But we explicitly zero the IRQ line select anyway. Don't do
-		 * it on EISA cards, it prevents the module from getting an
-		 * IRQ after unload+reload... */
-		outw(0x0f00, ioaddr + WN0_IRQ);
-	}
-
-	return 0;
-}
-
-static int
-el3_link_ok(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-	u16 tmp;
-
-	EL3WINDOW(4);
-	tmp = inw(ioaddr + WN4_MEDIA);
-	EL3WINDOW(1);
-	return tmp & (1<<11);
-}
-
-static int
-el3_netdev_get_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-	u16 tmp;
-	int ioaddr = dev->base_addr;
-
-	EL3WINDOW(0);
-	/* obtain current transceiver via WN4_MEDIA? */
-	tmp = inw(ioaddr + WN0_ADDR_CONF);
-	ecmd->transceiver = XCVR_INTERNAL;
-	switch (tmp >> 14) {
-	case 0:
-		ecmd->port = PORT_TP;
-		break;
-	case 1:
-		ecmd->port = PORT_AUI;
-		ecmd->transceiver = XCVR_EXTERNAL;
-		break;
-	case 3:
-		ecmd->port = PORT_BNC;
-	default:
-		break;
-	}
-
-	ecmd->duplex = DUPLEX_HALF;
-	ecmd->supported = 0;
-	tmp = inw(ioaddr + WN0_CONF_CTRL);
-	if (tmp & (1<<13))
-		ecmd->supported |= SUPPORTED_AUI;
-	if (tmp & (1<<12))
-		ecmd->supported |= SUPPORTED_BNC;
-	if (tmp & (1<<9)) {
-		ecmd->supported |= SUPPORTED_TP | SUPPORTED_10baseT_Half |
-				SUPPORTED_10baseT_Full;	/* hmm... */
-		EL3WINDOW(4);
-		tmp = inw(ioaddr + WN4_NETDIAG);
-		if (tmp & FD_ENABLE)
-			ecmd->duplex = DUPLEX_FULL;
-	}
-
-	ethtool_cmd_speed_set(ecmd, SPEED_10);
-	EL3WINDOW(1);
-	return 0;
-}
-
-static int
-el3_netdev_set_ecmd(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-	u16 tmp;
-	int ioaddr = dev->base_addr;
-
-	if (ecmd->speed != SPEED_10)
-		return -EINVAL;
-	if ((ecmd->duplex != DUPLEX_HALF) && (ecmd->duplex != DUPLEX_FULL))
-		return -EINVAL;
-	if ((ecmd->transceiver != XCVR_INTERNAL) && (ecmd->transceiver != XCVR_EXTERNAL))
-		return -EINVAL;
-
-	/* change XCVR type */
-	EL3WINDOW(0);
-	tmp = inw(ioaddr + WN0_ADDR_CONF);
-	switch (ecmd->port) {
-	case PORT_TP:
-		tmp &= ~(3<<14);
-		dev->if_port = 0;
-		break;
-	case PORT_AUI:
-		tmp |= (1<<14);
-		dev->if_port = 1;
-		break;
-	case PORT_BNC:
-		tmp |= (3<<14);
-		dev->if_port = 3;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	outw(tmp, ioaddr + WN0_ADDR_CONF);
-	if (dev->if_port == 3) {
-		/* fire up the DC-DC convertor if BNC gets enabled */
-		tmp = inw(ioaddr + WN0_ADDR_CONF);
-		if (tmp & (3 << 14)) {
-			outw(StartCoax, ioaddr + EL3_CMD);
-			udelay(800);
-		} else
-			return -EIO;
-	}
-
-	EL3WINDOW(4);
-	tmp = inw(ioaddr + WN4_NETDIAG);
-	if (ecmd->duplex == DUPLEX_FULL)
-		tmp |= FD_ENABLE;
-	else
-		tmp &= ~FD_ENABLE;
-	outw(tmp, ioaddr + WN4_NETDIAG);
-	EL3WINDOW(1);
-
-	return 0;
-}
-
-static void el3_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
-	strcpy(info->driver, DRV_NAME);
-	strcpy(info->version, DRV_VERSION);
-}
-
-static int el3_get_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-	struct el3_private *lp = netdev_priv(dev);
-	int ret;
-
-	spin_lock_irq(&lp->lock);
-	ret = el3_netdev_get_ecmd(dev, ecmd);
-	spin_unlock_irq(&lp->lock);
-	return ret;
-}
-
-static int el3_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd)
-{
-	struct el3_private *lp = netdev_priv(dev);
-	int ret;
-
-	spin_lock_irq(&lp->lock);
-	ret = el3_netdev_set_ecmd(dev, ecmd);
-	spin_unlock_irq(&lp->lock);
-	return ret;
-}
-
-static u32 el3_get_link(struct net_device *dev)
-{
-	struct el3_private *lp = netdev_priv(dev);
-	u32 ret;
-
-	spin_lock_irq(&lp->lock);
-	ret = el3_link_ok(dev);
-	spin_unlock_irq(&lp->lock);
-	return ret;
-}
-
-static u32 el3_get_msglevel(struct net_device *dev)
-{
-	return el3_debug;
-}
-
-static void el3_set_msglevel(struct net_device *dev, u32 v)
-{
-	el3_debug = v;
-}
-
-static const struct ethtool_ops ethtool_ops = {
-	.get_drvinfo = el3_get_drvinfo,
-	.get_settings = el3_get_settings,
-	.set_settings = el3_set_settings,
-	.get_link = el3_get_link,
-	.get_msglevel = el3_get_msglevel,
-	.set_msglevel = el3_set_msglevel,
-};
-
-static void
-el3_down(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-
-	netif_stop_queue(dev);
-
-	/* Turn off statistics ASAP.  We update lp->stats below. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
-
-	/* Disable the receiver and transmitter. */
-	outw(RxDisable, ioaddr + EL3_CMD);
-	outw(TxDisable, ioaddr + EL3_CMD);
-
-	if (dev->if_port == 3)
-		/* Turn off thinnet power.  Green! */
-		outw(StopCoax, ioaddr + EL3_CMD);
-	else if (dev->if_port == 0) {
-		/* Disable link beat and jabber, if_port may change here next open(). */
-		EL3WINDOW(4);
-		outw(inw(ioaddr + WN4_MEDIA) & ~MEDIA_TP, ioaddr + WN4_MEDIA);
-	}
-
-	outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
-
-	update_stats(dev);
-}
-
-static void
-el3_up(struct net_device *dev)
-{
-	int i, sw_info, net_diag;
-	int ioaddr = dev->base_addr;
-
-	/* Activating the board required and does no harm otherwise */
-	outw(0x0001, ioaddr + 4);
-
-	/* Set the IRQ line. */
-	outw((dev->irq << 12) | 0x0f00, ioaddr + WN0_IRQ);
-
-	/* Set the station address in window 2 each time opened. */
-	EL3WINDOW(2);
-
-	for (i = 0; i < 6; i++)
-		outb(dev->dev_addr[i], ioaddr + i);
-
-	if ((dev->if_port & 0x03) == 3) /* BNC interface */
-		/* Start the thinnet transceiver. We should really wait 50ms...*/
-		outw(StartCoax, ioaddr + EL3_CMD);
-	else if ((dev->if_port & 0x03) == 0) { /* 10baseT interface */
-		/* Combine secondary sw_info word (the adapter level) and primary
-			sw_info word (duplex setting plus other useless bits) */
-		EL3WINDOW(0);
-		sw_info = (read_eeprom(ioaddr, 0x14) & 0x400f) |
-			(read_eeprom(ioaddr, 0x0d) & 0xBff0);
-
-		EL3WINDOW(4);
-		net_diag = inw(ioaddr + WN4_NETDIAG);
-		net_diag = (net_diag | FD_ENABLE); /* temporarily assume full-duplex will be set */
-		pr_info("%s: ", dev->name);
-		switch (dev->if_port & 0x0c) {
-			case 12:
-				/* force full-duplex mode if 3c5x9b */
-				if (sw_info & 0x000f) {
-					pr_cont("Forcing 3c5x9b full-duplex mode");
-					break;
-				}
-			case 8:
-				/* set full-duplex mode based on eeprom config setting */
-				if ((sw_info & 0x000f) && (sw_info & 0x8000)) {
-					pr_cont("Setting 3c5x9b full-duplex mode (from EEPROM configuration bit)");
-					break;
-				}
-			default:
-				/* xcvr=(0 || 4) OR user has an old 3c5x9 non "B" model */
-				pr_cont("Setting 3c5x9/3c5x9B half-duplex mode");
-				net_diag = (net_diag & ~FD_ENABLE); /* disable full duplex */
-		}
-
-		outw(net_diag, ioaddr + WN4_NETDIAG);
-		pr_cont(" if_port: %d, sw_info: %4.4x\n", dev->if_port, sw_info);
-		if (el3_debug > 3)
-			pr_debug("%s: 3c5x9 net diag word is now: %4.4x.\n", dev->name, net_diag);
-		/* Enable link beat and jabber check. */
-		outw(inw(ioaddr + WN4_MEDIA) | MEDIA_TP, ioaddr + WN4_MEDIA);
-	}
-
-	/* Switch to the stats window, and clear all stats by reading. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
-	EL3WINDOW(6);
-	for (i = 0; i < 9; i++)
-		inb(ioaddr + i);
-	inw(ioaddr + 10);
-	inw(ioaddr + 12);
-
-	/* Switch to register set 1 for normal use. */
-	EL3WINDOW(1);
-
-	/* Accept b-case and phys addr only. */
-	outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD);
-	outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
-
-	outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
-	outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
-	/* Allow status bits to be seen. */
-	outw(SetStatusEnb | 0xff, ioaddr + EL3_CMD);
-	/* Ack all pending events, and set active indicator mask. */
-	outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
-		 ioaddr + EL3_CMD);
-	outw(SetIntrEnb | IntLatch|TxAvailable|TxComplete|RxComplete|StatsFull,
-		 ioaddr + EL3_CMD);
-
-	netif_start_queue(dev);
-}
-
-/* Power Management support functions */
-#ifdef CONFIG_PM
-
-static int
-el3_suspend(struct device *pdev, pm_message_t state)
-{
-	unsigned long flags;
-	struct net_device *dev;
-	struct el3_private *lp;
-	int ioaddr;
-
-	dev = dev_get_drvdata(pdev);
-	lp = netdev_priv(dev);
-	ioaddr = dev->base_addr;
-
-	spin_lock_irqsave(&lp->lock, flags);
-
-	if (netif_running(dev))
-		netif_device_detach(dev);
-
-	el3_down(dev);
-	outw(PowerDown, ioaddr + EL3_CMD);
-
-	spin_unlock_irqrestore(&lp->lock, flags);
-	return 0;
-}
-
-static int
-el3_resume(struct device *pdev)
-{
-	unsigned long flags;
-	struct net_device *dev;
-	struct el3_private *lp;
-	int ioaddr;
-
-	dev = dev_get_drvdata(pdev);
-	lp = netdev_priv(dev);
-	ioaddr = dev->base_addr;
-
-	spin_lock_irqsave(&lp->lock, flags);
-
-	outw(PowerUp, ioaddr + EL3_CMD);
-	EL3WINDOW(0);
-	el3_up(dev);
-
-	if (netif_running(dev))
-		netif_device_attach(dev);
-
-	spin_unlock_irqrestore(&lp->lock, flags);
-	return 0;
-}
-
-#endif /* CONFIG_PM */
-
-module_param(debug,int, 0);
-module_param_array(irq, 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(max_interrupt_work, "maximum events handled per interrupt");
-#ifdef CONFIG_PNP
-module_param(nopnp, int, 0);
-MODULE_PARM_DESC(nopnp, "disable ISA PnP support (0-1)");
-#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;
-
-	if (debug >= 0)
-		el3_debug = debug;
-
-#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;
-		pr_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
-	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)
-{
-#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
-	if (eisa_registered)
-		eisa_driver_unregister(&el3_eisa_driver);
-#endif
-#ifdef CONFIG_MCA
-	if (mca_registered)
-		mca_unregister_driver(&el3_mca_driver);
-#endif
-}
-
-module_init (el3_init_module);
-module_exit (el3_cleanup_module);

+ 0 - 1584
drivers/net/3c515.c

@@ -1,1584 +0,0 @@
-/*
-	Written 1997-1998 by Donald Becker.
-
-	This software may be used and distributed according to the terms
-	of the GNU General Public License, incorporated herein by reference.
-
-	This driver is for the 3Com ISA EtherLink XL "Corkscrew" 3c515 ethercard.
-
-	The author may be reached as becker@scyld.com, or C/O
-	Scyld Computing Corporation
-	410 Severn Ave., Suite 210
-	Annapolis MD 21403
-
-
-	2000/2/2- Added support for kernel-level ISAPnP
-		by Stephen Frost <sfrost@snowman.net> and Alessandro Zummo
-	Cleaned up for 2.3.x/softnet by Jeff Garzik and Alan Cox.
-
-	2001/11/17 - Added ethtool support (jgarzik)
-
-	2002/10/28 - Locking updates for 2.5 (alan@lxorguk.ukuu.org.uk)
-
-*/
-
-#define DRV_NAME		"3c515"
-#define DRV_VERSION		"0.99t-ac"
-#define DRV_RELDATE		"28-Oct-2002"
-
-static char *version =
-DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " becker@scyld.com and others\n";
-
-#define CORKSCREW 1
-
-/* "Knobs" that adjust features and parameters. */
-/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
-   Setting to > 1512 effectively disables this feature. */
-static int rx_copybreak = 200;
-
-/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
-static const int mtu = 1500;
-
-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 20;
-
-/* Enable the automatic media selection code -- usually set. */
-#define AUTOMEDIA 1
-
-/* Allow the use of fragment bus master transfers instead of only
-   programmed-I/O for Vortex cards.  Full-bus-master transfers are always
-   enabled by default on Boomerang cards.  If VORTEX_BUS_MASTER is defined,
-   the feature may be turned on using 'options'. */
-#define VORTEX_BUS_MASTER
-
-/* A few values that may be tweaked. */
-/* Keep the ring sizes a power of two for efficiency. */
-#define TX_RING_SIZE	16
-#define RX_RING_SIZE	16
-#define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer. */
-
-#include <linux/module.h>
-#include <linux/isapnp.h>
-#include <linux/kernel.h>
-#include <linux/netdevice.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/ioport.h>
-#include <linux/skbuff.h>
-#include <linux/etherdevice.h>
-#include <linux/interrupt.h>
-#include <linux/timer.h>
-#include <linux/ethtool.h>
-#include <linux/bitops.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#define NEW_MULTICAST
-#include <linux/delay.h>
-
-#define MAX_UNITS 8
-
-MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
-MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
-
-/* "Knobs" for adjusting internal parameters. */
-/* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */
-#define DRIVER_DEBUG 1
-/* Some values here only for performance evaluation and path-coverage
-   debugging. */
-static int rx_nocopy, rx_copy, queued_packet;
-
-/* Number of times to check to see if the Tx FIFO has space, used in some
-   limited cases. */
-#define WAIT_TX_AVAIL 200
-
-/* Operational parameter that usually are not changed. */
-#define TX_TIMEOUT  ((4*HZ)/10)	/* Time in jiffies before concluding Tx hung */
-
-/* The size here is somewhat misleading: the Corkscrew also uses the ISA
-   aliased registers at <base>+0x400.
-   */
-#define CORKSCREW_TOTAL_SIZE 0x20
-
-#ifdef DRIVER_DEBUG
-static int corkscrew_debug = DRIVER_DEBUG;
-#else
-static int corkscrew_debug = 1;
-#endif
-
-#define CORKSCREW_ID 10
-
-/*
-				Theory of Operation
-
-I. Board Compatibility
-
-This device driver is designed for the 3Com 3c515 ISA Fast EtherLink XL,
-3Com's ISA bus adapter for Fast Ethernet.  Due to the unique I/O port layout,
-it's not practical to integrate this driver with the other EtherLink drivers.
-
-II. Board-specific settings
-
-The Corkscrew has an EEPROM for configuration, but no special settings are
-needed for Linux.
-
-III. Driver operation
-
-The 3c515 series use an interface that's very similar to the 3c900 "Boomerang"
-PCI cards, with the bus master interface extensively modified to work with
-the ISA bus.
-
-The card is capable of full-bus-master transfers with separate
-lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
-DEC Tulip and Intel Speedo3.
-
-This driver uses a "RX_COPYBREAK" scheme rather than a fixed intermediate
-receive buffer.  This scheme allocates full-sized skbuffs as receive
-buffers.  The value RX_COPYBREAK is used as the copying breakpoint: it is
-chosen to trade-off the memory wasted by passing the full-sized skbuff to
-the queue layer for all frames vs. the copying cost of copying a frame to a
-correctly-sized skbuff.
-
-
-IIIC. Synchronization
-The driver runs as two independent, single-threaded flows of control.  One
-is the send-packet routine, which enforces single-threaded use by the netif
-layer.  The other thread is the interrupt handler, which is single
-threaded by the hardware and other software.
-
-IV. Notes
-
-Thanks to Terry Murphy of 3Com for providing documentation and a development
-board.
-
-The names "Vortex", "Boomerang" and "Corkscrew" are the internal 3Com
-project names.  I use these names to eliminate confusion -- 3Com product
-numbers and names are very similar and often confused.
-
-The new chips support both ethernet (1.5K) and FDDI (4.5K) frame sizes!
-This driver only supports ethernet frames because of the recent MTU limit
-of 1.5K, but the changes to support 4.5K are minimal.
-*/
-
-/* Operational definitions.
-   These are not used by other compilation units and thus are not
-   exported in a ".h" file.
-
-   First the windows.  There are eight register windows, with the command
-   and status registers available in each.
-   */
-#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
-#define EL3_CMD 0x0e
-#define EL3_STATUS 0x0e
-
-/* The top five bits written to EL3_CMD are a command, the lower
-   11 bits are the parameter, if applicable.
-   Note that 11 parameters bits was fine for ethernet, but the new chips
-   can handle FDDI length frames (~4500 octets) and now parameters count
-   32-bit 'Dwords' rather than octets. */
-
-enum corkscrew_cmd {
-	TotalReset = 0 << 11, SelectWindow = 1 << 11, StartCoax = 2 << 11,
-	RxDisable = 3 << 11, RxEnable = 4 << 11, RxReset = 5 << 11,
-	UpStall = 6 << 11, UpUnstall = (6 << 11) + 1, DownStall = (6 << 11) + 2,
-	DownUnstall = (6 << 11) + 3, RxDiscard = 8 << 11, TxEnable = 9 << 11,
-	TxDisable = 10 << 11, TxReset = 11 << 11, FakeIntr = 12 << 11,
-	AckIntr = 13 << 11, SetIntrEnb = 14 << 11, SetStatusEnb = 15 << 11,
-	SetRxFilter = 16 << 11, SetRxThreshold = 17 << 11,
-	SetTxThreshold = 18 << 11, SetTxStart = 19 << 11, StartDMAUp = 20 << 11,
-	StartDMADown = (20 << 11) + 1, StatsEnable = 21 << 11,
-	StatsDisable = 22 << 11, StopCoax = 23 << 11,
-};
-
-/* The SetRxFilter command accepts the following classes: */
-enum RxFilter {
-	RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8
-};
-
-/* Bits in the general status register. */
-enum corkscrew_status {
-	IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
-	TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
-	IntReq = 0x0040, StatsFull = 0x0080,
-	DMADone = 1 << 8, DownComplete = 1 << 9, UpComplete = 1 << 10,
-	DMAInProgress = 1 << 11,	/* DMA controller is still busy. */
-	CmdInProgress = 1 << 12,	/* EL3_CMD is still busy. */
-};
-
-/* Register window 1 offsets, the window used in normal operation.
-   On the Corkscrew this window is always mapped at offsets 0x10-0x1f. */
-enum Window1 {
-	TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14,
-	RxStatus = 0x18, Timer = 0x1A, TxStatus = 0x1B,
-	TxFree = 0x1C,		/* Remaining free bytes in Tx buffer. */
-};
-enum Window0 {
-	Wn0IRQ = 0x08,
-#if defined(CORKSCREW)
-	Wn0EepromCmd = 0x200A,	/* Corkscrew EEPROM command register. */
-	Wn0EepromData = 0x200C,	/* Corkscrew EEPROM results register. */
-#else
-	Wn0EepromCmd = 10,	/* Window 0: EEPROM command register. */
-	Wn0EepromData = 12,	/* Window 0: EEPROM results register. */
-#endif
-};
-enum Win0_EEPROM_bits {
-	EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0,
-	EEPROM_EWENB = 0x30,	/* Enable erasing/writing for 10 msec. */
-	EEPROM_EWDIS = 0x00,	/* Disable EWENB before 10 msec timeout. */
-};
-
-/* EEPROM locations. */
-enum eeprom_offset {
-	PhysAddr01 = 0, PhysAddr23 = 1, PhysAddr45 = 2, ModelID = 3,
-	EtherLink3ID = 7,
-};
-
-enum Window3 {			/* Window 3: MAC/config bits. */
-	Wn3_Config = 0, Wn3_MAC_Ctrl = 6, Wn3_Options = 8,
-};
-enum wn3_config {
-	Ram_size = 7,
-	Ram_width = 8,
-	Ram_speed = 0x30,
-	Rom_size = 0xc0,
-	Ram_split_shift = 16,
-	Ram_split = 3 << Ram_split_shift,
-	Xcvr_shift = 20,
-	Xcvr = 7 << Xcvr_shift,
-	Autoselect = 0x1000000,
-};
-
-enum Window4 {
-	Wn4_NetDiag = 6, Wn4_Media = 10,	/* Window 4: Xcvr/media bits. */
-};
-enum Win4_Media_bits {
-	Media_SQE = 0x0008,	/* Enable SQE error counting for AUI. */
-	Media_10TP = 0x00C0,	/* Enable link beat and jabber for 10baseT. */
-	Media_Lnk = 0x0080,	/* Enable just link beat for 100TX/100FX. */
-	Media_LnkBeat = 0x0800,
-};
-enum Window7 {			/* Window 7: Bus Master control. */
-	Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12,
-};
-
-/* Boomerang-style bus master control registers.  Note ISA aliases! */
-enum MasterCtrl {
-	PktStatus = 0x400, DownListPtr = 0x404, FragAddr = 0x408, FragLen =
-	    0x40c,
-	TxFreeThreshold = 0x40f, UpPktStatus = 0x410, UpListPtr = 0x418,
-};
-
-/* The Rx and Tx descriptor lists.
-   Caution Alpha hackers: these types are 32 bits!  Note also the 8 byte
-   alignment contraint on tx_ring[] and rx_ring[]. */
-struct boom_rx_desc {
-	u32 next;
-	s32 status;
-	u32 addr;
-	s32 length;
-};
-
-/* Values for the Rx status entry. */
-enum rx_desc_status {
-	RxDComplete = 0x00008000, RxDError = 0x4000,
-	/* See boomerang_rx() for actual error bits */
-};
-
-struct boom_tx_desc {
-	u32 next;
-	s32 status;
-	u32 addr;
-	s32 length;
-};
-
-struct corkscrew_private {
-	const char *product_name;
-	struct list_head list;
-	struct net_device *our_dev;
-	/* The Rx and Tx rings are here to keep them quad-word-aligned. */
-	struct boom_rx_desc rx_ring[RX_RING_SIZE];
-	struct boom_tx_desc tx_ring[TX_RING_SIZE];
-	/* The addresses of transmit- and receive-in-place skbuffs. */
-	struct sk_buff *rx_skbuff[RX_RING_SIZE];
-	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 sk_buff *tx_skb;	/* Packet being eaten by bus master ctrl.  */
-	struct timer_list timer;	/* Media selection timer. */
-	int capabilities	;	/* Adapter capabilities word. */
-	int options;			/* User-settable misc. driver options. */
-	int last_rx_packets;		/* For media autoselection. */
-	unsigned int available_media:8,	/* From Wn3_Options */
-		media_override:3,	/* Passed-in media type. */
-		default_media:3,	/* Read from the EEPROM. */
-		full_duplex:1, autoselect:1, bus_master:1,	/* Vortex can only do a fragment bus-m. */
-		full_bus_master_tx:1, full_bus_master_rx:1,	/* Boomerang  */
-		tx_full:1;
-	spinlock_t lock;
-	struct device *dev;
-};
-
-/* The action to take with a media selection timer tick.
-   Note that we deviate from the 3Com order by checking 10base2 before AUI.
- */
-enum xcvr_types {
-	XCVR_10baseT = 0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx,
-	XCVR_100baseFx, XCVR_MII = 6, XCVR_Default = 8,
-};
-
-static struct media_table {
-	char *name;
-	unsigned int media_bits:16,	/* Bits to set in Wn4_Media register. */
-		mask:8,			/* The transceiver-present bit in Wn3_Config. */
-		next:8;			/* The media type to try next. */
-	short wait;			/* Time before we check media status. */
-} media_tbl[] = {
-	{ "10baseT", Media_10TP, 0x08, XCVR_10base2, (14 * HZ) / 10 },
-	{ "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1 * HZ) / 10},
-	{ "undefined", 0, 0x80, XCVR_10baseT, 10000},
-	{ "10base2", 0, 0x10, XCVR_AUI, (1 * HZ) / 10},
-	{ "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14 * HZ) / 10},
-	{ "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14 * HZ) / 10},
-	{ "MII", 0, 0x40, XCVR_10baseT, 3 * HZ},
-	{ "undefined", 0, 0x01, XCVR_10baseT, 10000},
-	{ "Default", 0, 0xFF, XCVR_10baseT, 10000},
-};
-
-#ifdef __ISAPNP__
-static struct isapnp_device_id corkscrew_isapnp_adapters[] = {
-	{	ISAPNP_ANY_ID, ISAPNP_ANY_ID,
-		ISAPNP_VENDOR('T', 'C', 'M'), ISAPNP_FUNCTION(0x5051),
-		(long) "3Com Fast EtherLink ISA" },
-	{ }	/* terminate list */
-};
-
-MODULE_DEVICE_TABLE(isapnp, corkscrew_isapnp_adapters);
-
-static int nopnp;
-#endif /* __ISAPNP__ */
-
-static struct net_device *corkscrew_scan(int unit);
-static int corkscrew_setup(struct net_device *dev, int ioaddr,
-			    struct pnp_dev *idev, int card_number);
-static int corkscrew_open(struct net_device *dev);
-static void corkscrew_timer(unsigned long arg);
-static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
-					struct net_device *dev);
-static int corkscrew_rx(struct net_device *dev);
-static void corkscrew_timeout(struct net_device *dev);
-static int boomerang_rx(struct net_device *dev);
-static irqreturn_t corkscrew_interrupt(int irq, void *dev_id);
-static int corkscrew_close(struct net_device *dev);
-static void update_stats(int addr, struct net_device *dev);
-static struct net_device_stats *corkscrew_get_stats(struct net_device *dev);
-static void set_rx_mode(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
-
-
-/*
-   Unfortunately maximizing the shared code between the integrated and
-   module version of the driver results in a complicated set of initialization
-   procedures.
-   init_module() -- modules /  tc59x_init()  -- built-in
-		The wrappers for corkscrew_scan()
-   corkscrew_scan()  		 The common routine that scans for PCI and EISA cards
-   corkscrew_found_device() Allocate a device structure when we find a card.
-					Different versions exist for modules and built-in.
-   corkscrew_probe1()		Fill in the device structure -- this is separated
-					so that the modules code can put it in dev->init.
-*/
-/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
-/* Note: this is the only limit on the number of cards supported!! */
-static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1, };
-
-#ifdef MODULE
-static int debug = -1;
-
-module_param(debug, int, 0);
-module_param_array(options, int, NULL, 0);
-module_param(rx_copybreak, int, 0);
-module_param(max_interrupt_work, int, 0);
-MODULE_PARM_DESC(debug, "3c515 debug level (0-6)");
-MODULE_PARM_DESC(options, "3c515: Bits 0-2: media type, bit 3: full duplex, bit 4: bus mastering");
-MODULE_PARM_DESC(rx_copybreak, "3c515 copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(max_interrupt_work, "3c515 maximum events handled per interrupt");
-
-/* A list of all installed Vortex devices, for removing the driver module. */
-/* we will need locking (and refcounting) if we ever use it for more */
-static LIST_HEAD(root_corkscrew_dev);
-
-int init_module(void)
-{
-	int found = 0;
-	if (debug >= 0)
-		corkscrew_debug = debug;
-	if (corkscrew_debug)
-		pr_debug("%s", version);
-	while (corkscrew_scan(-1))
-		found++;
-	return found ? 0 : -ENODEV;
-}
-
-#else
-struct net_device *tc515_probe(int unit)
-{
-	struct net_device *dev = corkscrew_scan(unit);
-	static int printed;
-
-	if (!dev)
-		return ERR_PTR(-ENODEV);
-
-	if (corkscrew_debug > 0 && !printed) {
-		printed = 1;
-		pr_debug("%s", version);
-	}
-
-	return dev;
-}
-#endif				/* not MODULE */
-
-static int check_device(unsigned ioaddr)
-{
-	int timer;
-
-	if (!request_region(ioaddr, CORKSCREW_TOTAL_SIZE, "3c515"))
-		return 0;
-	/* Check the resource configuration for a matching ioaddr. */
-	if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0)) {
-		release_region(ioaddr, CORKSCREW_TOTAL_SIZE);
-		return 0;
-	}
-	/* Verify by reading the device ID from the EEPROM. */
-	outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
-	/* Pause for at least 162 us. for the read to take place. */
-	for (timer = 4; timer >= 0; timer--) {
-		udelay(162);
-		if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
-			break;
-	}
-	if (inw(ioaddr + Wn0EepromData) != 0x6d50) {
-		release_region(ioaddr, CORKSCREW_TOTAL_SIZE);
-		return 0;
-	}
-	return 1;
-}
-
-static void cleanup_card(struct net_device *dev)
-{
-	struct corkscrew_private *vp = netdev_priv(dev);
-	list_del_init(&vp->list);
-	if (dev->dma)
-		free_dma(dev->dma);
-	outw(TotalReset, dev->base_addr + EL3_CMD);
-	release_region(dev->base_addr, CORKSCREW_TOTAL_SIZE);
-	if (vp->dev)
-		pnp_device_detach(to_pnp_dev(vp->dev));
-}
-
-static struct net_device *corkscrew_scan(int unit)
-{
-	struct net_device *dev;
-	static int cards_found = 0;
-	static int ioaddr;
-	int err;
-#ifdef __ISAPNP__
-	short i;
-	static int pnp_cards;
-#endif
-
-	dev = alloc_etherdev(sizeof(struct corkscrew_private));
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	if (unit >= 0) {
-		sprintf(dev->name, "eth%d", unit);
-		netdev_boot_setup_check(dev);
-	}
-
-#ifdef __ISAPNP__
-	if(nopnp == 1)
-		goto no_pnp;
-	for(i=0; corkscrew_isapnp_adapters[i].vendor != 0; i++) {
-		struct pnp_dev *idev = NULL;
-		int irq;
-		while((idev = pnp_find_dev(NULL,
-					   corkscrew_isapnp_adapters[i].vendor,
-					   corkscrew_isapnp_adapters[i].function,
-					   idev))) {
-
-			if (pnp_device_attach(idev) < 0)
-				continue;
-			if (pnp_activate_dev(idev) < 0) {
-				pr_warning("pnp activate failed (out of resources?)\n");
-				pnp_device_detach(idev);
-				continue;
-			}
-			if (!pnp_port_valid(idev, 0) || !pnp_irq_valid(idev, 0)) {
-				pnp_device_detach(idev);
-				continue;
-			}
-			ioaddr = pnp_port_start(idev, 0);
-			irq = pnp_irq(idev, 0);
-			if (!check_device(ioaddr)) {
-				pnp_device_detach(idev);
-				continue;
-			}
-			if(corkscrew_debug)
-				pr_debug("ISAPNP reports %s at i/o 0x%x, irq %d\n",
-					(char*) corkscrew_isapnp_adapters[i].driver_data, ioaddr, irq);
-			pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
-		     		inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
-			/* irq = inw(ioaddr + 0x2002) & 15; */ /* Use the irq from isapnp */
-			SET_NETDEV_DEV(dev, &idev->dev);
-			pnp_cards++;
-			err = corkscrew_setup(dev, ioaddr, idev, cards_found++);
-			if (!err)
-				return dev;
-			cleanup_card(dev);
-		}
-	}
-no_pnp:
-#endif /* __ISAPNP__ */
-
-	/* Check all locations on the ISA bus -- evil! */
-	for (ioaddr = 0x100; ioaddr < 0x400; ioaddr += 0x20) {
-		if (!check_device(ioaddr))
-			continue;
-
-		pr_info("3c515 Resource configuration register %#4.4x, DCR %4.4x.\n",
-		     inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
-		err = corkscrew_setup(dev, ioaddr, NULL, cards_found++);
-		if (!err)
-			return dev;
-		cleanup_card(dev);
-	}
-	free_netdev(dev);
-	return NULL;
-}
-
-
-static const struct net_device_ops netdev_ops = {
-	.ndo_open		= corkscrew_open,
-	.ndo_stop		= corkscrew_close,
-	.ndo_start_xmit		= corkscrew_start_xmit,
-	.ndo_tx_timeout		= corkscrew_timeout,
-	.ndo_get_stats		= corkscrew_get_stats,
-	.ndo_set_multicast_list = set_rx_mode,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-
-static int corkscrew_setup(struct net_device *dev, int ioaddr,
-			    struct pnp_dev *idev, int card_number)
-{
-	struct corkscrew_private *vp = netdev_priv(dev);
-	unsigned int eeprom[0x40], checksum = 0;	/* EEPROM contents */
-	int i;
-	int irq;
-
-#ifdef __ISAPNP__
-	if (idev) {
-		irq = pnp_irq(idev, 0);
-		vp->dev = &idev->dev;
-	} else {
-		irq = inw(ioaddr + 0x2002) & 15;
-	}
-#else
-	irq = inw(ioaddr + 0x2002) & 15;
-#endif
-
-	dev->base_addr = ioaddr;
-	dev->irq = irq;
-	dev->dma = inw(ioaddr + 0x2000) & 7;
-	vp->product_name = "3c515";
-	vp->options = dev->mem_start;
-	vp->our_dev = dev;
-
-	if (!vp->options) {
-		 if (card_number >= MAX_UNITS)
-			vp->options = -1;
-		else
-			vp->options = options[card_number];
-	}
-
-	if (vp->options >= 0) {
-		vp->media_override = vp->options & 7;
-		if (vp->media_override == 2)
-			vp->media_override = 0;
-		vp->full_duplex = (vp->options & 8) ? 1 : 0;
-		vp->bus_master = (vp->options & 16) ? 1 : 0;
-	} else {
-		vp->media_override = 7;
-		vp->full_duplex = 0;
-		vp->bus_master = 0;
-	}
-#ifdef MODULE
-	list_add(&vp->list, &root_corkscrew_dev);
-#endif
-
-	pr_info("%s: 3Com %s at %#3x,", dev->name, vp->product_name, ioaddr);
-
-	spin_lock_init(&vp->lock);
-
-	/* Read the station address from the EEPROM. */
-	EL3WINDOW(0);
-	for (i = 0; i < 0x18; i++) {
-		__be16 *phys_addr = (__be16 *) dev->dev_addr;
-		int timer;
-		outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
-		/* Pause for at least 162 us. for the read to take place. */
-		for (timer = 4; timer >= 0; timer--) {
-			udelay(162);
-			if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
-				break;
-		}
-		eeprom[i] = inw(ioaddr + Wn0EepromData);
-		checksum ^= eeprom[i];
-		if (i < 3)
-			phys_addr[i] = htons(eeprom[i]);
-	}
-	checksum = (checksum ^ (checksum >> 8)) & 0xff;
-	if (checksum != 0x00)
-		pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
-	pr_cont(" %pM", dev->dev_addr);
-	if (eeprom[16] == 0x11c7) {	/* Corkscrew */
-		if (request_dma(dev->dma, "3c515")) {
-			pr_cont(", DMA %d allocation failed", dev->dma);
-			dev->dma = 0;
-		} else
-			pr_cont(", DMA %d", dev->dma);
-	}
-	pr_cont(", IRQ %d\n", dev->irq);
-	/* Tell them about an invalid IRQ. */
-	if (corkscrew_debug && (dev->irq <= 0 || dev->irq > 15))
-		pr_warning(" *** Warning: this IRQ is unlikely to work! ***\n");
-
-	{
-		static const char * const ram_split[] = {
-			"5:3", "3:1", "1:1", "3:5"
-		};
-		__u32 config;
-		EL3WINDOW(3);
-		vp->available_media = inw(ioaddr + Wn3_Options);
-		config = inl(ioaddr + Wn3_Config);
-		if (corkscrew_debug > 1)
-			pr_info("  Internal config register is %4.4x, transceivers %#x.\n",
-				config, inw(ioaddr + Wn3_Options));
-		pr_info("  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
-			8 << config & Ram_size,
-			config & Ram_width ? "word" : "byte",
-			ram_split[(config & Ram_split) >> Ram_split_shift],
-			config & Autoselect ? "autoselect/" : "",
-			media_tbl[(config & Xcvr) >> Xcvr_shift].name);
-		vp->default_media = (config & Xcvr) >> Xcvr_shift;
-		vp->autoselect = config & Autoselect ? 1 : 0;
-		dev->if_port = vp->default_media;
-	}
-	if (vp->media_override != 7) {
-		pr_info("  Media override to transceiver type %d (%s).\n",
-		       vp->media_override,
-		       media_tbl[vp->media_override].name);
-		dev->if_port = vp->media_override;
-	}
-
-	vp->capabilities = eeprom[16];
-	vp->full_bus_master_tx = (vp->capabilities & 0x20) ? 1 : 0;
-	/* Rx is broken at 10mbps, so we always disable it. */
-	/* vp->full_bus_master_rx = 0; */
-	vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
-
-	/* The 3c51x-specific entries in the device structure. */
-	dev->netdev_ops = &netdev_ops;
-	dev->watchdog_timeo = (400 * HZ) / 1000;
-	dev->ethtool_ops = &netdev_ethtool_ops;
-
-	return register_netdev(dev);
-}
-
-
-static int corkscrew_open(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-	struct corkscrew_private *vp = netdev_priv(dev);
-	__u32 config;
-	int i;
-
-	/* Before initializing select the active media port. */
-	EL3WINDOW(3);
-	if (vp->full_duplex)
-		outb(0x20, ioaddr + Wn3_MAC_Ctrl);	/* Set the full-duplex bit. */
-	config = inl(ioaddr + Wn3_Config);
-
-	if (vp->media_override != 7) {
-		if (corkscrew_debug > 1)
-			pr_info("%s: Media override to transceiver %d (%s).\n",
-				dev->name, vp->media_override,
-				media_tbl[vp->media_override].name);
-		dev->if_port = vp->media_override;
-	} else if (vp->autoselect) {
-		/* Find first available media type, starting with 100baseTx. */
-		dev->if_port = 4;
-		while (!(vp->available_media & media_tbl[dev->if_port].mask))
-			dev->if_port = media_tbl[dev->if_port].next;
-
-		if (corkscrew_debug > 1)
-			pr_debug("%s: Initial media type %s.\n",
-			       dev->name, media_tbl[dev->if_port].name);
-
-		init_timer(&vp->timer);
-		vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
-		vp->timer.data = (unsigned long) dev;
-		vp->timer.function = corkscrew_timer;	/* timer handler */
-		add_timer(&vp->timer);
-	} else
-		dev->if_port = vp->default_media;
-
-	config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift);
-	outl(config, ioaddr + Wn3_Config);
-
-	if (corkscrew_debug > 1) {
-		pr_debug("%s: corkscrew_open() InternalConfig %8.8x.\n",
-		       dev->name, config);
-	}
-
-	outw(TxReset, ioaddr + EL3_CMD);
-	for (i = 20; i >= 0; i--)
-		if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
-			break;
-
-	outw(RxReset, ioaddr + EL3_CMD);
-	/* Wait a few ticks for the RxReset command to complete. */
-	for (i = 20; i >= 0; i--)
-		if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
-			break;
-
-	outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
-
-	/* Use the now-standard shared IRQ implementation. */
-	if (vp->capabilities == 0x11c7) {
-		/* Corkscrew: Cannot share ISA resources. */
-		if (dev->irq == 0 ||
-		    dev->dma == 0 ||
-		    request_irq(dev->irq, corkscrew_interrupt, 0,
-				vp->product_name, dev))
-			return -EAGAIN;
-		enable_dma(dev->dma);
-		set_dma_mode(dev->dma, DMA_MODE_CASCADE);
-	} else if (request_irq(dev->irq, corkscrew_interrupt, IRQF_SHARED,
-			       vp->product_name, dev)) {
-		return -EAGAIN;
-	}
-
-	if (corkscrew_debug > 1) {
-		EL3WINDOW(4);
-		pr_debug("%s: corkscrew_open() irq %d media status %4.4x.\n",
-		       dev->name, dev->irq, inw(ioaddr + Wn4_Media));
-	}
-
-	/* Set the station address and mask in window 2 each time opened. */
-	EL3WINDOW(2);
-	for (i = 0; i < 6; i++)
-		outb(dev->dev_addr[i], ioaddr + i);
-	for (; i < 12; i += 2)
-		outw(0, ioaddr + i);
-
-	if (dev->if_port == 3)
-		/* Start the thinnet transceiver. We should really wait 50ms... */
-		outw(StartCoax, ioaddr + EL3_CMD);
-	EL3WINDOW(4);
-	outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP | Media_SQE)) |
-	     media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
-
-	/* Switch to the stats window, and clear all stats by reading. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
-	EL3WINDOW(6);
-	for (i = 0; i < 10; i++)
-		inb(ioaddr + i);
-	inw(ioaddr + 10);
-	inw(ioaddr + 12);
-	/* New: On the Vortex we must also clear the BadSSD counter. */
-	EL3WINDOW(4);
-	inb(ioaddr + 12);
-	/* ..and on the Boomerang we enable the extra statistics bits. */
-	outw(0x0040, ioaddr + Wn4_NetDiag);
-
-	/* Switch to register set 7 for normal use. */
-	EL3WINDOW(7);
-
-	if (vp->full_bus_master_rx) {	/* Boomerang bus master. */
-		vp->cur_rx = vp->dirty_rx = 0;
-		if (corkscrew_debug > 2)
-			pr_debug("%s:  Filling in the Rx ring.\n", dev->name);
-		for (i = 0; i < RX_RING_SIZE; i++) {
-			struct sk_buff *skb;
-			if (i < (RX_RING_SIZE - 1))
-				vp->rx_ring[i].next =
-				    isa_virt_to_bus(&vp->rx_ring[i + 1]);
-			else
-				vp->rx_ring[i].next = 0;
-			vp->rx_ring[i].status = 0;	/* Clear complete bit. */
-			vp->rx_ring[i].length = PKT_BUF_SZ | 0x80000000;
-			skb = dev_alloc_skb(PKT_BUF_SZ);
-			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 */
-			vp->rx_ring[i].addr = isa_virt_to_bus(skb->data);
-		}
-		if (i != 0)
-			vp->rx_ring[i - 1].next =
-				isa_virt_to_bus(&vp->rx_ring[0]);	/* Wrap the ring. */
-		outl(isa_virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
-	}
-	if (vp->full_bus_master_tx) {	/* Boomerang bus master Tx. */
-		vp->cur_tx = vp->dirty_tx = 0;
-		outb(PKT_BUF_SZ >> 8, ioaddr + TxFreeThreshold);	/* Room for a packet. */
-		/* Clear the Tx ring. */
-		for (i = 0; i < TX_RING_SIZE; i++)
-			vp->tx_skbuff[i] = NULL;
-		outl(0, ioaddr + DownListPtr);
-	}
-	/* Set receiver mode: presumably accept b-case and phys addr only. */
-	set_rx_mode(dev);
-	outw(StatsEnable, ioaddr + EL3_CMD);	/* Turn on statistics. */
-
-	netif_start_queue(dev);
-
-	outw(RxEnable, ioaddr + EL3_CMD);	/* Enable the receiver. */
-	outw(TxEnable, ioaddr + EL3_CMD);	/* Enable transmitter. */
-	/* Allow status bits to be seen. */
-	outw(SetStatusEnb | AdapterFailure | IntReq | StatsFull |
-	     (vp->full_bus_master_tx ? DownComplete : TxAvailable) |
-	     (vp->full_bus_master_rx ? UpComplete : RxComplete) |
-	     (vp->bus_master ? DMADone : 0), ioaddr + EL3_CMD);
-	/* Ack all pending events, and set active indicator mask. */
-	outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
-	     ioaddr + EL3_CMD);
-	outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull
-	     | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete,
-	     ioaddr + EL3_CMD);
-
-	return 0;
-}
-
-static void corkscrew_timer(unsigned long data)
-{
-#ifdef AUTOMEDIA
-	struct net_device *dev = (struct net_device *) data;
-	struct corkscrew_private *vp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-	unsigned long flags;
-	int ok = 0;
-
-	if (corkscrew_debug > 1)
-		pr_debug("%s: Media selection timer tick happened, %s.\n",
-		       dev->name, media_tbl[dev->if_port].name);
-
-	spin_lock_irqsave(&vp->lock, flags);
-
-	{
-		int old_window = inw(ioaddr + EL3_CMD) >> 13;
-		int media_status;
-		EL3WINDOW(4);
-		media_status = inw(ioaddr + Wn4_Media);
-		switch (dev->if_port) {
-		case 0:
-		case 4:
-		case 5:	/* 10baseT, 100baseTX, 100baseFX  */
-			if (media_status & Media_LnkBeat) {
-				ok = 1;
-				if (corkscrew_debug > 1)
-					pr_debug("%s: Media %s has link beat, %x.\n",
-						dev->name,
-						media_tbl[dev->if_port].name,
-						media_status);
-			} else if (corkscrew_debug > 1)
-				pr_debug("%s: Media %s is has no link beat, %x.\n",
-					dev->name,
-					media_tbl[dev->if_port].name,
-					media_status);
-
-			break;
-		default:	/* Other media types handled by Tx timeouts. */
-			if (corkscrew_debug > 1)
-				pr_debug("%s: Media %s is has no indication, %x.\n",
-					dev->name,
-					media_tbl[dev->if_port].name,
-					media_status);
-			ok = 1;
-		}
-		if (!ok) {
-			__u32 config;
-
-			do {
-				dev->if_port =
-				    media_tbl[dev->if_port].next;
-			}
-			while (!(vp->available_media & media_tbl[dev->if_port].mask));
-
-			if (dev->if_port == 8) {	/* Go back to default. */
-				dev->if_port = vp->default_media;
-				if (corkscrew_debug > 1)
-					pr_debug("%s: Media selection failing, using default %s port.\n",
-						dev->name,
-						media_tbl[dev->if_port].name);
-			} else {
-				if (corkscrew_debug > 1)
-					pr_debug("%s: Media selection failed, now trying %s port.\n",
-						dev->name,
-						media_tbl[dev->if_port].name);
-				vp->timer.expires = jiffies + media_tbl[dev->if_port].wait;
-				add_timer(&vp->timer);
-			}
-			outw((media_status & ~(Media_10TP | Media_SQE)) |
-			     media_tbl[dev->if_port].media_bits,
-			     ioaddr + Wn4_Media);
-
-			EL3WINDOW(3);
-			config = inl(ioaddr + Wn3_Config);
-			config = (config & ~Xcvr) | (dev->if_port << Xcvr_shift);
-			outl(config, ioaddr + Wn3_Config);
-
-			outw(dev->if_port == 3 ? StartCoax : StopCoax,
-			     ioaddr + EL3_CMD);
-		}
-		EL3WINDOW(old_window);
-	}
-
-	spin_unlock_irqrestore(&vp->lock, flags);
-	if (corkscrew_debug > 1)
-		pr_debug("%s: Media selection timer finished, %s.\n",
-		       dev->name, media_tbl[dev->if_port].name);
-
-#endif				/* AUTOMEDIA */
-}
-
-static void corkscrew_timeout(struct net_device *dev)
-{
-	int i;
-	struct corkscrew_private *vp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-
-	pr_warning("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
-	       dev->name, inb(ioaddr + TxStatus),
-	       inw(ioaddr + EL3_STATUS));
-	/* Slight code bloat to be user friendly. */
-	if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
-		pr_warning("%s: Transmitter encountered 16 collisions --"
-		       " network cable problem?\n", dev->name);
-#ifndef final_version
-	pr_debug("  Flags; bus-master %d, full %d; dirty %d current %d.\n",
-	       vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx,
-	       vp->cur_tx);
-	pr_debug("  Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
-	       &vp->tx_ring[0]);
-	for (i = 0; i < TX_RING_SIZE; i++) {
-		pr_debug("  %d: %p  length %8.8x status %8.8x\n", i,
-		       &vp->tx_ring[i],
-		       vp->tx_ring[i].length, vp->tx_ring[i].status);
-	}
-#endif
-	/* Issue TX_RESET and TX_START commands. */
-	outw(TxReset, ioaddr + EL3_CMD);
-	for (i = 20; i >= 0; i--)
-		if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
-			break;
-	outw(TxEnable, ioaddr + EL3_CMD);
-	dev->trans_start = jiffies; /* prevent tx timeout */
-	dev->stats.tx_errors++;
-	dev->stats.tx_dropped++;
-	netif_wake_queue(dev);
-}
-
-static netdev_tx_t corkscrew_start_xmit(struct sk_buff *skb,
-					struct net_device *dev)
-{
-	struct corkscrew_private *vp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-
-	/* Block a timer-based transmit from overlapping. */
-
-	netif_stop_queue(dev);
-
-	if (vp->full_bus_master_tx) {	/* BOOMERANG bus-master */
-		/* Calculate the next Tx descriptor entry. */
-		int entry = vp->cur_tx % TX_RING_SIZE;
-		struct boom_tx_desc *prev_entry;
-		unsigned long flags;
-		int i;
-
-		if (vp->tx_full)	/* No room to transmit with */
-			return NETDEV_TX_BUSY;
-		if (vp->cur_tx != 0)
-			prev_entry = &vp->tx_ring[(vp->cur_tx - 1) % TX_RING_SIZE];
-		else
-			prev_entry = NULL;
-		if (corkscrew_debug > 3)
-			pr_debug("%s: Trying to send a packet, Tx index %d.\n",
-				dev->name, vp->cur_tx);
-		/* vp->tx_full = 1; */
-		vp->tx_skbuff[entry] = skb;
-		vp->tx_ring[entry].next = 0;
-		vp->tx_ring[entry].addr = isa_virt_to_bus(skb->data);
-		vp->tx_ring[entry].length = skb->len | 0x80000000;
-		vp->tx_ring[entry].status = skb->len | 0x80000000;
-
-		spin_lock_irqsave(&vp->lock, flags);
-		outw(DownStall, ioaddr + EL3_CMD);
-		/* Wait for the stall to complete. */
-		for (i = 20; i >= 0; i--)
-			if ((inw(ioaddr + EL3_STATUS) & CmdInProgress) == 0)
-				break;
-		if (prev_entry)
-			prev_entry->next = isa_virt_to_bus(&vp->tx_ring[entry]);
-		if (inl(ioaddr + DownListPtr) == 0) {
-			outl(isa_virt_to_bus(&vp->tx_ring[entry]),
-			     ioaddr + DownListPtr);
-			queued_packet++;
-		}
-		outw(DownUnstall, ioaddr + EL3_CMD);
-		spin_unlock_irqrestore(&vp->lock, flags);
-
-		vp->cur_tx++;
-		if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1)
-			vp->tx_full = 1;
-		else {		/* Clear previous interrupt enable. */
-			if (prev_entry)
-				prev_entry->status &= ~0x80000000;
-			netif_wake_queue(dev);
-		}
-		return NETDEV_TX_OK;
-	}
-	/* Put out the doubleword header... */
-	outl(skb->len, ioaddr + TX_FIFO);
-	dev->stats.tx_bytes += skb->len;
-#ifdef VORTEX_BUS_MASTER
-	if (vp->bus_master) {
-		/* Set the bus-master controller to transfer the packet. */
-		outl((int) (skb->data), ioaddr + Wn7_MasterAddr);
-		outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
-		vp->tx_skb = skb;
-		outw(StartDMADown, ioaddr + EL3_CMD);
-		/* queue will be woken at the DMADone interrupt. */
-	} else {
-		/* ... and the packet rounded to a doubleword. */
-		outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
-		dev_kfree_skb(skb);
-		if (inw(ioaddr + TxFree) > 1536) {
-			netif_wake_queue(dev);
-		} else
-			/* Interrupt us when the FIFO has room for max-sized packet. */
-			outw(SetTxThreshold + (1536 >> 2),
-			     ioaddr + EL3_CMD);
-	}
-#else
-	/* ... and the packet rounded to a doubleword. */
-	outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
-	dev_kfree_skb(skb);
-	if (inw(ioaddr + TxFree) > 1536) {
-		netif_wake_queue(dev);
-	} else
-		/* Interrupt us when the FIFO has room for max-sized packet. */
-		outw(SetTxThreshold + (1536 >> 2), ioaddr + EL3_CMD);
-#endif				/* bus master */
-
-
-	/* Clear the Tx status stack. */
-	{
-		short tx_status;
-		int i = 4;
-
-		while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
-			if (tx_status & 0x3C) {	/* A Tx-disabling error occurred.  */
-				if (corkscrew_debug > 2)
-					pr_debug("%s: Tx error, status %2.2x.\n",
-						dev->name, tx_status);
-				if (tx_status & 0x04)
-					dev->stats.tx_fifo_errors++;
-				if (tx_status & 0x38)
-					dev->stats.tx_aborted_errors++;
-				if (tx_status & 0x30) {
-					int j;
-					outw(TxReset, ioaddr + EL3_CMD);
-					for (j = 20; j >= 0; j--)
-						if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
-							break;
-				}
-				outw(TxEnable, ioaddr + EL3_CMD);
-			}
-			outb(0x00, ioaddr + TxStatus);	/* Pop the status stack. */
-		}
-	}
-	return NETDEV_TX_OK;
-}
-
-/* The interrupt handler does all of the Rx thread work and cleans up
-   after the Tx thread. */
-
-static irqreturn_t corkscrew_interrupt(int irq, void *dev_id)
-{
-	/* Use the now-standard shared IRQ implementation. */
-	struct net_device *dev = dev_id;
-	struct corkscrew_private *lp = netdev_priv(dev);
-	int ioaddr, status;
-	int latency;
-	int i = max_interrupt_work;
-
-	ioaddr = dev->base_addr;
-	latency = inb(ioaddr + Timer);
-
-	spin_lock(&lp->lock);
-
-	status = inw(ioaddr + EL3_STATUS);
-
-	if (corkscrew_debug > 4)
-		pr_debug("%s: interrupt, status %4.4x, timer %d.\n",
-			dev->name, status, latency);
-	if ((status & 0xE000) != 0xE000) {
-		static int donedidthis;
-		/* Some interrupt controllers store a bogus interrupt from boot-time.
-		   Ignore a single early interrupt, but don't hang the machine for
-		   other interrupt problems. */
-		if (donedidthis++ > 100) {
-			pr_err("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
-				   dev->name, status, netif_running(dev));
-			free_irq(dev->irq, dev);
-			dev->irq = -1;
-		}
-	}
-
-	do {
-		if (corkscrew_debug > 5)
-			pr_debug("%s: In interrupt loop, status %4.4x.\n",
-			       dev->name, status);
-		if (status & RxComplete)
-			corkscrew_rx(dev);
-
-		if (status & TxAvailable) {
-			if (corkscrew_debug > 5)
-				pr_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);
-		}
-		if (status & DownComplete) {
-			unsigned int dirty_tx = lp->dirty_tx;
-
-			while (lp->cur_tx - dirty_tx > 0) {
-				int entry = dirty_tx % TX_RING_SIZE;
-				if (inl(ioaddr + DownListPtr) == isa_virt_to_bus(&lp->tx_ring[entry]))
-					break;	/* It still hasn't been processed. */
-				if (lp->tx_skbuff[entry]) {
-					dev_kfree_skb_irq(lp->tx_skbuff[entry]);
-					lp->tx_skbuff[entry] = NULL;
-				}
-				dirty_tx++;
-			}
-			lp->dirty_tx = dirty_tx;
-			outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
-			if (lp->tx_full && (lp->cur_tx - dirty_tx <= TX_RING_SIZE - 1)) {
-				lp->tx_full = 0;
-				netif_wake_queue(dev);
-			}
-		}
-#ifdef VORTEX_BUS_MASTER
-		if (status & DMADone) {
-			outw(0x1000, ioaddr + Wn7_MasterStatus);	/* Ack the event. */
-			dev_kfree_skb_irq(lp->tx_skb);	/* Release the transferred buffer */
-			netif_wake_queue(dev);
-		}
-#endif
-		if (status & UpComplete) {
-			boomerang_rx(dev);
-			outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
-		}
-		if (status & (AdapterFailure | RxEarly | StatsFull)) {
-			/* Handle all uncommon interrupts at once. */
-			if (status & RxEarly) {	/* Rx early is unused. */
-				corkscrew_rx(dev);
-				outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
-			}
-			if (status & StatsFull) {	/* Empty statistics. */
-				static int DoneDidThat;
-				if (corkscrew_debug > 4)
-					pr_debug("%s: Updating stats.\n", dev->name);
-				update_stats(ioaddr, dev);
-				/* DEBUG HACK: Disable statistics as an interrupt source. */
-				/* This occurs when we have the wrong media type! */
-				if (DoneDidThat == 0 && inw(ioaddr + EL3_STATUS) & StatsFull) {
-					int win, reg;
-					pr_notice("%s: Updating stats failed, disabling stats as an interrupt source.\n",
-						dev->name);
-					for (win = 0; win < 8; win++) {
-						EL3WINDOW(win);
-						pr_notice("Vortex window %d:", win);
-						for (reg = 0; reg < 16; reg++)
-							pr_cont(" %2.2x", inb(ioaddr + reg));
-						pr_cont("\n");
-					}
-					EL3WINDOW(7);
-					outw(SetIntrEnb | TxAvailable |
-					     RxComplete | AdapterFailure |
-					     UpComplete | DownComplete |
-					     TxComplete, ioaddr + EL3_CMD);
-					DoneDidThat++;
-				}
-			}
-			if (status & AdapterFailure) {
-				/* Adapter failure requires Rx reset and reinit. */
-				outw(RxReset, ioaddr + EL3_CMD);
-				/* Set the Rx filter to the current state. */
-				set_rx_mode(dev);
-				outw(RxEnable, ioaddr + EL3_CMD);	/* Re-enable the receiver. */
-				outw(AckIntr | AdapterFailure,
-				     ioaddr + EL3_CMD);
-			}
-		}
-
-		if (--i < 0) {
-			pr_err("%s: Too much work in interrupt, status %4.4x. Disabling functions (%4.4x).\n",
-				dev->name, status, SetStatusEnb | ((~status) & 0x7FE));
-			/* Disable all pending interrupts. */
-			outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
-			outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
-			break;
-		}
-		/* Acknowledge the IRQ. */
-		outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
-
-	} while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
-
-	spin_unlock(&lp->lock);
-
-	if (corkscrew_debug > 4)
-		pr_debug("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
-	return IRQ_HANDLED;
-}
-
-static int corkscrew_rx(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-	int i;
-	short rx_status;
-
-	if (corkscrew_debug > 5)
-		pr_debug("   In rx_packet(), status %4.4x, rx_status %4.4x.\n",
-		     inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
-	while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
-		if (rx_status & 0x4000) {	/* Error, update stats. */
-			unsigned char rx_error = inb(ioaddr + RxErrors);
-			if (corkscrew_debug > 2)
-				pr_debug(" Rx error: status %2.2x.\n",
-				       rx_error);
-			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!. */
-			short pkt_len = rx_status & 0x1fff;
-			struct sk_buff *skb;
-
-			skb = dev_alloc_skb(pkt_len + 5 + 2);
-			if (corkscrew_debug > 4)
-				pr_debug("Receiving packet size %d status %4.4x.\n",
-				     pkt_len, rx_status);
-			if (skb != NULL) {
-				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-				/* 'skb_put()' points to the start of sk_buff data area. */
-				insl(ioaddr + RX_FIFO,
-				     skb_put(skb, pkt_len),
-				     (pkt_len + 3) >> 2);
-				outw(RxDiscard, ioaddr + EL3_CMD);	/* Pop top Rx packet. */
-				skb->protocol = eth_type_trans(skb, dev);
-				netif_rx(skb);
-				dev->stats.rx_packets++;
-				dev->stats.rx_bytes += pkt_len;
-				/* Wait a limited time to go to next packet. */
-				for (i = 200; i >= 0; i--)
-					if (! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
-						break;
-				continue;
-			} else if (corkscrew_debug)
-				pr_debug("%s: Couldn't allocate a sk_buff of size %d.\n", dev->name, pkt_len);
-		}
-		outw(RxDiscard, ioaddr + EL3_CMD);
-		dev->stats.rx_dropped++;
-		/* Wait a limited time to skip this packet. */
-		for (i = 200; i >= 0; i--)
-			if (!(inw(ioaddr + EL3_STATUS) & CmdInProgress))
-				break;
-	}
-	return 0;
-}
-
-static int boomerang_rx(struct net_device *dev)
-{
-	struct corkscrew_private *vp = netdev_priv(dev);
-	int entry = vp->cur_rx % RX_RING_SIZE;
-	int ioaddr = dev->base_addr;
-	int rx_status;
-
-	if (corkscrew_debug > 5)
-		pr_debug("   In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
-			inw(ioaddr + EL3_STATUS), inw(ioaddr + RxStatus));
-	while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
-		if (rx_status & RxDError) {	/* Error, update stats. */
-			unsigned char rx_error = rx_status >> 16;
-			if (corkscrew_debug > 2)
-				pr_debug(" Rx error: status %2.2x.\n",
-				       rx_error);
-			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!. */
-			short pkt_len = rx_status & 0x1fff;
-			struct sk_buff *skb;
-
-			dev->stats.rx_bytes += pkt_len;
-			if (corkscrew_debug > 4)
-				pr_debug("Receiving packet size %d status %4.4x.\n",
-				     pkt_len, rx_status);
-
-			/* Check if the packet is long enough to just accept without
-			   copying to a properly sized skbuff. */
-			if (pkt_len < rx_copybreak &&
-			    (skb = dev_alloc_skb(pkt_len + 4)) != NULL) {
-				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-				/* 'skb_put()' points to the start of sk_buff data area. */
-				memcpy(skb_put(skb, pkt_len),
-				       isa_bus_to_virt(vp->rx_ring[entry].
-						   addr), pkt_len);
-				rx_copy++;
-			} else {
-				void *temp;
-				/* Pass up the skbuff already on the Rx ring. */
-				skb = vp->rx_skbuff[entry];
-				vp->rx_skbuff[entry] = NULL;
-				temp = skb_put(skb, pkt_len);
-				/* Remove this checking code for final release. */
-				if (isa_bus_to_virt(vp->rx_ring[entry].addr) != temp)
-					pr_warning("%s: Warning -- the skbuff addresses do not match"
-					     " in boomerang_rx: %p vs. %p / %p.\n",
-					     dev->name,
-					     isa_bus_to_virt(vp->
-							 rx_ring[entry].
-							 addr), skb->head,
-					     temp);
-				rx_nocopy++;
-			}
-			skb->protocol = eth_type_trans(skb, dev);
-			netif_rx(skb);
-			dev->stats.rx_packets++;
-		}
-		entry = (++vp->cur_rx) % RX_RING_SIZE;
-	}
-	/* Refill the Rx ring buffers. */
-	for (; vp->cur_rx - vp->dirty_rx > 0; vp->dirty_rx++) {
-		struct sk_buff *skb;
-		entry = vp->dirty_rx % RX_RING_SIZE;
-		if (vp->rx_skbuff[entry] == NULL) {
-			skb = dev_alloc_skb(PKT_BUF_SZ);
-			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 */
-			vp->rx_ring[entry].addr = isa_virt_to_bus(skb->data);
-			vp->rx_skbuff[entry] = skb;
-		}
-		vp->rx_ring[entry].status = 0;	/* Clear complete bit. */
-	}
-	return 0;
-}
-
-static int corkscrew_close(struct net_device *dev)
-{
-	struct corkscrew_private *vp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-	int i;
-
-	netif_stop_queue(dev);
-
-	if (corkscrew_debug > 1) {
-		pr_debug("%s: corkscrew_close() status %4.4x, Tx status %2.2x.\n",
-		     dev->name, inw(ioaddr + EL3_STATUS),
-		     inb(ioaddr + TxStatus));
-		pr_debug("%s: corkscrew close stats: rx_nocopy %d rx_copy %d tx_queued %d.\n",
-			dev->name, rx_nocopy, rx_copy, queued_packet);
-	}
-
-	del_timer(&vp->timer);
-
-	/* Turn off statistics ASAP.  We update lp->stats below. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
-
-	/* Disable the receiver and transmitter. */
-	outw(RxDisable, ioaddr + EL3_CMD);
-	outw(TxDisable, ioaddr + EL3_CMD);
-
-	if (dev->if_port == XCVR_10base2)
-		/* Turn off thinnet power.  Green! */
-		outw(StopCoax, ioaddr + EL3_CMD);
-
-	free_irq(dev->irq, dev);
-
-	outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
-
-	update_stats(ioaddr, dev);
-	if (vp->full_bus_master_rx) {	/* Free Boomerang bus master Rx buffers. */
-		outl(0, ioaddr + UpListPtr);
-		for (i = 0; i < RX_RING_SIZE; i++)
-			if (vp->rx_skbuff[i]) {
-				dev_kfree_skb(vp->rx_skbuff[i]);
-				vp->rx_skbuff[i] = NULL;
-			}
-	}
-	if (vp->full_bus_master_tx) {	/* Free Boomerang bus master Tx buffers. */
-		outl(0, ioaddr + DownListPtr);
-		for (i = 0; i < TX_RING_SIZE; i++)
-			if (vp->tx_skbuff[i]) {
-				dev_kfree_skb(vp->tx_skbuff[i]);
-				vp->tx_skbuff[i] = NULL;
-			}
-	}
-
-	return 0;
-}
-
-static struct net_device_stats *corkscrew_get_stats(struct net_device *dev)
-{
-	struct corkscrew_private *vp = netdev_priv(dev);
-	unsigned long flags;
-
-	if (netif_running(dev)) {
-		spin_lock_irqsave(&vp->lock, flags);
-		update_stats(dev->base_addr, dev);
-		spin_unlock_irqrestore(&vp->lock, flags);
-	}
-	return &dev->stats;
-}
-
-/*  Update statistics.
-	Unlike with the EL3 we need not worry about interrupts changing
-	the window setting from underneath us, but we must still guard
-	against a race condition with a StatsUpdate interrupt updating the
-	table.  This is done by checking that the ASM (!) code generated uses
-	atomic updates with '+='.
-	*/
-static void update_stats(int 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);
-	dev->stats.tx_carrier_errors += inb(ioaddr + 0);
-	dev->stats.tx_heartbeat_errors += inb(ioaddr + 1);
-	/* Multiple collisions. */ inb(ioaddr + 2);
-	dev->stats.collisions += inb(ioaddr + 3);
-	dev->stats.tx_window_errors += inb(ioaddr + 4);
-	dev->stats.rx_fifo_errors += inb(ioaddr + 5);
-	dev->stats.tx_packets += inb(ioaddr + 6);
-	dev->stats.tx_packets += (inb(ioaddr + 9) & 0x30) << 4;
-						/* Rx packets   */ inb(ioaddr + 7);
-						/* Must read to clear */
-	/* Tx deferrals */ inb(ioaddr + 8);
-	/* 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. */
-	inw(ioaddr + 10);	/* Total Rx and Tx octets. */
-	inw(ioaddr + 12);
-	/* New: On the Vortex we must also clear the BadSSD counter. */
-	EL3WINDOW(4);
-	inb(ioaddr + 12);
-
-	/* We change back to window 7 (not 1) with the Vortex. */
-	EL3WINDOW(7);
-}
-
-/* This new version of set_rx_mode() supports v1.4 kernels.
-   The Vortex chip has no documented multicast filter, so the only
-   multicast setting is to receive all multicast frames.  At least
-   the chip has a very clean way to set the mode, unlike many others. */
-static void set_rx_mode(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-	short new_mode;
-
-	if (dev->flags & IFF_PROMISC) {
-		if (corkscrew_debug > 3)
-			pr_debug("%s: Setting promiscuous mode.\n",
-			       dev->name);
-		new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm;
-	} else if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
-		new_mode = SetRxFilter | RxStation | RxMulticast | RxBroadcast;
-	} else
-		new_mode = SetRxFilter | RxStation | RxBroadcast;
-
-	outw(new_mode, ioaddr + EL3_CMD);
-}
-
-static void netdev_get_drvinfo(struct net_device *dev,
-			       struct ethtool_drvinfo *info)
-{
-	strcpy(info->driver, DRV_NAME);
-	strcpy(info->version, DRV_VERSION);
-	sprintf(info->bus_info, "ISA 0x%lx", dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
-	return corkscrew_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
-	corkscrew_debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
-	.get_drvinfo		= netdev_get_drvinfo,
-	.get_msglevel		= netdev_get_msglevel,
-	.set_msglevel		= netdev_set_msglevel,
-};
-
-
-#ifdef MODULE
-void cleanup_module(void)
-{
-	while (!list_empty(&root_corkscrew_dev)) {
-		struct net_device *dev;
-		struct corkscrew_private *vp;
-
-		vp = list_entry(root_corkscrew_dev.next,
-				struct corkscrew_private, list);
-		dev = vp->our_dev;
-		unregister_netdev(dev);
-		cleanup_card(dev);
-		free_netdev(dev);
-	}
-}
-#endif				/* MODULE */

+ 0 - 1312
drivers/net/3c523.c

@@ -1,1312 +0,0 @@
-/*
-   net-3-driver for the 3c523 Etherlink/MC card (i82586 Ethernet chip)
-
-
-   This is an extension to the Linux operating system, and is covered by the
-   same GNU General Public License that covers that work.
-
-   Copyright 1995, 1996 by Chris Beauregard (cpbeaure@undergrad.math.uwaterloo.ca)
-
-   This is basically Michael Hipp's ni52 driver, with a new probing
-   algorithm and some minor changes to the 82586 CA and reset routines.
-   Thanks a lot Michael for a really clean i82586 implementation!  Unless
-   otherwise documented in ni52.c, any bugs are mine.
-
-   Contrary to the Ethernet-HOWTO, this isn't based on the 3c507 driver in
-   any way.  The ni52 is a lot easier to modify.
-
-   sources:
-   ni52.c
-
-   Crynwr packet driver collection was a great reference for my first
-   attempt at this sucker.  The 3c507 driver also helped, until I noticed
-   that ni52.c was a lot nicer.
-
-   EtherLink/MC: Micro Channel Ethernet Adapter Technical Reference
-   Manual, courtesy of 3Com CardFacts, documents the 3c523-specific
-   stuff.  Information on CardFacts is found in the Ethernet HOWTO.
-   Also see <a href="http://www.3com.com/">
-
-   Microprocessor Communications Support Chips, T.J. Byers, ISBN
-   0-444-01224-9, has a section on the i82586.  It tells you just enough
-   to know that you really don't want to learn how to program the chip.
-
-   The original device probe code was stolen from ps2esdi.c
-
-   Known Problems:
-   Since most of the code was stolen from ni52.c, you'll run across the
-   same bugs in the 0.62 version of ni52.c, plus maybe a few because of
-   the 3c523 idiosynchacies.  The 3c523 has 16K of RAM though, so there
-   shouldn't be the overrun problem that the 8K ni52 has.
-
-   This driver is for a 16K adapter.  It should work fine on the 64K
-   adapters, but it will only use one of the 4 banks of RAM.  Modifying
-   this for the 64K version would require a lot of heinous bank
-   switching, which I'm sure not interested in doing.  If you try to
-   implement a bank switching version, you'll basically have to remember
-   what bank is enabled and do a switch every time you access a memory
-   location that's not current.  You'll also have to remap pointers on
-   the driver side, because it only knows about 16K of the memory.
-   Anyone desperate or masochistic enough to try?
-
-   It seems to be stable now when multiple transmit buffers are used.  I
-   can't see any performance difference, but then I'm working on a 386SX.
-
-   Multicast doesn't work.  It doesn't even pretend to work.  Don't use
-   it.  Don't compile your kernel with multicast support.  I don't know
-   why.
-
-   Features:
-   This driver is useable as a loadable module.  If you try to specify an
-   IRQ or a IO address (via insmod 3c523.o irq=xx io=0xyyy), it will
-   search the MCA slots until it finds a 3c523 with the specified
-   parameters.
-
-   This driver does support multiple ethernet cards when used as a module
-   (up to MAX_3C523_CARDS, the default being 4)
-
-   This has been tested with both BNC and TP versions, internal and
-   external transceivers.  Haven't tested with the 64K version (that I
-   know of).
-
-   History:
-   Jan 1st, 1996
-   first public release
-   Feb 4th, 1996
-   update to 1.3.59, incorporated multicast diffs from ni52.c
-   Feb 15th, 1996
-   added shared irq support
-   Apr 1999
-   added support for multiple cards when used as a module
-   added option to disable multicast as is causes problems
-       Ganesh Sittampalam <ganesh.sittampalam@magdalen.oxford.ac.uk>
-       Stuart Adamson <stuart.adamson@compsoc.net>
-   Nov 2001
-   added support for ethtool (jgarzik)
-
-   $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
- */
-
-#define DRV_NAME		"3c523"
-#define DRV_VERSION		"17-Nov-2001"
-
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/skbuff.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/mca-legacy.h>
-#include <linux/ethtool.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-
-#include <asm/uaccess.h>
-#include <asm/processor.h>
-#include <asm/io.h>
-
-#include "3c523.h"
-
-/*************************************************************************/
-#define DEBUG			/* debug on */
-#define SYSBUSVAL 0		/* 1 = 8 Bit, 0 = 16 bit - 3c523 only does 16 bit */
-#undef ELMC_MULTICAST		/* Disable multicast support as it is somewhat seriously broken at the moment */
-
-#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 ))
-
-/*************************************************************************/
-/*
-   Tables to which we can map values in the configuration registers.
- */
-static int irq_table[] __initdata = {
-	12, 7, 3, 9
-};
-
-static int csr_table[] __initdata = {
-	0x300, 0x1300, 0x2300, 0x3300
-};
-
-static int shm_table[] __initdata = {
-	0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000
-};
-
-/******************* how to calculate the buffers *****************************
-
-
-  * IMPORTANT NOTE: if you configure only one NUM_XMIT_BUFFS, the driver works
-  * --------------- in a different (more stable?) mode. Only in this mode it's
-  *                 possible to configure the driver with 'NO_NOPCOMMANDS'
-
-sizeof(scp)=12; sizeof(scb)=16; sizeof(iscp)=8;
-sizeof(scp)+sizeof(iscp)+sizeof(scb) = 36 = INIT
-sizeof(rfd) = 24; sizeof(rbd) = 12;
-sizeof(tbd) = 8; sizeof(transmit_cmd) = 16;
-sizeof(nop_cmd) = 8;
-
-  * if you don't know the driver, better do not change this values: */
-
-#define RECV_BUFF_SIZE 1524	/* slightly oversized */
-#define XMIT_BUFF_SIZE 1524	/* slightly oversized */
-#define NUM_XMIT_BUFFS 1	/* config for both, 8K and 16K shmem */
-#define NUM_RECV_BUFFS_8  4	/* config for 8K shared mem */
-#define NUM_RECV_BUFFS_16 9	/* config for 16K shared mem */
-
-#if (NUM_XMIT_BUFFS == 1)
-#define NO_NOPCOMMANDS		/* only possible with NUM_XMIT_BUFFS=1 */
-#endif
-
-/**************************************************************************/
-
-#define DELAY(x) { mdelay(32 * x); }
-
-/* a much shorter delay: */
-#define DELAY_16(); { udelay(16) ; }
-
-/* wait for command with timeout: */
-#define WAIT_4_SCB_CMD() { int i; \
-  for(i=0;i<1024;i++) { \
-    if(!p->scb->cmd) break; \
-    DELAY_16(); \
-    if(i == 1023) { \
-      pr_warning("%s:%d: scb_cmd timed out .. resetting i82586\n",\
-      	dev->name,__LINE__); \
-      elmc_id_reset586(); } } }
-
-static irqreturn_t elmc_interrupt(int irq, void *dev_id);
-static int elmc_open(struct net_device *dev);
-static int elmc_close(struct net_device *dev);
-static netdev_tx_t elmc_send_packet(struct sk_buff *, struct net_device *);
-static struct net_device_stats *elmc_get_stats(struct net_device *dev);
-static void elmc_timeout(struct net_device *dev);
-#ifdef ELMC_MULTICAST
-static void set_multicast_list(struct net_device *dev);
-#endif
-static const struct ethtool_ops netdev_ethtool_ops;
-
-/* helper-functions */
-static int init586(struct net_device *dev);
-static int check586(struct net_device *dev, unsigned long 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 elmc_rcv_int(struct net_device *dev);
-static void elmc_xmt_int(struct net_device *dev);
-static void elmc_rnr_int(struct net_device *dev);
-
-struct priv {
-	unsigned long base;
-	char *memtop;
-	unsigned long mapped_start;		/* Start of ioremap */
-	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];
-#if (NUM_XMIT_BUFFS == 1)
-	volatile struct transmit_cmd_struct *xmit_cmds[2];
-	volatile 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];
-#endif
-	volatile int nop_point, num_recv_buffs;
-	volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
-	volatile int xmit_count, xmit_last;
-	volatile int slot;
-};
-
-#define elmc_attn586()  {elmc_do_attn586(dev->base_addr,ELMC_CTRL_INTE);}
-#define elmc_reset586() {elmc_do_reset586(dev->base_addr,ELMC_CTRL_INTE);}
-
-/* with interrupts disabled - this will clear the interrupt bit in the
-   3c523 control register, and won't put it back.  This effectively
-   disables interrupts on the card. */
-#define elmc_id_attn586()  {elmc_do_attn586(dev->base_addr,0);}
-#define elmc_id_reset586() {elmc_do_reset586(dev->base_addr,0);}
-
-/*************************************************************************/
-/*
-   Do a Channel Attention on the 3c523.  This is extremely board dependent.
- */
-static void elmc_do_attn586(int ioaddr, int ints)
-{
-	/* the 3c523 requires a minimum of 500 ns.  The delays here might be
-	   a little too large, and hence they may cut the performance of the
-	   card slightly.  If someone who knows a little more about Linux
-	   timing would care to play with these, I'd appreciate it. */
-
-	/* this bit masking stuff is crap.  I'd rather have separate
-	   registers with strobe triggers for each of these functions.  <sigh>
-	   Ya take what ya got. */
-
-	outb(ELMC_CTRL_RST | 0x3 | ELMC_CTRL_CA | ints, ioaddr + ELMC_CTRL);
-	DELAY_16();		/* > 500 ns */
-	outb(ELMC_CTRL_RST | 0x3 | ints, ioaddr + ELMC_CTRL);
-}
-
-/*************************************************************************/
-/*
-   Reset the 82586 on the 3c523.  Also very board dependent.
- */
-static void elmc_do_reset586(int ioaddr, int ints)
-{
-	/* toggle the RST bit low then high */
-	outb(0x3 | ELMC_CTRL_LBK, ioaddr + ELMC_CTRL);
-	DELAY_16();		/* > 500 ns */
-	outb(ELMC_CTRL_RST | ELMC_CTRL_LBK | 0x3, ioaddr + ELMC_CTRL);
-
-	elmc_do_attn586(ioaddr, ints);
-}
-
-/**********************************************
- * close device
- */
-
-static int elmc_close(struct net_device *dev)
-{
-	netif_stop_queue(dev);
-	elmc_id_reset586();	/* the hard way to stop the receiver */
-	free_irq(dev->irq, dev);
-	return 0;
-}
-
-/**********************************************
- * open device
- */
-
-static int elmc_open(struct net_device *dev)
-{
-	int ret;
-
-	elmc_id_attn586();	/* disable interrupts */
-
-	ret = request_irq(dev->irq, elmc_interrupt, IRQF_SHARED,
-			  dev->name, dev);
-	if (ret) {
-		pr_err("%s: couldn't get irq %d\n", dev->name, dev->irq);
-		elmc_id_reset586();
-		return ret;
-	}
-	alloc586(dev);
-	init586(dev);
-	startrecv586(dev);
-	netif_start_queue(dev);
-	return 0;		/* most done by init */
-}
-
-/**********************************************
- * Check to see if there's an 82586 out there.
- */
-
-static int __init check586(struct net_device *dev, unsigned long where, unsigned size)
-{
-	struct priv *p = netdev_priv(dev);
-	char *iscp_addrs[2];
-	int i = 0;
-
-	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));
-	p->scp->sysbus = SYSBUSVAL;	/* 1 = 8Bit-Bus, 0 = 16 Bit */
-
-	iscp_addrs[0] = isa_bus_to_virt((unsigned long)where);
-	iscp_addrs[1] = (char *) p->scp - sizeof(struct iscp_struct);
-
-	for (i = 0; i < 2; i++) {
-		p->iscp = (struct iscp_struct *) iscp_addrs[i];
-		memset((char *) p->iscp, 0, sizeof(struct iscp_struct));
-
-		p->scp->iscp = make24(p->iscp);
-		p->iscp->busy = 1;
-
-		elmc_id_reset586();
-
-		/* reset586 does an implicit CA */
-
-		/* apparently, you sometimes have to kick the 82586 twice... */
-		elmc_id_attn586();
-		DELAY(1);
-
-		if (p->iscp->busy) {	/* i82586 clears 'busy' after successful init */
-			return 0;
-		}
-	}
-	return 1;
-}
-
-/******************************************************************
- * set iscp at the right place, called by elmc_probe and open586.
- */
-
-static void alloc586(struct net_device *dev)
-{
-	struct priv *p = netdev_priv(dev);
-
-	elmc_id_reset586();
-	DELAY(2);
-
-	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));
-
-	memset((char *) p->iscp, 0, sizeof(struct iscp_struct));
-	memset((char *) p->scp, 0, sizeof(struct scp_struct));
-
-	p->scp->iscp = make24(p->iscp);
-	p->scp->sysbus = SYSBUSVAL;
-	p->iscp->scb_offset = make16(p->scb);
-
-	p->iscp->busy = 1;
-	elmc_id_reset586();
-	elmc_id_attn586();
-
-	DELAY(2);
-
-	if (p->iscp->busy)
-		pr_err("%s: Init-Problems (alloc).\n", dev->name);
-
-	memset((char *) p->scb, 0, sizeof(struct scb_struct));
-}
-
-/*****************************************************************/
-
-static int elmc_getinfo(char *buf, int slot, void *d)
-{
-	int len = 0;
-	struct net_device *dev = d;
-
-	if (dev == NULL)
-		return len;
-
-	len += sprintf(buf + len, "Revision: 0x%x\n",
-		       inb(dev->base_addr + ELMC_REVISION) & 0xf);
-	len += sprintf(buf + len, "IRQ: %d\n", dev->irq);
-	len += sprintf(buf + len, "IO Address: %#lx-%#lx\n", dev->base_addr,
-		       dev->base_addr + ELMC_IO_EXTENT);
-	len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start,
-		       dev->mem_end - 1);
-	len += sprintf(buf + len, "Transceiver: %s\n", dev->if_port ?
-		       "External" : "Internal");
-	len += sprintf(buf + len, "Device: %s\n", dev->name);
-	len += sprintf(buf + len, "Hardware Address: %pM\n",
-		       dev->dev_addr);
-
-	return len;
-}				/* elmc_getinfo() */
-
-static const struct net_device_ops netdev_ops = {
-	.ndo_open 		= elmc_open,
-	.ndo_stop		= elmc_close,
-	.ndo_get_stats		= elmc_get_stats,
-	.ndo_start_xmit		= elmc_send_packet,
-	.ndo_tx_timeout		= elmc_timeout,
-#ifdef ELMC_MULTICAST
-	.ndo_set_multicast_list = set_multicast_list,
-#endif
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-/*****************************************************************/
-
-static int __init do_elmc_probe(struct net_device *dev)
-{
-	static int slot;
-	int base_addr = dev->base_addr;
-	int irq = dev->irq;
-	u_char status = 0;
-	u_char revision = 0;
-	int i = 0;
-	unsigned int size = 0;
-	int retval;
-	struct priv *pr = netdev_priv(dev);
-
-	if (MCA_bus == 0) {
-		return -ENODEV;
-	}
-	/* search through the slots for the 3c523. */
-	slot = mca_find_adapter(ELMC_MCA_ID, 0);
-	while (slot != -1) {
-		status = mca_read_stored_pos(slot, 2);
-
-		dev->irq=irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6];
-		dev->base_addr=csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1];
-
-		/*
-		   If we're trying to match a specified irq or IO address,
-		   we'll reject a match unless it's what we're looking for.
-		   Also reject it if the card is already in use.
-		 */
-
-		if ((irq && irq != dev->irq) ||
-		    (base_addr && base_addr != dev->base_addr)) {
-			slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
-			continue;
-		}
-		if (!request_region(dev->base_addr, ELMC_IO_EXTENT, DRV_NAME)) {
-			slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
-			continue;
-		}
-
-		/* found what we're looking for... */
-		break;
-	}
-
-	/* we didn't find any 3c523 in the slots we checked for */
-	if (slot == MCA_NOTFOUND)
-		return (base_addr || irq) ? -ENXIO : -ENODEV;
-
-	mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC");
-	mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
-
-	/* if we get this far, adapter has been found - carry on */
-	pr_info("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
-
-	/* Now we extract configuration info from the card.
-	   The 3c523 provides information in two of the POS registers, but
-	   the second one is only needed if we want to tell the card what IRQ
-	   to use.  I suspect that whoever sets the thing up initially would
-	   prefer we don't screw with those things.
-
-	   Note that we read the status info when we found the card...
-
-	   See 3c523.h for more details.
-	 */
-
-	/* revision is stored in the first 4 bits of the revision register */
-	revision = inb(dev->base_addr + ELMC_REVISION) & 0xf;
-
-	/* according to docs, we read the interrupt and write it back to
-	   the IRQ select register, since the POST might not configure the IRQ
-	   properly. */
-	switch (dev->irq) {
-	case 3:
-		mca_write_pos(slot, 3, 0x04);
-		break;
-	case 7:
-		mca_write_pos(slot, 3, 0x02);
-		break;
-	case 9:
-		mca_write_pos(slot, 3, 0x08);
-		break;
-	case 12:
-		mca_write_pos(slot, 3, 0x01);
-		break;
-	}
-
-	pr->slot = slot;
-
-	pr_info("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
-	       dev->base_addr);
-
-	/* Determine if we're using the on-board transceiver (i.e. coax) or
-	   an external one.  The information is pretty much useless, but I
-	   guess it's worth brownie points. */
-	dev->if_port = (status & ELMC_STATUS_DISABLE_THIN);
-
-	/* The 3c523 has a 24K chunk of memory.  The first 16K is the
-	   shared memory, while the last 8K is for the EtherStart BIOS ROM.
-	   Which we don't care much about here.  We'll just tell Linux that
-	   we're using 16K.  MCA won't permit address space conflicts caused
-	   by not mapping the other 8K. */
-	dev->mem_start = shm_table[(status & ELMC_STATUS_MEMORY_SELECT) >> 3];
-
-	/* We're using MCA, so it's a given that the information about memory
-	   size is correct.  The Crynwr drivers do something like this. */
-
-	elmc_id_reset586();	/* seems like a good idea before checking it... */
-
-	size = 0x4000;		/* check for 16K mem */
-	if (!check586(dev, dev->mem_start, size)) {
-		pr_err("%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
-		       dev->mem_start);
-		retval = -ENODEV;
-		goto err_out;
-	}
-	dev->mem_end = dev->mem_start + size;	/* set mem_end showed by 'ifconfig' */
-
-	pr->memtop = isa_bus_to_virt(dev->mem_start) + size;
-	pr->base = (unsigned long) isa_bus_to_virt(dev->mem_start) + size - 0x01000000;
-	alloc586(dev);
-
-	elmc_id_reset586();	/* make sure it doesn't generate spurious ints */
-
-	/* set number of receive-buffs according to memsize */
-	pr->num_recv_buffs = NUM_RECV_BUFFS_16;
-
-	/* dump all the assorted information */
-	pr_info("%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
-	       dev->irq, dev->if_port ? "ex" : "in",
-	       dev->mem_start, dev->mem_end - 1);
-
-	/* The hardware address for the 3c523 is stored in the first six
-	   bytes of the IO address. */
-	for (i = 0; i < 6; i++)
-		dev->dev_addr[i] = inb(dev->base_addr + i);
-
-	pr_info("%s: hardware address %pM\n",
-	       dev->name, dev->dev_addr);
-
-	dev->netdev_ops = &netdev_ops;
-	dev->watchdog_timeo = HZ;
-	dev->ethtool_ops = &netdev_ethtool_ops;
-
-	/* note that we haven't actually requested the IRQ from the kernel.
-	   That gets done in elmc_open().  I'm not sure that's such a good idea,
-	   but it works, so I'll go with it. */
-
-#ifndef ELMC_MULTICAST
-        dev->flags&=~IFF_MULTICAST;     /* Multicast doesn't work */
-#endif
-
-	retval = register_netdev(dev);
-	if (retval)
-		goto err_out;
-
-	return 0;
-err_out:
-	mca_set_adapter_procfn(slot, NULL, NULL);
-	release_region(dev->base_addr, ELMC_IO_EXTENT);
-	return retval;
-}
-
-#ifdef MODULE
-static void cleanup_card(struct net_device *dev)
-{
-	mca_set_adapter_procfn(((struct priv *)netdev_priv(dev))->slot,
-				NULL, NULL);
-	release_region(dev->base_addr, ELMC_IO_EXTENT);
-}
-#else
-struct net_device * __init elmc_probe(int unit)
-{
-	struct net_device *dev = alloc_etherdev(sizeof(struct priv));
-	int err;
-
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	sprintf(dev->name, "eth%d", unit);
-	netdev_boot_setup_check(dev);
-
-	err = do_elmc_probe(dev);
-	if (err)
-		goto out;
-	return dev;
-out:
-	free_netdev(dev);
-	return ERR_PTR(err);
-}
-#endif
-
-/**********************************************
- * init the chip (elmc-interrupt should be disabled?!)
- * needs a correct 'allocated' memory
- */
-
-static int init586(struct net_device *dev)
-{
-	void *ptr;
-	unsigned long s;
-	int i, result = 0;
-	struct priv *p = netdev_priv(dev);
-	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 netdev_hw_addr *ha;
-	int num_addrs = netdev_mc_count(dev);
-
-	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 = 0x08;	/* 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 | IFF_PROMISC))
-		cfg_cmd->promisc = 1;
-	cfg_cmd->carr_coll = 0x00;
-
-	p->scb->cbl_offset = make16(cfg_cmd);
-
-	p->scb->cmd = CUC_START;	/* cmd.-unit start */
-	elmc_id_attn586();
-
-	s = jiffies;		/* warning: only active with interrupts on !! */
-	while (!(cfg_cmd->cmd_status & STAT_COMPL)) {
-		if (time_after(jiffies, s + 30*HZ/100))
-			break;
-	}
-
-	if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) {
-		pr_warning("%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
-		return 1;
-	}
-	/*
-	 * individual address setup
-	 */
-	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;
-
-	memcpy((char *) &ias_cmd->iaddr, (char *) dev->dev_addr, ETH_ALEN);
-
-	p->scb->cbl_offset = make16(ias_cmd);
-
-	p->scb->cmd = CUC_START;	/* cmd.-unit start */
-	elmc_id_attn586();
-
-	s = jiffies;
-	while (!(ias_cmd->cmd_status & STAT_COMPL)) {
-		if (time_after(jiffies, s + 30*HZ/100))
-			break;
-	}
-
-	if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) {
-		pr_warning("%s (elmc): individual address setup command failed: %04x\n",
-			dev->name, ias_cmd->cmd_status);
-		return 1;
-	}
-	/*
-	 * TDR, wire check .. e.g. no resistor e.t.c
-	 */
-	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;
-
-	p->scb->cbl_offset = make16(tdr_cmd);
-
-	p->scb->cmd = CUC_START;	/* cmd.-unit start */
-	elmc_attn586();
-
-	s = jiffies;
-	while (!(tdr_cmd->cmd_status & STAT_COMPL)) {
-		if (time_after(jiffies, s + 30*HZ/100)) {
-			pr_warning("%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
-			result = 1;
-			break;
-		}
-	}
-
-	if (!result) {
-		DELAY(2);	/* wait for result */
-		result = tdr_cmd->status;
-
-		p->scb->cmd = p->scb->status & STAT_MASK;
-		elmc_id_attn586();	/* ack the interrupts */
-
-		if (result & TDR_LNK_OK) {
-			/* empty */
-		} else if (result & TDR_XCVR_PRB) {
-			pr_warning("%s: TDR: Transceiver problem!\n", dev->name);
-		} else if (result & TDR_ET_OPN) {
-			pr_warning("%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 :-) */
-				pr_warning("%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
-		} else {
-			pr_warning("%s: TDR: Unknown status %04x\n", dev->name, result);
-		}
-	}
-	/*
-	 * ack interrupts
-	 */
-	p->scb->cmd = p->scb->status & STAT_MASK;
-	elmc_id_attn586();
-
-	/*
-	 * 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]));
-		ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
-	}
-	p->xmit_cmds[0] = (struct transmit_cmd_struct *) ptr;	/* transmit cmd/buff 0 */
-	ptr = (char *) ptr + sizeof(struct transmit_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]));
-		ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
-		p->xmit_cmds[i] = (struct transmit_cmd_struct *) ptr;	/*transmit cmd/buff 0 */
-		ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
-	}
-#endif
-
-	ptr = alloc_rfa(dev, (void *) ptr);	/* init receive-frame-area */
-
-	/*
-	 * Multicast setup
-	 */
-
-	if (num_addrs) {
-		/* I don't understand this: do we really need memory after the init? */
-		int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
-		if (len <= 0) {
-			pr_err("%s: Ooooops, no memory for MC-Setup!\n", dev->name);
-		} else {
-			if (len < num_addrs) {
-				num_addrs = len;
-				pr_warning("%s: Sorry, can only apply %d MC-Address(es).\n",
-				       dev->name, num_addrs);
-			}
-			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;
-			i = 0;
-			netdev_for_each_mc_addr(ha, dev)
-				memcpy((char *) mc_cmd->mc_list[i++],
-				       ha->addr, 6);
-			p->scb->cbl_offset = make16(mc_cmd);
-			p->scb->cmd = CUC_START;
-			elmc_id_attn586();
-			s = jiffies;
-			while (!(mc_cmd->cmd_status & STAT_COMPL)) {
-				if (time_after(jiffies, s + 30*HZ/100))
-					break;
-			}
-			if (!(mc_cmd->cmd_status & STAT_COMPL)) {
-				pr_warning("%s: Can't apply multicast-address-list.\n", dev->name);
-			}
-		}
-	}
-	/*
-	 * alloc xmit-buffs / init xmit_cmds
-	 */
-	for (i = 0; i < NUM_XMIT_BUFFS; i++) {
-		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) {
-			pr_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_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]));
-	}
-
-	p->xmit_count = 0;
-	p->xmit_last = 0;
-#ifndef NO_NOPCOMMANDS
-	p->nop_point = 0;
-#endif
-
-	/*
-	 * 'start transmitter' (nop-loop)
-	 */
-#ifndef NO_NOPCOMMANDS
-	p->scb->cbl_offset = make16(p->nop_cmds[0]);
-	p->scb->cmd = CUC_START;
-	elmc_id_attn586();
-	WAIT_4_SCB_CMD();
-#else
-	p->xmit_cmds[0]->cmd_link = 0xffff;
-	p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT;
-#endif
-
-	return 0;
-}
-
-/******************************************************
- * This is a helper routine for elmc_rnr_int() and init586().
- * It sets up the Receive Frame Area (RFA).
- */
-
-static void *alloc_rfa(struct net_device *dev, void *ptr)
-{
-	volatile struct rfd_struct *rfd = (struct rfd_struct *) ptr;
-	volatile struct rbd_struct *rbd;
-	int i;
-	struct priv *p = netdev_priv(dev);
-
-	memset((char *) rfd, 0, sizeof(struct rfd_struct) * p->num_recv_buffs);
-	p->rfd_first = rfd;
-
-	for (i = 0; i < p->num_recv_buffs; i++) {
-		rfd[i].next = make16(rfd + (i + 1) % p->num_recv_buffs);
-	}
-	rfd[p->num_recv_buffs - 1].last = RFD_SUSP;	/* RU suspend */
-
-	ptr = (void *) (rfd + p->num_recv_buffs);
-
-	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);
-
-	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);
-		ptr = (char *) ptr + RECV_BUFF_SIZE;
-	}
-
-	p->rfd_top = p->rfd_first;
-	p->rfd_last = p->rfd_first + p->num_recv_buffs - 1;
-
-	p->scb->rfa_offset = make16(p->rfd_first);
-	p->rfd_first->rbd_offset = make16(rbd);
-
-	return ptr;
-}
-
-
-/**************************************************
- * Interrupt Handler ...
- */
-
-static irqreturn_t
-elmc_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	unsigned short stat;
-	struct priv *p;
-
-	if (!netif_running(dev)) {
-		/* The 3c523 has this habit of generating interrupts during the
-		   reset.  I'm not sure if the ni52 has this same problem, but it's
-		   really annoying if we haven't finished initializing it.  I was
-		   hoping all the elmc_id_* commands would disable this, but I
-		   might have missed a few. */
-
-		elmc_id_attn586();	/* ack inter. and disable any more */
-		return IRQ_HANDLED;
-	} else if (!(ELMC_CTRL_INT & inb(dev->base_addr + ELMC_CTRL))) {
-		/* wasn't this device */
-		return IRQ_NONE;
-	}
-	/* reading ELMC_CTRL also clears the INT bit. */
-
-	p = netdev_priv(dev);
-
-	while ((stat = p->scb->status & STAT_MASK))
-	{
-		p->scb->cmd = stat;
-		elmc_attn586();	/* ack inter. */
-
-		if (stat & STAT_CX) {
-			/* command with I-bit set complete */
-			elmc_xmt_int(dev);
-		}
-		if (stat & STAT_FR) {
-			/* received a frame */
-			elmc_rcv_int(dev);
-		}
-#ifndef NO_NOPCOMMANDS
-		if (stat & STAT_CNA) {
-			/* CU went 'not ready' */
-			if (netif_running(dev)) {
-				pr_warning("%s: oops! CU has left active state. stat: %04x/%04x.\n",
-					dev->name, (int) stat, (int) p->scb->status);
-			}
-		}
-#endif
-
-		if (stat & STAT_RNR) {
-			/* RU went 'not ready' */
-
-			if (p->scb->status & RU_SUSPEND) {
-				/* special case: RU_SUSPEND */
-
-				WAIT_4_SCB_CMD();
-				p->scb->cmd = RUC_RESUME;
-				elmc_attn586();
-			} else {
-				pr_warning("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",
-					dev->name, (int) stat, (int) p->scb->status);
-				elmc_rnr_int(dev);
-			}
-		}
-		WAIT_4_SCB_CMD();	/* wait for ack. (elmc_xmt_int can be faster than ack!!) */
-		if (p->scb->cmd) {	/* timed out? */
-			break;
-		}
-	}
-	return IRQ_HANDLED;
-}
-
-/*******************************************************
- * receive-interrupt
- */
-
-static void elmc_rcv_int(struct net_device *dev)
-{
-	int status;
-	unsigned short totlen;
-	struct sk_buff *skb;
-	struct rbd_struct *rbd;
-	struct priv *p = netdev_priv(dev);
-
-	for (; (status = p->rfd_top->status) & STAT_COMPL;) {
-		rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
-
-		if (status & STAT_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);	/* 16 byte alignment */
-					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->stats.rx_packets++;
-					dev->stats.rx_bytes += totlen;
-				} else {
-					dev->stats.rx_dropped++;
-				}
-			} else {
-				pr_warning("%s: received oversized frame.\n", dev->name);
-				dev->stats.rx_dropped++;
-			}
-		} else {	/* frame !(ok), only with 'save-bad-frames' */
-			pr_warning("%s: oops! rfd-error-status: %04x\n", dev->name, status);
-			dev->stats.rx_errors++;
-		}
-		p->rfd_top->status = 0;
-		p->rfd_top->last = RFD_SUSP;
-		p->rfd_last->last = 0;	/* delete RU_SUSP  */
-		p->rfd_last = p->rfd_top;
-		p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next);	/* step to next RFD */
-	}
-}
-
-/**********************************************************
- * handle 'Receiver went not ready'.
- */
-
-static void elmc_rnr_int(struct net_device *dev)
-{
-	struct priv *p = netdev_priv(dev);
-
-	dev->stats.rx_errors++;
-
-	WAIT_4_SCB_CMD();	/* wait for the last cmd */
-	p->scb->cmd = RUC_ABORT;	/* usually the RU is in the 'no resource'-state .. abort it now. */
-	elmc_attn586();
-	WAIT_4_SCB_CMD();	/* wait for accept cmd. */
-
-	alloc_rfa(dev, (char *) p->rfd_first);
-	startrecv586(dev);	/* restart RU */
-
-	pr_warning("%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
-
-}
-
-/**********************************************************
- * handle xmit - interrupt
- */
-
-static void elmc_xmt_int(struct net_device *dev)
-{
-	int status;
-	struct priv *p = netdev_priv(dev);
-
-	status = p->xmit_cmds[p->xmit_last]->cmd_status;
-	if (!(status & STAT_COMPL)) {
-		pr_warning("%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
-	}
-	if (status & STAT_OK) {
-		dev->stats.tx_packets++;
-		dev->stats.collisions += (status & TCMD_MAXCOLLMASK);
-	} else {
-		dev->stats.tx_errors++;
-		if (status & TCMD_LATECOLL) {
-			pr_warning("%s: late collision detected.\n", dev->name);
-			dev->stats.collisions++;
-		} else if (status & TCMD_NOCARRIER) {
-			dev->stats.tx_carrier_errors++;
-			pr_warning("%s: no carrier detected.\n", dev->name);
-		} else if (status & TCMD_LOSTCTS) {
-			pr_warning("%s: loss of CTS detected.\n", dev->name);
-		} else if (status & TCMD_UNDERRUN) {
-			dev->stats.tx_fifo_errors++;
-			pr_warning("%s: DMA underrun detected.\n", dev->name);
-		} else if (status & TCMD_MAXCOLL) {
-			pr_warning("%s: Max. collisions exceeded.\n", dev->name);
-			dev->stats.collisions += 16;
-		}
-	}
-
-#if (NUM_XMIT_BUFFS != 1)
-	if ((++p->xmit_last) == NUM_XMIT_BUFFS) {
-		p->xmit_last = 0;
-	}
-#endif
-
-	netif_wake_queue(dev);
-}
-
-/***********************************************************
- * (re)start the receiver
- */
-
-static void startrecv586(struct net_device *dev)
-{
-	struct priv *p = netdev_priv(dev);
-
-	p->scb->rfa_offset = make16(p->rfd_first);
-	p->scb->cmd = RUC_START;
-	elmc_attn586();		/* start cmd. */
-	WAIT_4_SCB_CMD();	/* wait for accept cmd. (no timeout!!) */
-}
-
-/******************************************************
- * timeout
- */
-
-static void elmc_timeout(struct net_device *dev)
-{
-	struct priv *p = netdev_priv(dev);
-	/* COMMAND-UNIT active? */
-	if (p->scb->status & CU_ACTIVE) {
-		pr_debug("%s: strange ... timeout with CU active?!?\n", dev->name);
-		pr_debug("%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);
-		p->scb->cmd = CUC_ABORT;
-		elmc_attn586();
-		WAIT_4_SCB_CMD();
-		p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
-		p->scb->cmd = CUC_START;
-		elmc_attn586();
-		WAIT_4_SCB_CMD();
-		netif_wake_queue(dev);
-	} else {
-		pr_debug("%s: xmitter timed out, try to restart! stat: %04x\n",
-			dev->name, p->scb->status);
-		pr_debug("%s: command-stats: %04x %04x\n", dev->name,
-			p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
-		elmc_close(dev);
-		elmc_open(dev);
-	}
-}
-
-/******************************************************
- * send frame
- */
-
-static netdev_tx_t elmc_send_packet(struct sk_buff *skb, struct net_device *dev)
-{
-	int len;
-	int i;
-#ifndef NO_NOPCOMMANDS
-	int next_nop;
-#endif
-	struct priv *p = netdev_priv(dev);
-
-	netif_stop_queue(dev);
-
-	len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
-
-	if (len != skb->len)
-		memset((char *) p->xmit_cbuffs[p->xmit_count], 0, ETH_ZLEN);
-	skb_copy_from_linear_data(skb, (char *) p->xmit_cbuffs[p->xmit_count], skb->len);
-
-#if (NUM_XMIT_BUFFS == 1)
-#ifdef NO_NOPCOMMANDS
-	p->xmit_buffs[0]->size = TBD_LAST | len;
-	for (i = 0; i < 16; i++) {
-		p->scb->cbl_offset = make16(p->xmit_cmds[0]);
-		p->scb->cmd = CUC_START;
-		p->xmit_cmds[0]->cmd_status = 0;
-			elmc_attn586();
-		if (!i) {
-			dev_kfree_skb(skb);
-		}
-		WAIT_4_SCB_CMD();
-		if ((p->scb->status & CU_ACTIVE)) {	/* test it, because CU sometimes doesn't start immediately */
-			break;
-		}
-		if (p->xmit_cmds[0]->cmd_status) {
-			break;
-		}
-		if (i == 15) {
-			pr_warning("%s: Can't start transmit-command.\n", dev->name);
-		}
-	}
-#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]));
-	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;
-	p->xmit_cmds[p->xmit_count]->cmd_link = 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]));
-	p->xmit_count = next_nop;
-	if (p->xmit_count != p->xmit_last)
-		netif_wake_queue(dev);
-	dev_kfree_skb(skb);
-#endif
-	return NETDEV_TX_OK;
-}
-
-/*******************************************
- * Someone wanna have the statistics
- */
-
-static struct net_device_stats *elmc_get_stats(struct net_device *dev)
-{
-	struct priv *p = netdev_priv(dev);
-	unsigned short crc, aln, rsc, ovrn;
-
-	crc = p->scb->crc_errs;	/* get error-statistic from the ni82586 */
-	p->scb->crc_errs -= crc;
-	aln = p->scb->aln_errs;
-	p->scb->aln_errs -= aln;
-	rsc = p->scb->rsc_errs;
-	p->scb->rsc_errs -= rsc;
-	ovrn = p->scb->ovrn_errs;
-	p->scb->ovrn_errs -= ovrn;
-
-	dev->stats.rx_crc_errors += crc;
-	dev->stats.rx_fifo_errors += ovrn;
-	dev->stats.rx_frame_errors += aln;
-	dev->stats.rx_dropped += rsc;
-
-	return &dev->stats;
-}
-
-/********************************************************
- * Set MC list ..
- */
-
-#ifdef ELMC_MULTICAST
-static void set_multicast_list(struct net_device *dev)
-{
-	if (!dev->start) {
-		/* without a running interface, promiscuous doesn't work */
-		return;
-	}
-	dev->start = 0;
-	alloc586(dev);
-	init586(dev);
-	startrecv586(dev);
-	dev->start = 1;
-}
-#endif
-
-static void netdev_get_drvinfo(struct net_device *dev,
-			       struct ethtool_drvinfo *info)
-{
-	strcpy(info->driver, DRV_NAME);
-	strcpy(info->version, DRV_VERSION);
-	sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr);
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
-	.get_drvinfo		= netdev_get_drvinfo,
-};
-
-#ifdef MODULE
-
-/* Increase if needed ;) */
-#define MAX_3C523_CARDS 4
-
-static struct net_device *dev_elmc[MAX_3C523_CARDS];
-static int irq[MAX_3C523_CARDS];
-static int io[MAX_3C523_CARDS];
-module_param_array(irq, int, NULL, 0);
-module_param_array(io, int, NULL, 0);
-MODULE_PARM_DESC(io, "EtherLink/MC I/O base address(es)");
-MODULE_PARM_DESC(irq, "EtherLink/MC IRQ number(s)");
-MODULE_LICENSE("GPL");
-
-int __init init_module(void)
-{
-	int this_dev,found = 0;
-
-	/* Loop until we either can't find any more cards, or we have MAX_3C523_CARDS */
-	for(this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
-		struct net_device *dev = alloc_etherdev(sizeof(struct priv));
-		if (!dev)
-			break;
-		dev->irq=irq[this_dev];
-		dev->base_addr=io[this_dev];
-		if (do_elmc_probe(dev) == 0) {
-			dev_elmc[this_dev] = dev;
-			found++;
-			continue;
-		}
-		free_netdev(dev);
-		if (io[this_dev]==0)
-			break;
-		pr_warning("3c523.c: No 3c523 card found at io=%#x\n",io[this_dev]);
-	}
-
-	if(found==0) {
-		if (io[0]==0)
-			pr_notice("3c523.c: No 3c523 cards found\n");
-		return -ENXIO;
-	} else return 0;
-}
-
-void __exit cleanup_module(void)
-{
-	int this_dev;
-	for (this_dev=0; this_dev<MAX_3C523_CARDS; this_dev++) {
-		struct net_device *dev = dev_elmc[this_dev];
-		if (dev) {
-			unregister_netdev(dev);
-			cleanup_card(dev);
-			free_netdev(dev);
-		}
-	}
-}
-
-#endif				/* MODULE */

+ 0 - 1661
drivers/net/3c527.c

@@ -1,1661 +0,0 @@
-/* 3c527.c: 3Com Etherlink/MC32 driver for Linux 2.4 and 2.6.
- *
- *	(c) Copyright 1998 Red Hat Software Inc
- *	Written by Alan Cox.
- *	Further debugging by Carl Drougge.
- *      Initial SMP support by Felipe W Damasio <felipewd@terra.com.br>
- *      Heavily modified by Richard Procter <rnp@paradise.net.nz>
- *
- *	Based on skeleton.c written 1993-94 by Donald Becker and ne2.c
- *	(for the MCA stuff) written by Wim Dumon.
- *
- *	Thanks to 3Com for making this possible by providing me with the
- *	documentation.
- *
- *	This software may be used and distributed according to the terms
- *	of the GNU General Public License, incorporated herein by reference.
- *
- */
-
-#define DRV_NAME		"3c527"
-#define DRV_VERSION		"0.7-SMP"
-#define DRV_RELDATE		"2003/09/21"
-
-static const char *version =
-DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Richard Procter <rnp@paradise.net.nz>\n";
-
-/**
- * DOC: Traps for the unwary
- *
- *	The diagram (Figure 1-1) and the POS summary disagree with the
- *	"Interrupt Level" section in the manual.
- *
- *	The manual contradicts itself when describing the minimum number
- *	buffers in the 'configure lists' command.
- *	My card accepts a buffer config of 4/4.
- *
- *	Setting the SAV BP bit does not save bad packets, but
- *	only enables RX on-card stats collection.
- *
- *	The documentation in places seems to miss things. In actual fact
- *	I've always eventually found everything is documented, it just
- *	requires careful study.
- *
- * DOC: Theory Of Operation
- *
- *	The 3com 3c527 is a 32bit MCA bus mastering adapter with a large
- *	amount of on board intelligence that housekeeps a somewhat dumber
- *	Intel NIC. For performance we want to keep the transmit queue deep
- *	as the card can transmit packets while fetching others from main
- *	memory by bus master DMA. Transmission and reception are driven by
- *	circular buffer queues.
- *
- *	The mailboxes can be used for controlling how the card traverses
- *	its buffer rings, but are used only for initial setup in this
- *	implementation.  The exec mailbox allows a variety of commands to
- *	be executed. Each command must complete before the next is
- *	executed. Primarily we use the exec mailbox for controlling the
- *	multicast lists.  We have to do a certain amount of interesting
- *	hoop jumping as the multicast list changes can occur in interrupt
- *	state when the card has an exec command pending. We defer such
- *	events until the command completion interrupt.
- *
- *	A copy break scheme (taken from 3c59x.c) is employed whereby
- *	received frames exceeding a configurable length are passed
- *	directly to the higher networking layers without incuring a copy,
- *	in what amounts to a time/space trade-off.
- *
- *	The card also keeps a large amount of statistical information
- *	on-board. In a perfect world, these could be used safely at no
- *	cost. However, lacking information to the contrary, processing
- *	them without races would involve so much extra complexity as to
- *	make it unworthwhile to do so. In the end, a hybrid SW/HW
- *	implementation was made necessary --- see mc32_update_stats().
- *
- * DOC: Notes
- *
- *	It should be possible to use two or more cards, but at this stage
- *	only by loading two copies of the same module.
- *
- *	The on-board 82586 NIC has trouble receiving multiple
- *	back-to-back frames and so is likely to drop packets from fast
- *	senders.
-**/
-
-#include <linux/module.h>
-
-#include <linux/errno.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/if_ether.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/mca-legacy.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/wait.h>
-#include <linux/ethtool.h>
-#include <linux/completion.h>
-#include <linux/bitops.h>
-#include <linux/semaphore.h>
-
-#include <asm/uaccess.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
-#include "3c527.h"
-
-MODULE_LICENSE("GPL");
-
-/*
- * The name of the card. Is used for messages and in the requests for
- * io regions, irqs and dma channels
- */
-static const char* cardname = DRV_NAME;
-
-/* use 0 for production, 1 for verification, >2 for debug */
-#ifndef NET_DEBUG
-#define NET_DEBUG 2
-#endif
-
-static unsigned int mc32_debug = NET_DEBUG;
-
-/* The number of low I/O ports used by the ethercard. */
-#define MC32_IO_EXTENT	8
-
-/* As implemented, values must be a power-of-2 -- 4/8/16/32 */
-#define TX_RING_LEN     32       /* Typically the card supports 37  */
-#define RX_RING_LEN     8        /*     "       "        "          */
-
-/* Copy break point, see above for details.
- * Setting to > 1512 effectively disables this feature.	*/
-#define RX_COPYBREAK    200      /* Value from 3c59x.c */
-
-/* Issue the 82586 workaround command - this is for "busy lans", but
- * basically means for all lans now days - has a performance (latency)
- * cost, but best set. */
-static const int WORKAROUND_82586=1;
-
-/* Pointers to buffers and their on-card records */
-struct mc32_ring_desc
-{
-	volatile struct skb_header *p;
-	struct sk_buff *skb;
-};
-
-/* Information that needs to be kept for each board. */
-struct mc32_local
-{
-	int slot;
-
-	u32 base;
-	volatile struct mc32_mailbox *rx_box;
-	volatile struct mc32_mailbox *tx_box;
-	volatile struct mc32_mailbox *exec_box;
-        volatile struct mc32_stats *stats;    /* Start of on-card statistics */
-        u16 tx_chain;           /* Transmit list start offset */
-	u16 rx_chain;           /* Receive list start offset */
-        u16 tx_len;             /* Transmit list count */
-        u16 rx_len;             /* Receive list count */
-
-	u16 xceiver_desired_state; /* HALTED or RUNNING */
-	u16 cmd_nonblocking;    /* Thread is uninterested in command result */
-	u16 mc_reload_wait;	/* A multicast load request is pending */
-	u32 mc_list_valid;	/* True when the mclist is set */
-
-	struct mc32_ring_desc tx_ring[TX_RING_LEN];	/* Host Transmit ring */
-	struct mc32_ring_desc rx_ring[RX_RING_LEN];	/* Host Receive ring */
-
-	atomic_t tx_count;	/* buffers left */
-	atomic_t tx_ring_head;  /* index to tx en-queue end */
-	u16 tx_ring_tail;       /* index to tx de-queue end */
-
-	u16 rx_ring_tail;       /* index to rx de-queue end */
-
-	struct semaphore cmd_mutex;    /* Serialises issuing of execute commands */
-        struct completion execution_cmd; /* Card has completed an execute command */
-	struct completion xceiver_cmd;   /* Card has completed a tx or rx command */
-};
-
-/* The station (ethernet) address prefix, used for a sanity check. */
-#define SA_ADDR0 0x02
-#define SA_ADDR1 0x60
-#define SA_ADDR2 0xAC
-
-struct mca_adapters_t {
-	unsigned int	id;
-	char		*name;
-};
-
-static const struct mca_adapters_t mc32_adapters[] = {
-	{ 0x0041, "3COM EtherLink MC/32" },
-	{ 0x8EF5, "IBM High Performance Lan Adapter" },
-	{ 0x0000, NULL }
-};
-
-
-/* Macros for ring index manipulations */
-static inline u16 next_rx(u16 rx) { return (rx+1)&(RX_RING_LEN-1); };
-static inline u16 prev_rx(u16 rx) { return (rx-1)&(RX_RING_LEN-1); };
-
-static inline u16 next_tx(u16 tx) { return (tx+1)&(TX_RING_LEN-1); };
-
-
-/* Index to functions, as function prototypes. */
-static int	mc32_probe1(struct net_device *dev, int ioaddr);
-static int      mc32_command(struct net_device *dev, u16 cmd, void *data, int len);
-static int	mc32_open(struct net_device *dev);
-static void	mc32_timeout(struct net_device *dev);
-static netdev_tx_t mc32_send_packet(struct sk_buff *skb,
-				    struct net_device *dev);
-static irqreturn_t mc32_interrupt(int irq, void *dev_id);
-static int	mc32_close(struct net_device *dev);
-static struct	net_device_stats *mc32_get_stats(struct net_device *dev);
-static void	mc32_set_multicast_list(struct net_device *dev);
-static void	mc32_reset_multicast_list(struct net_device *dev);
-static const struct ethtool_ops netdev_ethtool_ops;
-
-static void cleanup_card(struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	unsigned slot = lp->slot;
-	mca_mark_as_unused(slot);
-	mca_set_adapter_name(slot, NULL);
-	free_irq(dev->irq, dev);
-	release_region(dev->base_addr, MC32_IO_EXTENT);
-}
-
-/**
- * mc32_probe 	-	Search for supported boards
- * @unit: interface number to use
- *
- * Because MCA bus is a real bus and we can scan for cards we could do a
- * single scan for all boards here. Right now we use the passed in device
- * structure and scan for only one board. This needs fixing for modules
- * in particular.
- */
-
-struct net_device *__init mc32_probe(int unit)
-{
-	struct net_device *dev = alloc_etherdev(sizeof(struct mc32_local));
-	static int current_mca_slot = -1;
-	int i;
-	int err;
-
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	if (unit >= 0)
-		sprintf(dev->name, "eth%d", unit);
-
-	/* Do not check any supplied i/o locations.
-	   POS registers usually don't fail :) */
-
-	/* MCA cards have POS registers.
-	   Autodetecting MCA cards is extremely simple.
-	   Just search for the card. */
-
-	for(i = 0; (mc32_adapters[i].name != NULL); i++) {
-		current_mca_slot =
-			mca_find_unused_adapter(mc32_adapters[i].id, 0);
-
-		if(current_mca_slot != MCA_NOTFOUND) {
-			if(!mc32_probe1(dev, current_mca_slot))
-			{
-				mca_set_adapter_name(current_mca_slot,
-						mc32_adapters[i].name);
-				mca_mark_as_used(current_mca_slot);
-				err = register_netdev(dev);
-				if (err) {
-					cleanup_card(dev);
-					free_netdev(dev);
-					dev = ERR_PTR(err);
-				}
-				return dev;
-			}
-
-		}
-	}
-	free_netdev(dev);
-	return ERR_PTR(-ENODEV);
-}
-
-static const struct net_device_ops netdev_ops = {
-	.ndo_open		= mc32_open,
-	.ndo_stop		= mc32_close,
-	.ndo_start_xmit		= mc32_send_packet,
-	.ndo_get_stats		= mc32_get_stats,
-	.ndo_set_multicast_list = mc32_set_multicast_list,
-	.ndo_tx_timeout		= mc32_timeout,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-/**
- * mc32_probe1	-	Check a given slot for a board and test the card
- * @dev:  Device structure to fill in
- * @slot: The MCA bus slot being used by this card
- *
- * Decode the slot data and configure the card structures. Having done this we
- * can reset the card and configure it. The card does a full self test cycle
- * in firmware so we have to wait for it to return and post us either a
- * failure case or some addresses we use to find the board internals.
- */
-
-static int __init mc32_probe1(struct net_device *dev, int slot)
-{
-	static unsigned version_printed;
-	int i, err;
-	u8 POS;
-	u32 base;
-	struct mc32_local *lp = netdev_priv(dev);
-	static const u16 mca_io_bases[] = {
-		0x7280,0x7290,
-		0x7680,0x7690,
-		0x7A80,0x7A90,
-		0x7E80,0x7E90
-	};
-	static const u32 mca_mem_bases[] = {
-		0x00C0000,
-		0x00C4000,
-		0x00C8000,
-		0x00CC000,
-		0x00D0000,
-		0x00D4000,
-		0x00D8000,
-		0x00DC000
-	};
-	static const char * const failures[] = {
-		"Processor instruction",
-		"Processor data bus",
-		"Processor data bus",
-		"Processor data bus",
-		"Adapter bus",
-		"ROM checksum",
-		"Base RAM",
-		"Extended RAM",
-		"82586 internal loopback",
-		"82586 initialisation failure",
-		"Adapter list configuration error"
-	};
-
-	/* Time to play MCA games */
-
-	if (mc32_debug  &&  version_printed++ == 0)
-		pr_debug("%s", version);
-
-	pr_info("%s: %s found in slot %d: ", dev->name, cardname, slot);
-
-	POS = mca_read_stored_pos(slot, 2);
-
-	if(!(POS&1))
-	{
-		pr_cont("disabled.\n");
-		return -ENODEV;
-	}
-
-	/* Fill in the 'dev' fields. */
-	dev->base_addr = mca_io_bases[(POS>>1)&7];
-	dev->mem_start = mca_mem_bases[(POS>>4)&7];
-
-	POS = mca_read_stored_pos(slot, 4);
-	if(!(POS&1))
-	{
-		pr_cont("memory window disabled.\n");
-		return -ENODEV;
-	}
-
-	POS = mca_read_stored_pos(slot, 5);
-
-	i=(POS>>4)&3;
-	if(i==3)
-	{
-		pr_cont("invalid memory window.\n");
-		return -ENODEV;
-	}
-
-	i*=16384;
-	i+=16384;
-
-	dev->mem_end=dev->mem_start + i;
-
-	dev->irq = ((POS>>2)&3)+9;
-
-	if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname))
-	{
-		pr_cont("io 0x%3lX, which is busy.\n", dev->base_addr);
-		return -EBUSY;
-	}
-
-	pr_cont("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
-		dev->base_addr, dev->irq, dev->mem_start, i/1024);
-
-
-	/* We ought to set the cache line size here.. */
-
-
-	/*
-	 *	Go PROM browsing
-	 */
-
-	/* Retrieve and print the ethernet address. */
-	for (i = 0; i < 6; i++)
-	{
-		mca_write_pos(slot, 6, i+12);
-		mca_write_pos(slot, 7, 0);
-
-		dev->dev_addr[i] = mca_read_pos(slot,3);
-	}
-
-	pr_info("%s: Address %pM ", dev->name, dev->dev_addr);
-
-	mca_write_pos(slot, 6, 0);
-	mca_write_pos(slot, 7, 0);
-
-	POS = mca_read_stored_pos(slot, 4);
-
-	if(POS&2)
-		pr_cont(": BNC port selected.\n");
-	else
-		pr_cont(": AUI port selected.\n");
-
-	POS=inb(dev->base_addr+HOST_CTRL);
-	POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET;
-	POS&=~HOST_CTRL_INTE;
-	outb(POS, dev->base_addr+HOST_CTRL);
-	/* Reset adapter */
-	udelay(100);
-	/* Reset off */
-	POS&=~(HOST_CTRL_ATTN|HOST_CTRL_RESET);
-	outb(POS, dev->base_addr+HOST_CTRL);
-
-	udelay(300);
-
-	/*
-	 *	Grab the IRQ
-	 */
-
-	err = request_irq(dev->irq, mc32_interrupt, IRQF_SHARED, DRV_NAME, dev);
-	if (err) {
-		release_region(dev->base_addr, MC32_IO_EXTENT);
-		pr_err("%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
-		goto err_exit_ports;
-	}
-
-	memset(lp, 0, sizeof(struct mc32_local));
-	lp->slot = slot;
-
-	i=0;
-
-	base = inb(dev->base_addr);
-
-	while(base == 0xFF)
-	{
-		i++;
-		if(i == 1000)
-		{
-			pr_err("%s: failed to boot adapter.\n", dev->name);
-			err = -ENODEV;
-			goto err_exit_irq;
-		}
-		udelay(1000);
-		if(inb(dev->base_addr+2)&(1<<5))
-			base = inb(dev->base_addr);
-	}
-
-	if(base>0)
-	{
-		if(base < 0x0C)
-			pr_err("%s: %s%s.\n", dev->name, failures[base-1],
-				base<0x0A?" test failure":"");
-		else
-			pr_err("%s: unknown failure %d.\n", dev->name, base);
-		err = -ENODEV;
-		goto err_exit_irq;
-	}
-
-	base=0;
-	for(i=0;i<4;i++)
-	{
-		int n=0;
-
-		while(!(inb(dev->base_addr+2)&(1<<5)))
-		{
-			n++;
-			udelay(50);
-			if(n>100)
-			{
-				pr_err("%s: mailbox read fail (%d).\n", dev->name, i);
-				err = -ENODEV;
-				goto err_exit_irq;
-			}
-		}
-
-		base|=(inb(dev->base_addr)<<(8*i));
-	}
-
-	lp->exec_box=isa_bus_to_virt(dev->mem_start+base);
-
-	base=lp->exec_box->data[1]<<16|lp->exec_box->data[0];
-
-	lp->base = dev->mem_start+base;
-
-	lp->rx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[2]);
-	lp->tx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[3]);
-
-	lp->stats = isa_bus_to_virt(lp->base + lp->exec_box->data[5]);
-
-	/*
-	 *	Descriptor chains (card relative)
-	 */
-
-	lp->tx_chain 		= lp->exec_box->data[8];   /* Transmit list start offset */
-	lp->rx_chain 		= lp->exec_box->data[10];  /* Receive list start offset */
-	lp->tx_len 		= lp->exec_box->data[9];   /* Transmit list count */
-	lp->rx_len 		= lp->exec_box->data[11];  /* Receive list count */
-
-	sema_init(&lp->cmd_mutex, 0);
-	init_completion(&lp->execution_cmd);
-	init_completion(&lp->xceiver_cmd);
-
-	pr_info("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
-		dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);
-
-	dev->netdev_ops		= &netdev_ops;
-	dev->watchdog_timeo	= HZ*5;	/* Board does all the work */
-	dev->ethtool_ops	= &netdev_ethtool_ops;
-
-	return 0;
-
-err_exit_irq:
-	free_irq(dev->irq, dev);
-err_exit_ports:
-	release_region(dev->base_addr, MC32_IO_EXTENT);
-	return err;
-}
-
-
-/**
- *	mc32_ready_poll		-	wait until we can feed it a command
- *	@dev:	The device to wait for
- *
- *	Wait until the card becomes ready to accept a command via the
- *	command register. This tells us nothing about the completion
- *	status of any pending commands and takes very little time at all.
- */
-
-static inline void mc32_ready_poll(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-	while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR));
-}
-
-
-/**
- *	mc32_command_nowait	-	send a command non blocking
- *	@dev: The 3c527 to issue the command to
- *	@cmd: The command word to write to the mailbox
- *	@data: A data block if the command expects one
- *	@len: Length of the data block
- *
- *	Send a command from interrupt state. If there is a command
- *	currently being executed then we return an error of -1. It
- *	simply isn't viable to wait around as commands may be
- *	slow. This can theoretically be starved on SMP, but it's hard
- *	to see a realistic situation.  We do not wait for the command
- *	to complete --- we rely on the interrupt handler to tidy up
- *	after us.
- */
-
-static int mc32_command_nowait(struct net_device *dev, u16 cmd, void *data, int len)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-	int ret = -1;
-
-	if (down_trylock(&lp->cmd_mutex) == 0)
-	{
-		lp->cmd_nonblocking=1;
-		lp->exec_box->mbox=0;
-		lp->exec_box->mbox=cmd;
-		memcpy((void *)lp->exec_box->data, data, len);
-		barrier();	/* the memcpy forgot the volatile so be sure */
-
-		/* Send the command */
-		mc32_ready_poll(dev);
-		outb(1<<6, ioaddr+HOST_CMD);
-
-		ret = 0;
-
-		/* Interrupt handler will signal mutex on completion */
-	}
-
-	return ret;
-}
-
-
-/**
- *	mc32_command	-	send a command and sleep until completion
- *	@dev: The 3c527 card to issue the command to
- *	@cmd: The command word to write to the mailbox
- *	@data: A data block if the command expects one
- *	@len: Length of the data block
- *
- *	Sends exec commands in a user context. This permits us to wait around
- *	for the replies and also to wait for the command buffer to complete
- *	from a previous command before we execute our command. After our
- *	command completes we will attempt any pending multicast reload
- *	we blocked off by hogging the exec buffer.
- *
- *	You feed the card a command, you wait, it interrupts you get a
- *	reply. All well and good. The complication arises because you use
- *	commands for filter list changes which come in at bh level from things
- *	like IPV6 group stuff.
- */
-
-static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-	int ret = 0;
-
-	down(&lp->cmd_mutex);
-
-	/*
-	 *     My Turn
-	 */
-
-	lp->cmd_nonblocking=0;
-	lp->exec_box->mbox=0;
-	lp->exec_box->mbox=cmd;
-	memcpy((void *)lp->exec_box->data, data, len);
-	barrier();	/* the memcpy forgot the volatile so be sure */
-
-	mc32_ready_poll(dev);
-	outb(1<<6, ioaddr+HOST_CMD);
-
-	wait_for_completion(&lp->execution_cmd);
-
-	if(lp->exec_box->mbox&(1<<13))
-		ret = -1;
-
-	up(&lp->cmd_mutex);
-
-	/*
-	 *	A multicast set got blocked - try it now
-         */
-
-	if(lp->mc_reload_wait)
-	{
-		mc32_reset_multicast_list(dev);
-	}
-
-	return ret;
-}
-
-
-/**
- *	mc32_start_transceiver	-	tell board to restart tx/rx
- *	@dev: The 3c527 card to issue the command to
- *
- *	This may be called from the interrupt state, where it is used
- *	to restart the rx ring if the card runs out of rx buffers.
- *
- * 	We must first check if it's ok to (re)start the transceiver. See
- *      mc32_close for details.
- */
-
-static void mc32_start_transceiver(struct net_device *dev) {
-
-	struct mc32_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-
-	/* Ignore RX overflow on device closure */
-	if (lp->xceiver_desired_state==HALTED)
-		return;
-
-	/* Give the card the offset to the post-EOL-bit RX descriptor */
-	mc32_ready_poll(dev);
-	lp->rx_box->mbox=0;
-	lp->rx_box->data[0]=lp->rx_ring[prev_rx(lp->rx_ring_tail)].p->next;
-	outb(HOST_CMD_START_RX, ioaddr+HOST_CMD);
-
-	mc32_ready_poll(dev);
-	lp->tx_box->mbox=0;
-	outb(HOST_CMD_RESTRT_TX, ioaddr+HOST_CMD);   /* card ignores this on RX restart */
-
-	/* We are not interrupted on start completion */
-}
-
-
-/**
- *	mc32_halt_transceiver	-	tell board to stop tx/rx
- *	@dev: The 3c527 card to issue the command to
- *
- *	We issue the commands to halt the card's transceiver. In fact,
- *	after some experimenting we now simply tell the card to
- *	suspend. When issuing aborts occasionally odd things happened.
- *
- *	We then sleep until the card has notified us that both rx and
- *	tx have been suspended.
- */
-
-static void mc32_halt_transceiver(struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-
-	mc32_ready_poll(dev);
-	lp->rx_box->mbox=0;
-	outb(HOST_CMD_SUSPND_RX, ioaddr+HOST_CMD);
-	wait_for_completion(&lp->xceiver_cmd);
-
-	mc32_ready_poll(dev);
-	lp->tx_box->mbox=0;
-	outb(HOST_CMD_SUSPND_TX, ioaddr+HOST_CMD);
-	wait_for_completion(&lp->xceiver_cmd);
-}
-
-
-/**
- *	mc32_load_rx_ring	-	load the ring of receive buffers
- *	@dev: 3c527 to build the ring for
- *
- *	This initialises the on-card and driver datastructures to
- *	the point where mc32_start_transceiver() can be called.
- *
- *	The card sets up the receive ring for us. We are required to use the
- *	ring it provides, although the size of the ring is configurable.
- *
- * 	We allocate an sk_buff for each ring entry in turn and
- * 	initialise its house-keeping info. At the same time, we read
- * 	each 'next' pointer in our rx_ring array. This reduces slow
- * 	shared-memory reads and makes it easy to access predecessor
- * 	descriptors.
- *
- *	We then set the end-of-list bit for the last entry so that the
- * 	card will know when it has run out of buffers.
- */
-
-static int mc32_load_rx_ring(struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	int i;
-	u16 rx_base;
-	volatile struct skb_header *p;
-
-	rx_base=lp->rx_chain;
-
-	for(i=0; i<RX_RING_LEN; i++) {
-		lp->rx_ring[i].skb=alloc_skb(1532, GFP_KERNEL);
-		if (lp->rx_ring[i].skb==NULL) {
-			for (;i>=0;i--)
-				kfree_skb(lp->rx_ring[i].skb);
-			return -ENOBUFS;
-		}
-		skb_reserve(lp->rx_ring[i].skb, 18);
-
-		p=isa_bus_to_virt(lp->base+rx_base);
-
-		p->control=0;
-		p->data=isa_virt_to_bus(lp->rx_ring[i].skb->data);
-		p->status=0;
-		p->length=1532;
-
-		lp->rx_ring[i].p=p;
-		rx_base=p->next;
-	}
-
-	lp->rx_ring[i-1].p->control |= CONTROL_EOL;
-
-	lp->rx_ring_tail=0;
-
-	return 0;
-}
-
-
-/**
- *	mc32_flush_rx_ring	-	free the ring of receive buffers
- *	@lp: Local data of 3c527 to flush the rx ring of
- *
- *	Free the buffer for each ring slot. This may be called
- *      before mc32_load_rx_ring(), eg. on error in mc32_open().
- *      Requires rx skb pointers to point to a valid skb, or NULL.
- */
-
-static void mc32_flush_rx_ring(struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	int i;
-
-	for(i=0; i < RX_RING_LEN; i++)
-	{
-		if (lp->rx_ring[i].skb) {
-			dev_kfree_skb(lp->rx_ring[i].skb);
-			lp->rx_ring[i].skb = NULL;
-		}
-		lp->rx_ring[i].p=NULL;
-	}
-}
-
-
-/**
- *	mc32_load_tx_ring	-	load transmit ring
- *	@dev: The 3c527 card to issue the command to
- *
- *	This sets up the host transmit data-structures.
- *
- *	First, we obtain from the card it's current position in the tx
- *	ring, so that we will know where to begin transmitting
- *	packets.
- *
- * 	Then, we read the 'next' pointers from the on-card tx ring into
- *  	our tx_ring array to reduce slow shared-mem reads. Finally, we
- * 	intitalise the tx house keeping variables.
- *
- */
-
-static void mc32_load_tx_ring(struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	volatile struct skb_header *p;
-	int i;
-	u16 tx_base;
-
-	tx_base=lp->tx_box->data[0];
-
-	for(i=0 ; i<TX_RING_LEN ; i++)
-	{
-		p=isa_bus_to_virt(lp->base+tx_base);
-		lp->tx_ring[i].p=p;
-		lp->tx_ring[i].skb=NULL;
-
-		tx_base=p->next;
-	}
-
-	/* -1 so that tx_ring_head cannot "lap" tx_ring_tail */
-	/* see mc32_tx_ring */
-
-	atomic_set(&lp->tx_count, TX_RING_LEN-1);
-	atomic_set(&lp->tx_ring_head, 0);
-	lp->tx_ring_tail=0;
-}
-
-
-/**
- *	mc32_flush_tx_ring 	-	free transmit ring
- *	@lp: Local data of 3c527 to flush the tx ring of
- *
- *      If the ring is non-empty, zip over the it, freeing any
- *      allocated skb_buffs.  The tx ring house-keeping variables are
- *      then reset. Requires rx skb pointers to point to a valid skb,
- *      or NULL.
- */
-
-static void mc32_flush_tx_ring(struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	int i;
-
-	for (i=0; i < TX_RING_LEN; i++)
-	{
-		if (lp->tx_ring[i].skb)
-		{
-			dev_kfree_skb(lp->tx_ring[i].skb);
-			lp->tx_ring[i].skb = NULL;
-		}
-	}
-
-	atomic_set(&lp->tx_count, 0);
-	atomic_set(&lp->tx_ring_head, 0);
-	lp->tx_ring_tail=0;
-}
-
-
-/**
- *	mc32_open	-	handle 'up' of card
- *	@dev: device to open
- *
- *	The user is trying to bring the card into ready state. This requires
- *	a brief dialogue with the card. Firstly we enable interrupts and then
- *	'indications'. Without these enabled the card doesn't bother telling
- *	us what it has done. This had me puzzled for a week.
- *
- *	We configure the number of card descriptors, then load the network
- *	address and multicast filters. Turn on the workaround mode. This
- *	works around a bug in the 82586 - it asks the firmware to do
- *	so. It has a performance (latency) hit but is needed on busy
- *	[read most] lans. We load the ring with buffers then we kick it
- *	all off.
- */
-
-static int mc32_open(struct net_device *dev)
-{
-	int ioaddr = dev->base_addr;
-	struct mc32_local *lp = netdev_priv(dev);
-	u8 one=1;
-	u8 regs;
-	u16 descnumbuffs[2] = {TX_RING_LEN, RX_RING_LEN};
-
-	/*
-	 *	Interrupts enabled
-	 */
-
-	regs=inb(ioaddr+HOST_CTRL);
-	regs|=HOST_CTRL_INTE;
-	outb(regs, ioaddr+HOST_CTRL);
-
-	/*
-	 *      Allow ourselves to issue commands
-	 */
-
-	up(&lp->cmd_mutex);
-
-
-	/*
-	 *	Send the indications on command
-	 */
-
-	mc32_command(dev, 4, &one, 2);
-
-	/*
-	 *	Poke it to make sure it's really dead.
-	 */
-
-	mc32_halt_transceiver(dev);
-	mc32_flush_tx_ring(dev);
-
-	/*
-	 *	Ask card to set up on-card descriptors to our spec
-	 */
-
-	if(mc32_command(dev, 8, descnumbuffs, 4)) {
-		pr_info("%s: %s rejected our buffer configuration!\n",
-	 	       dev->name, cardname);
-		mc32_close(dev);
-		return -ENOBUFS;
-	}
-
-	/* Report new configuration */
-	mc32_command(dev, 6, NULL, 0);
-
-	lp->tx_chain 		= lp->exec_box->data[8];   /* Transmit list start offset */
-	lp->rx_chain 		= lp->exec_box->data[10];  /* Receive list start offset */
-	lp->tx_len 		= lp->exec_box->data[9];   /* Transmit list count */
-	lp->rx_len 		= lp->exec_box->data[11];  /* Receive list count */
-
-	/* Set Network Address */
-	mc32_command(dev, 1, dev->dev_addr, 6);
-
-	/* Set the filters */
-	mc32_set_multicast_list(dev);
-
-	if (WORKAROUND_82586) {
-		u16 zero_word=0;
-		mc32_command(dev, 0x0D, &zero_word, 2);   /* 82586 bug workaround on  */
-	}
-
-	mc32_load_tx_ring(dev);
-
-	if(mc32_load_rx_ring(dev))
-	{
-		mc32_close(dev);
-		return -ENOBUFS;
-	}
-
-	lp->xceiver_desired_state = RUNNING;
-
-	/* And finally, set the ball rolling... */
-	mc32_start_transceiver(dev);
-
-	netif_start_queue(dev);
-
-	return 0;
-}
-
-
-/**
- *	mc32_timeout	-	handle a timeout from the network layer
- *	@dev: 3c527 that timed out
- *
- *	Handle a timeout on transmit from the 3c527. This normally means
- *	bad things as the hardware handles cable timeouts and mess for
- *	us.
- *
- */
-
-static void mc32_timeout(struct net_device *dev)
-{
-	pr_warning("%s: transmit timed out?\n", dev->name);
-	/* Try to restart the adaptor. */
-	netif_wake_queue(dev);
-}
-
-
-/**
- *	mc32_send_packet	-	queue a frame for transmit
- *	@skb: buffer to transmit
- *	@dev: 3c527 to send it out of
- *
- *	Transmit a buffer. This normally means throwing the buffer onto
- *	the transmit queue as the queue is quite large. If the queue is
- *	full then we set tx_busy and return. Once the interrupt handler
- *	gets messages telling it to reclaim transmit queue entries, we will
- *	clear tx_busy and the kernel will start calling this again.
- *
- *      We do not disable interrupts or acquire any locks; this can
- *      run concurrently with mc32_tx_ring(), and the function itself
- *      is serialised at a higher layer. However, similarly for the
- *      card itself, we must ensure that we update tx_ring_head only
- *      after we've established a valid packet on the tx ring (and
- *      before we let the card "see" it, to prevent it racing with the
- *      irq handler).
- *
- */
-
-static netdev_tx_t mc32_send_packet(struct sk_buff *skb,
-				    struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	u32 head = atomic_read(&lp->tx_ring_head);
-
-	volatile struct skb_header *p, *np;
-
-	netif_stop_queue(dev);
-
-	if(atomic_read(&lp->tx_count)==0) {
-		return NETDEV_TX_BUSY;
-	}
-
-	if (skb_padto(skb, ETH_ZLEN)) {
-		netif_wake_queue(dev);
-		return NETDEV_TX_OK;
-	}
-
-	atomic_dec(&lp->tx_count);
-
-	/* P is the last sending/sent buffer as a pointer */
-	p=lp->tx_ring[head].p;
-
-	head = next_tx(head);
-
-	/* NP is the buffer we will be loading */
-	np=lp->tx_ring[head].p;
-
-	/* We will need this to flush the buffer out */
-	lp->tx_ring[head].skb=skb;
-
-	np->length      = unlikely(skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
-	np->data	= isa_virt_to_bus(skb->data);
-	np->status	= 0;
-	np->control     = CONTROL_EOP | CONTROL_EOL;
-	wmb();
-
-	/*
-	 * The new frame has been setup; we can now
-	 * let the interrupt handler and card "see" it
-	 */
-
-	atomic_set(&lp->tx_ring_head, head);
-	p->control     &= ~CONTROL_EOL;
-
-	netif_wake_queue(dev);
-	return NETDEV_TX_OK;
-}
-
-
-/**
- *	mc32_update_stats	-	pull off the on board statistics
- *	@dev: 3c527 to service
- *
- *
- *	Query and reset the on-card stats. There's the small possibility
- *	of a race here, which would result in an underestimation of
- *	actual errors. As such, we'd prefer to keep all our stats
- *	collection in software. As a rule, we do. However it can't be
- *	used for rx errors and collisions as, by default, the card discards
- *	bad rx packets.
- *
- *	Setting the SAV BP in the rx filter command supposedly
- *	stops this behaviour. However, testing shows that it only seems to
- *	enable the collation of on-card rx statistics --- the driver
- *	never sees an RX descriptor with an error status set.
- *
- */
-
-static void mc32_update_stats(struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	volatile struct mc32_stats *st = lp->stats;
-
-	u32 rx_errors=0;
-
-	rx_errors+=dev->stats.rx_crc_errors   +=st->rx_crc_errors;
-	                                           st->rx_crc_errors=0;
-	rx_errors+=dev->stats.rx_fifo_errors  +=st->rx_overrun_errors;
-	                                           st->rx_overrun_errors=0;
-	rx_errors+=dev->stats.rx_frame_errors +=st->rx_alignment_errors;
- 	                                           st->rx_alignment_errors=0;
-	rx_errors+=dev->stats.rx_length_errors+=st->rx_tooshort_errors;
-	                                           st->rx_tooshort_errors=0;
-	rx_errors+=dev->stats.rx_missed_errors+=st->rx_outofresource_errors;
-	                                           st->rx_outofresource_errors=0;
-        dev->stats.rx_errors=rx_errors;
-
-	/* Number of packets which saw one collision */
-	dev->stats.collisions+=st->dataC[10];
-	st->dataC[10]=0;
-
-	/* Number of packets which saw 2--15 collisions */
-	dev->stats.collisions+=st->dataC[11];
-	st->dataC[11]=0;
-}
-
-
-/**
- *	mc32_rx_ring	-	process the receive ring
- *	@dev: 3c527 that needs its receive ring processing
- *
- *
- *	We have received one or more indications from the card that a
- *	receive has completed. The buffer ring thus contains dirty
- *	entries. We walk the ring by iterating over the circular rx_ring
- *	array, starting at the next dirty buffer (which happens to be the
- *	one we finished up at last time around).
- *
- *	For each completed packet, we will either copy it and pass it up
- * 	the stack or, if the packet is near MTU sized, we allocate
- *	another buffer and flip the old one up the stack.
- *
- *	We must succeed in keeping a buffer on the ring. If necessary we
- *	will toss a received packet rather than lose a ring entry. Once
- *	the first uncompleted descriptor is found, we move the
- *	End-Of-List bit to include the buffers just processed.
- *
- */
-
-static void mc32_rx_ring(struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	volatile struct skb_header *p;
-	u16 rx_ring_tail;
-	u16 rx_old_tail;
-	int x=0;
-
-	rx_old_tail = rx_ring_tail = lp->rx_ring_tail;
-
-	do
-	{
-		p=lp->rx_ring[rx_ring_tail].p;
-
-		if(!(p->status & (1<<7))) { /* Not COMPLETED */
-			break;
-		}
-		if(p->status & (1<<6)) /* COMPLETED_OK */
-		{
-
-			u16 length=p->length;
-			struct sk_buff *skb;
-			struct sk_buff *newskb;
-
-			/* Try to save time by avoiding a copy on big frames */
-
-			if ((length > RX_COPYBREAK) &&
-			    ((newskb=dev_alloc_skb(1532)) != NULL))
-			{
-				skb=lp->rx_ring[rx_ring_tail].skb;
-				skb_put(skb, length);
-
-				skb_reserve(newskb,18);
-				lp->rx_ring[rx_ring_tail].skb=newskb;
-				p->data=isa_virt_to_bus(newskb->data);
-			}
-			else
-			{
-				skb=dev_alloc_skb(length+2);
-
-				if(skb==NULL) {
-					dev->stats.rx_dropped++;
-					goto dropped;
-				}
-
-				skb_reserve(skb,2);
-				memcpy(skb_put(skb, length),
-				       lp->rx_ring[rx_ring_tail].skb->data, length);
-			}
-
-			skb->protocol=eth_type_trans(skb,dev);
- 			dev->stats.rx_packets++;
- 			dev->stats.rx_bytes += length;
-			netif_rx(skb);
-		}
-
-	dropped:
-		p->length = 1532;
-		p->status = 0;
-
-		rx_ring_tail=next_rx(rx_ring_tail);
-	}
-        while(x++<48);
-
-	/* If there was actually a frame to be processed, place the EOL bit */
-	/* at the descriptor prior to the one to be filled next */
-
-	if (rx_ring_tail != rx_old_tail)
-	{
-		lp->rx_ring[prev_rx(rx_ring_tail)].p->control |=  CONTROL_EOL;
-		lp->rx_ring[prev_rx(rx_old_tail)].p->control  &= ~CONTROL_EOL;
-
-		lp->rx_ring_tail=rx_ring_tail;
-	}
-}
-
-
-/**
- *	mc32_tx_ring	-	process completed transmits
- *	@dev: 3c527 that needs its transmit ring processing
- *
- *
- *	This operates in a similar fashion to mc32_rx_ring. We iterate
- *	over the transmit ring. For each descriptor which has been
- *	processed by the card, we free its associated buffer and note
- *	any errors. This continues until the transmit ring is emptied
- *	or we reach a descriptor that hasn't yet been processed by the
- *	card.
- *
- */
-
-static void mc32_tx_ring(struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	volatile struct skb_header *np;
-
-	/*
-	 * We rely on head==tail to mean 'queue empty'.
-	 * This is why lp->tx_count=TX_RING_LEN-1: in order to prevent
-	 * tx_ring_head wrapping to tail and confusing a 'queue empty'
-	 * condition with 'queue full'
-	 */
-
-	while (lp->tx_ring_tail != atomic_read(&lp->tx_ring_head))
-	{
-		u16 t;
-
-		t=next_tx(lp->tx_ring_tail);
-		np=lp->tx_ring[t].p;
-
-		if(!(np->status & (1<<7)))
-		{
-			/* Not COMPLETED */
-			break;
-		}
-		dev->stats.tx_packets++;
-		if(!(np->status & (1<<6))) /* Not COMPLETED_OK */
-		{
-			dev->stats.tx_errors++;
-
-			switch(np->status&0x0F)
-			{
-				case 1:
-					dev->stats.tx_aborted_errors++;
-					break; /* Max collisions */
-				case 2:
-					dev->stats.tx_fifo_errors++;
-					break;
-				case 3:
-					dev->stats.tx_carrier_errors++;
-					break;
-				case 4:
-					dev->stats.tx_window_errors++;
-					break;  /* CTS Lost */
-				case 5:
-					dev->stats.tx_aborted_errors++;
-					break; /* Transmit timeout */
-			}
-		}
-		/* Packets are sent in order - this is
-		    basically a FIFO queue of buffers matching
-		    the card ring */
-		dev->stats.tx_bytes+=lp->tx_ring[t].skb->len;
-		dev_kfree_skb_irq(lp->tx_ring[t].skb);
-		lp->tx_ring[t].skb=NULL;
-		atomic_inc(&lp->tx_count);
-		netif_wake_queue(dev);
-
-		lp->tx_ring_tail=t;
-	}
-
-}
-
-
-/**
- *	mc32_interrupt		-	handle an interrupt from a 3c527
- *	@irq: Interrupt number
- *	@dev_id: 3c527 that requires servicing
- *	@regs: Registers (unused)
- *
- *
- *	An interrupt is raised whenever the 3c527 writes to the command
- *	register. This register contains the message it wishes to send us
- *	packed into a single byte field. We keep reading status entries
- *	until we have processed all the control items, but simply count
- *	transmit and receive reports. When all reports are in we empty the
- *	transceiver rings as appropriate. This saves the overhead of
- *	multiple command requests.
- *
- *	Because MCA is level-triggered, we shouldn't miss indications.
- *	Therefore, we needn't ask the card to suspend interrupts within
- *	this handler. The card receives an implicit acknowledgment of the
- *	current interrupt when we read the command register.
- *
- */
-
-static irqreturn_t mc32_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct mc32_local *lp;
-	int ioaddr, status, boguscount = 0;
-	int rx_event = 0;
-	int tx_event = 0;
-
-	ioaddr = dev->base_addr;
-	lp = netdev_priv(dev);
-
-	/* See whats cooking */
-
-	while((inb(ioaddr+HOST_STATUS)&HOST_STATUS_CWR) && boguscount++<2000)
-	{
-		status=inb(ioaddr+HOST_CMD);
-
-		pr_debug("Status TX%d RX%d EX%d OV%d BC%d\n",
-			(status&7), (status>>3)&7, (status>>6)&1,
-			(status>>7)&1, boguscount);
-
-		switch(status&7)
-		{
-			case 0:
-				break;
-			case 6: /* TX fail */
-			case 2:	/* TX ok */
-				tx_event = 1;
-				break;
-			case 3: /* Halt */
-			case 4: /* Abort */
-				complete(&lp->xceiver_cmd);
-				break;
-			default:
-				pr_notice("%s: strange tx ack %d\n", dev->name, status&7);
-		}
-		status>>=3;
-		switch(status&7)
-		{
-			case 0:
-				break;
-			case 2:	/* RX */
-				rx_event=1;
-				break;
-			case 3: /* Halt */
-			case 4: /* Abort */
-				complete(&lp->xceiver_cmd);
-				break;
-			case 6:
-				/* Out of RX buffers stat */
-				/* Must restart rx */
-				dev->stats.rx_dropped++;
-				mc32_rx_ring(dev);
-				mc32_start_transceiver(dev);
-				break;
-			default:
-				pr_notice("%s: strange rx ack %d\n",
-					dev->name, status&7);
-		}
-		status>>=3;
-		if(status&1)
-		{
-			/*
-			 * No thread is waiting: we need to tidy
-			 * up ourself.
-			 */
-
-			if (lp->cmd_nonblocking) {
-				up(&lp->cmd_mutex);
-				if (lp->mc_reload_wait)
-					mc32_reset_multicast_list(dev);
-			}
-			else complete(&lp->execution_cmd);
-		}
-		if(status&2)
-		{
-			/*
-			 *	We get interrupted once per
-			 *	counter that is about to overflow.
-			 */
-
-			mc32_update_stats(dev);
-		}
-	}
-
-
-	/*
-	 *	Process the transmit and receive rings
-         */
-
-	if(tx_event)
-		mc32_tx_ring(dev);
-
-	if(rx_event)
-		mc32_rx_ring(dev);
-
-	return IRQ_HANDLED;
-}
-
-
-/**
- *	mc32_close	-	user configuring the 3c527 down
- *	@dev: 3c527 card to shut down
- *
- *	The 3c527 is a bus mastering device. We must be careful how we
- *	shut it down. It may also be running shared interrupt so we have
- *	to be sure to silence it properly
- *
- *	We indicate that the card is closing to the rest of the
- *	driver.  Otherwise, it is possible that the card may run out
- *	of receive buffers and restart the transceiver while we're
- *	trying to close it.
- *
- *	We abort any receive and transmits going on and then wait until
- *	any pending exec commands have completed in other code threads.
- *	In theory we can't get here while that is true, in practice I am
- *	paranoid
- *
- *	We turn off the interrupt enable for the board to be sure it can't
- *	intefere with other devices.
- */
-
-static int mc32_close(struct net_device *dev)
-{
-	struct mc32_local *lp = netdev_priv(dev);
-	int ioaddr = dev->base_addr;
-
-	u8 regs;
-	u16 one=1;
-
-	lp->xceiver_desired_state = HALTED;
-	netif_stop_queue(dev);
-
-	/*
-	 *	Send the indications on command (handy debug check)
-	 */
-
-	mc32_command(dev, 4, &one, 2);
-
-	/* Shut down the transceiver */
-
-	mc32_halt_transceiver(dev);
-
-	/* Ensure we issue no more commands beyond this point */
-
-	down(&lp->cmd_mutex);
-
-	/* Ok the card is now stopping */
-
-	regs=inb(ioaddr+HOST_CTRL);
-	regs&=~HOST_CTRL_INTE;
-	outb(regs, ioaddr+HOST_CTRL);
-
-	mc32_flush_rx_ring(dev);
-	mc32_flush_tx_ring(dev);
-
-	mc32_update_stats(dev);
-
-	return 0;
-}
-
-
-/**
- *	mc32_get_stats		-	hand back stats to network layer
- *	@dev: The 3c527 card to handle
- *
- *	We've collected all the stats we can in software already. Now
- *	it's time to update those kept on-card and return the lot.
- *
- */
-
-static struct net_device_stats *mc32_get_stats(struct net_device *dev)
-{
-	mc32_update_stats(dev);
-	return &dev->stats;
-}
-
-
-/**
- *	do_mc32_set_multicast_list	-	attempt to update multicasts
- *	@dev: 3c527 device to load the list on
- *	@retry: indicates this is not the first call.
- *
- *
- * 	Actually set or clear the multicast filter for this adaptor. The
- *	locking issues are handled by this routine. We have to track
- *	state as it may take multiple calls to get the command sequence
- *	completed. We just keep trying to schedule the loads until we
- *	manage to process them all.
- *
- *	num_addrs == -1	Promiscuous mode, receive all packets
- *
- *	num_addrs == 0	Normal mode, clear multicast list
- *
- *	num_addrs > 0	Multicast mode, receive normal and MC packets,
- *			and do best-effort filtering.
- *
- *	See mc32_update_stats() regards setting the SAV BP bit.
- *
- */
-
-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) ||
-	    (dev->flags&IFF_ALLMULTI) ||
-	    netdev_mc_count(dev) > 10)
-		/* Enable promiscuous mode */
-		filt |= 1;
-	else if (!netdev_mc_empty(dev))
-	{
-		unsigned char block[62];
-		unsigned char *bp;
-		struct netdev_hw_addr *ha;
-
-		if(retry==0)
-			lp->mc_list_valid = 0;
-		if(!lp->mc_list_valid)
-		{
-			block[1]=0;
-			block[0]=netdev_mc_count(dev);
-			bp=block+2;
-
-			netdev_for_each_mc_addr(ha, dev) {
-				memcpy(bp, ha->addr, 6);
-				bp+=6;
-			}
-			if(mc32_command_nowait(dev, 2, block,
-					       2+6*netdev_mc_count(dev))==-1)
-			{
-				lp->mc_reload_wait = 1;
-				return;
-			}
-			lp->mc_list_valid=1;
-		}
-	}
-
-	if(mc32_command_nowait(dev, 0, &filt, 2)==-1)
-	{
-		lp->mc_reload_wait = 1;
-	}
-	else {
-		lp->mc_reload_wait = 0;
-	}
-}
-
-
-/**
- *	mc32_set_multicast_list	-	queue multicast list update
- *	@dev: The 3c527 to use
- *
- *	Commence loading the multicast list. This is called when the kernel
- *	changes the lists. It will override any pending list we are trying to
- *	load.
- */
-
-static void mc32_set_multicast_list(struct net_device *dev)
-{
-	do_mc32_set_multicast_list(dev,0);
-}
-
-
-/**
- *	mc32_reset_multicast_list	-	reset multicast list
- *	@dev: The 3c527 to use
- *
- *	Attempt the next step in loading the multicast lists. If this attempt
- *	fails to complete then it will be scheduled and this function called
- *	again later from elsewhere.
- */
-
-static void mc32_reset_multicast_list(struct net_device *dev)
-{
-	do_mc32_set_multicast_list(dev,1);
-}
-
-static void netdev_get_drvinfo(struct net_device *dev,
-			       struct ethtool_drvinfo *info)
-{
-	strcpy(info->driver, DRV_NAME);
-	strcpy(info->version, DRV_VERSION);
-	sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr);
-}
-
-static u32 netdev_get_msglevel(struct net_device *dev)
-{
-	return mc32_debug;
-}
-
-static void netdev_set_msglevel(struct net_device *dev, u32 level)
-{
-	mc32_debug = level;
-}
-
-static const struct ethtool_ops netdev_ethtool_ops = {
-	.get_drvinfo		= netdev_get_drvinfo,
-	.get_msglevel		= netdev_get_msglevel,
-	.set_msglevel		= netdev_set_msglevel,
-};
-
-#ifdef MODULE
-
-static struct net_device *this_device;
-
-/**
- *	init_module		-	entry point
- *
- *	Probe and locate a 3c527 card. This really should probe and locate
- *	all the 3c527 cards in the machine not just one of them. Yes you can
- *	insmod multiple modules for now but it's a hack.
- */
-
-int __init init_module(void)
-{
-	this_device = mc32_probe(-1);
-	if (IS_ERR(this_device))
-		return PTR_ERR(this_device);
-	return 0;
-}
-
-/**
- *	cleanup_module	-	free resources for an unload
- *
- *	Unloading time. We release the MCA bus resources and the interrupt
- *	at which point everything is ready to unload. The card must be stopped
- *	at this point or we would not have been called. When we unload we
- *	leave the card stopped but not totally shut down. When the card is
- *	initialized it must be rebooted or the rings reloaded before any
- *	transmit operations are allowed to start scribbling into memory.
- */
-
-void __exit cleanup_module(void)
-{
-	unregister_netdev(this_device);
-	cleanup_card(this_device);
-	free_netdev(this_device);
-}
-
-#endif /* MODULE */

+ 0 - 3326
drivers/net/3c59x.c

@@ -1,3326 +0,0 @@
-/* EtherLinkXL.c: A 3Com EtherLink PCI III/XL ethernet driver for linux. */
-/*
-	Written 1996-1999 by Donald Becker.
-
-	This software may be used and distributed according to the terms
-	of the GNU General Public License, incorporated herein by reference.
-
-	This driver is for the 3Com "Vortex" and "Boomerang" series ethercards.
-	Members of the series include Fast EtherLink 3c590/3c592/3c595/3c597
-	and the EtherLink XL 3c900 and 3c905 cards.
-
-	Problem reports and questions should be directed to
-	vortex@scyld.com
-
-	The author may be reached as becker@scyld.com, or C/O
-	Scyld Computing Corporation
-	410 Severn Ave., Suite 210
-	Annapolis MD 21403
-
-*/
-
-/*
- * FIXME: This driver _could_ support MTU changing, but doesn't.  See Don's hamachi.c implementation
- * as well as other drivers
- *
- * NOTE: If you make 'vortex_debug' a constant (#define vortex_debug 0) the driver shrinks by 2k
- * due to dead code elimination.  There will be some performance benefits from this due to
- * elimination of all the tests and reduced cache footprint.
- */
-
-
-#define DRV_NAME	"3c59x"
-
-
-
-/* A few values that may be tweaked. */
-/* Keep the ring sizes a power of two for efficiency. */
-#define TX_RING_SIZE	16
-#define RX_RING_SIZE	32
-#define PKT_BUF_SZ		1536			/* Size of each temporary Rx buffer.*/
-
-/* "Knobs" that adjust features and parameters. */
-/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
-   Setting to > 1512 effectively disables this feature. */
-#ifndef __arm__
-static int rx_copybreak = 200;
-#else
-/* ARM systems perform better by disregarding the bus-master
-   transfer capability of these cards. -- rmk */
-static int rx_copybreak = 1513;
-#endif
-/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
-static const int mtu = 1500;
-/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 32;
-/* Tx timeout interval (millisecs) */
-static int watchdog = 5000;
-
-/* Allow aggregation of Tx interrupts.  Saves CPU load at the cost
- * of possible Tx stalls if the system is blocking interrupts
- * somewhere else.  Undefine this to disable.
- */
-#define tx_interrupt_mitigation 1
-
-/* Put out somewhat more debugging messages. (0: no msg, 1 minimal .. 6). */
-#define vortex_debug debug
-#ifdef VORTEX_DEBUG
-static int vortex_debug = VORTEX_DEBUG;
-#else
-static int vortex_debug = 1;
-#endif
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/errno.h>
-#include <linux/in.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/mii.h>
-#include <linux/init.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/ethtool.h>
-#include <linux/highmem.h>
-#include <linux/eisa.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-#include <linux/gfp.h>
-#include <asm/irq.h>			/* For nr_irqs only. */
-#include <asm/io.h>
-#include <asm/uaccess.h>
-
-/* Kernel compatibility defines, some common to David Hinds' PCMCIA package.
-   This is only in the support-all-kernels source code. */
-
-#define RUN_AT(x) (jiffies + (x))
-
-#include <linux/delay.h>
-
-
-static const char version[] __devinitconst =
-	DRV_NAME ": Donald Becker and others.\n";
-
-MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
-MODULE_DESCRIPTION("3Com 3c59x/3c9xx ethernet driver ");
-MODULE_LICENSE("GPL");
-
-
-/* Operational parameter that usually are not changed. */
-
-/* The Vortex size is twice that of the original EtherLinkIII series: the
-   runtime register window, window 1, is now always mapped in.
-   The Boomerang size is twice as large as the Vortex -- it has additional
-   bus master control registers. */
-#define VORTEX_TOTAL_SIZE 0x20
-#define BOOMERANG_TOTAL_SIZE 0x40
-
-/* Set iff a MII transceiver on any interface requires mdio preamble.
-   This only set with the original DP83840 on older 3c905 boards, so the extra
-   code size of a per-interface flag is not worthwhile. */
-static char mii_preamble_required;
-
-#define PFX DRV_NAME ": "
-
-
-
-/*
-				Theory of Operation
-
-I. Board Compatibility
-
-This device driver is designed for the 3Com FastEtherLink and FastEtherLink
-XL, 3Com's PCI to 10/100baseT adapters.  It also works with the 10Mbs
-versions of the FastEtherLink cards.  The supported product IDs are
-  3c590, 3c592, 3c595, 3c597, 3c900, 3c905
-
-The related ISA 3c515 is supported with a separate driver, 3c515.c, included
-with the kernel source or available from
-    cesdis.gsfc.nasa.gov:/pub/linux/drivers/3c515.html
-
-II. Board-specific settings
-
-PCI bus devices are configured by the system at boot time, so no jumpers
-need to be set on the board.  The system BIOS should be set to assign the
-PCI INTA signal to an otherwise unused system IRQ line.
-
-The EEPROM settings for media type and forced-full-duplex are observed.
-The EEPROM media type should be left at the default "autoselect" unless using
-10base2 or AUI connections which cannot be reliably detected.
-
-III. Driver operation
-
-The 3c59x series use an interface that's very similar to the previous 3c5x9
-series.  The primary interface is two programmed-I/O FIFOs, with an
-alternate single-contiguous-region bus-master transfer (see next).
-
-The 3c900 "Boomerang" series uses a full-bus-master interface with separate
-lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
-DEC Tulip and Intel Speedo3.  The first chip version retains a compatible
-programmed-I/O interface that has been removed in 'B' and subsequent board
-revisions.
-
-One extension that is advertised in a very large font is that the adapters
-are capable of being bus masters.  On the Vortex chip this capability was
-only for a single contiguous region making it far less useful than the full
-bus master capability.  There is a significant performance impact of taking
-an extra interrupt or polling for the completion of each transfer, as well
-as difficulty sharing the single transfer engine between the transmit and
-receive threads.  Using DMA transfers is a win only with large blocks or
-with the flawed versions of the Intel Orion motherboard PCI controller.
-
-The Boomerang chip's full-bus-master interface is useful, and has the
-currently-unused advantages over other similar chips that queued transmit
-packets may be reordered and receive buffer groups are associated with a
-single frame.
-
-With full-bus-master support, this driver uses a "RX_COPYBREAK" scheme.
-Rather than a fixed intermediate receive buffer, this scheme allocates
-full-sized skbuffs as receive buffers.  The value RX_COPYBREAK is used as
-the copying breakpoint: it is chosen to trade-off the memory wasted by
-passing the full-sized skbuff to the queue layer for all frames vs. the
-copying cost of copying a frame to a correctly-sized skbuff.
-
-IIIC. Synchronization
-The driver runs as two independent, single-threaded flows of control.  One
-is the send-packet routine, which enforces single-threaded use by the
-dev->tbusy flag.  The other thread is the interrupt handler, which is single
-threaded by the hardware and other software.
-
-IV. Notes
-
-Thanks to Cameron Spitzer and Terry Murphy of 3Com for providing development
-3c590, 3c595, and 3c900 boards.
-The name "Vortex" is the internal 3Com project name for the PCI ASIC, and
-the EISA version is called "Demon".  According to Terry these names come
-from rides at the local amusement park.
-
-The new chips support both ethernet (1.5K) and FDDI (4.5K) packet sizes!
-This driver only supports ethernet packets because of the skbuff allocation
-limit of 4K.
-*/
-
-/* This table drives the PCI probe routines.  It's mostly boilerplate in all
-   of the drivers, and will likely be provided by some future kernel.
-*/
-enum pci_flags_bit {
-	PCI_USES_MASTER=4,
-};
-
-enum {	IS_VORTEX=1, IS_BOOMERANG=2, IS_CYCLONE=4, IS_TORNADO=8,
-	EEPROM_8BIT=0x10,	/* AKPM: Uses 0x230 as the base bitmaps for EEPROM reads */
-	HAS_PWR_CTRL=0x20, HAS_MII=0x40, HAS_NWAY=0x80, HAS_CB_FNS=0x100,
-	INVERT_MII_PWR=0x200, INVERT_LED_PWR=0x400, MAX_COLLISION_RESET=0x800,
-	EEPROM_OFFSET=0x1000, HAS_HWCKSM=0x2000, WNO_XCVR_PWR=0x4000,
-	EXTRA_PREAMBLE=0x8000, EEPROM_RESET=0x10000, };
-
-enum vortex_chips {
-	CH_3C590 = 0,
-	CH_3C592,
-	CH_3C597,
-	CH_3C595_1,
-	CH_3C595_2,
-
-	CH_3C595_3,
-	CH_3C900_1,
-	CH_3C900_2,
-	CH_3C900_3,
-	CH_3C900_4,
-
-	CH_3C900_5,
-	CH_3C900B_FL,
-	CH_3C905_1,
-	CH_3C905_2,
-	CH_3C905B_TX,
-	CH_3C905B_1,
-
-	CH_3C905B_2,
-	CH_3C905B_FX,
-	CH_3C905C,
-	CH_3C9202,
-	CH_3C980,
-	CH_3C9805,
-
-	CH_3CSOHO100_TX,
-	CH_3C555,
-	CH_3C556,
-	CH_3C556B,
-	CH_3C575,
-
-	CH_3C575_1,
-	CH_3CCFE575,
-	CH_3CCFE575CT,
-	CH_3CCFE656,
-	CH_3CCFEM656,
-
-	CH_3CCFEM656_1,
-	CH_3C450,
-	CH_3C920,
-	CH_3C982A,
-	CH_3C982B,
-
-	CH_905BT4,
-	CH_920B_EMB_WNM,
-};
-
-
-/* note: this array directly indexed by above enums, and MUST
- * be kept in sync with both the enums above, and the PCI device
- * table below
- */
-static struct vortex_chip_info {
-	const char *name;
-	int flags;
-	int drv_flags;
-	int io_size;
-} vortex_info_tbl[] __devinitdata = {
-	{"3c590 Vortex 10Mbps",
-	 PCI_USES_MASTER, IS_VORTEX, 32, },
-	{"3c592 EISA 10Mbps Demon/Vortex",					/* AKPM: from Don's 3c59x_cb.c 0.49H */
-	 PCI_USES_MASTER, IS_VORTEX, 32, },
-	{"3c597 EISA Fast Demon/Vortex",					/* AKPM: from Don's 3c59x_cb.c 0.49H */
-	 PCI_USES_MASTER, IS_VORTEX, 32, },
-	{"3c595 Vortex 100baseTx",
-	 PCI_USES_MASTER, IS_VORTEX, 32, },
-	{"3c595 Vortex 100baseT4",
-	 PCI_USES_MASTER, IS_VORTEX, 32, },
-
-	{"3c595 Vortex 100base-MII",
-	 PCI_USES_MASTER, IS_VORTEX, 32, },
-	{"3c900 Boomerang 10baseT",
-	 PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, },
-	{"3c900 Boomerang 10Mbps Combo",
-	 PCI_USES_MASTER, IS_BOOMERANG|EEPROM_RESET, 64, },
-	{"3c900 Cyclone 10Mbps TPO",						/* AKPM: from Don's 0.99M */
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
-	{"3c900 Cyclone 10Mbps Combo",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
-
-	{"3c900 Cyclone 10Mbps TPC",						/* AKPM: from Don's 0.99M */
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
-	{"3c900B-FL Cyclone 10base-FL",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
-	{"3c905 Boomerang 100baseTx",
-	 PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
-	{"3c905 Boomerang 100baseT4",
-	 PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_RESET, 64, },
-	{"3C905B-TX Fast Etherlink XL PCI",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
-	{"3c905B Cyclone 100baseTx",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
-
-	{"3c905B Cyclone 10/100/BNC",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM, 128, },
-	{"3c905B-FX Cyclone 100baseFx",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_HWCKSM, 128, },
-	{"3c905C Tornado",
-	PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
-	{"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|EXTRA_PREAMBLE, 128, },
-
-	{"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|EXTRA_PREAMBLE, 128, },
-	{"3c555 Laptop Hurricane",
-	 PCI_USES_MASTER, IS_CYCLONE|EEPROM_8BIT|HAS_HWCKSM, 128, },
-	{"3c556 Laptop Tornado",
-	 PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|EEPROM_8BIT|HAS_CB_FNS|INVERT_MII_PWR|
-									HAS_HWCKSM, 128, },
-	{"3c556B Laptop Hurricane",
-	 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_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
-	{"3c575 Boomerang CardBus",
-	 PCI_USES_MASTER, IS_BOOMERANG|HAS_MII|EEPROM_8BIT, 128, },
-	{"3CCFE575BT Cyclone CardBus",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_CB_FNS|EEPROM_8BIT|
-									INVERT_LED_PWR|HAS_HWCKSM, 128, },
-	{"3CCFE575CT Tornado CardBus",
-	 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_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_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_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_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
-	{"3c920 Tornado",
-	 PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
-	{"3c982 Hydra Dual Port A",
-	 PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
-
-	{"3c982 Hydra Dual Port B",
-	 PCI_USES_MASTER, IS_TORNADO|HAS_HWCKSM|HAS_NWAY, 128, },
-	{"3c905B-T4",
-	 PCI_USES_MASTER, IS_CYCLONE|HAS_NWAY|HAS_HWCKSM|EXTRA_PREAMBLE, 128, },
-	{"3c920B-EMB-WNM Tornado",
-	 PCI_USES_MASTER, IS_TORNADO|HAS_NWAY|HAS_HWCKSM, 128, },
-
-	{NULL,}, /* NULL terminated list. */
-};
-
-
-static DEFINE_PCI_DEVICE_TABLE(vortex_pci_tbl) = {
-	{ 0x10B7, 0x5900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C590 },
-	{ 0x10B7, 0x5920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C592 },
-	{ 0x10B7, 0x5970, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C597 },
-	{ 0x10B7, 0x5950, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C595_1 },
-	{ 0x10B7, 0x5951, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C595_2 },
-
-	{ 0x10B7, 0x5952, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C595_3 },
-	{ 0x10B7, 0x9000, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C900_1 },
-	{ 0x10B7, 0x9001, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C900_2 },
-	{ 0x10B7, 0x9004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C900_3 },
-	{ 0x10B7, 0x9005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C900_4 },
-
-	{ 0x10B7, 0x9006, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C900_5 },
-	{ 0x10B7, 0x900A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C900B_FL },
-	{ 0x10B7, 0x9050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905_1 },
-	{ 0x10B7, 0x9051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905_2 },
-	{ 0x10B7, 0x9054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_TX },
-	{ 0x10B7, 0x9055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_1 },
-
-	{ 0x10B7, 0x9058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_2 },
-	{ 0x10B7, 0x905A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905B_FX },
-	{ 0x10B7, 0x9200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C905C },
-	{ 0x10B7, 0x9202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9202 },
-	{ 0x10B7, 0x9800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C980 },
-	{ 0x10B7, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C9805 },
-
-	{ 0x10B7, 0x7646, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CSOHO100_TX },
-	{ 0x10B7, 0x5055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C555 },
-	{ 0x10B7, 0x6055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C556 },
-	{ 0x10B7, 0x6056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C556B },
-	{ 0x10B7, 0x5b57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C575 },
-
-	{ 0x10B7, 0x5057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C575_1 },
-	{ 0x10B7, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFE575 },
-	{ 0x10B7, 0x5257, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFE575CT },
-	{ 0x10B7, 0x6560, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFE656 },
-	{ 0x10B7, 0x6562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFEM656 },
-
-	{ 0x10B7, 0x6564, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3CCFEM656_1 },
-	{ 0x10B7, 0x4500, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C450 },
-	{ 0x10B7, 0x9201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C920 },
-	{ 0x10B7, 0x1201, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C982A },
-	{ 0x10B7, 0x1202, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_3C982B },
-
-	{ 0x10B7, 0x9056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_905BT4 },
-	{ 0x10B7, 0x9210, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CH_920B_EMB_WNM },
-
-	{0,}						/* 0 terminated list. */
-};
-MODULE_DEVICE_TABLE(pci, vortex_pci_tbl);
-
-
-/* Operational definitions.
-   These are not used by other compilation units and thus are not
-   exported in a ".h" file.
-
-   First the windows.  There are eight register windows, with the command
-   and status registers available in each.
-   */
-#define EL3_CMD 0x0e
-#define EL3_STATUS 0x0e
-
-/* The top five bits written to EL3_CMD are a command, the lower
-   11 bits are the parameter, if applicable.
-   Note that 11 parameters bits was fine for ethernet, but the new chip
-   can handle FDDI length frames (~4500 octets) and now parameters count
-   32-bit 'Dwords' rather than octets. */
-
-enum vortex_cmd {
-	TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
-	RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11,
-	UpStall = 6<<11, UpUnstall = (6<<11)+1,
-	DownStall = (6<<11)+2, DownUnstall = (6<<11)+3,
-	RxDiscard = 8<<11, TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
-	FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
-	SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
-	SetTxThreshold = 18<<11, SetTxStart = 19<<11,
-	StartDMAUp = 20<<11, StartDMADown = (20<<11)+1, StatsEnable = 21<<11,
-	StatsDisable = 22<<11, StopCoax = 23<<11, SetFilterBit = 25<<11,};
-
-/* The SetRxFilter command accepts the following classes: */
-enum RxFilter {
-	RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
-
-/* Bits in the general status register. */
-enum vortex_status {
-	IntLatch = 0x0001, HostError = 0x0002, TxComplete = 0x0004,
-	TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
-	IntReq = 0x0040, StatsFull = 0x0080,
-	DMADone = 1<<8, DownComplete = 1<<9, UpComplete = 1<<10,
-	DMAInProgress = 1<<11,			/* DMA controller is still busy.*/
-	CmdInProgress = 1<<12,			/* EL3_CMD is still busy.*/
-};
-
-/* Register window 1 offsets, the window used in normal operation.
-   On the Vortex this window is always mapped at offsets 0x10-0x1f. */
-enum Window1 {
-	TX_FIFO = 0x10,  RX_FIFO = 0x10,  RxErrors = 0x14,
-	RxStatus = 0x18,  Timer=0x1A, TxStatus = 0x1B,
-	TxFree = 0x1C, /* Remaining free bytes in Tx buffer. */
-};
-enum Window0 {
-	Wn0EepromCmd = 10,		/* Window 0: EEPROM command register. */
-	Wn0EepromData = 12,		/* Window 0: EEPROM results register. */
-	IntrStatus=0x0E,		/* Valid in all windows. */
-};
-enum Win0_EEPROM_bits {
-	EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0,
-	EEPROM_EWENB = 0x30,		/* Enable erasing/writing for 10 msec. */
-	EEPROM_EWDIS = 0x00,		/* Disable EWENB before 10 msec timeout. */
-};
-/* EEPROM locations. */
-enum eeprom_offset {
-	PhysAddr01=0, PhysAddr23=1, PhysAddr45=2, ModelID=3,
-	EtherLink3ID=7, IFXcvrIO=8, IRQLine=9,
-	NodeAddr01=10, NodeAddr23=11, NodeAddr45=12,
-	DriverTune=13, Checksum=15};
-
-enum Window2 {			/* Window 2. */
-	Wn2_ResetOptions=12,
-};
-enum Window3 {			/* Window 3: MAC/config bits. */
-	Wn3_Config=0, Wn3_MaxPktSize=4, Wn3_MAC_Ctrl=6, Wn3_Options=8,
-};
-
-#define BFEXT(value, offset, bitcount)  \
-    ((((unsigned long)(value)) >> (offset)) & ((1 << (bitcount)) - 1))
-
-#define BFINS(lhs, rhs, offset, bitcount)					\
-	(((lhs) & ~((((1 << (bitcount)) - 1)) << (offset))) |	\
-	(((rhs) & ((1 << (bitcount)) - 1)) << (offset)))
-
-#define RAM_SIZE(v)		BFEXT(v, 0, 3)
-#define RAM_WIDTH(v)	BFEXT(v, 3, 1)
-#define RAM_SPEED(v)	BFEXT(v, 4, 2)
-#define ROM_SIZE(v)		BFEXT(v, 6, 2)
-#define RAM_SPLIT(v)	BFEXT(v, 16, 2)
-#define XCVR(v)			BFEXT(v, 20, 4)
-#define AUTOSELECT(v)	BFEXT(v, 24, 1)
-
-enum Window4 {		/* Window 4: Xcvr/media bits. */
-	Wn4_FIFODiag = 4, Wn4_NetDiag = 6, Wn4_PhysicalMgmt=8, Wn4_Media = 10,
-};
-enum Win4_Media_bits {
-	Media_SQE = 0x0008,		/* Enable SQE error counting for AUI. */
-	Media_10TP = 0x00C0,	/* Enable link beat and jabber for 10baseT. */
-	Media_Lnk = 0x0080,		/* Enable just link beat for 100TX/100FX. */
-	Media_LnkBeat = 0x0800,
-};
-enum Window7 {					/* Window 7: Bus Master control. */
-	Wn7_MasterAddr = 0, Wn7_VlanEtherType=4, Wn7_MasterLen = 6,
-	Wn7_MasterStatus = 12,
-};
-/* Boomerang bus master control registers. */
-enum MasterCtrl {
-	PktStatus = 0x20, DownListPtr = 0x24, FragAddr = 0x28, FragLen = 0x2c,
-	TxFreeThreshold = 0x2f, UpPktStatus = 0x30, UpListPtr = 0x38,
-};
-
-/* The Rx and Tx descriptor lists.
-   Caution Alpha hackers: these types are 32 bits!  Note also the 8 byte
-   alignment contraint on tx_ring[] and rx_ring[]. */
-#define LAST_FRAG 	0x80000000			/* Last Addr/Len pair in descriptor. */
-#define DN_COMPLETE	0x00010000			/* This packet has been downloaded */
-struct boom_rx_desc {
-	__le32 next;					/* Last entry points to 0.   */
-	__le32 status;
-	__le32 addr;					/* Up to 63 addr/len pairs possible. */
-	__le32 length;					/* Set LAST_FRAG to indicate last pair. */
-};
-/* Values for the Rx status entry. */
-enum rx_desc_status {
-	RxDComplete=0x00008000, RxDError=0x4000,
-	/* See boomerang_rx() for actual error bits */
-	IPChksumErr=1<<25, TCPChksumErr=1<<26, UDPChksumErr=1<<27,
-	IPChksumValid=1<<29, TCPChksumValid=1<<30, UDPChksumValid=1<<31,
-};
-
-#ifdef MAX_SKB_FRAGS
-#define DO_ZEROCOPY 1
-#else
-#define DO_ZEROCOPY 0
-#endif
-
-struct boom_tx_desc {
-	__le32 next;					/* Last entry points to 0.   */
-	__le32 status;					/* bits 0:12 length, others see below.  */
-#if DO_ZEROCOPY
-	struct {
-		__le32 addr;
-		__le32 length;
-	} frag[1+MAX_SKB_FRAGS];
-#else
-		__le32 addr;
-		__le32 length;
-#endif
-};
-
-/* Values for the Tx status entry. */
-enum tx_desc_status {
-	CRCDisable=0x2000, TxDComplete=0x8000,
-	AddIPChksum=0x02000000, AddTCPChksum=0x04000000, AddUDPChksum=0x08000000,
-	TxIntrUploaded=0x80000000,		/* IRQ when in FIFO, but maybe not sent. */
-};
-
-/* Chip features we care about in vp->capabilities, read from the EEPROM. */
-enum ChipCaps { CapBusMaster=0x20, CapPwrMgmt=0x2000 };
-
-struct vortex_extra_stats {
-	unsigned long tx_deferred;
-	unsigned long tx_max_collisions;
-	unsigned long tx_multiple_collisions;
-	unsigned long tx_single_collisions;
-	unsigned long rx_bad_ssd;
-};
-
-struct vortex_private {
-	/* The Rx and Tx rings should be quad-word-aligned. */
-	struct boom_rx_desc* rx_ring;
-	struct boom_tx_desc* tx_ring;
-	dma_addr_t rx_ring_dma;
-	dma_addr_t tx_ring_dma;
-	/* The addresses of transmit- and receive-in-place skbuffs. */
-	struct sk_buff* rx_skbuff[RX_RING_SIZE];
-	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 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.   */
-
-	/* PCI configuration space information. */
-	struct device *gendev;
-	void __iomem *ioaddr;			/* IO address space */
-	void __iomem *cb_fn_base;		/* CardBus function status addr space. */
-
-	/* Some values here only for performance evaluation and path-coverage */
-	int rx_nocopy, rx_copy, queued_packet, rx_csumhits;
-	int card_idx;
-
-	/* The remainder are related to chip state, mostly media selection. */
-	struct timer_list timer;			/* Media selection timer. */
-	struct timer_list rx_oom_timer;		/* Rx skb allocation retry timer */
-	int options;						/* User-settable misc. driver options. */
-	unsigned int media_override:4, 		/* Passed-in media type. */
-		default_media:4,				/* Read from the EEPROM/Wn3_Config. */
-		full_duplex:1, autoselect:1,
-		bus_master:1,					/* Vortex can only do a fragment bus-m. */
-		full_bus_master_tx:1, full_bus_master_rx:2, /* Boomerang  */
-		flow_ctrl:1,					/* Use 802.3x flow control (PAUSE only) */
-		partner_flow_ctrl:1,			/* Partner supports flow control */
-		has_nway:1,
-		enable_wol:1,					/* Wake-on-LAN is enabled */
-		pm_state_valid:1,				/* pci_dev->saved_config_space has sane contents */
-		open:1,
-		medialock:1,
-		must_free_region:1,				/* Flag: if zero, Cardbus owns the I/O region */
-		large_frames:1,			/* accept large frames */
-		handling_irq:1;			/* private in_irq indicator */
-	/* {get|set}_wol operations are already serialized by rtnl.
-	 * no additional locking is required for the enable_wol and acpi_set_WOL()
-	 */
-	int drv_flags;
-	u16 status_enable;
-	u16 intr_enable;
-	u16 available_media;				/* From Wn3_Options. */
-	u16 capabilities, info1, info2;		/* Various, from EEPROM. */
-	u16 advertising;					/* NWay media advertisement */
-	unsigned char phys[2];				/* MII device addresses. */
-	u16 deferred;						/* Resend these interrupts when we
-										 * bale from the ISR */
-	u16 io_size;						/* Size of PCI region (for release_region) */
-
-	/* Serialises access to hardware other than MII and variables below.
-	 * The lock hierarchy is rtnl_lock > {lock, mii_lock} > window_lock. */
-	spinlock_t lock;
-
-	spinlock_t mii_lock;		/* Serialises access to MII */
-	struct mii_if_info mii;		/* MII lib hooks/info */
-	spinlock_t window_lock;		/* Serialises access to windowed regs */
-	int window;			/* Register window */
-};
-
-static void window_set(struct vortex_private *vp, int window)
-{
-	if (window != vp->window) {
-		iowrite16(SelectWindow + window, vp->ioaddr + EL3_CMD);
-		vp->window = window;
-	}
-}
-
-#define DEFINE_WINDOW_IO(size)						\
-static u ## size							\
-window_read ## size(struct vortex_private *vp, int window, int addr)	\
-{									\
-	unsigned long flags;						\
-	u ## size ret;							\
-	spin_lock_irqsave(&vp->window_lock, flags);			\
-	window_set(vp, window);						\
-	ret = ioread ## size(vp->ioaddr + addr);			\
-	spin_unlock_irqrestore(&vp->window_lock, flags);		\
-	return ret;							\
-}									\
-static void								\
-window_write ## size(struct vortex_private *vp, u ## size value,	\
-		     int window, int addr)				\
-{									\
-	unsigned long flags;						\
-	spin_lock_irqsave(&vp->window_lock, flags);			\
-	window_set(vp, window);						\
-	iowrite ## size(value, vp->ioaddr + addr);			\
-	spin_unlock_irqrestore(&vp->window_lock, flags);		\
-}
-DEFINE_WINDOW_IO(8)
-DEFINE_WINDOW_IO(16)
-DEFINE_WINDOW_IO(32)
-
-#ifdef CONFIG_PCI
-#define DEVICE_PCI(dev) (((dev)->bus == &pci_bus_type) ? to_pci_dev((dev)) : NULL)
-#else
-#define DEVICE_PCI(dev) NULL
-#endif
-
-#define VORTEX_PCI(vp)							\
-	((struct pci_dev *) (((vp)->gendev) ? DEVICE_PCI((vp)->gendev) : NULL))
-
-#ifdef CONFIG_EISA
-#define DEVICE_EISA(dev) (((dev)->bus == &eisa_bus_type) ? to_eisa_device((dev)) : NULL)
-#else
-#define DEVICE_EISA(dev) NULL
-#endif
-
-#define VORTEX_EISA(vp)							\
-	((struct eisa_device *) (((vp)->gendev) ? DEVICE_EISA((vp)->gendev) : NULL))
-
-/* The action to take with a media selection timer tick.
-   Note that we deviate from the 3Com order by checking 10base2 before AUI.
- */
-enum xcvr_types {
-	XCVR_10baseT=0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx,
-	XCVR_100baseFx, XCVR_MII=6, XCVR_NWAY=8, XCVR_ExtMII=9, XCVR_Default=10,
-};
-
-static const struct media_table {
-	char *name;
-	unsigned int media_bits:16,		/* Bits to set in Wn4_Media register. */
-		mask:8,						/* The transceiver-present bit in Wn3_Config.*/
-		next:8;						/* The media type to try next. */
-	int wait;						/* Time before we check media status. */
-} media_tbl[] = {
-  {	"10baseT",   Media_10TP,0x08, XCVR_10base2, (14*HZ)/10},
-  { "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1*HZ)/10},
-  { "undefined", 0,			0x80, XCVR_10baseT, 10000},
-  { "10base2",   0,			0x10, XCVR_AUI,		(1*HZ)/10},
-  { "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14*HZ)/10},
-  { "100baseFX", Media_Lnk, 0x04, XCVR_MII,		(14*HZ)/10},
-  { "MII",		 0,			0x41, XCVR_10baseT, 3*HZ },
-  { "undefined", 0,			0x01, XCVR_10baseT, 10000},
-  { "Autonegotiate", 0,		0x41, XCVR_10baseT, 3*HZ},
-  { "MII-External",	 0,		0x41, XCVR_10baseT, 3*HZ },
-  { "Default",	 0,			0xFF, XCVR_10baseT, 10000},
-};
-
-static struct {
-	const char str[ETH_GSTRING_LEN];
-} ethtool_stats_keys[] = {
-	{ "tx_deferred" },
-	{ "tx_max_collisions" },
-	{ "tx_multiple_collisions" },
-	{ "tx_single_collisions" },
-	{ "rx_bad_ssd" },
-};
-
-/* number of ETHTOOL_GSTATS u64's */
-#define VORTEX_NUM_STATS    5
-
-static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
-				   int chip_idx, int card_idx);
-static int vortex_up(struct net_device *dev);
-static void vortex_down(struct net_device *dev, int final);
-static int vortex_open(struct net_device *dev);
-static void mdio_sync(struct vortex_private *vp, int bits);
-static int mdio_read(struct net_device *dev, int phy_id, int location);
-static void mdio_write(struct net_device *vp, int phy_id, int location, int value);
-static void vortex_timer(unsigned long arg);
-static void rx_oom_timer(unsigned long arg);
-static netdev_tx_t vortex_start_xmit(struct sk_buff *skb,
-				     struct net_device *dev);
-static netdev_tx_t boomerang_start_xmit(struct sk_buff *skb,
-					struct net_device *dev);
-static int vortex_rx(struct net_device *dev);
-static int boomerang_rx(struct net_device *dev);
-static irqreturn_t vortex_interrupt(int irq, void *dev_id);
-static irqreturn_t boomerang_interrupt(int irq, void *dev_id);
-static int vortex_close(struct net_device *dev);
-static void dump_tx_ring(struct net_device *dev);
-static void update_stats(void __iomem *ioaddr, struct net_device *dev);
-static struct net_device_stats *vortex_get_stats(struct net_device *dev);
-static void set_rx_mode(struct net_device *dev);
-#ifdef CONFIG_PCI
-static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-#endif
-static void vortex_tx_timeout(struct net_device *dev);
-static void acpi_set_WOL(struct net_device *dev);
-static const struct ethtool_ops vortex_ethtool_ops;
-static void set_8021q_mode(struct net_device *dev, int enable);
-
-/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
-/* Option count limit only -- unlimited interfaces are supported. */
-#define MAX_UNITS 8
-static int options[MAX_UNITS] = { [0 ... MAX_UNITS-1] = -1 };
-static int full_duplex[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
-static int hw_checksums[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
-static int flow_ctrl[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
-static int enable_wol[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
-static int use_mmio[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
-static int global_options = -1;
-static int global_full_duplex = -1;
-static int global_enable_wol = -1;
-static int global_use_mmio = -1;
-
-/* Variables to work-around the Compaq PCI BIOS32 problem. */
-static int compaq_ioaddr, compaq_irq, compaq_device_id = 0x5900;
-static struct net_device *compaq_net_device;
-
-static int vortex_cards_found;
-
-module_param(debug, int, 0);
-module_param(global_options, int, 0);
-module_param_array(options, int, NULL, 0);
-module_param(global_full_duplex, int, 0);
-module_param_array(full_duplex, int, NULL, 0);
-module_param_array(hw_checksums, int, NULL, 0);
-module_param_array(flow_ctrl, int, NULL, 0);
-module_param(global_enable_wol, int, 0);
-module_param_array(enable_wol, int, NULL, 0);
-module_param(rx_copybreak, int, 0);
-module_param(max_interrupt_work, int, 0);
-module_param(compaq_ioaddr, int, 0);
-module_param(compaq_irq, int, 0);
-module_param(compaq_device_id, int, 0);
-module_param(watchdog, int, 0);
-module_param(global_use_mmio, int, 0);
-module_param_array(use_mmio, int, NULL, 0);
-MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
-MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
-MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
-MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
-MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if full_duplex is unset");
-MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
-MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
-MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
-MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if enable_wol is unset");
-MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
-MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
-MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
-MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)");
-MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)");
-MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
-MODULE_PARM_DESC(global_use_mmio, "3c59x: same as use_mmio, but applies to all NICs if options is unset");
-MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)");
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void poll_vortex(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	unsigned long flags;
-	local_irq_save(flags);
-	(vp->full_bus_master_rx ? boomerang_interrupt:vortex_interrupt)(dev->irq,dev);
-	local_irq_restore(flags);
-}
-#endif
-
-#ifdef CONFIG_PM
-
-static int vortex_suspend(struct device *dev)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct net_device *ndev = pci_get_drvdata(pdev);
-
-	if (!ndev || !netif_running(ndev))
-		return 0;
-
-	netif_device_detach(ndev);
-	vortex_down(ndev, 1);
-
-	return 0;
-}
-
-static int vortex_resume(struct device *dev)
-{
-	struct pci_dev *pdev = to_pci_dev(dev);
-	struct net_device *ndev = pci_get_drvdata(pdev);
-	int err;
-
-	if (!ndev || !netif_running(ndev))
-		return 0;
-
-	err = vortex_up(ndev);
-	if (err)
-		return err;
-
-	netif_device_attach(ndev);
-
-	return 0;
-}
-
-static const struct dev_pm_ops vortex_pm_ops = {
-	.suspend = vortex_suspend,
-	.resume = vortex_resume,
-	.freeze = vortex_suspend,
-	.thaw = vortex_resume,
-	.poweroff = vortex_suspend,
-	.restore = vortex_resume,
-};
-
-#define VORTEX_PM_OPS (&vortex_pm_ops)
-
-#else /* !CONFIG_PM */
-
-#define VORTEX_PM_OPS NULL
-
-#endif /* !CONFIG_PM */
-
-#ifdef CONFIG_EISA
-static struct eisa_device_id vortex_eisa_ids[] = {
-	{ "TCM5920", CH_3C592 },
-	{ "TCM5970", CH_3C597 },
-	{ "" }
-};
-MODULE_DEVICE_TABLE(eisa, vortex_eisa_ids);
-
-static int __init vortex_eisa_probe(struct device *device)
-{
-	void __iomem *ioaddr;
-	struct eisa_device *edev;
-
-	edev = to_eisa_device(device);
-
-	if (!request_region(edev->base_addr, VORTEX_TOTAL_SIZE, DRV_NAME))
-		return -EBUSY;
-
-	ioaddr = ioport_map(edev->base_addr, VORTEX_TOTAL_SIZE);
-
-	if (vortex_probe1(device, ioaddr, ioread16(ioaddr + 0xC88) >> 12,
-					  edev->id.driver_data, vortex_cards_found)) {
-		release_region(edev->base_addr, VORTEX_TOTAL_SIZE);
-		return -ENODEV;
-	}
-
-	vortex_cards_found++;
-
-	return 0;
-}
-
-static int __devexit vortex_eisa_remove(struct device *device)
-{
-	struct eisa_device *edev;
-	struct net_device *dev;
-	struct vortex_private *vp;
-	void __iomem *ioaddr;
-
-	edev = to_eisa_device(device);
-	dev = eisa_get_drvdata(edev);
-
-	if (!dev) {
-		pr_err("vortex_eisa_remove called for Compaq device!\n");
-		BUG();
-	}
-
-	vp = netdev_priv(dev);
-	ioaddr = vp->ioaddr;
-
-	unregister_netdev(dev);
-	iowrite16(TotalReset|0x14, ioaddr + EL3_CMD);
-	release_region(dev->base_addr, VORTEX_TOTAL_SIZE);
-
-	free_netdev(dev);
-	return 0;
-}
-
-static struct eisa_driver vortex_eisa_driver = {
-	.id_table = vortex_eisa_ids,
-	.driver   = {
-		.name    = "3c59x",
-		.probe   = vortex_eisa_probe,
-		.remove  = __devexit_p(vortex_eisa_remove)
-	}
-};
-
-#endif /* CONFIG_EISA */
-
-/* returns count found (>= 0), or negative on error */
-static int __init vortex_eisa_init(void)
-{
-	int eisa_found = 0;
-	int orig_cards_found = vortex_cards_found;
-
-#ifdef CONFIG_EISA
-	int err;
-
-	err = eisa_driver_register (&vortex_eisa_driver);
-	if (!err) {
-		/*
-		 * Because of the way EISA bus is probed, we cannot assume
-		 * any device have been found when we exit from
-		 * eisa_driver_register (the bus root driver may not be
-		 * initialized yet). So we blindly assume something was
-		 * found, and let the sysfs magic happened...
-		 */
-		eisa_found = 1;
-	}
-#endif
-
-	/* Special code to work-around the Compaq PCI BIOS32 problem. */
-	if (compaq_ioaddr) {
-		vortex_probe1(NULL, ioport_map(compaq_ioaddr, VORTEX_TOTAL_SIZE),
-			      compaq_irq, compaq_device_id, vortex_cards_found++);
-	}
-
-	return vortex_cards_found - orig_cards_found + eisa_found;
-}
-
-/* returns count (>= 0), or negative on error */
-static int __devinit vortex_init_one(struct pci_dev *pdev,
-				      const struct pci_device_id *ent)
-{
-	int rc, unit, pci_bar;
-	struct vortex_chip_info *vci;
-	void __iomem *ioaddr;
-
-	/* wake up and enable device */
-	rc = pci_enable_device(pdev);
-	if (rc < 0)
-		goto out;
-
-	unit = vortex_cards_found;
-
-	if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
-		/* Determine the default if the user didn't override us */
-		vci = &vortex_info_tbl[ent->driver_data];
-		pci_bar = vci->drv_flags & (IS_CYCLONE | IS_TORNADO) ? 1 : 0;
-	} else if (unit < MAX_UNITS && use_mmio[unit] >= 0)
-		pci_bar = use_mmio[unit] ? 1 : 0;
-	else
-		pci_bar = global_use_mmio ? 1 : 0;
-
-	ioaddr = pci_iomap(pdev, pci_bar, 0);
-	if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
-		ioaddr = pci_iomap(pdev, 0, 0);
-	if (!ioaddr) {
-		pci_disable_device(pdev);
-		rc = -ENOMEM;
-		goto out;
-	}
-
-	rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,
-			   ent->driver_data, unit);
-	if (rc < 0) {
-		pci_iounmap(pdev, ioaddr);
-		pci_disable_device(pdev);
-		goto out;
-	}
-
-	vortex_cards_found++;
-
-out:
-	return rc;
-}
-
-static const struct net_device_ops boomrang_netdev_ops = {
-	.ndo_open		= vortex_open,
-	.ndo_stop		= vortex_close,
-	.ndo_start_xmit		= boomerang_start_xmit,
-	.ndo_tx_timeout		= vortex_tx_timeout,
-	.ndo_get_stats		= vortex_get_stats,
-#ifdef CONFIG_PCI
-	.ndo_do_ioctl 		= vortex_ioctl,
-#endif
-	.ndo_set_multicast_list = set_rx_mode,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= poll_vortex,
-#endif
-};
-
-static const struct net_device_ops vortex_netdev_ops = {
-	.ndo_open		= vortex_open,
-	.ndo_stop		= vortex_close,
-	.ndo_start_xmit		= vortex_start_xmit,
-	.ndo_tx_timeout		= vortex_tx_timeout,
-	.ndo_get_stats		= vortex_get_stats,
-#ifdef CONFIG_PCI
-	.ndo_do_ioctl 		= vortex_ioctl,
-#endif
-	.ndo_set_multicast_list = set_rx_mode,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= poll_vortex,
-#endif
-};
-
-/*
- * Start up the PCI/EISA device which is described by *gendev.
- * Return 0 on success.
- *
- * NOTE: pdev can be NULL, for the case of a Compaq device
- */
-static int __devinit vortex_probe1(struct device *gendev,
-				   void __iomem *ioaddr, int irq,
-				   int chip_idx, int card_idx)
-{
-	struct vortex_private *vp;
-	int option;
-	unsigned int eeprom[0x40], checksum = 0;		/* EEPROM contents */
-	int i, step;
-	struct net_device *dev;
-	static int printed_version;
-	int retval, print_info;
-	struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx];
-	const char *print_name = "3c59x";
-	struct pci_dev *pdev = NULL;
-	struct eisa_device *edev = NULL;
-
-	if (!printed_version) {
-		pr_info("%s", version);
-		printed_version = 1;
-	}
-
-	if (gendev) {
-		if ((pdev = DEVICE_PCI(gendev))) {
-			print_name = pci_name(pdev);
-		}
-
-		if ((edev = DEVICE_EISA(gendev))) {
-			print_name = dev_name(&edev->dev);
-		}
-	}
-
-	dev = alloc_etherdev(sizeof(*vp));
-	retval = -ENOMEM;
-	if (!dev) {
-		pr_err(PFX "unable to allocate etherdev, aborting\n");
-		goto out;
-	}
-	SET_NETDEV_DEV(dev, gendev);
-	vp = netdev_priv(dev);
-
-	option = global_options;
-
-	/* The lower four bits are the media type. */
-	if (dev->mem_start) {
-		/*
-		 * The 'options' param is passed in as the third arg to the
-		 * LILO 'ether=' argument for non-modular use
-		 */
-		option = dev->mem_start;
-	}
-	else if (card_idx < MAX_UNITS) {
-		if (options[card_idx] >= 0)
-			option = options[card_idx];
-	}
-
-	if (option > 0) {
-		if (option & 0x8000)
-			vortex_debug = 7;
-		if (option & 0x4000)
-			vortex_debug = 2;
-		if (option & 0x0400)
-			vp->enable_wol = 1;
-	}
-
-	print_info = (vortex_debug > 1);
-	if (print_info)
-		pr_info("See Documentation/networking/vortex.txt\n");
-
-	pr_info("%s: 3Com %s %s at %p.\n",
-	       print_name,
-	       pdev ? "PCI" : "EISA",
-	       vci->name,
-	       ioaddr);
-
-	dev->base_addr = (unsigned long)ioaddr;
-	dev->irq = irq;
-	dev->mtu = mtu;
-	vp->ioaddr = ioaddr;
-	vp->large_frames = mtu > 1500;
-	vp->drv_flags = vci->drv_flags;
-	vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
-	vp->io_size = vci->io_size;
-	vp->card_idx = card_idx;
-	vp->window = -1;
-
-	/* module list only for Compaq device */
-	if (gendev == NULL) {
-		compaq_net_device = dev;
-	}
-
-	/* PCI-only startup logic */
-	if (pdev) {
-		/* EISA resources already marked, so only PCI needs to do this here */
-		/* Ignore return value, because Cardbus drivers already allocate for us */
-		if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
-			vp->must_free_region = 1;
-
-		/* enable bus-mastering if necessary */
-		if (vci->flags & PCI_USES_MASTER)
-			pci_set_master(pdev);
-
-		if (vci->drv_flags & IS_VORTEX) {
-			u8 pci_latency;
-			u8 new_latency = 248;
-
-			/* Check the PCI latency value.  On the 3c590 series the latency timer
-			   must be set to the maximum value to avoid data corruption that occurs
-			   when the timer expires during a transfer.  This bug exists the Vortex
-			   chip only. */
-			pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &pci_latency);
-			if (pci_latency < new_latency) {
-				pr_info("%s: Overriding PCI latency timer (CFLT) setting of %d, new value is %d.\n",
-					print_name, pci_latency, new_latency);
-				pci_write_config_byte(pdev, PCI_LATENCY_TIMER, new_latency);
-			}
-		}
-	}
-
-	spin_lock_init(&vp->lock);
-	spin_lock_init(&vp->mii_lock);
-	spin_lock_init(&vp->window_lock);
-	vp->gendev = gendev;
-	vp->mii.dev = dev;
-	vp->mii.mdio_read = mdio_read;
-	vp->mii.mdio_write = mdio_write;
-	vp->mii.phy_id_mask = 0x1f;
-	vp->mii.reg_num_mask = 0x1f;
-
-	/* Makes sure rings are at least 16 byte aligned. */
-	vp->rx_ring = pci_alloc_consistent(pdev, sizeof(struct boom_rx_desc) * RX_RING_SIZE
-					   + sizeof(struct boom_tx_desc) * TX_RING_SIZE,
-					   &vp->rx_ring_dma);
-	retval = -ENOMEM;
-	if (!vp->rx_ring)
-		goto free_region;
-
-	vp->tx_ring = (struct boom_tx_desc *)(vp->rx_ring + RX_RING_SIZE);
-	vp->tx_ring_dma = vp->rx_ring_dma + sizeof(struct boom_rx_desc) * RX_RING_SIZE;
-
-	/* if we are a PCI driver, we store info in pdev->driver_data
-	 * instead of a module list */
-	if (pdev)
-		pci_set_drvdata(pdev, dev);
-	if (edev)
-		eisa_set_drvdata(edev, dev);
-
-	vp->media_override = 7;
-	if (option >= 0) {
-		vp->media_override = ((option & 7) == 2)  ?  0  :  option & 15;
-		if (vp->media_override != 7)
-			vp->medialock = 1;
-		vp->full_duplex = (option & 0x200) ? 1 : 0;
-		vp->bus_master = (option & 16) ? 1 : 0;
-	}
-
-	if (global_full_duplex > 0)
-		vp->full_duplex = 1;
-	if (global_enable_wol > 0)
-		vp->enable_wol = 1;
-
-	if (card_idx < MAX_UNITS) {
-		if (full_duplex[card_idx] > 0)
-			vp->full_duplex = 1;
-		if (flow_ctrl[card_idx] > 0)
-			vp->flow_ctrl = 1;
-		if (enable_wol[card_idx] > 0)
-			vp->enable_wol = 1;
-	}
-
-	vp->mii.force_media = vp->full_duplex;
-	vp->options = option;
-	/* Read the station address from the EEPROM. */
-	{
-		int base;
-
-		if (vci->drv_flags & EEPROM_8BIT)
-			base = 0x230;
-		else if (vci->drv_flags & EEPROM_OFFSET)
-			base = EEPROM_Read + 0x30;
-		else
-			base = EEPROM_Read;
-
-		for (i = 0; i < 0x40; i++) {
-			int timer;
-			window_write16(vp, base + i, 0, Wn0EepromCmd);
-			/* Pause for at least 162 us. for the read to take place. */
-			for (timer = 10; timer >= 0; timer--) {
-				udelay(162);
-				if ((window_read16(vp, 0, Wn0EepromCmd) &
-				     0x8000) == 0)
-					break;
-			}
-			eeprom[i] = window_read16(vp, 0, Wn0EepromData);
-		}
-	}
-	for (i = 0; i < 0x18; i++)
-		checksum ^= eeprom[i];
-	checksum = (checksum ^ (checksum >> 8)) & 0xff;
-	if (checksum != 0x00) {		/* Grrr, needless incompatible change 3Com. */
-		while (i < 0x21)
-			checksum ^= eeprom[i++];
-		checksum = (checksum ^ (checksum >> 8)) & 0xff;
-	}
-	if ((checksum != 0x00) && !(vci->drv_flags & IS_TORNADO))
-		pr_cont(" ***INVALID CHECKSUM %4.4x*** ", checksum);
-	for (i = 0; i < 3; i++)
-		((__be16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-	if (print_info)
-		pr_cont(" %pM", dev->dev_addr);
-	/* Unfortunately an all zero eeprom passes the checksum and this
-	   gets found in the wild in failure cases. Crypto is hard 8) */
-	if (!is_valid_ether_addr(dev->dev_addr)) {
-		retval = -EINVAL;
-		pr_err("*** EEPROM MAC address is invalid.\n");
-		goto free_ring;	/* With every pack */
-	}
-	for (i = 0; i < 6; i++)
-		window_write8(vp, dev->dev_addr[i], 2, i);
-
-	if (print_info)
-		pr_cont(", IRQ %d\n", dev->irq);
-	/* Tell them about an invalid IRQ. */
-	if (dev->irq <= 0 || dev->irq >= nr_irqs)
-		pr_warning(" *** Warning: IRQ %d is unlikely to work! ***\n",
-			   dev->irq);
-
-	step = (window_read8(vp, 4, Wn4_NetDiag) & 0x1e) >> 1;
-	if (print_info) {
-		pr_info("  product code %02x%02x rev %02x.%d date %02d-%02d-%02d\n",
-			eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
-			step, (eeprom[4]>>5) & 15, eeprom[4] & 31, eeprom[4]>>9);
-	}
-
-
-	if (pdev && vci->drv_flags & HAS_CB_FNS) {
-		unsigned short n;
-
-		vp->cb_fn_base = pci_iomap(pdev, 2, 0);
-		if (!vp->cb_fn_base) {
-			retval = -ENOMEM;
-			goto free_ring;
-		}
-
-		if (print_info) {
-			pr_info("%s: CardBus functions mapped %16.16llx->%p\n",
-				print_name,
-				(unsigned long long)pci_resource_start(pdev, 2),
-				vp->cb_fn_base);
-		}
-
-		n = window_read16(vp, 2, Wn2_ResetOptions) & ~0x4010;
-		if (vp->drv_flags & INVERT_LED_PWR)
-			n |= 0x10;
-		if (vp->drv_flags & INVERT_MII_PWR)
-			n |= 0x4000;
-		window_write16(vp, n, 2, Wn2_ResetOptions);
-		if (vp->drv_flags & WNO_XCVR_PWR) {
-			window_write16(vp, 0x0800, 0, 0);
-		}
-	}
-
-	/* Extract our information from the EEPROM data. */
-	vp->info1 = eeprom[13];
-	vp->info2 = eeprom[15];
-	vp->capabilities = eeprom[16];
-
-	if (vp->info1 & 0x8000) {
-		vp->full_duplex = 1;
-		if (print_info)
-			pr_info("Full duplex capable\n");
-	}
-
-	{
-		static const char * const ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
-		unsigned int config;
-		vp->available_media = window_read16(vp, 3, Wn3_Options);
-		if ((vp->available_media & 0xff) == 0)		/* Broken 3c916 */
-			vp->available_media = 0x40;
-		config = window_read32(vp, 3, Wn3_Config);
-		if (print_info) {
-			pr_debug("  Internal config register is %4.4x, transceivers %#x.\n",
-				config, window_read16(vp, 3, Wn3_Options));
-			pr_info("  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
-				   8 << RAM_SIZE(config),
-				   RAM_WIDTH(config) ? "word" : "byte",
-				   ram_split[RAM_SPLIT(config)],
-				   AUTOSELECT(config) ? "autoselect/" : "",
-				   XCVR(config) > XCVR_ExtMII ? "<invalid transceiver>" :
-				   media_tbl[XCVR(config)].name);
-		}
-		vp->default_media = XCVR(config);
-		if (vp->default_media == XCVR_NWAY)
-			vp->has_nway = 1;
-		vp->autoselect = AUTOSELECT(config);
-	}
-
-	if (vp->media_override != 7) {
-		pr_info("%s:  Media override to transceiver type %d (%s).\n",
-				print_name, vp->media_override,
-				media_tbl[vp->media_override].name);
-		dev->if_port = vp->media_override;
-	} else
-		dev->if_port = vp->default_media;
-
-	if ((vp->available_media & 0x40) || (vci->drv_flags & HAS_NWAY) ||
-		dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
-		int phy, phy_idx = 0;
-		mii_preamble_required++;
-		if (vp->drv_flags & EXTRA_PREAMBLE)
-			mii_preamble_required++;
-		mdio_sync(vp, 32);
-		mdio_read(dev, 24, MII_BMSR);
-		for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
-			int mii_status, phyx;
-
-			/*
-			 * For the 3c905CX we look at index 24 first, because it bogusly
-			 * reports an external PHY at all indices
-			 */
-			if (phy == 0)
-				phyx = 24;
-			else if (phy <= 24)
-				phyx = phy - 1;
-			else
-				phyx = phy;
-			mii_status = mdio_read(dev, phyx, MII_BMSR);
-			if (mii_status  &&  mii_status != 0xffff) {
-				vp->phys[phy_idx++] = phyx;
-				if (print_info) {
-					pr_info("  MII transceiver found at address %d, status %4x.\n",
-						phyx, mii_status);
-				}
-				if ((mii_status & 0x0040) == 0)
-					mii_preamble_required++;
-			}
-		}
-		mii_preamble_required--;
-		if (phy_idx == 0) {
-			pr_warning("  ***WARNING*** No MII transceivers found!\n");
-			vp->phys[0] = 24;
-		} else {
-			vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
-			if (vp->full_duplex) {
-				/* Only advertise the FD media types. */
-				vp->advertising &= ~0x02A0;
-				mdio_write(dev, vp->phys[0], 4, vp->advertising);
-			}
-		}
-		vp->mii.phy_id = vp->phys[0];
-	}
-
-	if (vp->capabilities & CapBusMaster) {
-		vp->full_bus_master_tx = 1;
-		if (print_info) {
-			pr_info("  Enabling bus-master transmits and %s receives.\n",
-			(vp->info2 & 1) ? "early" : "whole-frame" );
-		}
-		vp->full_bus_master_rx = (vp->info2 & 1) ? 1 : 2;
-		vp->bus_master = 0;		/* AKPM: vortex only */
-	}
-
-	/* The 3c59x-specific entries in the device structure. */
-	if (vp->full_bus_master_tx) {
-		dev->netdev_ops = &boomrang_netdev_ops;
-		/* Actually, it still should work with iommu. */
-		if (card_idx < MAX_UNITS &&
-		    ((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
-				hw_checksums[card_idx] == 1)) {
-			dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
-		}
-	} else
-		dev->netdev_ops =  &vortex_netdev_ops;
-
-	if (print_info) {
-		pr_info("%s: scatter/gather %sabled. h/w checksums %sabled\n",
-				print_name,
-				(dev->features & NETIF_F_SG) ? "en":"dis",
-				(dev->features & NETIF_F_IP_CSUM) ? "en":"dis");
-	}
-
-	dev->ethtool_ops = &vortex_ethtool_ops;
-	dev->watchdog_timeo = (watchdog * HZ) / 1000;
-
-	if (pdev) {
-		vp->pm_state_valid = 1;
- 		pci_save_state(VORTEX_PCI(vp));
- 		acpi_set_WOL(dev);
-	}
-	retval = register_netdev(dev);
-	if (retval == 0)
-		return 0;
-
-free_ring:
-	pci_free_consistent(pdev,
-						sizeof(struct boom_rx_desc) * RX_RING_SIZE
-							+ sizeof(struct boom_tx_desc) * TX_RING_SIZE,
-						vp->rx_ring,
-						vp->rx_ring_dma);
-free_region:
-	if (vp->must_free_region)
-		release_region(dev->base_addr, vci->io_size);
-	free_netdev(dev);
-	pr_err(PFX "vortex_probe1 fails.  Returns %d\n", retval);
-out:
-	return retval;
-}
-
-static void
-issue_and_wait(struct net_device *dev, int cmd)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-	int i;
-
-	iowrite16(cmd, ioaddr + EL3_CMD);
-	for (i = 0; i < 2000; i++) {
-		if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
-			return;
-	}
-
-	/* OK, that didn't work.  Do it the slow way.  One second */
-	for (i = 0; i < 100000; i++) {
-		if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
-			if (vortex_debug > 1)
-				pr_info("%s: command 0x%04x took %d usecs\n",
-					   dev->name, cmd, i * 10);
-			return;
-		}
-		udelay(10);
-	}
-	pr_err("%s: command 0x%04x did not complete! Status=0x%x\n",
-			   dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
-}
-
-static void
-vortex_set_duplex(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-
-	pr_info("%s:  setting %s-duplex.\n",
-		dev->name, (vp->full_duplex) ? "full" : "half");
-
-	/* Set the full-duplex bit. */
-	window_write16(vp,
-		       ((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
-		       (vp->large_frames ? 0x40 : 0) |
-		       ((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ?
-			0x100 : 0),
-		       3, Wn3_MAC_Ctrl);
-}
-
-static void vortex_check_media(struct net_device *dev, unsigned int init)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	unsigned int ok_to_print = 0;
-
-	if (vortex_debug > 3)
-		ok_to_print = 1;
-
-	if (mii_check_media(&vp->mii, ok_to_print, init)) {
-		vp->full_duplex = vp->mii.full_duplex;
-		vortex_set_duplex(dev);
-	} else if (init) {
-		vortex_set_duplex(dev);
-	}
-}
-
-static int
-vortex_up(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-	unsigned int config;
-	int i, mii_reg1, mii_reg5, err = 0;
-
-	if (VORTEX_PCI(vp)) {
-		pci_set_power_state(VORTEX_PCI(vp), PCI_D0);	/* Go active */
-		if (vp->pm_state_valid)
-			pci_restore_state(VORTEX_PCI(vp));
-		err = pci_enable_device(VORTEX_PCI(vp));
-		if (err) {
-			pr_warning("%s: Could not enable device\n",
-				dev->name);
-			goto err_out;
-		}
-	}
-
-	/* Before initializing select the active media port. */
-	config = window_read32(vp, 3, Wn3_Config);
-
-	if (vp->media_override != 7) {
-		pr_info("%s: Media override to transceiver %d (%s).\n",
-			   dev->name, vp->media_override,
-			   media_tbl[vp->media_override].name);
-		dev->if_port = vp->media_override;
-	} else if (vp->autoselect) {
-		if (vp->has_nway) {
-			if (vortex_debug > 1)
-				pr_info("%s: using NWAY device table, not %d\n",
-								dev->name, dev->if_port);
-			dev->if_port = XCVR_NWAY;
-		} else {
-			/* Find first available media type, starting with 100baseTx. */
-			dev->if_port = XCVR_100baseTx;
-			while (! (vp->available_media & media_tbl[dev->if_port].mask))
-				dev->if_port = media_tbl[dev->if_port].next;
-			if (vortex_debug > 1)
-				pr_info("%s: first available media type: %s\n",
-					dev->name, media_tbl[dev->if_port].name);
-		}
-	} else {
-		dev->if_port = vp->default_media;
-		if (vortex_debug > 1)
-			pr_info("%s: using default media %s\n",
-				dev->name, media_tbl[dev->if_port].name);
-	}
-
-	init_timer(&vp->timer);
-	vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait);
-	vp->timer.data = (unsigned long)dev;
-	vp->timer.function = vortex_timer;		/* timer handler */
-	add_timer(&vp->timer);
-
-	init_timer(&vp->rx_oom_timer);
-	vp->rx_oom_timer.data = (unsigned long)dev;
-	vp->rx_oom_timer.function = rx_oom_timer;
-
-	if (vortex_debug > 1)
-		pr_debug("%s: Initial media type %s.\n",
-			   dev->name, media_tbl[dev->if_port].name);
-
-	vp->full_duplex = vp->mii.force_media;
-	config = BFINS(config, dev->if_port, 20, 4);
-	if (vortex_debug > 6)
-		pr_debug("vortex_up(): writing 0x%x to InternalConfig\n", config);
-	window_write32(vp, config, 3, Wn3_Config);
-
-	if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
-		mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
-		mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
-		vp->partner_flow_ctrl = ((mii_reg5 & 0x0400) != 0);
-		vp->mii.full_duplex = vp->full_duplex;
-
-		vortex_check_media(dev, 1);
-	}
-	else
-		vortex_set_duplex(dev);
-
-	issue_and_wait(dev, TxReset);
-	/*
-	 * Don't reset the PHY - that upsets autonegotiation during DHCP operations.
-	 */
-	issue_and_wait(dev, RxReset|0x04);
-
-
-	iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
-
-	if (vortex_debug > 1) {
-		pr_debug("%s: vortex_up() irq %d media status %4.4x.\n",
-			   dev->name, dev->irq, window_read16(vp, 4, Wn4_Media));
-	}
-
-	/* Set the station address and mask in window 2 each time opened. */
-	for (i = 0; i < 6; i++)
-		window_write8(vp, dev->dev_addr[i], 2, i);
-	for (; i < 12; i+=2)
-		window_write16(vp, 0, 2, i);
-
-	if (vp->cb_fn_base) {
-		unsigned short n = window_read16(vp, 2, Wn2_ResetOptions) & ~0x4010;
-		if (vp->drv_flags & INVERT_LED_PWR)
-			n |= 0x10;
-		if (vp->drv_flags & INVERT_MII_PWR)
-			n |= 0x4000;
-		window_write16(vp, n, 2, Wn2_ResetOptions);
-	}
-
-	if (dev->if_port == XCVR_10base2)
-		/* Start the thinnet transceiver. We should really wait 50ms...*/
-		iowrite16(StartCoax, ioaddr + EL3_CMD);
-	if (dev->if_port != XCVR_NWAY) {
-		window_write16(vp,
-			       (window_read16(vp, 4, Wn4_Media) &
-				~(Media_10TP|Media_SQE)) |
-			       media_tbl[dev->if_port].media_bits,
-			       4, Wn4_Media);
-	}
-
-	/* Switch to the stats window, and clear all stats by reading. */
-	iowrite16(StatsDisable, ioaddr + EL3_CMD);
-	for (i = 0; i < 10; i++)
-		window_read8(vp, 6, i);
-	window_read16(vp, 6, 10);
-	window_read16(vp, 6, 12);
-	/* New: On the Vortex we must also clear the BadSSD counter. */
-	window_read8(vp, 4, 12);
-	/* ..and on the Boomerang we enable the extra statistics bits. */
-	window_write16(vp, 0x0040, 4, Wn4_NetDiag);
-
-	if (vp->full_bus_master_rx) { /* Boomerang bus master. */
-		vp->cur_rx = vp->dirty_rx = 0;
-		/* Initialize the RxEarly register as recommended. */
-		iowrite16(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
-		iowrite32(0x0020, ioaddr + PktStatus);
-		iowrite32(vp->rx_ring_dma, ioaddr + UpListPtr);
-	}
-	if (vp->full_bus_master_tx) { 		/* Boomerang bus master Tx. */
-		vp->cur_tx = vp->dirty_tx = 0;
-		if (vp->drv_flags & IS_BOOMERANG)
-			iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
-		/* Clear the Rx, Tx rings. */
-		for (i = 0; i < RX_RING_SIZE; i++)	/* AKPM: this is done in vortex_open, too */
-			vp->rx_ring[i].status = 0;
-		for (i = 0; i < TX_RING_SIZE; i++)
-			vp->tx_skbuff[i] = NULL;
-		iowrite32(0, ioaddr + DownListPtr);
-	}
-	/* Set receiver mode: presumably accept b-case and phys addr only. */
-	set_rx_mode(dev);
-	/* enable 802.1q tagged frames */
-	set_8021q_mode(dev, 1);
-	iowrite16(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
-
-	iowrite16(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
-	iowrite16(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
-	/* Allow status bits to be seen. */
-	vp->status_enable = SetStatusEnb | HostError|IntReq|StatsFull|TxComplete|
-		(vp->full_bus_master_tx ? DownComplete : TxAvailable) |
-		(vp->full_bus_master_rx ? UpComplete : RxComplete) |
-		(vp->bus_master ? DMADone : 0);
-	vp->intr_enable = SetIntrEnb | IntLatch | TxAvailable |
-		(vp->full_bus_master_rx ? 0 : RxComplete) |
-		StatsFull | HostError | TxComplete | IntReq
-		| (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete;
-	iowrite16(vp->status_enable, ioaddr + EL3_CMD);
-	/* Ack all pending events, and set active indicator mask. */
-	iowrite16(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
-		 ioaddr + EL3_CMD);
-	iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
-	if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */
-		iowrite32(0x8000, vp->cb_fn_base + 4);
-	netif_start_queue (dev);
-err_out:
-	return err;
-}
-
-static int
-vortex_open(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	int i;
-	int retval;
-
-	/* Use the now-standard shared IRQ implementation. */
-	if ((retval = request_irq(dev->irq, vp->full_bus_master_rx ?
-				boomerang_interrupt : vortex_interrupt, IRQF_SHARED, dev->name, dev))) {
-		pr_err("%s: Could not reserve IRQ %d\n", dev->name, dev->irq);
-		goto err;
-	}
-
-	if (vp->full_bus_master_rx) { /* Boomerang bus master. */
-		if (vortex_debug > 2)
-			pr_debug("%s:  Filling in the Rx ring.\n", dev->name);
-		for (i = 0; i < RX_RING_SIZE; i++) {
-			struct sk_buff *skb;
-			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 = __netdev_alloc_skb(dev, PKT_BUF_SZ + NET_IP_ALIGN,
-						 GFP_KERNEL);
-			vp->rx_skbuff[i] = skb;
-			if (skb == NULL)
-				break;			/* Bad news!  */
-
-			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) {
-			int j;
-			pr_emerg("%s: no memory for rx ring\n", dev->name);
-			for (j = 0; j < i; j++) {
-				if (vp->rx_skbuff[j]) {
-					dev_kfree_skb(vp->rx_skbuff[j]);
-					vp->rx_skbuff[j] = NULL;
-				}
-			}
-			retval = -ENOMEM;
-			goto err_free_irq;
-		}
-		/* Wrap the ring. */
-		vp->rx_ring[i-1].next = cpu_to_le32(vp->rx_ring_dma);
-	}
-
-	retval = vortex_up(dev);
-	if (!retval)
-		goto out;
-
-err_free_irq:
-	free_irq(dev->irq, dev);
-err:
-	if (vortex_debug > 1)
-		pr_err("%s: vortex_open() fails: returning %d\n", dev->name, retval);
-out:
-	return retval;
-}
-
-static void
-vortex_timer(unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-	int next_tick = 60*HZ;
-	int ok = 0;
-	int media_status;
-
-	if (vortex_debug > 2) {
-		pr_debug("%s: Media selection timer tick happened, %s.\n",
-			   dev->name, media_tbl[dev->if_port].name);
-		pr_debug("dev->watchdog_timeo=%d\n", dev->watchdog_timeo);
-	}
-
-	media_status = window_read16(vp, 4, Wn4_Media);
-	switch (dev->if_port) {
-	case XCVR_10baseT:  case XCVR_100baseTx:  case XCVR_100baseFx:
-		if (media_status & Media_LnkBeat) {
-			netif_carrier_on(dev);
-			ok = 1;
-			if (vortex_debug > 1)
-				pr_debug("%s: Media %s has link beat, %x.\n",
-					   dev->name, media_tbl[dev->if_port].name, media_status);
-		} else {
-			netif_carrier_off(dev);
-			if (vortex_debug > 1) {
-				pr_debug("%s: Media %s has no link beat, %x.\n",
-					   dev->name, media_tbl[dev->if_port].name, media_status);
-			}
-		}
-		break;
-	case XCVR_MII: case XCVR_NWAY:
-		{
-			ok = 1;
-			vortex_check_media(dev, 0);
-		}
-		break;
-	  default:					/* Other media types handled by Tx timeouts. */
-		if (vortex_debug > 1)
-		  pr_debug("%s: Media %s has no indication, %x.\n",
-				 dev->name, media_tbl[dev->if_port].name, media_status);
-		ok = 1;
-	}
-
-	if (!netif_carrier_ok(dev))
-		next_tick = 5*HZ;
-
-	if (vp->medialock)
-		goto leave_media_alone;
-
-	if (!ok) {
-		unsigned int config;
-
-		spin_lock_irq(&vp->lock);
-
-		do {
-			dev->if_port = media_tbl[dev->if_port].next;
-		} while ( ! (vp->available_media & media_tbl[dev->if_port].mask));
-		if (dev->if_port == XCVR_Default) { /* Go back to default. */
-		  dev->if_port = vp->default_media;
-		  if (vortex_debug > 1)
-			pr_debug("%s: Media selection failing, using default %s port.\n",
-				   dev->name, media_tbl[dev->if_port].name);
-		} else {
-			if (vortex_debug > 1)
-				pr_debug("%s: Media selection failed, now trying %s port.\n",
-					   dev->name, media_tbl[dev->if_port].name);
-			next_tick = media_tbl[dev->if_port].wait;
-		}
-		window_write16(vp,
-			       (media_status & ~(Media_10TP|Media_SQE)) |
-			       media_tbl[dev->if_port].media_bits,
-			       4, Wn4_Media);
-
-		config = window_read32(vp, 3, Wn3_Config);
-		config = BFINS(config, dev->if_port, 20, 4);
-		window_write32(vp, config, 3, Wn3_Config);
-
-		iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
-			 ioaddr + EL3_CMD);
-		if (vortex_debug > 1)
-			pr_debug("wrote 0x%08x to Wn3_Config\n", config);
-		/* AKPM: FIXME: Should reset Rx & Tx here.  P60 of 3c90xc.pdf */
-
-		spin_unlock_irq(&vp->lock);
-	}
-
-leave_media_alone:
-	if (vortex_debug > 2)
-	  pr_debug("%s: Media selection timer finished, %s.\n",
-			 dev->name, media_tbl[dev->if_port].name);
-
-	mod_timer(&vp->timer, RUN_AT(next_tick));
-	if (vp->deferred)
-		iowrite16(FakeIntr, ioaddr + EL3_CMD);
-}
-
-static void vortex_tx_timeout(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-
-	pr_err("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
-		   dev->name, ioread8(ioaddr + TxStatus),
-		   ioread16(ioaddr + EL3_STATUS));
-	pr_err("  diagnostics: net %04x media %04x dma %08x fifo %04x\n",
-			window_read16(vp, 4, Wn4_NetDiag),
-			window_read16(vp, 4, Wn4_Media),
-			ioread32(ioaddr + PktStatus),
-			window_read16(vp, 4, Wn4_FIFODiag));
-	/* Slight code bloat to be user friendly. */
-	if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
-		pr_err("%s: Transmitter encountered 16 collisions --"
-			   " network cable problem?\n", dev->name);
-	if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
-		pr_err("%s: Interrupt posted but not delivered --"
-			   " IRQ blocked by another device?\n", dev->name);
-		/* Bad idea here.. but we might as well handle a few events. */
-		{
-			/*
-			 * Block interrupts because vortex_interrupt does a bare spin_lock()
-			 */
-			unsigned long flags;
-			local_irq_save(flags);
-			if (vp->full_bus_master_tx)
-				boomerang_interrupt(dev->irq, dev);
-			else
-				vortex_interrupt(dev->irq, dev);
-			local_irq_restore(flags);
-		}
-	}
-
-	if (vortex_debug > 0)
-		dump_tx_ring(dev);
-
-	issue_and_wait(dev, TxReset);
-
-	dev->stats.tx_errors++;
-	if (vp->full_bus_master_tx) {
-		pr_debug("%s: Resetting the Tx ring pointer.\n", dev->name);
-		if (vp->cur_tx - vp->dirty_tx > 0  &&  ioread32(ioaddr + DownListPtr) == 0)
-			iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
-				 ioaddr + DownListPtr);
-		if (vp->cur_tx - vp->dirty_tx < TX_RING_SIZE)
-			netif_wake_queue (dev);
-		if (vp->drv_flags & IS_BOOMERANG)
-			iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
-		iowrite16(DownUnstall, ioaddr + EL3_CMD);
-	} else {
-		dev->stats.tx_dropped++;
-		netif_wake_queue(dev);
-	}
-
-	/* Issue Tx Enable */
-	iowrite16(TxEnable, ioaddr + EL3_CMD);
-	dev->trans_start = jiffies; /* prevent tx timeout */
-}
-
-/*
- * Handle uncommon interrupt sources.  This is a separate routine to minimize
- * the cache impact.
- */
-static void
-vortex_error(struct net_device *dev, int status)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-	int do_tx_reset = 0, reset_mask = 0;
-	unsigned char tx_status = 0;
-
-	if (vortex_debug > 2) {
-		pr_err("%s: vortex_error(), status=0x%x\n", dev->name, status);
-	}
-
-	if (status & TxComplete) {			/* Really "TxError" for us. */
-		tx_status = ioread8(ioaddr + TxStatus);
-		/* Presumably a tx-timeout. We must merely re-enable. */
-		if (vortex_debug > 2 ||
-		    (tx_status != 0x88 && vortex_debug > 0)) {
-			pr_err("%s: Transmit error, Tx status register %2.2x.\n",
-				   dev->name, tx_status);
-			if (tx_status == 0x82) {
-				pr_err("Probably a duplex mismatch.  See "
-						"Documentation/networking/vortex.txt\n");
-			}
-			dump_tx_ring(dev);
-		}
-		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 */
-			do_tx_reset = 1;
-		} else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET))  {	/* maxCollisions */
-			do_tx_reset = 1;
-			reset_mask = 0x0108;		/* Reset interface logic, but not download logic */
-		} else {				/* Merely re-enable the transmitter. */
-			iowrite16(TxEnable, ioaddr + EL3_CMD);
-		}
-	}
-
-	if (status & RxEarly)				/* Rx early is unused. */
-		iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD);
-
-	if (status & StatsFull) {			/* Empty statistics. */
-		static int DoneDidThat;
-		if (vortex_debug > 4)
-			pr_debug("%s: Updating stats.\n", dev->name);
-		update_stats(ioaddr, dev);
-		/* HACK: Disable statistics as an interrupt source. */
-		/* This occurs when we have the wrong media type! */
-		if (DoneDidThat == 0  &&
-			ioread16(ioaddr + EL3_STATUS) & StatsFull) {
-			pr_warning("%s: Updating statistics failed, disabling "
-				   "stats as an interrupt source.\n", dev->name);
-			iowrite16(SetIntrEnb |
-				  (window_read16(vp, 5, 10) & ~StatsFull),
-				  ioaddr + EL3_CMD);
-			vp->intr_enable &= ~StatsFull;
-			DoneDidThat++;
-		}
-	}
-	if (status & IntReq) {		/* Restore all interrupt sources.  */
-		iowrite16(vp->status_enable, ioaddr + EL3_CMD);
-		iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
-	}
-	if (status & HostError) {
-		u16 fifo_diag;
-		fifo_diag = window_read16(vp, 4, Wn4_FIFODiag);
-		pr_err("%s: Host error, FIFO diagnostic register %4.4x.\n",
-			   dev->name, fifo_diag);
-		/* Adapter failure requires Tx/Rx reset and reinit. */
-		if (vp->full_bus_master_tx) {
-			int bus_status = ioread32(ioaddr + PktStatus);
-			/* 0x80000000 PCI master abort. */
-			/* 0x40000000 PCI target abort. */
-			if (vortex_debug)
-				pr_err("%s: PCI bus error, bus status %8.8x\n", dev->name, bus_status);
-
-			/* In this case, blow the card away */
-			/* Must not enter D3 or we can't legally issue the reset! */
-			vortex_down(dev, 0);
-			issue_and_wait(dev, TotalReset | 0xff);
-			vortex_up(dev);		/* AKPM: bug.  vortex_up() assumes that the rx ring is full. It may not be. */
-		} else if (fifo_diag & 0x0400)
-			do_tx_reset = 1;
-		if (fifo_diag & 0x3000) {
-			/* Reset Rx fifo and upload logic */
-			issue_and_wait(dev, RxReset|0x07);
-			/* Set the Rx filter to the current state. */
-			set_rx_mode(dev);
-			/* enable 802.1q VLAN tagged frames */
-			set_8021q_mode(dev, 1);
-			iowrite16(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
-			iowrite16(AckIntr | HostError, ioaddr + EL3_CMD);
-		}
-	}
-
-	if (do_tx_reset) {
-		issue_and_wait(dev, TxReset|reset_mask);
-		iowrite16(TxEnable, ioaddr + EL3_CMD);
-		if (!vp->full_bus_master_tx)
-			netif_wake_queue(dev);
-	}
-}
-
-static netdev_tx_t
-vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-
-	/* Put out the doubleword header... */
-	iowrite32(skb->len, ioaddr + TX_FIFO);
-	if (vp->bus_master) {
-		/* Set the bus-master controller to transfer the packet. */
-		int len = (skb->len + 3) & ~3;
-		vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len,
-						PCI_DMA_TODEVICE);
-		spin_lock_irq(&vp->window_lock);
-		window_set(vp, 7);
-		iowrite32(vp->tx_skb_dma, ioaddr + Wn7_MasterAddr);
-		iowrite16(len, ioaddr + Wn7_MasterLen);
-		spin_unlock_irq(&vp->window_lock);
-		vp->tx_skb = skb;
-		iowrite16(StartDMADown, ioaddr + EL3_CMD);
-		/* netif_wake_queue() will be called at the DMADone interrupt. */
-	} else {
-		/* ... and the packet rounded to a doubleword. */
-		iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
-		dev_kfree_skb (skb);
-		if (ioread16(ioaddr + TxFree) > 1536) {
-			netif_start_queue (dev);	/* AKPM: redundant? */
-		} else {
-			/* Interrupt us when the FIFO has room for max-sized packet. */
-			netif_stop_queue(dev);
-			iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
-		}
-	}
-
-
-	/* Clear the Tx status stack. */
-	{
-		int tx_status;
-		int i = 32;
-
-		while (--i > 0	&&	(tx_status = ioread8(ioaddr + TxStatus)) > 0) {
-			if (tx_status & 0x3C) {		/* A Tx-disabling error occurred.  */
-				if (vortex_debug > 2)
-				  pr_debug("%s: Tx error, status %2.2x.\n",
-						 dev->name, tx_status);
-				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);
-				}
-				iowrite16(TxEnable, ioaddr + EL3_CMD);
-			}
-			iowrite8(0x00, ioaddr + TxStatus); /* Pop the status stack. */
-		}
-	}
-	return NETDEV_TX_OK;
-}
-
-static netdev_tx_t
-boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-	/* Calculate the next Tx descriptor entry. */
-	int entry = vp->cur_tx % TX_RING_SIZE;
-	struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
-	unsigned long flags;
-
-	if (vortex_debug > 6) {
-		pr_debug("boomerang_start_xmit()\n");
-		pr_debug("%s: Trying to send a packet, Tx index %d.\n",
-			   dev->name, vp->cur_tx);
-	}
-
-	/*
-	 * We can't allow a recursion from our interrupt handler back into the
-	 * tx routine, as they take the same spin lock, and that causes
-	 * deadlock.  Just return NETDEV_TX_BUSY and let the stack try again in
-	 * a bit
-	 */
-	if (vp->handling_irq)
-		return NETDEV_TX_BUSY;
-
-	if (vp->cur_tx - vp->dirty_tx >= TX_RING_SIZE) {
-		if (vortex_debug > 0)
-			pr_warning("%s: BUG! Tx Ring full, refusing to send buffer.\n",
-				   dev->name);
-		netif_stop_queue(dev);
-		return NETDEV_TX_BUSY;
-	}
-
-	vp->tx_skbuff[entry] = skb;
-
-	vp->tx_ring[entry].next = 0;
-#if DO_ZEROCOPY
-	if (skb->ip_summed != CHECKSUM_PARTIAL)
-			vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
-	else
-			vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded | AddTCPChksum | AddUDPChksum);
-
-	if (!skb_shinfo(skb)->nr_frags) {
-		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
-										skb->len, PCI_DMA_TODEVICE));
-		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len | LAST_FRAG);
-	} else {
-		int i;
-
-		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
-										skb_headlen(skb), PCI_DMA_TODEVICE));
-		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb_headlen(skb));
-
-		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
-			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-
-			vp->tx_ring[entry].frag[i+1].addr =
-					cpu_to_le32(pci_map_single(VORTEX_PCI(vp),
-											   (void*)page_address(frag->page) + frag->page_offset,
-											   frag->size, PCI_DMA_TODEVICE));
-
-			if (i == skb_shinfo(skb)->nr_frags-1)
-					vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(frag->size|LAST_FRAG);
-			else
-					vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(frag->size);
-		}
-	}
-#else
-	vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE));
-	vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
-	vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
-#endif
-
-	spin_lock_irqsave(&vp->lock, flags);
-	/* Wait for the stall to complete. */
-	issue_and_wait(dev, DownStall);
-	prev_entry->next = cpu_to_le32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc));
-	if (ioread32(ioaddr + DownListPtr) == 0) {
-		iowrite32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
-		vp->queued_packet++;
-	}
-
-	vp->cur_tx++;
-	if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1) {
-		netif_stop_queue (dev);
-	} else {					/* Clear previous interrupt enable. */
-#if defined(tx_interrupt_mitigation)
-		/* Dubious. If in boomeang_interrupt "faster" cyclone ifdef
-		 * were selected, this would corrupt DN_COMPLETE. No?
-		 */
-		prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
-#endif
-	}
-	iowrite16(DownUnstall, ioaddr + EL3_CMD);
-	spin_unlock_irqrestore(&vp->lock, flags);
-	return NETDEV_TX_OK;
-}
-
-/* The interrupt handler does all of the Rx thread work and cleans up
-   after the Tx thread. */
-
-/*
- * This is the ISR for the vortex series chips.
- * full_bus_master_tx == 0 && full_bus_master_rx == 0
- */
-
-static irqreturn_t
-vortex_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr;
-	int status;
-	int work_done = max_interrupt_work;
-	int handled = 0;
-
-	ioaddr = vp->ioaddr;
-	spin_lock(&vp->lock);
-
-	status = ioread16(ioaddr + EL3_STATUS);
-
-	if (vortex_debug > 6)
-		pr_debug("vortex_interrupt(). status=0x%4x\n", status);
-
-	if ((status & IntLatch) == 0)
-		goto handler_exit;		/* No interrupt: shared IRQs cause this */
-	handled = 1;
-
-	if (status & IntReq) {
-		status |= vp->deferred;
-		vp->deferred = 0;
-	}
-
-	if (status == 0xffff)		/* h/w no longer present (hotplug)? */
-		goto handler_exit;
-
-	if (vortex_debug > 4)
-		pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
-			   dev->name, status, ioread8(ioaddr + Timer));
-
-	spin_lock(&vp->window_lock);
-	window_set(vp, 7);
-
-	do {
-		if (vortex_debug > 5)
-				pr_debug("%s: In interrupt loop, status %4.4x.\n",
-					   dev->name, status);
-		if (status & RxComplete)
-			vortex_rx(dev);
-
-		if (status & TxAvailable) {
-			if (vortex_debug > 5)
-				pr_debug("	TX room bit was handled.\n");
-			/* There's room in the FIFO for a full-sized packet. */
-			iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
-			netif_wake_queue (dev);
-		}
-
-		if (status & DMADone) {
-			if (ioread16(ioaddr + Wn7_MasterStatus) & 0x1000) {
-				iowrite16(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
-				pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
-				dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
-				if (ioread16(ioaddr + TxFree) > 1536) {
-					/*
-					 * AKPM: FIXME: I don't think we need this.  If the queue was stopped due to
-					 * insufficient FIFO room, the TxAvailable test will succeed and call
-					 * netif_wake_queue()
-					 */
-					netif_wake_queue(dev);
-				} else { /* Interrupt when FIFO has room for max-sized packet. */
-					iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
-					netif_stop_queue(dev);
-				}
-			}
-		}
-		/* Check for all uncommon interrupts at once. */
-		if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) {
-			if (status == 0xffff)
-				break;
-			if (status & RxEarly)
-				vortex_rx(dev);
-			spin_unlock(&vp->window_lock);
-			vortex_error(dev, status);
-			spin_lock(&vp->window_lock);
-			window_set(vp, 7);
-		}
-
-		if (--work_done < 0) {
-			pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
-				dev->name, status);
-			/* Disable all pending interrupts. */
-			do {
-				vp->deferred |= status;
-				iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
-					 ioaddr + EL3_CMD);
-				iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
-			} while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
-			/* The timer will reenable interrupts. */
-			mod_timer(&vp->timer, jiffies + 1*HZ);
-			break;
-		}
-		/* Acknowledge the IRQ. */
-		iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
-	} while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
-
-	spin_unlock(&vp->window_lock);
-
-	if (vortex_debug > 4)
-		pr_debug("%s: exiting interrupt, status %4.4x.\n",
-			   dev->name, status);
-handler_exit:
-	spin_unlock(&vp->lock);
-	return IRQ_RETVAL(handled);
-}
-
-/*
- * This is the ISR for the boomerang series chips.
- * full_bus_master_tx == 1 && full_bus_master_rx == 1
- */
-
-static irqreturn_t
-boomerang_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr;
-	int status;
-	int work_done = max_interrupt_work;
-
-	ioaddr = vp->ioaddr;
-
-
-	/*
-	 * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout
-	 * and boomerang_start_xmit
-	 */
-	spin_lock(&vp->lock);
-	vp->handling_irq = 1;
-
-	status = ioread16(ioaddr + EL3_STATUS);
-
-	if (vortex_debug > 6)
-		pr_debug("boomerang_interrupt. status=0x%4x\n", status);
-
-	if ((status & IntLatch) == 0)
-		goto handler_exit;		/* No interrupt: shared IRQs can cause this */
-
-	if (status == 0xffff) {		/* h/w no longer present (hotplug)? */
-		if (vortex_debug > 1)
-			pr_debug("boomerang_interrupt(1): status = 0xffff\n");
-		goto handler_exit;
-	}
-
-	if (status & IntReq) {
-		status |= vp->deferred;
-		vp->deferred = 0;
-	}
-
-	if (vortex_debug > 4)
-		pr_debug("%s: interrupt, status %4.4x, latency %d ticks.\n",
-			   dev->name, status, ioread8(ioaddr + Timer));
-	do {
-		if (vortex_debug > 5)
-				pr_debug("%s: In interrupt loop, status %4.4x.\n",
-					   dev->name, status);
-		if (status & UpComplete) {
-			iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
-			if (vortex_debug > 5)
-				pr_debug("boomerang_interrupt->boomerang_rx\n");
-			boomerang_rx(dev);
-		}
-
-		if (status & DownComplete) {
-			unsigned int dirty_tx = vp->dirty_tx;
-
-			iowrite16(AckIntr | DownComplete, ioaddr + EL3_CMD);
-			while (vp->cur_tx - dirty_tx > 0) {
-				int entry = dirty_tx % TX_RING_SIZE;
-#if 1	/* AKPM: the latter is faster, but cyclone-only */
-				if (ioread32(ioaddr + DownListPtr) ==
-					vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc))
-					break;			/* It still hasn't been processed. */
-#else
-				if ((vp->tx_ring[entry].status & DN_COMPLETE) == 0)
-					break;			/* It still hasn't been processed. */
-#endif
-
-				if (vp->tx_skbuff[entry]) {
-					struct sk_buff *skb = vp->tx_skbuff[entry];
-#if DO_ZEROCOPY
-					int i;
-					for (i=0; i<=skb_shinfo(skb)->nr_frags; i++)
-							pci_unmap_single(VORTEX_PCI(vp),
-											 le32_to_cpu(vp->tx_ring[entry].frag[i].addr),
-											 le32_to_cpu(vp->tx_ring[entry].frag[i].length)&0xFFF,
-											 PCI_DMA_TODEVICE);
-#else
-					pci_unmap_single(VORTEX_PCI(vp),
-						le32_to_cpu(vp->tx_ring[entry].addr), skb->len, PCI_DMA_TODEVICE);
-#endif
-					dev_kfree_skb_irq(skb);
-					vp->tx_skbuff[entry] = NULL;
-				} else {
-					pr_debug("boomerang_interrupt: no skb!\n");
-				}
-				/* dev->stats.tx_packets++;  Counted below. */
-				dirty_tx++;
-			}
-			vp->dirty_tx = dirty_tx;
-			if (vp->cur_tx - dirty_tx <= TX_RING_SIZE - 1) {
-				if (vortex_debug > 6)
-					pr_debug("boomerang_interrupt: wake queue\n");
-				netif_wake_queue (dev);
-			}
-		}
-
-		/* Check for all uncommon interrupts at once. */
-		if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq))
-			vortex_error(dev, status);
-
-		if (--work_done < 0) {
-			pr_warning("%s: Too much work in interrupt, status %4.4x.\n",
-				dev->name, status);
-			/* Disable all pending interrupts. */
-			do {
-				vp->deferred |= status;
-				iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
-					 ioaddr + EL3_CMD);
-				iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
-			} while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
-			/* The timer will reenable interrupts. */
-			mod_timer(&vp->timer, jiffies + 1*HZ);
-			break;
-		}
-		/* Acknowledge the IRQ. */
-		iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
-		if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */
-			iowrite32(0x8000, vp->cb_fn_base + 4);
-
-	} while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
-
-	if (vortex_debug > 4)
-		pr_debug("%s: exiting interrupt, status %4.4x.\n",
-			   dev->name, status);
-handler_exit:
-	vp->handling_irq = 0;
-	spin_unlock(&vp->lock);
-	return IRQ_HANDLED;
-}
-
-static int vortex_rx(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-	int i;
-	short rx_status;
-
-	if (vortex_debug > 5)
-		pr_debug("vortex_rx(): status %4.4x, rx_status %4.4x.\n",
-			   ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
-	while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
-		if (rx_status & 0x4000) { /* Error, update stats. */
-			unsigned char rx_error = ioread8(ioaddr + RxErrors);
-			if (vortex_debug > 2)
-				pr_debug(" Rx error: status %2.2x.\n", rx_error);
-			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;
-			struct sk_buff *skb;
-
-			skb = dev_alloc_skb(pkt_len + 5);
-			if (vortex_debug > 4)
-				pr_debug("Receiving packet size %d status %4.4x.\n",
-					   pkt_len, rx_status);
-			if (skb != NULL) {
-				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-				/* 'skb_put()' points to the start of sk_buff data area. */
-				if (vp->bus_master &&
-					! (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)) {
-					dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len),
-									   pkt_len, PCI_DMA_FROMDEVICE);
-					iowrite32(dma, ioaddr + Wn7_MasterAddr);
-					iowrite16((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
-					iowrite16(StartDMAUp, ioaddr + EL3_CMD);
-					while (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)
-						;
-					pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE);
-				} else {
-					ioread32_rep(ioaddr + RX_FIFO,
-					             skb_put(skb, pkt_len),
-						     (pkt_len + 3) >> 2);
-				}
-				iowrite16(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
-				skb->protocol = eth_type_trans(skb, dev);
-				netif_rx(skb);
-				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))
-						break;
-				continue;
-			} else if (vortex_debug > 0)
-				pr_notice("%s: No memory to allocate a sk_buff of size %d.\n",
-					dev->name, pkt_len);
-			dev->stats.rx_dropped++;
-		}
-		issue_and_wait(dev, RxDiscard);
-	}
-
-	return 0;
-}
-
-static int
-boomerang_rx(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	int entry = vp->cur_rx % RX_RING_SIZE;
-	void __iomem *ioaddr = vp->ioaddr;
-	int rx_status;
-	int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
-
-	if (vortex_debug > 5)
-		pr_debug("boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
-
-	while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
-		if (--rx_work_limit < 0)
-			break;
-		if (rx_status & RxDError) { /* Error, update stats. */
-			unsigned char rx_error = rx_status >> 16;
-			if (vortex_debug > 2)
-				pr_debug(" Rx error: status %2.2x.\n", rx_error);
-			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;
-			struct sk_buff *skb;
-			dma_addr_t dma = le32_to_cpu(vp->rx_ring[entry].addr);
-
-			if (vortex_debug > 4)
-				pr_debug("Receiving packet size %d status %4.4x.\n",
-					   pkt_len, rx_status);
-
-			/* Check if the packet is long enough to just accept without
-			   copying to a properly sized skbuff. */
-			if (pkt_len < rx_copybreak && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
-				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
-				pci_dma_sync_single_for_cpu(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
-				/* 'skb_put()' points to the start of sk_buff data area. */
-				memcpy(skb_put(skb, pkt_len),
-					   vp->rx_skbuff[entry]->data,
-					   pkt_len);
-				pci_dma_sync_single_for_device(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
-				vp->rx_copy++;
-			} else {
-				/* Pass up the skbuff already on the Rx ring. */
-				skb = vp->rx_skbuff[entry];
-				vp->rx_skbuff[entry] = NULL;
-				skb_put(skb, pkt_len);
-				pci_unmap_single(VORTEX_PCI(vp), dma, PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
-				vp->rx_nocopy++;
-			}
-			skb->protocol = eth_type_trans(skb, dev);
-			{					/* Use hardware checksum info. */
-				int csum_bits = rx_status & 0xee000000;
-				if (csum_bits &&
-					(csum_bits == (IPChksumValid | TCPChksumValid) ||
-					 csum_bits == (IPChksumValid | UDPChksumValid))) {
-					skb->ip_summed = CHECKSUM_UNNECESSARY;
-					vp->rx_csumhits++;
-				}
-			}
-			netif_rx(skb);
-			dev->stats.rx_packets++;
-		}
-		entry = (++vp->cur_rx) % RX_RING_SIZE;
-	}
-	/* Refill the Rx ring buffers. */
-	for (; vp->cur_rx - vp->dirty_rx > 0; vp->dirty_rx++) {
-		struct sk_buff *skb;
-		entry = vp->dirty_rx % RX_RING_SIZE;
-		if (vp->rx_skbuff[entry] == NULL) {
-			skb = netdev_alloc_skb_ip_align(dev, PKT_BUF_SZ);
-			if (skb == NULL) {
-				static unsigned long last_jif;
-				if (time_after(jiffies, last_jif + 10 * HZ)) {
-					pr_warning("%s: memory shortage\n", dev->name);
-					last_jif = jiffies;
-				}
-				if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)
-					mod_timer(&vp->rx_oom_timer, RUN_AT(HZ * 1));
-				break;			/* Bad news!  */
-			}
-
-			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;
-		}
-		vp->rx_ring[entry].status = 0;	/* Clear complete bit. */
-		iowrite16(UpUnstall, ioaddr + EL3_CMD);
-	}
-	return 0;
-}
-
-/*
- * If we've hit a total OOM refilling the Rx ring we poll once a second
- * for some memory.  Otherwise there is no way to restart the rx process.
- */
-static void
-rx_oom_timer(unsigned long arg)
-{
-	struct net_device *dev = (struct net_device *)arg;
-	struct vortex_private *vp = netdev_priv(dev);
-
-	spin_lock_irq(&vp->lock);
-	if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)	/* This test is redundant, but makes me feel good */
-		boomerang_rx(dev);
-	if (vortex_debug > 1) {
-		pr_debug("%s: rx_oom_timer %s\n", dev->name,
-			((vp->cur_rx - vp->dirty_rx) != RX_RING_SIZE) ? "succeeded" : "retrying");
-	}
-	spin_unlock_irq(&vp->lock);
-}
-
-static void
-vortex_down(struct net_device *dev, int final_down)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-
-	netif_stop_queue (dev);
-
-	del_timer_sync(&vp->rx_oom_timer);
-	del_timer_sync(&vp->timer);
-
-	/* Turn off statistics ASAP.  We update dev->stats below. */
-	iowrite16(StatsDisable, ioaddr + EL3_CMD);
-
-	/* Disable the receiver and transmitter. */
-	iowrite16(RxDisable, ioaddr + EL3_CMD);
-	iowrite16(TxDisable, ioaddr + EL3_CMD);
-
-	/* Disable receiving 802.1q tagged frames */
-	set_8021q_mode(dev, 0);
-
-	if (dev->if_port == XCVR_10base2)
-		/* Turn off thinnet power.  Green! */
-		iowrite16(StopCoax, ioaddr + EL3_CMD);
-
-	iowrite16(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
-
-	update_stats(ioaddr, dev);
-	if (vp->full_bus_master_rx)
-		iowrite32(0, ioaddr + UpListPtr);
-	if (vp->full_bus_master_tx)
-		iowrite32(0, ioaddr + DownListPtr);
-
-	if (final_down && VORTEX_PCI(vp)) {
-		vp->pm_state_valid = 1;
-		pci_save_state(VORTEX_PCI(vp));
-		acpi_set_WOL(dev);
-	}
-}
-
-static int
-vortex_close(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-	int i;
-
-	if (netif_device_present(dev))
-		vortex_down(dev, 1);
-
-	if (vortex_debug > 1) {
-		pr_debug("%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
-			   dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
-		pr_debug("%s: vortex close stats: rx_nocopy %d rx_copy %d"
-			   " tx_queued %d Rx pre-checksummed %d.\n",
-			   dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
-	}
-
-#if DO_ZEROCOPY
-	if (vp->rx_csumhits &&
-	    (vp->drv_flags & HAS_HWCKSM) == 0 &&
-	    (vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
-		pr_warning("%s supports hardware checksums, and we're not using them!\n", dev->name);
-	}
-#endif
-
-	free_irq(dev->irq, dev);
-
-	if (vp->full_bus_master_rx) { /* Free Boomerang bus master Rx buffers. */
-		for (i = 0; i < RX_RING_SIZE; i++)
-			if (vp->rx_skbuff[i]) {
-				pci_unmap_single(	VORTEX_PCI(vp), le32_to_cpu(vp->rx_ring[i].addr),
-									PKT_BUF_SZ, PCI_DMA_FROMDEVICE);
-				dev_kfree_skb(vp->rx_skbuff[i]);
-				vp->rx_skbuff[i] = NULL;
-			}
-	}
-	if (vp->full_bus_master_tx) { /* Free Boomerang bus master Tx buffers. */
-		for (i = 0; i < TX_RING_SIZE; i++) {
-			if (vp->tx_skbuff[i]) {
-				struct sk_buff *skb = vp->tx_skbuff[i];
-#if DO_ZEROCOPY
-				int k;
-
-				for (k=0; k<=skb_shinfo(skb)->nr_frags; k++)
-						pci_unmap_single(VORTEX_PCI(vp),
-										 le32_to_cpu(vp->tx_ring[i].frag[k].addr),
-										 le32_to_cpu(vp->tx_ring[i].frag[k].length)&0xFFF,
-										 PCI_DMA_TODEVICE);
-#else
-				pci_unmap_single(VORTEX_PCI(vp), le32_to_cpu(vp->tx_ring[i].addr), skb->len, PCI_DMA_TODEVICE);
-#endif
-				dev_kfree_skb(skb);
-				vp->tx_skbuff[i] = NULL;
-			}
-		}
-	}
-
-	return 0;
-}
-
-static void
-dump_tx_ring(struct net_device *dev)
-{
-	if (vortex_debug > 0) {
-	struct vortex_private *vp = netdev_priv(dev);
-		void __iomem *ioaddr = vp->ioaddr;
-
-		if (vp->full_bus_master_tx) {
-			int i;
-			int stalled = ioread32(ioaddr + PktStatus) & 0x04;	/* Possible racy. But it's only debug stuff */
-
-			pr_err("  Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
-					vp->full_bus_master_tx,
-					vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
-					vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
-			pr_err("  Transmit list %8.8x vs. %p.\n",
-				   ioread32(ioaddr + DownListPtr),
-				   &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
-			issue_and_wait(dev, DownStall);
-			for (i = 0; i < TX_RING_SIZE; i++) {
-				unsigned int length;
-
-#if DO_ZEROCOPY
-				length = le32_to_cpu(vp->tx_ring[i].frag[0].length);
-#else
-				length = le32_to_cpu(vp->tx_ring[i].length);
-#endif
-				pr_err("  %d: @%p  length %8.8x status %8.8x\n",
-					   i, &vp->tx_ring[i], length,
-					   le32_to_cpu(vp->tx_ring[i].status));
-			}
-			if (!stalled)
-				iowrite16(DownUnstall, ioaddr + EL3_CMD);
-		}
-	}
-}
-
-static struct net_device_stats *vortex_get_stats(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-	unsigned long flags;
-
-	if (netif_device_present(dev)) {	/* AKPM: Used to be netif_running */
-		spin_lock_irqsave (&vp->lock, flags);
-		update_stats(ioaddr, dev);
-		spin_unlock_irqrestore (&vp->lock, flags);
-	}
-	return &dev->stats;
-}
-
-/*  Update statistics.
-	Unlike with the EL3 we need not worry about interrupts changing
-	the window setting from underneath us, but we must still guard
-	against a race condition with a StatsUpdate interrupt updating the
-	table.  This is done by checking that the ASM (!) code generated uses
-	atomic updates with '+='.
-	*/
-static void update_stats(void __iomem *ioaddr, struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-
-	/* Unlike the 3c5x9 we need not turn off stats updates while reading. */
-	/* Switch to the stats window, and read everything. */
-	dev->stats.tx_carrier_errors		+= window_read8(vp, 6, 0);
-	dev->stats.tx_heartbeat_errors		+= window_read8(vp, 6, 1);
-	dev->stats.tx_window_errors		+= window_read8(vp, 6, 4);
-	dev->stats.rx_fifo_errors		+= window_read8(vp, 6, 5);
-	dev->stats.tx_packets			+= window_read8(vp, 6, 6);
-	dev->stats.tx_packets			+= (window_read8(vp, 6, 9) &
-						    0x30) << 4;
-	/* Rx packets	*/			window_read8(vp, 6, 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. */
-	dev->stats.rx_bytes 			+= window_read16(vp, 6, 10);
-	dev->stats.tx_bytes 			+= window_read16(vp, 6, 12);
-	/* Extra stats for get_ethtool_stats() */
-	vp->xstats.tx_multiple_collisions	+= window_read8(vp, 6, 2);
-	vp->xstats.tx_single_collisions         += window_read8(vp, 6, 3);
-	vp->xstats.tx_deferred			+= window_read8(vp, 6, 8);
-	vp->xstats.rx_bad_ssd			+= window_read8(vp, 4, 12);
-
-	dev->stats.collisions = vp->xstats.tx_multiple_collisions
-		+ vp->xstats.tx_single_collisions
-		+ vp->xstats.tx_max_collisions;
-
-	{
-		u8 up = window_read8(vp, 4, 13);
-		dev->stats.rx_bytes += (up & 0x0f) << 16;
-		dev->stats.tx_bytes += (up & 0xf0) << 12;
-	}
-}
-
-static int vortex_nway_reset(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-
-	return mii_nway_restart(&vp->mii);
-}
-
-static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-
-	return mii_ethtool_gset(&vp->mii, cmd);
-}
-
-static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-
-	return mii_ethtool_sset(&vp->mii, cmd);
-}
-
-static u32 vortex_get_msglevel(struct net_device *dev)
-{
-	return vortex_debug;
-}
-
-static void vortex_set_msglevel(struct net_device *dev, u32 dbg)
-{
-	vortex_debug = dbg;
-}
-
-static int vortex_get_sset_count(struct net_device *dev, int sset)
-{
-	switch (sset) {
-	case ETH_SS_STATS:
-		return VORTEX_NUM_STATS;
-	default:
-		return -EOPNOTSUPP;
-	}
-}
-
-static void vortex_get_ethtool_stats(struct net_device *dev,
-	struct ethtool_stats *stats, u64 *data)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-	unsigned long flags;
-
-	spin_lock_irqsave(&vp->lock, flags);
-	update_stats(ioaddr, dev);
-	spin_unlock_irqrestore(&vp->lock, flags);
-
-	data[0] = vp->xstats.tx_deferred;
-	data[1] = vp->xstats.tx_max_collisions;
-	data[2] = vp->xstats.tx_multiple_collisions;
-	data[3] = vp->xstats.tx_single_collisions;
-	data[4] = vp->xstats.rx_bad_ssd;
-}
-
-
-static void vortex_get_strings(struct net_device *dev, u32 stringset, u8 *data)
-{
-	switch (stringset) {
-	case ETH_SS_STATS:
-		memcpy(data, &ethtool_stats_keys, sizeof(ethtool_stats_keys));
-		break;
-	default:
-		WARN_ON(1);
-		break;
-	}
-}
-
-static void vortex_get_drvinfo(struct net_device *dev,
-					struct ethtool_drvinfo *info)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-
-	strcpy(info->driver, DRV_NAME);
-	if (VORTEX_PCI(vp)) {
-		strcpy(info->bus_info, pci_name(VORTEX_PCI(vp)));
-	} else {
-		if (VORTEX_EISA(vp))
-			strcpy(info->bus_info, dev_name(vp->gendev));
-		else
-			sprintf(info->bus_info, "EISA 0x%lx %d",
-					dev->base_addr, dev->irq);
-	}
-}
-
-static void vortex_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-
-	if (!VORTEX_PCI(vp))
-		return;
-
-	wol->supported = WAKE_MAGIC;
-
-	wol->wolopts = 0;
-	if (vp->enable_wol)
-		wol->wolopts |= WAKE_MAGIC;
-}
-
-static int vortex_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-
-	if (!VORTEX_PCI(vp))
-		return -EOPNOTSUPP;
-
-	if (wol->wolopts & ~WAKE_MAGIC)
-		return -EINVAL;
-
-	if (wol->wolopts & WAKE_MAGIC)
-		vp->enable_wol = 1;
-	else
-		vp->enable_wol = 0;
-	acpi_set_WOL(dev);
-
-	return 0;
-}
-
-static const struct ethtool_ops vortex_ethtool_ops = {
-	.get_drvinfo		= vortex_get_drvinfo,
-	.get_strings            = vortex_get_strings,
-	.get_msglevel           = vortex_get_msglevel,
-	.set_msglevel           = vortex_set_msglevel,
-	.get_ethtool_stats      = vortex_get_ethtool_stats,
-	.get_sset_count		= vortex_get_sset_count,
-	.get_settings           = vortex_get_settings,
-	.set_settings           = vortex_set_settings,
-	.get_link               = ethtool_op_get_link,
-	.nway_reset             = vortex_nway_reset,
-	.get_wol                = vortex_get_wol,
-	.set_wol                = vortex_set_wol,
-};
-
-#ifdef CONFIG_PCI
-/*
- *	Must power the device up to do MDIO operations
- */
-static int vortex_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-	int err;
-	struct vortex_private *vp = netdev_priv(dev);
-	pci_power_t state = 0;
-
-	if(VORTEX_PCI(vp))
-		state = VORTEX_PCI(vp)->current_state;
-
-	/* The kernel core really should have pci_get_power_state() */
-
-	if(state != 0)
-		pci_set_power_state(VORTEX_PCI(vp), PCI_D0);
-	err = generic_mii_ioctl(&vp->mii, if_mii(rq), cmd, NULL);
-	if(state != 0)
-		pci_set_power_state(VORTEX_PCI(vp), state);
-
-	return err;
-}
-#endif
-
-
-/* Pre-Cyclone chips have no documented multicast filter, so the only
-   multicast setting is to receive all multicast frames.  At least
-   the chip has a very clean way to set the mode, unlike many others. */
-static void set_rx_mode(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-	int new_mode;
-
-	if (dev->flags & IFF_PROMISC) {
-		if (vortex_debug > 3)
-			pr_notice("%s: Setting promiscuous mode.\n", dev->name);
-		new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm;
-	} else	if (!netdev_mc_empty(dev) || dev->flags & IFF_ALLMULTI) {
-		new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast;
-	} else
-		new_mode = SetRxFilter | RxStation | RxBroadcast;
-
-	iowrite16(new_mode, ioaddr + EL3_CMD);
-}
-
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
-/* Setup the card so that it can receive frames with an 802.1q VLAN tag.
-   Note that this must be done after each RxReset due to some backwards
-   compatibility logic in the Cyclone and Tornado ASICs */
-
-/* The Ethernet Type used for 802.1q tagged frames */
-#define VLAN_ETHER_TYPE 0x8100
-
-static void set_8021q_mode(struct net_device *dev, int enable)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	int mac_ctrl;
-
-	if ((vp->drv_flags&IS_CYCLONE) || (vp->drv_flags&IS_TORNADO)) {
-		/* cyclone and tornado chipsets can recognize 802.1q
-		 * tagged frames and treat them correctly */
-
-		int max_pkt_size = dev->mtu+14;	/* MTU+Ethernet header */
-		if (enable)
-			max_pkt_size += 4;	/* 802.1Q VLAN tag */
-
-		window_write16(vp, max_pkt_size, 3, Wn3_MaxPktSize);
-
-		/* set VlanEtherType to let the hardware checksumming
-		   treat tagged frames correctly */
-		window_write16(vp, VLAN_ETHER_TYPE, 7, Wn7_VlanEtherType);
-	} else {
-		/* on older cards we have to enable large frames */
-
-		vp->large_frames = dev->mtu > 1500 || enable;
-
-		mac_ctrl = window_read16(vp, 3, Wn3_MAC_Ctrl);
-		if (vp->large_frames)
-			mac_ctrl |= 0x40;
-		else
-			mac_ctrl &= ~0x40;
-		window_write16(vp, mac_ctrl, 3, Wn3_MAC_Ctrl);
-	}
-}
-#else
-
-static void set_8021q_mode(struct net_device *dev, int enable)
-{
-}
-
-
-#endif
-
-/* MII transceiver control section.
-   Read and write the MII registers using software-generated serial
-   MDIO protocol.  See the MII specifications or DP83840A data sheet
-   for details. */
-
-/* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
-   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
-   "overclocking" issues. */
-static void mdio_delay(struct vortex_private *vp)
-{
-	window_read32(vp, 4, Wn4_PhysicalMgmt);
-}
-
-#define MDIO_SHIFT_CLK	0x01
-#define MDIO_DIR_WRITE	0x04
-#define MDIO_DATA_WRITE0 (0x00 | MDIO_DIR_WRITE)
-#define MDIO_DATA_WRITE1 (0x02 | MDIO_DIR_WRITE)
-#define MDIO_DATA_READ	0x02
-#define MDIO_ENB_IN		0x00
-
-/* Generate the preamble required for initial synchronization and
-   a few older transceivers. */
-static void mdio_sync(struct vortex_private *vp, int bits)
-{
-	/* Establish sync by sending at least 32 logic ones. */
-	while (-- bits >= 0) {
-		window_write16(vp, MDIO_DATA_WRITE1, 4, Wn4_PhysicalMgmt);
-		mdio_delay(vp);
-		window_write16(vp, MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK,
-			       4, Wn4_PhysicalMgmt);
-		mdio_delay(vp);
-	}
-}
-
-static int mdio_read(struct net_device *dev, int phy_id, int location)
-{
-	int i;
-	struct vortex_private *vp = netdev_priv(dev);
-	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
-	unsigned int retval = 0;
-
-	spin_lock_bh(&vp->mii_lock);
-
-	if (mii_preamble_required)
-		mdio_sync(vp, 32);
-
-	/* Shift the read command bits out. */
-	for (i = 14; i >= 0; i--) {
-		int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
-		window_write16(vp, dataval, 4, Wn4_PhysicalMgmt);
-		mdio_delay(vp);
-		window_write16(vp, dataval | MDIO_SHIFT_CLK,
-			       4, Wn4_PhysicalMgmt);
-		mdio_delay(vp);
-	}
-	/* Read the two transition, 16 data, and wire-idle bits. */
-	for (i = 19; i > 0; i--) {
-		window_write16(vp, MDIO_ENB_IN, 4, Wn4_PhysicalMgmt);
-		mdio_delay(vp);
-		retval = (retval << 1) |
-			((window_read16(vp, 4, Wn4_PhysicalMgmt) &
-			  MDIO_DATA_READ) ? 1 : 0);
-		window_write16(vp, MDIO_ENB_IN | MDIO_SHIFT_CLK,
-			       4, Wn4_PhysicalMgmt);
-		mdio_delay(vp);
-	}
-
-	spin_unlock_bh(&vp->mii_lock);
-
-	return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
-}
-
-static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
-	int i;
-
-	spin_lock_bh(&vp->mii_lock);
-
-	if (mii_preamble_required)
-		mdio_sync(vp, 32);
-
-	/* Shift the command bits out. */
-	for (i = 31; i >= 0; i--) {
-		int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
-		window_write16(vp, dataval, 4, Wn4_PhysicalMgmt);
-		mdio_delay(vp);
-		window_write16(vp, dataval | MDIO_SHIFT_CLK,
-			       4, Wn4_PhysicalMgmt);
-		mdio_delay(vp);
-	}
-	/* Leave the interface idle. */
-	for (i = 1; i >= 0; i--) {
-		window_write16(vp, MDIO_ENB_IN, 4, Wn4_PhysicalMgmt);
-		mdio_delay(vp);
-		window_write16(vp, MDIO_ENB_IN | MDIO_SHIFT_CLK,
-			       4, Wn4_PhysicalMgmt);
-		mdio_delay(vp);
-	}
-
-	spin_unlock_bh(&vp->mii_lock);
-}
-
-/* ACPI: Advanced Configuration and Power Interface. */
-/* Set Wake-On-LAN mode and put the board into D3 (power-down) state. */
-static void acpi_set_WOL(struct net_device *dev)
-{
-	struct vortex_private *vp = netdev_priv(dev);
-	void __iomem *ioaddr = vp->ioaddr;
-
-	device_set_wakeup_enable(vp->gendev, vp->enable_wol);
-
-	if (vp->enable_wol) {
-		/* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
-		window_write16(vp, 2, 7, 0x0c);
-		/* The RxFilter must accept the WOL frames. */
-		iowrite16(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
-		iowrite16(RxEnable, ioaddr + EL3_CMD);
-
-		if (pci_enable_wake(VORTEX_PCI(vp), PCI_D3hot, 1)) {
-			pr_info("%s: WOL not supported.\n", pci_name(VORTEX_PCI(vp)));
-
-			vp->enable_wol = 0;
-			return;
-		}
-
-		if (VORTEX_PCI(vp)->current_state < PCI_D3hot)
-			return;
-
-		/* Change the power state to D3; RxEnable doesn't take effect. */
-		pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot);
-	}
-}
-
-
-static void __devexit vortex_remove_one(struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct vortex_private *vp;
-
-	if (!dev) {
-		pr_err("vortex_remove_one called for Compaq device!\n");
-		BUG();
-	}
-
-	vp = netdev_priv(dev);
-
-	if (vp->cb_fn_base)
-		pci_iounmap(VORTEX_PCI(vp), vp->cb_fn_base);
-
-	unregister_netdev(dev);
-
-	if (VORTEX_PCI(vp)) {
-		pci_set_power_state(VORTEX_PCI(vp), PCI_D0);	/* Go active */
-		if (vp->pm_state_valid)
-			pci_restore_state(VORTEX_PCI(vp));
-		pci_disable_device(VORTEX_PCI(vp));
-	}
-	/* Should really use issue_and_wait() here */
-	iowrite16(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
-	     vp->ioaddr + EL3_CMD);
-
-	pci_iounmap(VORTEX_PCI(vp), vp->ioaddr);
-
-	pci_free_consistent(pdev,
-						sizeof(struct boom_rx_desc) * RX_RING_SIZE
-							+ sizeof(struct boom_tx_desc) * TX_RING_SIZE,
-						vp->rx_ring,
-						vp->rx_ring_dma);
-	if (vp->must_free_region)
-		release_region(dev->base_addr, vp->io_size);
-	free_netdev(dev);
-}
-
-
-static struct pci_driver vortex_driver = {
-	.name		= "3c59x",
-	.probe		= vortex_init_one,
-	.remove		= __devexit_p(vortex_remove_one),
-	.id_table	= vortex_pci_tbl,
-	.driver.pm	= VORTEX_PM_OPS,
-};
-
-
-static int vortex_have_pci;
-static int vortex_have_eisa;
-
-
-static int __init vortex_init(void)
-{
-	int pci_rc, eisa_rc;
-
-	pci_rc = pci_register_driver(&vortex_driver);
-	eisa_rc = vortex_eisa_init();
-
-	if (pci_rc == 0)
-		vortex_have_pci = 1;
-	if (eisa_rc > 0)
-		vortex_have_eisa = 1;
-
-	return (vortex_have_pci + vortex_have_eisa) ? 0 : -ENODEV;
-}
-
-
-static void __exit vortex_eisa_cleanup(void)
-{
-	struct vortex_private *vp;
-	void __iomem *ioaddr;
-
-#ifdef CONFIG_EISA
-	/* Take care of the EISA devices */
-	eisa_driver_unregister(&vortex_eisa_driver);
-#endif
-
-	if (compaq_net_device) {
-		vp = netdev_priv(compaq_net_device);
-		ioaddr = ioport_map(compaq_net_device->base_addr,
-		                    VORTEX_TOTAL_SIZE);
-
-		unregister_netdev(compaq_net_device);
-		iowrite16(TotalReset, ioaddr + EL3_CMD);
-		release_region(compaq_net_device->base_addr,
-		               VORTEX_TOTAL_SIZE);
-
-		free_netdev(compaq_net_device);
-	}
-}
-
-
-static void __exit vortex_cleanup(void)
-{
-	if (vortex_have_pci)
-		pci_unregister_driver(&vortex_driver);
-	if (vortex_have_eisa)
-		vortex_eisa_cleanup();
-}
-
-
-module_init(vortex_init);
-module_exit(vortex_cleanup);

+ 0 - 2064
drivers/net/8139cp.c

@@ -1,2064 +0,0 @@
-/* 8139cp.c: A Linux PCI Ethernet driver for the RealTek 8139C+ chips. */
-/*
-	Copyright 2001-2004 Jeff Garzik <jgarzik@pobox.com>
-
-	Copyright (C) 2001, 2002 David S. Miller (davem@redhat.com) [tg3.c]
-	Copyright (C) 2000, 2001 David S. Miller (davem@redhat.com) [sungem.c]
-	Copyright 2001 Manfred Spraul				    [natsemi.c]
-	Copyright 1999-2001 by Donald Becker.			    [natsemi.c]
-       	Written 1997-2001 by Donald Becker.			    [8139too.c]
-	Copyright 1998-2001 by Jes Sorensen, <jes@trained-monkey.org>. [acenic.c]
-
-	This software may be used and distributed according to the terms of
-	the GNU General Public License (GPL), incorporated herein by reference.
-	Drivers based on or derived from this code fall under the GPL and must
-	retain the authorship, copyright and license notice.  This file is not
-	a complete program and may only be used when the entire operating
-	system is licensed under the GPL.
-
-	See the file COPYING in this distribution for more information.
-
-	Contributors:
-
-		Wake-on-LAN support - Felipe Damasio <felipewd@terra.com.br>
-		PCI suspend/resume  - Felipe Damasio <felipewd@terra.com.br>
-		LinkChg interrupt   - Felipe Damasio <felipewd@terra.com.br>
-
-	TODO:
-	* Test Tx checksumming thoroughly
-
-	Low priority TODO:
-	* Complete reset on PciErr
-	* Consider Rx interrupt mitigation using TimerIntr
-	* Investigate using skb->priority with h/w VLAN priority
-	* Investigate using High Priority Tx Queue with skb->priority
-	* Adjust Rx FIFO threshold and Max Rx DMA burst on Rx FIFO error
-	* Adjust Tx FIFO threshold and Max Tx DMA burst on Tx FIFO error
-	* Implement Tx software interrupt mitigation via
-	  Tx descriptor bit
-	* The real minimum of CP_MIN_MTU is 4 bytes.  However,
-	  for this to be supported, one must(?) turn on packet padding.
-	* Support external MII transceivers (patch available)
-
-	NOTES:
-	* TX checksumming is considered experimental.  It is off by
-	  default, use ethtool to turn it on.
-
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define DRV_NAME		"8139cp"
-#define DRV_VERSION		"1.3"
-#define DRV_RELDATE		"Mar 22, 2004"
-
-
-#include <linux/module.h>
-#include <linux/moduleparam.h>
-#include <linux/kernel.h>
-#include <linux/compiler.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/pci.h>
-#include <linux/dma-mapping.h>
-#include <linux/delay.h>
-#include <linux/ethtool.h>
-#include <linux/gfp.h>
-#include <linux/mii.h>
-#include <linux/if_vlan.h>
-#include <linux/crc32.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#include <linux/udp.h>
-#include <linux/cache.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
-
-/* These identify the driver base version and may not be removed. */
-static char version[] =
-DRV_NAME ": 10/100 PCI Ethernet driver v" DRV_VERSION " (" DRV_RELDATE ")\n";
-
-MODULE_AUTHOR("Jeff Garzik <jgarzik@pobox.com>");
-MODULE_DESCRIPTION("RealTek RTL-8139C+ series 10/100 PCI Ethernet driver");
-MODULE_VERSION(DRV_VERSION);
-MODULE_LICENSE("GPL");
-
-static int debug = -1;
-module_param(debug, int, 0);
-MODULE_PARM_DESC (debug, "8139cp: bitmapped message enable number");
-
-/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
-   The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
-static int multicast_filter_limit = 32;
-module_param(multicast_filter_limit, int, 0);
-MODULE_PARM_DESC (multicast_filter_limit, "8139cp: maximum number of filtered multicast addresses");
-
-#define CP_DEF_MSG_ENABLE	(NETIF_MSG_DRV		| \
-				 NETIF_MSG_PROBE 	| \
-				 NETIF_MSG_LINK)
-#define CP_NUM_STATS		14	/* struct cp_dma_stats, plus one */
-#define CP_STATS_SIZE		64	/* size in bytes of DMA stats block */
-#define CP_REGS_SIZE		(0xff + 1)
-#define CP_REGS_VER		1		/* version 1 */
-#define CP_RX_RING_SIZE		64
-#define CP_TX_RING_SIZE		64
-#define CP_RING_BYTES		\
-		((sizeof(struct cp_desc) * CP_RX_RING_SIZE) +	\
-		 (sizeof(struct cp_desc) * CP_TX_RING_SIZE) +	\
-		 CP_STATS_SIZE)
-#define NEXT_TX(N)		(((N) + 1) & (CP_TX_RING_SIZE - 1))
-#define NEXT_RX(N)		(((N) + 1) & (CP_RX_RING_SIZE - 1))
-#define TX_BUFFS_AVAIL(CP)					\
-	(((CP)->tx_tail <= (CP)->tx_head) ?			\
-	  (CP)->tx_tail + (CP_TX_RING_SIZE - 1) - (CP)->tx_head :	\
-	  (CP)->tx_tail - (CP)->tx_head - 1)
-
-#define PKT_BUF_SZ		1536	/* Size of each temporary Rx buffer.*/
-#define CP_INTERNAL_PHY		32
-
-/* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024, 7==end of packet. */
-#define RX_FIFO_THRESH		5	/* Rx buffer level before first PCI xfer.  */
-#define RX_DMA_BURST		4	/* Maximum PCI burst, '4' is 256 */
-#define TX_DMA_BURST		6	/* Maximum PCI burst, '6' is 1024 */
-#define TX_EARLY_THRESH		256	/* Early Tx threshold, in bytes */
-
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT		(6*HZ)
-
-/* hardware minimum and maximum for a single frame's data payload */
-#define CP_MIN_MTU		60	/* TODO: allow lower, but pad */
-#define CP_MAX_MTU		4096
-
-enum {
-	/* NIC register offsets */
-	MAC0		= 0x00,	/* Ethernet hardware address. */
-	MAR0		= 0x08,	/* Multicast filter. */
-	StatsAddr	= 0x10,	/* 64-bit start addr of 64-byte DMA stats blk */
-	TxRingAddr	= 0x20, /* 64-bit start addr of Tx ring */
-	HiTxRingAddr	= 0x28, /* 64-bit start addr of high priority Tx ring */
-	Cmd		= 0x37, /* Command register */
-	IntrMask	= 0x3C, /* Interrupt mask */
-	IntrStatus	= 0x3E, /* Interrupt status */
-	TxConfig	= 0x40, /* Tx configuration */
-	ChipVersion	= 0x43, /* 8-bit chip version, inside TxConfig */
-	RxConfig	= 0x44, /* Rx configuration */
-	RxMissed	= 0x4C,	/* 24 bits valid, write clears */
-	Cfg9346		= 0x50, /* EEPROM select/control; Cfg reg [un]lock */
-	Config1		= 0x52, /* Config1 */
-	Config3		= 0x59, /* Config3 */
-	Config4		= 0x5A, /* Config4 */
-	MultiIntr	= 0x5C, /* Multiple interrupt select */
-	BasicModeCtrl	= 0x62,	/* MII BMCR */
-	BasicModeStatus	= 0x64, /* MII BMSR */
-	NWayAdvert	= 0x66, /* MII ADVERTISE */
-	NWayLPAR	= 0x68, /* MII LPA */
-	NWayExpansion	= 0x6A, /* MII Expansion */
-	Config5		= 0xD8,	/* Config5 */
-	TxPoll		= 0xD9,	/* Tell chip to check Tx descriptors for work */
-	RxMaxSize	= 0xDA, /* Max size of an Rx packet (8169 only) */
-	CpCmd		= 0xE0, /* C+ Command register (C+ mode only) */
-	IntrMitigate	= 0xE2,	/* rx/tx interrupt mitigation control */
-	RxRingAddr	= 0xE4, /* 64-bit start addr of Rx ring */
-	TxThresh	= 0xEC, /* Early Tx threshold */
-	OldRxBufAddr	= 0x30, /* DMA address of Rx ring buffer (C mode) */
-	OldTSD0		= 0x10, /* DMA address of first Tx desc (C mode) */
-
-	/* Tx and Rx status descriptors */
-	DescOwn		= (1 << 31), /* Descriptor is owned by NIC */
-	RingEnd		= (1 << 30), /* End of descriptor ring */
-	FirstFrag	= (1 << 29), /* First segment of a packet */
-	LastFrag	= (1 << 28), /* Final segment of a packet */
-	LargeSend	= (1 << 27), /* TCP Large Send Offload (TSO) */
-	MSSShift	= 16,	     /* MSS value position */
-	MSSMask		= 0xfff,     /* MSS value: 11 bits */
-	TxError		= (1 << 23), /* Tx error summary */
-	RxError		= (1 << 20), /* Rx error summary */
-	IPCS		= (1 << 18), /* Calculate IP checksum */
-	UDPCS		= (1 << 17), /* Calculate UDP/IP checksum */
-	TCPCS		= (1 << 16), /* Calculate TCP/IP checksum */
-	TxVlanTag	= (1 << 17), /* Add VLAN tag */
-	RxVlanTagged	= (1 << 16), /* Rx VLAN tag available */
-	IPFail		= (1 << 15), /* IP checksum failed */
-	UDPFail		= (1 << 14), /* UDP/IP checksum failed */
-	TCPFail		= (1 << 13), /* TCP/IP checksum failed */
-	NormalTxPoll	= (1 << 6),  /* One or more normal Tx packets to send */
-	PID1		= (1 << 17), /* 2 protocol id bits:  0==non-IP, */
-	PID0		= (1 << 16), /* 1==UDP/IP, 2==TCP/IP, 3==IP */
-	RxProtoTCP	= 1,
-	RxProtoUDP	= 2,
-	RxProtoIP	= 3,
-	TxFIFOUnder	= (1 << 25), /* Tx FIFO underrun */
-	TxOWC		= (1 << 22), /* Tx Out-of-window collision */
-	TxLinkFail	= (1 << 21), /* Link failed during Tx of packet */
-	TxMaxCol	= (1 << 20), /* Tx aborted due to excessive collisions */
-	TxColCntShift	= 16,	     /* Shift, to get 4-bit Tx collision cnt */
-	TxColCntMask	= 0x01 | 0x02 | 0x04 | 0x08, /* 4-bit collision count */
-	RxErrFrame	= (1 << 27), /* Rx frame alignment error */
-	RxMcast		= (1 << 26), /* Rx multicast packet rcv'd */
-	RxErrCRC	= (1 << 18), /* Rx CRC error */
-	RxErrRunt	= (1 << 19), /* Rx error, packet < 64 bytes */
-	RxErrLong	= (1 << 21), /* Rx error, packet > 4096 bytes */
-	RxErrFIFO	= (1 << 22), /* Rx error, FIFO overflowed, pkt bad */
-
-	/* StatsAddr register */
-	DumpStats	= (1 << 3),  /* Begin stats dump */
-
-	/* RxConfig register */
-	RxCfgFIFOShift	= 13,	     /* Shift, to get Rx FIFO thresh value */
-	RxCfgDMAShift	= 8,	     /* Shift, to get Rx Max DMA value */
-	AcceptErr	= 0x20,	     /* Accept packets with CRC errors */
-	AcceptRunt	= 0x10,	     /* Accept runt (<64 bytes) packets */
-	AcceptBroadcast	= 0x08,	     /* Accept broadcast packets */
-	AcceptMulticast	= 0x04,	     /* Accept multicast packets */
-	AcceptMyPhys	= 0x02,	     /* Accept pkts with our MAC as dest */
-	AcceptAllPhys	= 0x01,	     /* Accept all pkts w/ physical dest */
-
-	/* IntrMask / IntrStatus registers */
-	PciErr		= (1 << 15), /* System error on the PCI bus */
-	TimerIntr	= (1 << 14), /* Asserted when TCTR reaches TimerInt value */
-	LenChg		= (1 << 13), /* Cable length change */
-	SWInt		= (1 << 8),  /* Software-requested interrupt */
-	TxEmpty		= (1 << 7),  /* No Tx descriptors available */
-	RxFIFOOvr	= (1 << 6),  /* Rx FIFO Overflow */
-	LinkChg		= (1 << 5),  /* Packet underrun, or link change */
-	RxEmpty		= (1 << 4),  /* No Rx descriptors available */
-	TxErr		= (1 << 3),  /* Tx error */
-	TxOK		= (1 << 2),  /* Tx packet sent */
-	RxErr		= (1 << 1),  /* Rx error */
-	RxOK		= (1 << 0),  /* Rx packet received */
-	IntrResvd	= (1 << 10), /* reserved, according to RealTek engineers,
-					but hardware likes to raise it */
-
-	IntrAll		= PciErr | TimerIntr | LenChg | SWInt | TxEmpty |
-			  RxFIFOOvr | LinkChg | RxEmpty | TxErr | TxOK |
-			  RxErr | RxOK | IntrResvd,
-
-	/* C mode command register */
-	CmdReset	= (1 << 4),  /* Enable to reset; self-clearing */
-	RxOn		= (1 << 3),  /* Rx mode enable */
-	TxOn		= (1 << 2),  /* Tx mode enable */
-
-	/* C+ mode command register */
-	RxVlanOn	= (1 << 6),  /* Rx VLAN de-tagging enable */
-	RxChkSum	= (1 << 5),  /* Rx checksum offload enable */
-	PCIDAC		= (1 << 4),  /* PCI Dual Address Cycle (64-bit PCI) */
-	PCIMulRW	= (1 << 3),  /* Enable PCI read/write multiple */
-	CpRxOn		= (1 << 1),  /* Rx mode enable */
-	CpTxOn		= (1 << 0),  /* Tx mode enable */
-
-	/* Cfg9436 EEPROM control register */
-	Cfg9346_Lock	= 0x00,	     /* Lock ConfigX/MII register access */
-	Cfg9346_Unlock	= 0xC0,	     /* Unlock ConfigX/MII register access */
-
-	/* TxConfig register */
-	IFG		= (1 << 25) | (1 << 24), /* standard IEEE interframe gap */
-	TxDMAShift	= 8,	     /* DMA burst value (0-7) is shift this many bits */
-
-	/* Early Tx Threshold register */
-	TxThreshMask	= 0x3f,	     /* Mask bits 5-0 */
-	TxThreshMax	= 2048,	     /* Max early Tx threshold */
-
-	/* Config1 register */
-	DriverLoaded	= (1 << 5),  /* Software marker, driver is loaded */
-	LWACT           = (1 << 4),  /* LWAKE active mode */
-	PMEnable	= (1 << 0),  /* Enable various PM features of chip */
-
-	/* Config3 register */
-	PARMEnable	= (1 << 6),  /* Enable auto-loading of PHY parms */
-	MagicPacket     = (1 << 5),  /* Wake up when receives a Magic Packet */
-	LinkUp          = (1 << 4),  /* Wake up when the cable connection is re-established */
-
-	/* Config4 register */
-	LWPTN           = (1 << 1),  /* LWAKE Pattern */
-	LWPME           = (1 << 4),  /* LANWAKE vs PMEB */
-
-	/* Config5 register */
-	BWF             = (1 << 6),  /* Accept Broadcast wakeup frame */
-	MWF             = (1 << 5),  /* Accept Multicast wakeup frame */
-	UWF             = (1 << 4),  /* Accept Unicast wakeup frame */
-	LANWake         = (1 << 1),  /* Enable LANWake signal */
-	PMEStatus	= (1 << 0),  /* PME status can be reset by PCI RST# */
-
-	cp_norx_intr_mask = PciErr | LinkChg | TxOK | TxErr | TxEmpty,
-	cp_rx_intr_mask = RxOK | RxErr | RxEmpty | RxFIFOOvr,
-	cp_intr_mask = cp_rx_intr_mask | cp_norx_intr_mask,
-};
-
-static const unsigned int cp_rx_config =
-	  (RX_FIFO_THRESH << RxCfgFIFOShift) |
-	  (RX_DMA_BURST << RxCfgDMAShift);
-
-struct cp_desc {
-	__le32		opts1;
-	__le32		opts2;
-	__le64		addr;
-};
-
-struct cp_dma_stats {
-	__le64			tx_ok;
-	__le64			rx_ok;
-	__le64			tx_err;
-	__le32			rx_err;
-	__le16			rx_fifo;
-	__le16			frame_align;
-	__le32			tx_ok_1col;
-	__le32			tx_ok_mcol;
-	__le64			rx_ok_phys;
-	__le64			rx_ok_bcast;
-	__le32			rx_ok_mcast;
-	__le16			tx_abort;
-	__le16			tx_underrun;
-} __packed;
-
-struct cp_extra_stats {
-	unsigned long		rx_frags;
-};
-
-struct cp_private {
-	void			__iomem *regs;
-	struct net_device	*dev;
-	spinlock_t		lock;
-	u32			msg_enable;
-
-	struct napi_struct	napi;
-
-	struct pci_dev		*pdev;
-	u32			rx_config;
-	u16			cpcmd;
-
-	struct cp_extra_stats	cp_stats;
-
-	unsigned		rx_head		____cacheline_aligned;
-	unsigned		rx_tail;
-	struct cp_desc		*rx_ring;
-	struct sk_buff		*rx_skb[CP_RX_RING_SIZE];
-
-	unsigned		tx_head		____cacheline_aligned;
-	unsigned		tx_tail;
-	struct cp_desc		*tx_ring;
-	struct sk_buff		*tx_skb[CP_TX_RING_SIZE];
-
-	unsigned		rx_buf_sz;
-	unsigned		wol_enabled : 1; /* Is Wake-on-LAN enabled? */
-
-	dma_addr_t		ring_dma;
-
-	struct mii_if_info	mii_if;
-};
-
-#define cpr8(reg)	readb(cp->regs + (reg))
-#define cpr16(reg)	readw(cp->regs + (reg))
-#define cpr32(reg)	readl(cp->regs + (reg))
-#define cpw8(reg,val)	writeb((val), cp->regs + (reg))
-#define cpw16(reg,val)	writew((val), cp->regs + (reg))
-#define cpw32(reg,val)	writel((val), cp->regs + (reg))
-#define cpw8_f(reg,val) do {			\
-	writeb((val), cp->regs + (reg));	\
-	readb(cp->regs + (reg));		\
-	} while (0)
-#define cpw16_f(reg,val) do {			\
-	writew((val), cp->regs + (reg));	\
-	readw(cp->regs + (reg));		\
-	} while (0)
-#define cpw32_f(reg,val) do {			\
-	writel((val), cp->regs + (reg));	\
-	readl(cp->regs + (reg));		\
-	} while (0)
-
-
-static void __cp_set_rx_mode (struct net_device *dev);
-static void cp_tx (struct cp_private *cp);
-static void cp_clean_rings (struct cp_private *cp);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void cp_poll_controller(struct net_device *dev);
-#endif
-static int cp_get_eeprom_len(struct net_device *dev);
-static int cp_get_eeprom(struct net_device *dev,
-			 struct ethtool_eeprom *eeprom, u8 *data);
-static int cp_set_eeprom(struct net_device *dev,
-			 struct ethtool_eeprom *eeprom, u8 *data);
-
-static DEFINE_PCI_DEVICE_TABLE(cp_pci_tbl) = {
-	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	PCI_DEVICE_ID_REALTEK_8139), },
-	{ PCI_DEVICE(PCI_VENDOR_ID_TTTECH,	PCI_DEVICE_ID_TTTECH_MC322), },
-	{ },
-};
-MODULE_DEVICE_TABLE(pci, cp_pci_tbl);
-
-static struct {
-	const char str[ETH_GSTRING_LEN];
-} ethtool_stats_keys[] = {
-	{ "tx_ok" },
-	{ "rx_ok" },
-	{ "tx_err" },
-	{ "rx_err" },
-	{ "rx_fifo" },
-	{ "frame_align" },
-	{ "tx_ok_1col" },
-	{ "tx_ok_mcol" },
-	{ "rx_ok_phys" },
-	{ "rx_ok_bcast" },
-	{ "rx_ok_mcast" },
-	{ "tx_abort" },
-	{ "tx_underrun" },
-	{ "rx_frags" },
-};
-
-
-static inline void cp_set_rxbufsize (struct cp_private *cp)
-{
-	unsigned int mtu = cp->dev->mtu;
-
-	if (mtu > ETH_DATA_LEN)
-		/* MTU + ethernet header + FCS + optional VLAN tag */
-		cp->rx_buf_sz = mtu + ETH_HLEN + 8;
-	else
-		cp->rx_buf_sz = PKT_BUF_SZ;
-}
-
-static inline void cp_rx_skb (struct cp_private *cp, struct sk_buff *skb,
-			      struct cp_desc *desc)
-{
-	u32 opts2 = le32_to_cpu(desc->opts2);
-
-	skb->protocol = eth_type_trans (skb, cp->dev);
-
-	cp->dev->stats.rx_packets++;
-	cp->dev->stats.rx_bytes += skb->len;
-
-	if (opts2 & RxVlanTagged)
-		__vlan_hwaccel_put_tag(skb, swab16(opts2 & 0xffff));
-
-	napi_gro_receive(&cp->napi, skb);
-}
-
-static void cp_rx_err_acct (struct cp_private *cp, unsigned rx_tail,
-			    u32 status, u32 len)
-{
-	netif_dbg(cp, rx_err, cp->dev, "rx err, slot %d status 0x%x len %d\n",
-		  rx_tail, status, len);
-	cp->dev->stats.rx_errors++;
-	if (status & RxErrFrame)
-		cp->dev->stats.rx_frame_errors++;
-	if (status & RxErrCRC)
-		cp->dev->stats.rx_crc_errors++;
-	if ((status & RxErrRunt) || (status & RxErrLong))
-		cp->dev->stats.rx_length_errors++;
-	if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag))
-		cp->dev->stats.rx_length_errors++;
-	if (status & RxErrFIFO)
-		cp->dev->stats.rx_fifo_errors++;
-}
-
-static inline unsigned int cp_rx_csum_ok (u32 status)
-{
-	unsigned int protocol = (status >> 16) & 0x3;
-
-	if (((protocol == RxProtoTCP) && !(status & TCPFail)) ||
-	    ((protocol == RxProtoUDP) && !(status & UDPFail)))
-		return 1;
-	else
-		return 0;
-}
-
-static int cp_rx_poll(struct napi_struct *napi, int budget)
-{
-	struct cp_private *cp = container_of(napi, struct cp_private, napi);
-	struct net_device *dev = cp->dev;
-	unsigned int rx_tail = cp->rx_tail;
-	int rx;
-
-rx_status_loop:
-	rx = 0;
-	cpw16(IntrStatus, cp_rx_intr_mask);
-
-	while (1) {
-		u32 status, len;
-		dma_addr_t mapping;
-		struct sk_buff *skb, *new_skb;
-		struct cp_desc *desc;
-		const unsigned buflen = cp->rx_buf_sz;
-
-		skb = cp->rx_skb[rx_tail];
-		BUG_ON(!skb);
-
-		desc = &cp->rx_ring[rx_tail];
-		status = le32_to_cpu(desc->opts1);
-		if (status & DescOwn)
-			break;
-
-		len = (status & 0x1fff) - 4;
-		mapping = le64_to_cpu(desc->addr);
-
-		if ((status & (FirstFrag | LastFrag)) != (FirstFrag | LastFrag)) {
-			/* we don't support incoming fragmented frames.
-			 * instead, we attempt to ensure that the
-			 * pre-allocated RX skbs are properly sized such
-			 * that RX fragments are never encountered
-			 */
-			cp_rx_err_acct(cp, rx_tail, status, len);
-			dev->stats.rx_dropped++;
-			cp->cp_stats.rx_frags++;
-			goto rx_next;
-		}
-
-		if (status & (RxError | RxErrFIFO)) {
-			cp_rx_err_acct(cp, rx_tail, status, len);
-			goto rx_next;
-		}
-
-		netif_dbg(cp, rx_status, dev, "rx slot %d status 0x%x len %d\n",
-			  rx_tail, status, len);
-
-		new_skb = netdev_alloc_skb_ip_align(dev, buflen);
-		if (!new_skb) {
-			dev->stats.rx_dropped++;
-			goto rx_next;
-		}
-
-		dma_unmap_single(&cp->pdev->dev, mapping,
-				 buflen, PCI_DMA_FROMDEVICE);
-
-		/* Handle checksum offloading for incoming packets. */
-		if (cp_rx_csum_ok(status))
-			skb->ip_summed = CHECKSUM_UNNECESSARY;
-		else
-			skb_checksum_none_assert(skb);
-
-		skb_put(skb, len);
-
-		mapping = dma_map_single(&cp->pdev->dev, new_skb->data, buflen,
-					 PCI_DMA_FROMDEVICE);
-		cp->rx_skb[rx_tail] = new_skb;
-
-		cp_rx_skb(cp, skb, desc);
-		rx++;
-
-rx_next:
-		cp->rx_ring[rx_tail].opts2 = 0;
-		cp->rx_ring[rx_tail].addr = cpu_to_le64(mapping);
-		if (rx_tail == (CP_RX_RING_SIZE - 1))
-			desc->opts1 = cpu_to_le32(DescOwn | RingEnd |
-						  cp->rx_buf_sz);
-		else
-			desc->opts1 = cpu_to_le32(DescOwn | cp->rx_buf_sz);
-		rx_tail = NEXT_RX(rx_tail);
-
-		if (rx >= budget)
-			break;
-	}
-
-	cp->rx_tail = rx_tail;
-
-	/* if we did not reach work limit, then we're done with
-	 * this round of polling
-	 */
-	if (rx < budget) {
-		unsigned long flags;
-
-		if (cpr16(IntrStatus) & cp_rx_intr_mask)
-			goto rx_status_loop;
-
-		spin_lock_irqsave(&cp->lock, flags);
-		__napi_complete(napi);
-		cpw16_f(IntrMask, cp_intr_mask);
-		spin_unlock_irqrestore(&cp->lock, flags);
-	}
-
-	return rx;
-}
-
-static irqreturn_t cp_interrupt (int irq, void *dev_instance)
-{
-	struct net_device *dev = dev_instance;
-	struct cp_private *cp;
-	u16 status;
-
-	if (unlikely(dev == NULL))
-		return IRQ_NONE;
-	cp = netdev_priv(dev);
-
-	status = cpr16(IntrStatus);
-	if (!status || (status == 0xFFFF))
-		return IRQ_NONE;
-
-	netif_dbg(cp, intr, dev, "intr, status %04x cmd %02x cpcmd %04x\n",
-		  status, cpr8(Cmd), cpr16(CpCmd));
-
-	cpw16(IntrStatus, status & ~cp_rx_intr_mask);
-
-	spin_lock(&cp->lock);
-
-	/* close possible race's with dev_close */
-	if (unlikely(!netif_running(dev))) {
-		cpw16(IntrMask, 0);
-		spin_unlock(&cp->lock);
-		return IRQ_HANDLED;
-	}
-
-	if (status & (RxOK | RxErr | RxEmpty | RxFIFOOvr))
-		if (napi_schedule_prep(&cp->napi)) {
-			cpw16_f(IntrMask, cp_norx_intr_mask);
-			__napi_schedule(&cp->napi);
-		}
-
-	if (status & (TxOK | TxErr | TxEmpty | SWInt))
-		cp_tx(cp);
-	if (status & LinkChg)
-		mii_check_media(&cp->mii_if, netif_msg_link(cp), false);
-
-	spin_unlock(&cp->lock);
-
-	if (status & PciErr) {
-		u16 pci_status;
-
-		pci_read_config_word(cp->pdev, PCI_STATUS, &pci_status);
-		pci_write_config_word(cp->pdev, PCI_STATUS, pci_status);
-		netdev_err(dev, "PCI bus error, status=%04x, PCI status=%04x\n",
-			   status, pci_status);
-
-		/* TODO: reset hardware */
-	}
-
-	return IRQ_HANDLED;
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling receive - used by netconsole and other diagnostic tools
- * to allow network i/o with interrupts disabled.
- */
-static void cp_poll_controller(struct net_device *dev)
-{
-	disable_irq(dev->irq);
-	cp_interrupt(dev->irq, dev);
-	enable_irq(dev->irq);
-}
-#endif
-
-static void cp_tx (struct cp_private *cp)
-{
-	unsigned tx_head = cp->tx_head;
-	unsigned tx_tail = cp->tx_tail;
-
-	while (tx_tail != tx_head) {
-		struct cp_desc *txd = cp->tx_ring + tx_tail;
-		struct sk_buff *skb;
-		u32 status;
-
-		rmb();
-		status = le32_to_cpu(txd->opts1);
-		if (status & DescOwn)
-			break;
-
-		skb = cp->tx_skb[tx_tail];
-		BUG_ON(!skb);
-
-		dma_unmap_single(&cp->pdev->dev, le64_to_cpu(txd->addr),
-				 le32_to_cpu(txd->opts1) & 0xffff,
-				 PCI_DMA_TODEVICE);
-
-		if (status & LastFrag) {
-			if (status & (TxError | TxFIFOUnder)) {
-				netif_dbg(cp, tx_err, cp->dev,
-					  "tx err, status 0x%x\n", status);
-				cp->dev->stats.tx_errors++;
-				if (status & TxOWC)
-					cp->dev->stats.tx_window_errors++;
-				if (status & TxMaxCol)
-					cp->dev->stats.tx_aborted_errors++;
-				if (status & TxLinkFail)
-					cp->dev->stats.tx_carrier_errors++;
-				if (status & TxFIFOUnder)
-					cp->dev->stats.tx_fifo_errors++;
-			} else {
-				cp->dev->stats.collisions +=
-					((status >> TxColCntShift) & TxColCntMask);
-				cp->dev->stats.tx_packets++;
-				cp->dev->stats.tx_bytes += skb->len;
-				netif_dbg(cp, tx_done, cp->dev,
-					  "tx done, slot %d\n", tx_tail);
-			}
-			dev_kfree_skb_irq(skb);
-		}
-
-		cp->tx_skb[tx_tail] = NULL;
-
-		tx_tail = NEXT_TX(tx_tail);
-	}
-
-	cp->tx_tail = tx_tail;
-
-	if (TX_BUFFS_AVAIL(cp) > (MAX_SKB_FRAGS + 1))
-		netif_wake_queue(cp->dev);
-}
-
-static inline u32 cp_tx_vlan_tag(struct sk_buff *skb)
-{
-	return vlan_tx_tag_present(skb) ?
-		TxVlanTag | swab16(vlan_tx_tag_get(skb)) : 0x00;
-}
-
-static netdev_tx_t cp_start_xmit (struct sk_buff *skb,
-					struct net_device *dev)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned entry;
-	u32 eor, flags;
-	unsigned long intr_flags;
-	__le32 opts2;
-	int mss = 0;
-
-	spin_lock_irqsave(&cp->lock, intr_flags);
-
-	/* This is a hard error, log it. */
-	if (TX_BUFFS_AVAIL(cp) <= (skb_shinfo(skb)->nr_frags + 1)) {
-		netif_stop_queue(dev);
-		spin_unlock_irqrestore(&cp->lock, intr_flags);
-		netdev_err(dev, "BUG! Tx Ring full when queue awake!\n");
-		return NETDEV_TX_BUSY;
-	}
-
-	entry = cp->tx_head;
-	eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
-	mss = skb_shinfo(skb)->gso_size;
-
-	opts2 = cpu_to_le32(cp_tx_vlan_tag(skb));
-
-	if (skb_shinfo(skb)->nr_frags == 0) {
-		struct cp_desc *txd = &cp->tx_ring[entry];
-		u32 len;
-		dma_addr_t mapping;
-
-		len = skb->len;
-		mapping = dma_map_single(&cp->pdev->dev, skb->data, len, PCI_DMA_TODEVICE);
-		txd->opts2 = opts2;
-		txd->addr = cpu_to_le64(mapping);
-		wmb();
-
-		flags = eor | len | DescOwn | FirstFrag | LastFrag;
-
-		if (mss)
-			flags |= LargeSend | ((mss & MSSMask) << MSSShift);
-		else if (skb->ip_summed == CHECKSUM_PARTIAL) {
-			const struct iphdr *ip = ip_hdr(skb);
-			if (ip->protocol == IPPROTO_TCP)
-				flags |= IPCS | TCPCS;
-			else if (ip->protocol == IPPROTO_UDP)
-				flags |= IPCS | UDPCS;
-			else
-				WARN_ON(1);	/* we need a WARN() */
-		}
-
-		txd->opts1 = cpu_to_le32(flags);
-		wmb();
-
-		cp->tx_skb[entry] = skb;
-		entry = NEXT_TX(entry);
-	} else {
-		struct cp_desc *txd;
-		u32 first_len, first_eor;
-		dma_addr_t first_mapping;
-		int frag, first_entry = entry;
-		const struct iphdr *ip = ip_hdr(skb);
-
-		/* We must give this initial chunk to the device last.
-		 * Otherwise we could race with the device.
-		 */
-		first_eor = eor;
-		first_len = skb_headlen(skb);
-		first_mapping = dma_map_single(&cp->pdev->dev, skb->data,
-					       first_len, PCI_DMA_TODEVICE);
-		cp->tx_skb[entry] = skb;
-		entry = NEXT_TX(entry);
-
-		for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) {
-			skb_frag_t *this_frag = &skb_shinfo(skb)->frags[frag];
-			u32 len;
-			u32 ctrl;
-			dma_addr_t mapping;
-
-			len = this_frag->size;
-			mapping = dma_map_single(&cp->pdev->dev,
-						 ((void *) page_address(this_frag->page) +
-						  this_frag->page_offset),
-						 len, PCI_DMA_TODEVICE);
-			eor = (entry == (CP_TX_RING_SIZE - 1)) ? RingEnd : 0;
-
-			ctrl = eor | len | DescOwn;
-
-			if (mss)
-				ctrl |= LargeSend |
-					((mss & MSSMask) << MSSShift);
-			else if (skb->ip_summed == CHECKSUM_PARTIAL) {
-				if (ip->protocol == IPPROTO_TCP)
-					ctrl |= IPCS | TCPCS;
-				else if (ip->protocol == IPPROTO_UDP)
-					ctrl |= IPCS | UDPCS;
-				else
-					BUG();
-			}
-
-			if (frag == skb_shinfo(skb)->nr_frags - 1)
-				ctrl |= LastFrag;
-
-			txd = &cp->tx_ring[entry];
-			txd->opts2 = opts2;
-			txd->addr = cpu_to_le64(mapping);
-			wmb();
-
-			txd->opts1 = cpu_to_le32(ctrl);
-			wmb();
-
-			cp->tx_skb[entry] = skb;
-			entry = NEXT_TX(entry);
-		}
-
-		txd = &cp->tx_ring[first_entry];
-		txd->opts2 = opts2;
-		txd->addr = cpu_to_le64(first_mapping);
-		wmb();
-
-		if (skb->ip_summed == CHECKSUM_PARTIAL) {
-			if (ip->protocol == IPPROTO_TCP)
-				txd->opts1 = cpu_to_le32(first_eor | first_len |
-							 FirstFrag | DescOwn |
-							 IPCS | TCPCS);
-			else if (ip->protocol == IPPROTO_UDP)
-				txd->opts1 = cpu_to_le32(first_eor | first_len |
-							 FirstFrag | DescOwn |
-							 IPCS | UDPCS);
-			else
-				BUG();
-		} else
-			txd->opts1 = cpu_to_le32(first_eor | first_len |
-						 FirstFrag | DescOwn);
-		wmb();
-	}
-	cp->tx_head = entry;
-	netif_dbg(cp, tx_queued, cp->dev, "tx queued, slot %d, skblen %d\n",
-		  entry, skb->len);
-	if (TX_BUFFS_AVAIL(cp) <= (MAX_SKB_FRAGS + 1))
-		netif_stop_queue(dev);
-
-	spin_unlock_irqrestore(&cp->lock, intr_flags);
-
-	cpw8(TxPoll, NormalTxPoll);
-
-	return NETDEV_TX_OK;
-}
-
-/* Set or clear the multicast filter for this adaptor.
-   This routine is not state sensitive and need not be SMP locked. */
-
-static void __cp_set_rx_mode (struct net_device *dev)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	u32 mc_filter[2];	/* Multicast hash filter */
-	int rx_mode;
-	u32 tmp;
-
-	/* Note: do not reorder, GCC is clever about common statements. */
-	if (dev->flags & IFF_PROMISC) {
-		/* Unconditionally log net taps. */
-		rx_mode =
-		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
-		    AcceptAllPhys;
-		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
-		   (dev->flags & IFF_ALLMULTI)) {
-		/* Too many to filter perfectly -- accept all multicasts. */
-		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
-		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else {
-		struct netdev_hw_addr *ha;
-		rx_mode = AcceptBroadcast | AcceptMyPhys;
-		mc_filter[1] = mc_filter[0] = 0;
-		netdev_for_each_mc_addr(ha, dev) {
-			int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
-
-			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
-			rx_mode |= AcceptMulticast;
-		}
-	}
-
-	/* We can safely update without stopping the chip. */
-	tmp = cp_rx_config | rx_mode;
-	if (cp->rx_config != tmp) {
-		cpw32_f (RxConfig, tmp);
-		cp->rx_config = tmp;
-	}
-	cpw32_f (MAR0 + 0, mc_filter[0]);
-	cpw32_f (MAR0 + 4, mc_filter[1]);
-}
-
-static void cp_set_rx_mode (struct net_device *dev)
-{
-	unsigned long flags;
-	struct cp_private *cp = netdev_priv(dev);
-
-	spin_lock_irqsave (&cp->lock, flags);
-	__cp_set_rx_mode(dev);
-	spin_unlock_irqrestore (&cp->lock, flags);
-}
-
-static void __cp_get_stats(struct cp_private *cp)
-{
-	/* only lower 24 bits valid; write any value to clear */
-	cp->dev->stats.rx_missed_errors += (cpr32 (RxMissed) & 0xffffff);
-	cpw32 (RxMissed, 0);
-}
-
-static struct net_device_stats *cp_get_stats(struct net_device *dev)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned long flags;
-
-	/* The chip only need report frame silently dropped. */
-	spin_lock_irqsave(&cp->lock, flags);
- 	if (netif_running(dev) && netif_device_present(dev))
- 		__cp_get_stats(cp);
-	spin_unlock_irqrestore(&cp->lock, flags);
-
-	return &dev->stats;
-}
-
-static void cp_stop_hw (struct cp_private *cp)
-{
-	cpw16(IntrStatus, ~(cpr16(IntrStatus)));
-	cpw16_f(IntrMask, 0);
-	cpw8(Cmd, 0);
-	cpw16_f(CpCmd, 0);
-	cpw16_f(IntrStatus, ~(cpr16(IntrStatus)));
-
-	cp->rx_tail = 0;
-	cp->tx_head = cp->tx_tail = 0;
-}
-
-static void cp_reset_hw (struct cp_private *cp)
-{
-	unsigned work = 1000;
-
-	cpw8(Cmd, CmdReset);
-
-	while (work--) {
-		if (!(cpr8(Cmd) & CmdReset))
-			return;
-
-		schedule_timeout_uninterruptible(10);
-	}
-
-	netdev_err(cp->dev, "hardware reset timeout\n");
-}
-
-static inline void cp_start_hw (struct cp_private *cp)
-{
-	cpw16(CpCmd, cp->cpcmd);
-	cpw8(Cmd, RxOn | TxOn);
-}
-
-static void cp_init_hw (struct cp_private *cp)
-{
-	struct net_device *dev = cp->dev;
-	dma_addr_t ring_dma;
-
-	cp_reset_hw(cp);
-
-	cpw8_f (Cfg9346, Cfg9346_Unlock);
-
-	/* Restore our idea of the MAC address. */
-	cpw32_f (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
-	cpw32_f (MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
-
-	cp_start_hw(cp);
-	cpw8(TxThresh, 0x06); /* XXX convert magic num to a constant */
-
-	__cp_set_rx_mode(dev);
-	cpw32_f (TxConfig, IFG | (TX_DMA_BURST << TxDMAShift));
-
-	cpw8(Config1, cpr8(Config1) | DriverLoaded | PMEnable);
-	/* Disable Wake-on-LAN. Can be turned on with ETHTOOL_SWOL */
-	cpw8(Config3, PARMEnable);
-	cp->wol_enabled = 0;
-
-	cpw8(Config5, cpr8(Config5) & PMEStatus);
-
-	cpw32_f(HiTxRingAddr, 0);
-	cpw32_f(HiTxRingAddr + 4, 0);
-
-	ring_dma = cp->ring_dma;
-	cpw32_f(RxRingAddr, ring_dma & 0xffffffff);
-	cpw32_f(RxRingAddr + 4, (ring_dma >> 16) >> 16);
-
-	ring_dma += sizeof(struct cp_desc) * CP_RX_RING_SIZE;
-	cpw32_f(TxRingAddr, ring_dma & 0xffffffff);
-	cpw32_f(TxRingAddr + 4, (ring_dma >> 16) >> 16);
-
-	cpw16(MultiIntr, 0);
-
-	cpw16_f(IntrMask, cp_intr_mask);
-
-	cpw8_f(Cfg9346, Cfg9346_Lock);
-}
-
-static int cp_refill_rx(struct cp_private *cp)
-{
-	struct net_device *dev = cp->dev;
-	unsigned i;
-
-	for (i = 0; i < CP_RX_RING_SIZE; i++) {
-		struct sk_buff *skb;
-		dma_addr_t mapping;
-
-		skb = netdev_alloc_skb_ip_align(dev, cp->rx_buf_sz);
-		if (!skb)
-			goto err_out;
-
-		mapping = dma_map_single(&cp->pdev->dev, skb->data,
-					 cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
-		cp->rx_skb[i] = skb;
-
-		cp->rx_ring[i].opts2 = 0;
-		cp->rx_ring[i].addr = cpu_to_le64(mapping);
-		if (i == (CP_RX_RING_SIZE - 1))
-			cp->rx_ring[i].opts1 =
-				cpu_to_le32(DescOwn | RingEnd | cp->rx_buf_sz);
-		else
-			cp->rx_ring[i].opts1 =
-				cpu_to_le32(DescOwn | cp->rx_buf_sz);
-	}
-
-	return 0;
-
-err_out:
-	cp_clean_rings(cp);
-	return -ENOMEM;
-}
-
-static void cp_init_rings_index (struct cp_private *cp)
-{
-	cp->rx_tail = 0;
-	cp->tx_head = cp->tx_tail = 0;
-}
-
-static int cp_init_rings (struct cp_private *cp)
-{
-	memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
-	cp->tx_ring[CP_TX_RING_SIZE - 1].opts1 = cpu_to_le32(RingEnd);
-
-	cp_init_rings_index(cp);
-
-	return cp_refill_rx (cp);
-}
-
-static int cp_alloc_rings (struct cp_private *cp)
-{
-	void *mem;
-
-	mem = dma_alloc_coherent(&cp->pdev->dev, CP_RING_BYTES,
-				 &cp->ring_dma, GFP_KERNEL);
-	if (!mem)
-		return -ENOMEM;
-
-	cp->rx_ring = mem;
-	cp->tx_ring = &cp->rx_ring[CP_RX_RING_SIZE];
-
-	return cp_init_rings(cp);
-}
-
-static void cp_clean_rings (struct cp_private *cp)
-{
-	struct cp_desc *desc;
-	unsigned i;
-
-	for (i = 0; i < CP_RX_RING_SIZE; i++) {
-		if (cp->rx_skb[i]) {
-			desc = cp->rx_ring + i;
-			dma_unmap_single(&cp->pdev->dev,le64_to_cpu(desc->addr),
-					 cp->rx_buf_sz, PCI_DMA_FROMDEVICE);
-			dev_kfree_skb(cp->rx_skb[i]);
-		}
-	}
-
-	for (i = 0; i < CP_TX_RING_SIZE; i++) {
-		if (cp->tx_skb[i]) {
-			struct sk_buff *skb = cp->tx_skb[i];
-
-			desc = cp->tx_ring + i;
-			dma_unmap_single(&cp->pdev->dev,le64_to_cpu(desc->addr),
-					 le32_to_cpu(desc->opts1) & 0xffff,
-					 PCI_DMA_TODEVICE);
-			if (le32_to_cpu(desc->opts1) & LastFrag)
-				dev_kfree_skb(skb);
-			cp->dev->stats.tx_dropped++;
-		}
-	}
-
-	memset(cp->rx_ring, 0, sizeof(struct cp_desc) * CP_RX_RING_SIZE);
-	memset(cp->tx_ring, 0, sizeof(struct cp_desc) * CP_TX_RING_SIZE);
-
-	memset(cp->rx_skb, 0, sizeof(struct sk_buff *) * CP_RX_RING_SIZE);
-	memset(cp->tx_skb, 0, sizeof(struct sk_buff *) * CP_TX_RING_SIZE);
-}
-
-static void cp_free_rings (struct cp_private *cp)
-{
-	cp_clean_rings(cp);
-	dma_free_coherent(&cp->pdev->dev, CP_RING_BYTES, cp->rx_ring,
-			  cp->ring_dma);
-	cp->rx_ring = NULL;
-	cp->tx_ring = NULL;
-}
-
-static int cp_open (struct net_device *dev)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	int rc;
-
-	netif_dbg(cp, ifup, dev, "enabling interface\n");
-
-	rc = cp_alloc_rings(cp);
-	if (rc)
-		return rc;
-
-	napi_enable(&cp->napi);
-
-	cp_init_hw(cp);
-
-	rc = request_irq(dev->irq, cp_interrupt, IRQF_SHARED, dev->name, dev);
-	if (rc)
-		goto err_out_hw;
-
-	netif_carrier_off(dev);
-	mii_check_media(&cp->mii_if, netif_msg_link(cp), true);
-	netif_start_queue(dev);
-
-	return 0;
-
-err_out_hw:
-	napi_disable(&cp->napi);
-	cp_stop_hw(cp);
-	cp_free_rings(cp);
-	return rc;
-}
-
-static int cp_close (struct net_device *dev)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned long flags;
-
-	napi_disable(&cp->napi);
-
-	netif_dbg(cp, ifdown, dev, "disabling interface\n");
-
-	spin_lock_irqsave(&cp->lock, flags);
-
-	netif_stop_queue(dev);
-	netif_carrier_off(dev);
-
-	cp_stop_hw(cp);
-
-	spin_unlock_irqrestore(&cp->lock, flags);
-
-	free_irq(dev->irq, dev);
-
-	cp_free_rings(cp);
-	return 0;
-}
-
-static void cp_tx_timeout(struct net_device *dev)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned long flags;
-	int rc;
-
-	netdev_warn(dev, "Transmit timeout, status %2x %4x %4x %4x\n",
-		    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);
-}
-
-#ifdef BROKEN
-static int cp_change_mtu(struct net_device *dev, int new_mtu)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	int rc;
-	unsigned long flags;
-
-	/* check for invalid MTU, according to hardware limits */
-	if (new_mtu < CP_MIN_MTU || new_mtu > CP_MAX_MTU)
-		return -EINVAL;
-
-	/* if network interface not up, no need for complexity */
-	if (!netif_running(dev)) {
-		dev->mtu = new_mtu;
-		cp_set_rxbufsize(cp);	/* set new rx buf size */
-		return 0;
-	}
-
-	spin_lock_irqsave(&cp->lock, flags);
-
-	cp_stop_hw(cp);			/* stop h/w and free rings */
-	cp_clean_rings(cp);
-
-	dev->mtu = new_mtu;
-	cp_set_rxbufsize(cp);		/* set new rx buf size */
-
-	rc = cp_init_rings(cp);		/* realloc and restart h/w */
-	cp_start_hw(cp);
-
-	spin_unlock_irqrestore(&cp->lock, flags);
-
-	return rc;
-}
-#endif /* BROKEN */
-
-static const char mii_2_8139_map[8] = {
-	BasicModeCtrl,
-	BasicModeStatus,
-	0,
-	0,
-	NWayAdvert,
-	NWayLPAR,
-	NWayExpansion,
-	0
-};
-
-static int mdio_read(struct net_device *dev, int phy_id, int location)
-{
-	struct cp_private *cp = netdev_priv(dev);
-
-	return location < 8 && mii_2_8139_map[location] ?
-	       readw(cp->regs + mii_2_8139_map[location]) : 0;
-}
-
-
-static void mdio_write(struct net_device *dev, int phy_id, int location,
-		       int value)
-{
-	struct cp_private *cp = netdev_priv(dev);
-
-	if (location == 0) {
-		cpw8(Cfg9346, Cfg9346_Unlock);
-		cpw16(BasicModeCtrl, value);
-		cpw8(Cfg9346, Cfg9346_Lock);
-	} else if (location < 8 && mii_2_8139_map[location])
-		cpw16(mii_2_8139_map[location], value);
-}
-
-/* Set the ethtool Wake-on-LAN settings */
-static int netdev_set_wol (struct cp_private *cp,
-			   const struct ethtool_wolinfo *wol)
-{
-	u8 options;
-
-	options = cpr8 (Config3) & ~(LinkUp | MagicPacket);
-	/* If WOL is being disabled, no need for complexity */
-	if (wol->wolopts) {
-		if (wol->wolopts & WAKE_PHY)	options |= LinkUp;
-		if (wol->wolopts & WAKE_MAGIC)	options |= MagicPacket;
-	}
-
-	cpw8 (Cfg9346, Cfg9346_Unlock);
-	cpw8 (Config3, options);
-	cpw8 (Cfg9346, Cfg9346_Lock);
-
-	options = 0; /* Paranoia setting */
-	options = cpr8 (Config5) & ~(UWF | MWF | BWF);
-	/* If WOL is being disabled, no need for complexity */
-	if (wol->wolopts) {
-		if (wol->wolopts & WAKE_UCAST)  options |= UWF;
-		if (wol->wolopts & WAKE_BCAST)	options |= BWF;
-		if (wol->wolopts & WAKE_MCAST)	options |= MWF;
-	}
-
-	cpw8 (Config5, options);
-
-	cp->wol_enabled = (wol->wolopts) ? 1 : 0;
-
-	return 0;
-}
-
-/* Get the ethtool Wake-on-LAN settings */
-static void netdev_get_wol (struct cp_private *cp,
-	             struct ethtool_wolinfo *wol)
-{
-	u8 options;
-
-	wol->wolopts   = 0; /* Start from scratch */
-	wol->supported = WAKE_PHY   | WAKE_BCAST | WAKE_MAGIC |
-		         WAKE_MCAST | WAKE_UCAST;
-	/* We don't need to go on if WOL is disabled */
-	if (!cp->wol_enabled) return;
-
-	options        = cpr8 (Config3);
-	if (options & LinkUp)        wol->wolopts |= WAKE_PHY;
-	if (options & MagicPacket)   wol->wolopts |= WAKE_MAGIC;
-
-	options        = 0; /* Paranoia setting */
-	options        = cpr8 (Config5);
-	if (options & UWF)           wol->wolopts |= WAKE_UCAST;
-	if (options & BWF)           wol->wolopts |= WAKE_BCAST;
-	if (options & MWF)           wol->wolopts |= WAKE_MCAST;
-}
-
-static void cp_get_drvinfo (struct net_device *dev, struct ethtool_drvinfo *info)
-{
-	struct cp_private *cp = netdev_priv(dev);
-
-	strcpy (info->driver, DRV_NAME);
-	strcpy (info->version, DRV_VERSION);
-	strcpy (info->bus_info, pci_name(cp->pdev));
-}
-
-static int cp_get_regs_len(struct net_device *dev)
-{
-	return CP_REGS_SIZE;
-}
-
-static int cp_get_sset_count (struct net_device *dev, int sset)
-{
-	switch (sset) {
-	case ETH_SS_STATS:
-		return CP_NUM_STATS;
-	default:
-		return -EOPNOTSUPP;
-	}
-}
-
-static int cp_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	int rc;
-	unsigned long flags;
-
-	spin_lock_irqsave(&cp->lock, flags);
-	rc = mii_ethtool_gset(&cp->mii_if, cmd);
-	spin_unlock_irqrestore(&cp->lock, flags);
-
-	return rc;
-}
-
-static int cp_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	int rc;
-	unsigned long flags;
-
-	spin_lock_irqsave(&cp->lock, flags);
-	rc = mii_ethtool_sset(&cp->mii_if, cmd);
-	spin_unlock_irqrestore(&cp->lock, flags);
-
-	return rc;
-}
-
-static int cp_nway_reset(struct net_device *dev)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	return mii_nway_restart(&cp->mii_if);
-}
-
-static u32 cp_get_msglevel(struct net_device *dev)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	return cp->msg_enable;
-}
-
-static void cp_set_msglevel(struct net_device *dev, u32 value)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	cp->msg_enable = value;
-}
-
-static int cp_set_features(struct net_device *dev, u32 features)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned long flags;
-
-	if (!((dev->features ^ features) & NETIF_F_RXCSUM))
-		return 0;
-
-	spin_lock_irqsave(&cp->lock, flags);
-
-	if (features & NETIF_F_RXCSUM)
-		cp->cpcmd |= RxChkSum;
-	else
-		cp->cpcmd &= ~RxChkSum;
-
-	if (features & NETIF_F_HW_VLAN_RX)
-		cp->cpcmd |= RxVlanOn;
-	else
-		cp->cpcmd &= ~RxVlanOn;
-
-	cpw16_f(CpCmd, cp->cpcmd);
-	spin_unlock_irqrestore(&cp->lock, flags);
-
-	return 0;
-}
-
-static void cp_get_regs(struct net_device *dev, struct ethtool_regs *regs,
-		        void *p)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned long flags;
-
-	if (regs->len < CP_REGS_SIZE)
-		return /* -EINVAL */;
-
-	regs->version = CP_REGS_VER;
-
-	spin_lock_irqsave(&cp->lock, flags);
-	memcpy_fromio(p, cp->regs, CP_REGS_SIZE);
-	spin_unlock_irqrestore(&cp->lock, flags);
-}
-
-static void cp_get_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned long flags;
-
-	spin_lock_irqsave (&cp->lock, flags);
-	netdev_get_wol (cp, wol);
-	spin_unlock_irqrestore (&cp->lock, flags);
-}
-
-static int cp_set_wol (struct net_device *dev, struct ethtool_wolinfo *wol)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned long flags;
-	int rc;
-
-	spin_lock_irqsave (&cp->lock, flags);
-	rc = netdev_set_wol (cp, wol);
-	spin_unlock_irqrestore (&cp->lock, flags);
-
-	return rc;
-}
-
-static void cp_get_strings (struct net_device *dev, u32 stringset, u8 *buf)
-{
-	switch (stringset) {
-	case ETH_SS_STATS:
-		memcpy(buf, &ethtool_stats_keys, sizeof(ethtool_stats_keys));
-		break;
-	default:
-		BUG();
-		break;
-	}
-}
-
-static void cp_get_ethtool_stats (struct net_device *dev,
-				  struct ethtool_stats *estats, u64 *tmp_stats)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	struct cp_dma_stats *nic_stats;
-	dma_addr_t dma;
-	int i;
-
-	nic_stats = dma_alloc_coherent(&cp->pdev->dev, sizeof(*nic_stats),
-				       &dma, GFP_KERNEL);
-	if (!nic_stats)
-		return;
-
-	/* begin NIC statistics dump */
-	cpw32(StatsAddr + 4, (u64)dma >> 32);
-	cpw32(StatsAddr, ((u64)dma & DMA_BIT_MASK(32)) | DumpStats);
-	cpr32(StatsAddr);
-
-	for (i = 0; i < 1000; i++) {
-		if ((cpr32(StatsAddr) & DumpStats) == 0)
-			break;
-		udelay(10);
-	}
-	cpw32(StatsAddr, 0);
-	cpw32(StatsAddr + 4, 0);
-	cpr32(StatsAddr);
-
-	i = 0;
-	tmp_stats[i++] = le64_to_cpu(nic_stats->tx_ok);
-	tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok);
-	tmp_stats[i++] = le64_to_cpu(nic_stats->tx_err);
-	tmp_stats[i++] = le32_to_cpu(nic_stats->rx_err);
-	tmp_stats[i++] = le16_to_cpu(nic_stats->rx_fifo);
-	tmp_stats[i++] = le16_to_cpu(nic_stats->frame_align);
-	tmp_stats[i++] = le32_to_cpu(nic_stats->tx_ok_1col);
-	tmp_stats[i++] = le32_to_cpu(nic_stats->tx_ok_mcol);
-	tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok_phys);
-	tmp_stats[i++] = le64_to_cpu(nic_stats->rx_ok_bcast);
-	tmp_stats[i++] = le32_to_cpu(nic_stats->rx_ok_mcast);
-	tmp_stats[i++] = le16_to_cpu(nic_stats->tx_abort);
-	tmp_stats[i++] = le16_to_cpu(nic_stats->tx_underrun);
-	tmp_stats[i++] = cp->cp_stats.rx_frags;
-	BUG_ON(i != CP_NUM_STATS);
-
-	dma_free_coherent(&cp->pdev->dev, sizeof(*nic_stats), nic_stats, dma);
-}
-
-static const struct ethtool_ops cp_ethtool_ops = {
-	.get_drvinfo		= cp_get_drvinfo,
-	.get_regs_len		= cp_get_regs_len,
-	.get_sset_count		= cp_get_sset_count,
-	.get_settings		= cp_get_settings,
-	.set_settings		= cp_set_settings,
-	.nway_reset		= cp_nway_reset,
-	.get_link		= ethtool_op_get_link,
-	.get_msglevel		= cp_get_msglevel,
-	.set_msglevel		= cp_set_msglevel,
-	.get_regs		= cp_get_regs,
-	.get_wol		= cp_get_wol,
-	.set_wol		= cp_set_wol,
-	.get_strings		= cp_get_strings,
-	.get_ethtool_stats	= cp_get_ethtool_stats,
-	.get_eeprom_len		= cp_get_eeprom_len,
-	.get_eeprom		= cp_get_eeprom,
-	.set_eeprom		= cp_set_eeprom,
-};
-
-static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	int rc;
-	unsigned long flags;
-
-	if (!netif_running(dev))
-		return -EINVAL;
-
-	spin_lock_irqsave(&cp->lock, flags);
-	rc = generic_mii_ioctl(&cp->mii_if, if_mii(rq), cmd, NULL);
-	spin_unlock_irqrestore(&cp->lock, flags);
-	return rc;
-}
-
-static int cp_set_mac_address(struct net_device *dev, void *p)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	struct sockaddr *addr = p;
-
-	if (!is_valid_ether_addr(addr->sa_data))
-		return -EADDRNOTAVAIL;
-
-	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-
-	spin_lock_irq(&cp->lock);
-
-	cpw8_f(Cfg9346, Cfg9346_Unlock);
-	cpw32_f(MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
-	cpw32_f(MAC0 + 4, le32_to_cpu (*(__le32 *) (dev->dev_addr + 4)));
-	cpw8_f(Cfg9346, Cfg9346_Lock);
-
-	spin_unlock_irq(&cp->lock);
-
-	return 0;
-}
-
-/* Serial EEPROM section. */
-
-/*  EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK	0x04	/* EEPROM shift clock. */
-#define EE_CS			0x08	/* EEPROM chip select. */
-#define EE_DATA_WRITE	0x02	/* EEPROM chip data in. */
-#define EE_WRITE_0		0x00
-#define EE_WRITE_1		0x02
-#define EE_DATA_READ	0x01	/* EEPROM chip data out. */
-#define EE_ENB			(0x80 | EE_CS)
-
-/* Delay between EEPROM clock transitions.
-   No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
- */
-
-#define eeprom_delay()	readl(ee_addr)
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_EXTEND_CMD	(4)
-#define EE_WRITE_CMD	(5)
-#define EE_READ_CMD		(6)
-#define EE_ERASE_CMD	(7)
-
-#define EE_EWDS_ADDR	(0)
-#define EE_WRAL_ADDR	(1)
-#define EE_ERAL_ADDR	(2)
-#define EE_EWEN_ADDR	(3)
-
-#define CP_EEPROM_MAGIC PCI_DEVICE_ID_REALTEK_8139
-
-static void eeprom_cmd_start(void __iomem *ee_addr)
-{
-	writeb (EE_ENB & ~EE_CS, ee_addr);
-	writeb (EE_ENB, ee_addr);
-	eeprom_delay ();
-}
-
-static void eeprom_cmd(void __iomem *ee_addr, int cmd, int cmd_len)
-{
-	int i;
-
-	/* Shift the command bits out. */
-	for (i = cmd_len - 1; i >= 0; i--) {
-		int dataval = (cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-		writeb (EE_ENB | dataval, ee_addr);
-		eeprom_delay ();
-		writeb (EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
-		eeprom_delay ();
-	}
-	writeb (EE_ENB, ee_addr);
-	eeprom_delay ();
-}
-
-static void eeprom_cmd_end(void __iomem *ee_addr)
-{
-	writeb (~EE_CS, ee_addr);
-	eeprom_delay ();
-}
-
-static void eeprom_extend_cmd(void __iomem *ee_addr, int extend_cmd,
-			      int addr_len)
-{
-	int cmd = (EE_EXTEND_CMD << addr_len) | (extend_cmd << (addr_len - 2));
-
-	eeprom_cmd_start(ee_addr);
-	eeprom_cmd(ee_addr, cmd, 3 + addr_len);
-	eeprom_cmd_end(ee_addr);
-}
-
-static u16 read_eeprom (void __iomem *ioaddr, int location, int addr_len)
-{
-	int i;
-	u16 retval = 0;
-	void __iomem *ee_addr = ioaddr + Cfg9346;
-	int read_cmd = location | (EE_READ_CMD << addr_len);
-
-	eeprom_cmd_start(ee_addr);
-	eeprom_cmd(ee_addr, read_cmd, 3 + addr_len);
-
-	for (i = 16; i > 0; i--) {
-		writeb (EE_ENB | EE_SHIFT_CLK, ee_addr);
-		eeprom_delay ();
-		retval =
-		    (retval << 1) | ((readb (ee_addr) & EE_DATA_READ) ? 1 :
-				     0);
-		writeb (EE_ENB, ee_addr);
-		eeprom_delay ();
-	}
-
-	eeprom_cmd_end(ee_addr);
-
-	return retval;
-}
-
-static void write_eeprom(void __iomem *ioaddr, int location, u16 val,
-			 int addr_len)
-{
-	int i;
-	void __iomem *ee_addr = ioaddr + Cfg9346;
-	int write_cmd = location | (EE_WRITE_CMD << addr_len);
-
-	eeprom_extend_cmd(ee_addr, EE_EWEN_ADDR, addr_len);
-
-	eeprom_cmd_start(ee_addr);
-	eeprom_cmd(ee_addr, write_cmd, 3 + addr_len);
-	eeprom_cmd(ee_addr, val, 16);
-	eeprom_cmd_end(ee_addr);
-
-	eeprom_cmd_start(ee_addr);
-	for (i = 0; i < 20000; i++)
-		if (readb(ee_addr) & EE_DATA_READ)
-			break;
-	eeprom_cmd_end(ee_addr);
-
-	eeprom_extend_cmd(ee_addr, EE_EWDS_ADDR, addr_len);
-}
-
-static int cp_get_eeprom_len(struct net_device *dev)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	int size;
-
-	spin_lock_irq(&cp->lock);
-	size = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 256 : 128;
-	spin_unlock_irq(&cp->lock);
-
-	return size;
-}
-
-static int cp_get_eeprom(struct net_device *dev,
-			 struct ethtool_eeprom *eeprom, u8 *data)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned int addr_len;
-	u16 val;
-	u32 offset = eeprom->offset >> 1;
-	u32 len = eeprom->len;
-	u32 i = 0;
-
-	eeprom->magic = CP_EEPROM_MAGIC;
-
-	spin_lock_irq(&cp->lock);
-
-	addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6;
-
-	if (eeprom->offset & 1) {
-		val = read_eeprom(cp->regs, offset, addr_len);
-		data[i++] = (u8)(val >> 8);
-		offset++;
-	}
-
-	while (i < len - 1) {
-		val = read_eeprom(cp->regs, offset, addr_len);
-		data[i++] = (u8)val;
-		data[i++] = (u8)(val >> 8);
-		offset++;
-	}
-
-	if (i < len) {
-		val = read_eeprom(cp->regs, offset, addr_len);
-		data[i] = (u8)val;
-	}
-
-	spin_unlock_irq(&cp->lock);
-	return 0;
-}
-
-static int cp_set_eeprom(struct net_device *dev,
-			 struct ethtool_eeprom *eeprom, u8 *data)
-{
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned int addr_len;
-	u16 val;
-	u32 offset = eeprom->offset >> 1;
-	u32 len = eeprom->len;
-	u32 i = 0;
-
-	if (eeprom->magic != CP_EEPROM_MAGIC)
-		return -EINVAL;
-
-	spin_lock_irq(&cp->lock);
-
-	addr_len = read_eeprom(cp->regs, 0, 8) == 0x8129 ? 8 : 6;
-
-	if (eeprom->offset & 1) {
-		val = read_eeprom(cp->regs, offset, addr_len) & 0xff;
-		val |= (u16)data[i++] << 8;
-		write_eeprom(cp->regs, offset, val, addr_len);
-		offset++;
-	}
-
-	while (i < len - 1) {
-		val = (u16)data[i++];
-		val |= (u16)data[i++] << 8;
-		write_eeprom(cp->regs, offset, val, addr_len);
-		offset++;
-	}
-
-	if (i < len) {
-		val = read_eeprom(cp->regs, offset, addr_len) & 0xff00;
-		val |= (u16)data[i];
-		write_eeprom(cp->regs, offset, val, addr_len);
-	}
-
-	spin_unlock_irq(&cp->lock);
-	return 0;
-}
-
-/* Put the board into D3cold state and wait for WakeUp signal */
-static void cp_set_d3_state (struct cp_private *cp)
-{
-	pci_enable_wake (cp->pdev, 0, 1); /* Enable PME# generation */
-	pci_set_power_state (cp->pdev, PCI_D3hot);
-}
-
-static const struct net_device_ops cp_netdev_ops = {
-	.ndo_open		= cp_open,
-	.ndo_stop		= cp_close,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address 	= cp_set_mac_address,
-	.ndo_set_multicast_list	= cp_set_rx_mode,
-	.ndo_get_stats		= cp_get_stats,
-	.ndo_do_ioctl		= cp_ioctl,
-	.ndo_start_xmit		= cp_start_xmit,
-	.ndo_tx_timeout		= cp_tx_timeout,
-	.ndo_set_features	= cp_set_features,
-#ifdef BROKEN
-	.ndo_change_mtu		= cp_change_mtu,
-#endif
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= cp_poll_controller,
-#endif
-};
-
-static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
-{
-	struct net_device *dev;
-	struct cp_private *cp;
-	int rc;
-	void __iomem *regs;
-	resource_size_t pciaddr;
-	unsigned int addr_len, i, pci_using_dac;
-
-#ifndef MODULE
-	static int version_printed;
-	if (version_printed++ == 0)
-		pr_info("%s", version);
-#endif
-
-	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
-	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision < 0x20) {
-		dev_info(&pdev->dev,
-			 "This (id %04x:%04x rev %02x) is not an 8139C+ compatible chip, use 8139too\n",
-			 pdev->vendor, pdev->device, pdev->revision);
-		return -ENODEV;
-	}
-
-	dev = alloc_etherdev(sizeof(struct cp_private));
-	if (!dev)
-		return -ENOMEM;
-	SET_NETDEV_DEV(dev, &pdev->dev);
-
-	cp = netdev_priv(dev);
-	cp->pdev = pdev;
-	cp->dev = dev;
-	cp->msg_enable = (debug < 0 ? CP_DEF_MSG_ENABLE : debug);
-	spin_lock_init (&cp->lock);
-	cp->mii_if.dev = dev;
-	cp->mii_if.mdio_read = mdio_read;
-	cp->mii_if.mdio_write = mdio_write;
-	cp->mii_if.phy_id = CP_INTERNAL_PHY;
-	cp->mii_if.phy_id_mask = 0x1f;
-	cp->mii_if.reg_num_mask = 0x1f;
-	cp_set_rxbufsize(cp);
-
-	rc = pci_enable_device(pdev);
-	if (rc)
-		goto err_out_free;
-
-	rc = pci_set_mwi(pdev);
-	if (rc)
-		goto err_out_disable;
-
-	rc = pci_request_regions(pdev, DRV_NAME);
-	if (rc)
-		goto err_out_mwi;
-
-	pciaddr = pci_resource_start(pdev, 1);
-	if (!pciaddr) {
-		rc = -EIO;
-		dev_err(&pdev->dev, "no MMIO resource\n");
-		goto err_out_res;
-	}
-	if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) {
-		rc = -EIO;
-		dev_err(&pdev->dev, "MMIO resource (%llx) too small\n",
-		       (unsigned long long)pci_resource_len(pdev, 1));
-		goto err_out_res;
-	}
-
-	/* Configure DMA attributes. */
-	if ((sizeof(dma_addr_t) > 4) &&
-	    !pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) &&
-	    !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
-		pci_using_dac = 1;
-	} else {
-		pci_using_dac = 0;
-
-		rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
-		if (rc) {
-			dev_err(&pdev->dev,
-				"No usable DMA configuration, aborting\n");
-			goto err_out_res;
-		}
-		rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
-		if (rc) {
-			dev_err(&pdev->dev,
-				"No usable consistent DMA configuration, aborting\n");
-			goto err_out_res;
-		}
-	}
-
-	cp->cpcmd = (pci_using_dac ? PCIDAC : 0) |
-		    PCIMulRW | RxChkSum | CpRxOn | CpTxOn;
-
-	dev->features |= NETIF_F_RXCSUM;
-	dev->hw_features |= NETIF_F_RXCSUM;
-
-	regs = ioremap(pciaddr, CP_REGS_SIZE);
-	if (!regs) {
-		rc = -EIO;
-		dev_err(&pdev->dev, "Cannot map PCI MMIO (%Lx@%Lx)\n",
-			(unsigned long long)pci_resource_len(pdev, 1),
-		       (unsigned long long)pciaddr);
-		goto err_out_res;
-	}
-	dev->base_addr = (unsigned long) regs;
-	cp->regs = regs;
-
-	cp_stop_hw(cp);
-
-	/* read MAC address from EEPROM */
-	addr_len = read_eeprom (regs, 0, 8) == 0x8129 ? 8 : 6;
-	for (i = 0; i < 3; i++)
-		((__le16 *) (dev->dev_addr))[i] =
-		    cpu_to_le16(read_eeprom (regs, i + 7, addr_len));
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-
-	dev->netdev_ops = &cp_netdev_ops;
-	netif_napi_add(dev, &cp->napi, cp_rx_poll, 16);
-	dev->ethtool_ops = &cp_ethtool_ops;
-	dev->watchdog_timeo = TX_TIMEOUT;
-
-	dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-
-	if (pci_using_dac)
-		dev->features |= NETIF_F_HIGHDMA;
-
-	/* disabled by default until verified */
-	dev->hw_features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
-		NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
-	dev->vlan_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO |
-		NETIF_F_HIGHDMA;
-
-	dev->irq = pdev->irq;
-
-	rc = register_netdev(dev);
-	if (rc)
-		goto err_out_iomap;
-
-	netdev_info(dev, "RTL-8139C+ at 0x%lx, %pM, IRQ %d\n",
-		    dev->base_addr, dev->dev_addr, dev->irq);
-
-	pci_set_drvdata(pdev, dev);
-
-	/* enable busmastering and memory-write-invalidate */
-	pci_set_master(pdev);
-
-	if (cp->wol_enabled)
-		cp_set_d3_state (cp);
-
-	return 0;
-
-err_out_iomap:
-	iounmap(regs);
-err_out_res:
-	pci_release_regions(pdev);
-err_out_mwi:
-	pci_clear_mwi(pdev);
-err_out_disable:
-	pci_disable_device(pdev);
-err_out_free:
-	free_netdev(dev);
-	return rc;
-}
-
-static void cp_remove_one (struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct cp_private *cp = netdev_priv(dev);
-
-	unregister_netdev(dev);
-	iounmap(cp->regs);
-	if (cp->wol_enabled)
-		pci_set_power_state (pdev, PCI_D0);
-	pci_release_regions(pdev);
-	pci_clear_mwi(pdev);
-	pci_disable_device(pdev);
-	pci_set_drvdata(pdev, NULL);
-	free_netdev(dev);
-}
-
-#ifdef CONFIG_PM
-static int cp_suspend (struct pci_dev *pdev, pm_message_t state)
-{
-	struct net_device *dev = pci_get_drvdata(pdev);
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned long flags;
-
-	if (!netif_running(dev))
-		return 0;
-
-	netif_device_detach (dev);
-	netif_stop_queue (dev);
-
-	spin_lock_irqsave (&cp->lock, flags);
-
-	/* Disable Rx and Tx */
-	cpw16 (IntrMask, 0);
-	cpw8  (Cmd, cpr8 (Cmd) & (~RxOn | ~TxOn));
-
-	spin_unlock_irqrestore (&cp->lock, flags);
-
-	pci_save_state(pdev);
-	pci_enable_wake(pdev, pci_choose_state(pdev, state), cp->wol_enabled);
-	pci_set_power_state(pdev, pci_choose_state(pdev, state));
-
-	return 0;
-}
-
-static int cp_resume (struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata (pdev);
-	struct cp_private *cp = netdev_priv(dev);
-	unsigned long flags;
-
-	if (!netif_running(dev))
-		return 0;
-
-	netif_device_attach (dev);
-
-	pci_set_power_state(pdev, PCI_D0);
-	pci_restore_state(pdev);
-	pci_enable_wake(pdev, PCI_D0, 0);
-
-	/* FIXME: sh*t may happen if the Rx ring buffer is depleted */
-	cp_init_rings_index (cp);
-	cp_init_hw (cp);
-	netif_start_queue (dev);
-
-	spin_lock_irqsave (&cp->lock, flags);
-
-	mii_check_media(&cp->mii_if, netif_msg_link(cp), false);
-
-	spin_unlock_irqrestore (&cp->lock, flags);
-
-	return 0;
-}
-#endif /* CONFIG_PM */
-
-static struct pci_driver cp_driver = {
-	.name         = DRV_NAME,
-	.id_table     = cp_pci_tbl,
-	.probe        =	cp_init_one,
-	.remove       = cp_remove_one,
-#ifdef CONFIG_PM
-	.resume       = cp_resume,
-	.suspend      = cp_suspend,
-#endif
-};
-
-static int __init cp_init (void)
-{
-#ifdef MODULE
-	pr_info("%s", version);
-#endif
-	return pci_register_driver(&cp_driver);
-}
-
-static void __exit cp_exit (void)
-{
-	pci_unregister_driver (&cp_driver);
-}
-
-module_init(cp_init);
-module_exit(cp_exit);

+ 0 - 2622
drivers/net/8139too.c

@@ -1,2622 +0,0 @@
-/*
-
-	8139too.c: A RealTek RTL-8139 Fast Ethernet driver for Linux.
-
-	Maintained by Jeff Garzik <jgarzik@pobox.com>
-	Copyright 2000-2002 Jeff Garzik
-
-	Much code comes from Donald Becker's rtl8139.c driver,
-	versions 1.13 and older.  This driver was originally based
-	on rtl8139.c version 1.07.  Header of rtl8139.c version 1.13:
-
-	-----<snip>-----
-
-        	Written 1997-2001 by Donald Becker.
-		This software may be used and distributed according to the
-		terms of the GNU General Public License (GPL), incorporated
-		herein by reference.  Drivers based on or derived from this
-		code fall under the GPL and must retain the authorship,
-		copyright and license notice.  This file is not a complete
-		program and may only be used when the entire operating
-		system is licensed under the GPL.
-
-		This driver is for boards based on the RTL8129 and RTL8139
-		PCI ethernet chips.
-
-		The author may be reached as becker@scyld.com, or C/O Scyld
-		Computing Corporation 410 Severn Ave., Suite 210 Annapolis
-		MD 21403
-
-		Support and updates available at
-		http://www.scyld.com/network/rtl8139.html
-
-		Twister-tuning table provided by Kinston
-		<shangh@realtek.com.tw>.
-
-	-----<snip>-----
-
-	This software may be used and distributed according to the terms
-	of the GNU General Public License, incorporated herein by reference.
-
-	Contributors:
-
-		Donald Becker - he wrote the original driver, kudos to him!
-		(but please don't e-mail him for support, this isn't his driver)
-
-		Tigran Aivazian - bug fixes, skbuff free cleanup
-
-		Martin Mares - suggestions for PCI cleanup
-
-		David S. Miller - PCI DMA and softnet updates
-
-		Ernst Gill - fixes ported from BSD driver
-
-		Daniel Kobras - identified specific locations of
-			posted MMIO write bugginess
-
-		Gerard Sharp - bug fix, testing and feedback
-
-		David Ford - Rx ring wrap fix
-
-		Dan DeMaggio - swapped RTL8139 cards with me, and allowed me
-		to find and fix a crucial bug on older chipsets.
-
-		Donald Becker/Chris Butterworth/Marcus Westergren -
-		Noticed various Rx packet size-related buglets.
-
-		Santiago Garcia Mantinan - testing and feedback
-
-		Jens David - 2.2.x kernel backports
-
-		Martin Dennett - incredibly helpful insight on undocumented
-		features of the 8139 chips
-
-		Jean-Jacques Michel - bug fix
-
-		Tobias Ringström - Rx interrupt status checking suggestion
-
-		Andrew Morton - Clear blocked signals, avoid
-		buffer overrun setting current->comm.
-
-		Kalle Olavi Niemitalo - Wake-on-LAN ioctls
-
-		Robert Kuebel - Save kernel thread from dying on any signal.
-
-	Submitting bug reports:
-
-		"rtl8139-diag -mmmaaavvveefN" output
-		enable RTL8139_DEBUG below, and look at 'dmesg' or kernel log
-
-*/
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#define DRV_NAME	"8139too"
-#define DRV_VERSION	"0.9.28"
-
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/compiler.h>
-#include <linux/pci.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/rtnetlink.h>
-#include <linux/delay.h>
-#include <linux/ethtool.h>
-#include <linux/mii.h>
-#include <linux/completion.h>
-#include <linux/crc32.h>
-#include <linux/io.h>
-#include <linux/uaccess.h>
-#include <linux/gfp.h>
-#include <asm/irq.h>
-
-#define RTL8139_DRIVER_NAME   DRV_NAME " Fast Ethernet driver " DRV_VERSION
-
-/* Default Message level */
-#define RTL8139_DEF_MSG_ENABLE   (NETIF_MSG_DRV   | \
-                                 NETIF_MSG_PROBE  | \
-                                 NETIF_MSG_LINK)
-
-
-/* define to 1, 2 or 3 to enable copious debugging info */
-#define RTL8139_DEBUG 0
-
-/* define to 1 to disable lightweight runtime debugging checks */
-#undef RTL8139_NDEBUG
-
-
-#ifdef RTL8139_NDEBUG
-#  define assert(expr) do {} while (0)
-#else
-#  define assert(expr) \
-        if (unlikely(!(expr))) {				\
-		pr_err("Assertion failed! %s,%s,%s,line=%d\n",	\
-		       #expr, __FILE__, __func__, __LINE__);	\
-        }
-#endif
-
-
-/* A few user-configurable values. */
-/* media options */
-#define MAX_UNITS 8
-static int media[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-
-/* Whether to use MMIO or PIO. Default to MMIO. */
-#ifdef CONFIG_8139TOO_PIO
-static int use_io = 1;
-#else
-static int use_io = 0;
-#endif
-
-/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
-   The RTL chips use a 64 element hash table based on the Ethernet CRC.  */
-static int multicast_filter_limit = 32;
-
-/* bitmapped message enable number */
-static int debug = -1;
-
-/*
- * Receive ring size
- * Warning: 64K ring has hardware issues and may lock up.
- */
-#if defined(CONFIG_SH_DREAMCAST)
-#define RX_BUF_IDX 0	/* 8K ring */
-#else
-#define RX_BUF_IDX	2	/* 32K ring */
-#endif
-#define RX_BUF_LEN	(8192 << RX_BUF_IDX)
-#define RX_BUF_PAD	16
-#define RX_BUF_WRAP_PAD 2048 /* spare padding to handle lack of packet wrap */
-
-#if RX_BUF_LEN == 65536
-#define RX_BUF_TOT_LEN	RX_BUF_LEN
-#else
-#define RX_BUF_TOT_LEN	(RX_BUF_LEN + RX_BUF_PAD + RX_BUF_WRAP_PAD)
-#endif
-
-/* Number of Tx descriptor registers. */
-#define NUM_TX_DESC	4
-
-/* max supported ethernet frame size -- must be at least (dev->mtu+14+4).*/
-#define MAX_ETH_FRAME_SIZE	1536
-
-/* Size of the Tx bounce buffers -- must be at least (dev->mtu+14+4). */
-#define TX_BUF_SIZE	MAX_ETH_FRAME_SIZE
-#define TX_BUF_TOT_LEN	(TX_BUF_SIZE * NUM_TX_DESC)
-
-/* PCI Tuning Parameters
-   Threshold is bytes transferred to chip before transmission starts. */
-#define TX_FIFO_THRESH 256	/* In bytes, rounded down to 32 byte units. */
-
-/* The following settings are log_2(bytes)-4:  0 == 16 bytes .. 6==1024, 7==end of packet. */
-#define RX_FIFO_THRESH	7	/* Rx buffer level before first PCI xfer.  */
-#define RX_DMA_BURST	7	/* Maximum PCI burst, '6' is 1024 */
-#define TX_DMA_BURST	6	/* Maximum PCI burst, '6' is 1024 */
-#define TX_RETRY	8	/* 0-15.  retries = 16 + (TX_RETRY * 16) */
-
-/* Operational parameters that usually are not changed. */
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT  (6*HZ)
-
-
-enum {
-	HAS_MII_XCVR = 0x010000,
-	HAS_CHIP_XCVR = 0x020000,
-	HAS_LNK_CHNG = 0x040000,
-};
-
-#define RTL_NUM_STATS 4		/* number of ETHTOOL_GSTATS u64's */
-#define RTL_REGS_VER 1		/* version of reg. data in ETHTOOL_GREGS */
-#define RTL_MIN_IO_SIZE 0x80
-#define RTL8139B_IO_SIZE 256
-
-#define RTL8129_CAPS	HAS_MII_XCVR
-#define RTL8139_CAPS	(HAS_CHIP_XCVR|HAS_LNK_CHNG)
-
-typedef enum {
-	RTL8139 = 0,
-	RTL8129,
-} board_t;
-
-
-/* indexed by board_t, above */
-static const struct {
-	const char *name;
-	u32 hw_flags;
-} board_info[] __devinitdata = {
-	{ "RealTek RTL8139", RTL8139_CAPS },
-	{ "RealTek RTL8129", RTL8129_CAPS },
-};
-
-
-static DEFINE_PCI_DEVICE_TABLE(rtl8139_pci_tbl) = {
-	{0x10ec, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x10ec, 0x8138, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x1113, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x1500, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x4033, 0x1360, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x1186, 0x1300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x1186, 0x1340, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x13d1, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x1259, 0xa117, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x1259, 0xa11e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x14ea, 0xab06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x14ea, 0xab07, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x11db, 0x1234, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x1432, 0x9130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x02ac, 0x1012, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x018a, 0x0106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x126c, 0x1211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x1743, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-	{0x021b, 0x8139, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-
-#ifdef CONFIG_SH_SECUREEDGE5410
-	/* Bogus 8139 silicon reports 8129 without external PROM :-( */
-	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8139 },
-#endif
-#ifdef CONFIG_8139TOO_8129
-	{0x10ec, 0x8129, PCI_ANY_ID, PCI_ANY_ID, 0, 0, RTL8129 },
-#endif
-
-	/* some crazy cards report invalid vendor ids like
-	 * 0x0001 here.  The other ids are valid and constant,
-	 * so we simply don't match on the main vendor id.
-	 */
-	{PCI_ANY_ID, 0x8139, 0x10ec, 0x8139, 0, 0, RTL8139 },
-	{PCI_ANY_ID, 0x8139, 0x1186, 0x1300, 0, 0, RTL8139 },
-	{PCI_ANY_ID, 0x8139, 0x13d1, 0xab06, 0, 0, RTL8139 },
-
-	{0,}
-};
-MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
-
-static struct {
-	const char str[ETH_GSTRING_LEN];
-} ethtool_stats_keys[] = {
-	{ "early_rx" },
-	{ "tx_buf_mapped" },
-	{ "tx_timeouts" },
-	{ "rx_lost_in_ring" },
-};
-
-/* The rest of these values should never change. */
-
-/* Symbolic offsets to registers. */
-enum RTL8139_registers {
-	MAC0		= 0,	 /* Ethernet hardware address. */
-	MAR0		= 8,	 /* Multicast filter. */
-	TxStatus0	= 0x10,	 /* Transmit status (Four 32bit registers). */
-	TxAddr0		= 0x20,	 /* Tx descriptors (also four 32bit). */
-	RxBuf		= 0x30,
-	ChipCmd		= 0x37,
-	RxBufPtr	= 0x38,
-	RxBufAddr	= 0x3A,
-	IntrMask	= 0x3C,
-	IntrStatus	= 0x3E,
-	TxConfig	= 0x40,
-	RxConfig	= 0x44,
-	Timer		= 0x48,	 /* A general-purpose counter. */
-	RxMissed	= 0x4C,  /* 24 bits valid, write clears. */
-	Cfg9346		= 0x50,
-	Config0		= 0x51,
-	Config1		= 0x52,
-	TimerInt	= 0x54,
-	MediaStatus	= 0x58,
-	Config3		= 0x59,
-	Config4		= 0x5A,	 /* absent on RTL-8139A */
-	HltClk		= 0x5B,
-	MultiIntr	= 0x5C,
-	TxSummary	= 0x60,
-	BasicModeCtrl	= 0x62,
-	BasicModeStatus	= 0x64,
-	NWayAdvert	= 0x66,
-	NWayLPAR	= 0x68,
-	NWayExpansion	= 0x6A,
-	/* Undocumented registers, but required for proper operation. */
-	FIFOTMS		= 0x70,	 /* FIFO Control and test. */
-	CSCR		= 0x74,	 /* Chip Status and Configuration Register. */
-	PARA78		= 0x78,
-	FlashReg	= 0xD4,	/* Communication with Flash ROM, four bytes. */
-	PARA7c		= 0x7c,	 /* Magic transceiver parameter register. */
-	Config5		= 0xD8,	 /* absent on RTL-8139A */
-};
-
-enum ClearBitMasks {
-	MultiIntrClear	= 0xF000,
-	ChipCmdClear	= 0xE2,
-	Config1Clear	= (1<<7)|(1<<6)|(1<<3)|(1<<2)|(1<<1),
-};
-
-enum ChipCmdBits {
-	CmdReset	= 0x10,
-	CmdRxEnb	= 0x08,
-	CmdTxEnb	= 0x04,
-	RxBufEmpty	= 0x01,
-};
-
-/* Interrupt register bits, using my own meaningful names. */
-enum IntrStatusBits {
-	PCIErr		= 0x8000,
-	PCSTimeout	= 0x4000,
-	RxFIFOOver	= 0x40,
-	RxUnderrun	= 0x20,
-	RxOverflow	= 0x10,
-	TxErr		= 0x08,
-	TxOK		= 0x04,
-	RxErr		= 0x02,
-	RxOK		= 0x01,
-
-	RxAckBits	= RxFIFOOver | RxOverflow | RxOK,
-};
-
-enum TxStatusBits {
-	TxHostOwns	= 0x2000,
-	TxUnderrun	= 0x4000,
-	TxStatOK	= 0x8000,
-	TxOutOfWindow	= 0x20000000,
-	TxAborted	= 0x40000000,
-	TxCarrierLost	= 0x80000000,
-};
-enum RxStatusBits {
-	RxMulticast	= 0x8000,
-	RxPhysical	= 0x4000,
-	RxBroadcast	= 0x2000,
-	RxBadSymbol	= 0x0020,
-	RxRunt		= 0x0010,
-	RxTooLong	= 0x0008,
-	RxCRCErr	= 0x0004,
-	RxBadAlign	= 0x0002,
-	RxStatusOK	= 0x0001,
-};
-
-/* Bits in RxConfig. */
-enum rx_mode_bits {
-	AcceptErr	= 0x20,
-	AcceptRunt	= 0x10,
-	AcceptBroadcast	= 0x08,
-	AcceptMulticast	= 0x04,
-	AcceptMyPhys	= 0x02,
-	AcceptAllPhys	= 0x01,
-};
-
-/* Bits in TxConfig. */
-enum tx_config_bits {
-        /* Interframe Gap Time. Only TxIFG96 doesn't violate IEEE 802.3 */
-        TxIFGShift	= 24,
-        TxIFG84		= (0 << TxIFGShift), /* 8.4us / 840ns (10 / 100Mbps) */
-        TxIFG88		= (1 << TxIFGShift), /* 8.8us / 880ns (10 / 100Mbps) */
-        TxIFG92		= (2 << TxIFGShift), /* 9.2us / 920ns (10 / 100Mbps) */
-        TxIFG96		= (3 << TxIFGShift), /* 9.6us / 960ns (10 / 100Mbps) */
-
-	TxLoopBack	= (1 << 18) | (1 << 17), /* enable loopback test mode */
-	TxCRC		= (1 << 16),	/* DISABLE Tx pkt CRC append */
-	TxClearAbt	= (1 << 0),	/* Clear abort (WO) */
-	TxDMAShift	= 8, /* DMA burst value (0-7) is shifted X many bits */
-	TxRetryShift	= 4, /* TXRR value (0-15) is shifted X many bits */
-
-	TxVersionMask	= 0x7C800000, /* mask out version bits 30-26, 23 */
-};
-
-/* Bits in Config1 */
-enum Config1Bits {
-	Cfg1_PM_Enable	= 0x01,
-	Cfg1_VPD_Enable	= 0x02,
-	Cfg1_PIO	= 0x04,
-	Cfg1_MMIO	= 0x08,
-	LWAKE		= 0x10,		/* not on 8139, 8139A */
-	Cfg1_Driver_Load = 0x20,
-	Cfg1_LED0	= 0x40,
-	Cfg1_LED1	= 0x80,
-	SLEEP		= (1 << 1),	/* only on 8139, 8139A */
-	PWRDN		= (1 << 0),	/* only on 8139, 8139A */
-};
-
-/* Bits in Config3 */
-enum Config3Bits {
-	Cfg3_FBtBEn   	= (1 << 0), /* 1	= Fast Back to Back */
-	Cfg3_FuncRegEn	= (1 << 1), /* 1	= enable CardBus Function registers */
-	Cfg3_CLKRUN_En	= (1 << 2), /* 1	= enable CLKRUN */
-	Cfg3_CardB_En 	= (1 << 3), /* 1	= enable CardBus registers */
-	Cfg3_LinkUp   	= (1 << 4), /* 1	= wake up on link up */
-	Cfg3_Magic    	= (1 << 5), /* 1	= wake up on Magic Packet (tm) */
-	Cfg3_PARM_En  	= (1 << 6), /* 0	= software can set twister parameters */
-	Cfg3_GNTSel   	= (1 << 7), /* 1	= delay 1 clock from PCI GNT signal */
-};
-
-/* Bits in Config4 */
-enum Config4Bits {
-	LWPTN	= (1 << 2),	/* not on 8139, 8139A */
-};
-
-/* Bits in Config5 */
-enum Config5Bits {
-	Cfg5_PME_STS   	= (1 << 0), /* 1	= PCI reset resets PME_Status */
-	Cfg5_LANWake   	= (1 << 1), /* 1	= enable LANWake signal */
-	Cfg5_LDPS      	= (1 << 2), /* 0	= save power when link is down */
-	Cfg5_FIFOAddrPtr= (1 << 3), /* Realtek internal SRAM testing */
-	Cfg5_UWF        = (1 << 4), /* 1 = accept unicast wakeup frame */
-	Cfg5_MWF        = (1 << 5), /* 1 = accept multicast wakeup frame */
-	Cfg5_BWF        = (1 << 6), /* 1 = accept broadcast wakeup frame */
-};
-
-enum RxConfigBits {
-	/* rx fifo threshold */
-	RxCfgFIFOShift	= 13,
-	RxCfgFIFONone	= (7 << RxCfgFIFOShift),
-
-	/* Max DMA burst */
-	RxCfgDMAShift	= 8,
-	RxCfgDMAUnlimited = (7 << RxCfgDMAShift),
-
-	/* rx ring buffer length */
-	RxCfgRcv8K	= 0,
-	RxCfgRcv16K	= (1 << 11),
-	RxCfgRcv32K	= (1 << 12),
-	RxCfgRcv64K	= (1 << 11) | (1 << 12),
-
-	/* Disable packet wrap at end of Rx buffer. (not possible with 64k) */
-	RxNoWrap	= (1 << 7),
-};
-
-/* Twister tuning parameters from RealTek.
-   Completely undocumented, but required to tune bad links on some boards. */
-enum CSCRBits {
-	CSCR_LinkOKBit		= 0x0400,
-	CSCR_LinkChangeBit	= 0x0800,
-	CSCR_LinkStatusBits	= 0x0f000,
-	CSCR_LinkDownOffCmd	= 0x003c0,
-	CSCR_LinkDownCmd	= 0x0f3c0,
-};
-
-enum Cfg9346Bits {
-	Cfg9346_Lock	= 0x00,
-	Cfg9346_Unlock	= 0xC0,
-};
-
-typedef enum {
-	CH_8139	= 0,
-	CH_8139_K,
-	CH_8139A,
-	CH_8139A_G,
-	CH_8139B,
-	CH_8130,
-	CH_8139C,
-	CH_8100,
-	CH_8100B_8139D,
-	CH_8101,
-} chip_t;
-
-enum chip_flags {
-	HasHltClk	= (1 << 0),
-	HasLWake	= (1 << 1),
-};
-
-#define HW_REVID(b30, b29, b28, b27, b26, b23, b22) \
-	(b30<<30 | b29<<29 | b28<<28 | b27<<27 | b26<<26 | b23<<23 | b22<<22)
-#define HW_REVID_MASK	HW_REVID(1, 1, 1, 1, 1, 1, 1)
-
-/* directly indexed by chip_t, above */
-static const struct {
-	const char *name;
-	u32 version; /* from RTL8139C/RTL8139D docs */
-	u32 flags;
-} rtl_chip_info[] = {
-	{ "RTL-8139",
-	  HW_REVID(1, 0, 0, 0, 0, 0, 0),
-	  HasHltClk,
-	},
-
-	{ "RTL-8139 rev K",
-	  HW_REVID(1, 1, 0, 0, 0, 0, 0),
-	  HasHltClk,
-	},
-
-	{ "RTL-8139A",
-	  HW_REVID(1, 1, 1, 0, 0, 0, 0),
-	  HasHltClk, /* XXX undocumented? */
-	},
-
-	{ "RTL-8139A rev G",
-	  HW_REVID(1, 1, 1, 0, 0, 1, 0),
-	  HasHltClk, /* XXX undocumented? */
-	},
-
-	{ "RTL-8139B",
-	  HW_REVID(1, 1, 1, 1, 0, 0, 0),
-	  HasLWake,
-	},
-
-	{ "RTL-8130",
-	  HW_REVID(1, 1, 1, 1, 1, 0, 0),
-	  HasLWake,
-	},
-
-	{ "RTL-8139C",
-	  HW_REVID(1, 1, 1, 0, 1, 0, 0),
-	  HasLWake,
-	},
-
-	{ "RTL-8100",
-	  HW_REVID(1, 1, 1, 1, 0, 1, 0),
- 	  HasLWake,
- 	},
-
-	{ "RTL-8100B/8139D",
-	  HW_REVID(1, 1, 1, 0, 1, 0, 1),
-	  HasHltClk /* XXX undocumented? */
-	| HasLWake,
-	},
-
-	{ "RTL-8101",
-	  HW_REVID(1, 1, 1, 0, 1, 1, 1),
-	  HasLWake,
-	},
-};
-
-struct rtl_extra_stats {
-	unsigned long early_rx;
-	unsigned long tx_buf_mapped;
-	unsigned long tx_timeouts;
-	unsigned long rx_lost_in_ring;
-};
-
-struct rtl8139_private {
-	void __iomem		*mmio_addr;
-	int			drv_flags;
-	struct pci_dev		*pci_dev;
-	u32			msg_enable;
-	struct napi_struct	napi;
-	struct net_device	*dev;
-
-	unsigned char		*rx_ring;
-	unsigned int		cur_rx;	/* RX buf index of next pkt */
-	dma_addr_t		rx_ring_dma;
-
-	unsigned int		tx_flag;
-	unsigned long		cur_tx;
-	unsigned long		dirty_tx;
-	unsigned char		*tx_buf[NUM_TX_DESC];	/* Tx bounce buffers */
-	unsigned char		*tx_bufs;	/* Tx bounce buffer region. */
-	dma_addr_t		tx_bufs_dma;
-
-	signed char		phys[4];	/* MII device addresses. */
-
-				/* Twister tune state. */
-	char			twistie, twist_row, twist_col;
-
-	unsigned int		watchdog_fired : 1;
-	unsigned int		default_port : 4; /* Last dev->if_port value. */
-	unsigned int		have_thread : 1;
-
-	spinlock_t		lock;
-	spinlock_t		rx_lock;
-
-	chip_t			chipset;
-	u32			rx_config;
-	struct rtl_extra_stats	xstats;
-
-	struct delayed_work	thread;
-
-	struct mii_if_info	mii;
-	unsigned int		regs_len;
-	unsigned long		fifo_copy_timeout;
-};
-
-MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>");
-MODULE_DESCRIPTION ("RealTek RTL-8139 Fast Ethernet driver");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(DRV_VERSION);
-
-module_param(use_io, int, 0);
-MODULE_PARM_DESC(use_io, "Force use of I/O access mode. 0=MMIO 1=PIO");
-module_param(multicast_filter_limit, int, 0);
-module_param_array(media, int, NULL, 0);
-module_param_array(full_duplex, int, NULL, 0);
-module_param(debug, int, 0);
-MODULE_PARM_DESC (debug, "8139too bitmapped message enable number");
-MODULE_PARM_DESC (multicast_filter_limit, "8139too maximum number of filtered multicast addresses");
-MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
-MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
-
-static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
-static int rtl8139_open (struct net_device *dev);
-static int mdio_read (struct net_device *dev, int phy_id, int location);
-static void mdio_write (struct net_device *dev, int phy_id, int location,
-			int val);
-static void rtl8139_start_thread(struct rtl8139_private *tp);
-static void rtl8139_tx_timeout (struct net_device *dev);
-static void rtl8139_init_ring (struct net_device *dev);
-static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
-				       struct net_device *dev);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void rtl8139_poll_controller(struct net_device *dev);
-#endif
-static int rtl8139_set_mac_address(struct net_device *dev, void *p);
-static int rtl8139_poll(struct napi_struct *napi, int budget);
-static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance);
-static int rtl8139_close (struct net_device *dev);
-static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
-static struct net_device_stats *rtl8139_get_stats (struct net_device *dev);
-static void rtl8139_set_rx_mode (struct net_device *dev);
-static void __set_rx_mode (struct net_device *dev);
-static void rtl8139_hw_start (struct net_device *dev);
-static void rtl8139_thread (struct work_struct *work);
-static void rtl8139_tx_timeout_task(struct work_struct *work);
-static const struct ethtool_ops rtl8139_ethtool_ops;
-
-/* write MMIO register, with flush */
-/* Flush avoids rtl8139 bug w/ posted MMIO writes */
-#define RTL_W8_F(reg, val8)	do { iowrite8 ((val8), ioaddr + (reg)); ioread8 (ioaddr + (reg)); } while (0)
-#define RTL_W16_F(reg, val16)	do { iowrite16 ((val16), ioaddr + (reg)); ioread16 (ioaddr + (reg)); } while (0)
-#define RTL_W32_F(reg, val32)	do { iowrite32 ((val32), ioaddr + (reg)); ioread32 (ioaddr + (reg)); } while (0)
-
-/* write MMIO register */
-#define RTL_W8(reg, val8)	iowrite8 ((val8), ioaddr + (reg))
-#define RTL_W16(reg, val16)	iowrite16 ((val16), ioaddr + (reg))
-#define RTL_W32(reg, val32)	iowrite32 ((val32), ioaddr + (reg))
-
-/* read MMIO register */
-#define RTL_R8(reg)		ioread8 (ioaddr + (reg))
-#define RTL_R16(reg)		ioread16 (ioaddr + (reg))
-#define RTL_R32(reg)		ioread32 (ioaddr + (reg))
-
-
-static const u16 rtl8139_intr_mask =
-	PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver |
-	TxErr | TxOK | RxErr | RxOK;
-
-static const u16 rtl8139_norx_intr_mask =
-	PCIErr | PCSTimeout | RxUnderrun |
-	TxErr | TxOK | RxErr ;
-
-#if RX_BUF_IDX == 0
-static const unsigned int rtl8139_rx_config =
-	RxCfgRcv8K | RxNoWrap |
-	(RX_FIFO_THRESH << RxCfgFIFOShift) |
-	(RX_DMA_BURST << RxCfgDMAShift);
-#elif RX_BUF_IDX == 1
-static const unsigned int rtl8139_rx_config =
-	RxCfgRcv16K | RxNoWrap |
-	(RX_FIFO_THRESH << RxCfgFIFOShift) |
-	(RX_DMA_BURST << RxCfgDMAShift);
-#elif RX_BUF_IDX == 2
-static const unsigned int rtl8139_rx_config =
-	RxCfgRcv32K | RxNoWrap |
-	(RX_FIFO_THRESH << RxCfgFIFOShift) |
-	(RX_DMA_BURST << RxCfgDMAShift);
-#elif RX_BUF_IDX == 3
-static const unsigned int rtl8139_rx_config =
-	RxCfgRcv64K |
-	(RX_FIFO_THRESH << RxCfgFIFOShift) |
-	(RX_DMA_BURST << RxCfgDMAShift);
-#else
-#error "Invalid configuration for 8139_RXBUF_IDX"
-#endif
-
-static const unsigned int rtl8139_tx_config =
-	TxIFG96 | (TX_DMA_BURST << TxDMAShift) | (TX_RETRY << TxRetryShift);
-
-static void __rtl8139_cleanup_dev (struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	struct pci_dev *pdev;
-
-	assert (dev != NULL);
-	assert (tp->pci_dev != NULL);
-	pdev = tp->pci_dev;
-
-	if (tp->mmio_addr)
-		pci_iounmap (pdev, tp->mmio_addr);
-
-	/* it's ok to call this even if we have no regions to free */
-	pci_release_regions (pdev);
-
-	free_netdev(dev);
-	pci_set_drvdata (pdev, NULL);
-}
-
-
-static void rtl8139_chip_reset (void __iomem *ioaddr)
-{
-	int i;
-
-	/* Soft reset the chip. */
-	RTL_W8 (ChipCmd, CmdReset);
-
-	/* Check that the chip has finished the reset. */
-	for (i = 1000; i > 0; i--) {
-		barrier();
-		if ((RTL_R8 (ChipCmd) & CmdReset) == 0)
-			break;
-		udelay (10);
-	}
-}
-
-
-static __devinit struct net_device * rtl8139_init_board (struct pci_dev *pdev)
-{
-	void __iomem *ioaddr;
-	struct net_device *dev;
-	struct rtl8139_private *tp;
-	u8 tmp8;
-	int rc, disable_dev_on_err = 0;
-	unsigned int i;
-	unsigned long pio_start, pio_end, pio_flags, pio_len;
-	unsigned long mmio_start, mmio_end, mmio_flags, mmio_len;
-	u32 version;
-
-	assert (pdev != NULL);
-
-	/* dev and priv zeroed in alloc_etherdev */
-	dev = alloc_etherdev (sizeof (*tp));
-	if (dev == NULL) {
-		dev_err(&pdev->dev, "Unable to alloc new net device\n");
-		return ERR_PTR(-ENOMEM);
-	}
-	SET_NETDEV_DEV(dev, &pdev->dev);
-
-	tp = netdev_priv(dev);
-	tp->pci_dev = pdev;
-
-	/* enable device (incl. PCI PM wakeup and hotplug setup) */
-	rc = pci_enable_device (pdev);
-	if (rc)
-		goto err_out;
-
-	pio_start = pci_resource_start (pdev, 0);
-	pio_end = pci_resource_end (pdev, 0);
-	pio_flags = pci_resource_flags (pdev, 0);
-	pio_len = pci_resource_len (pdev, 0);
-
-	mmio_start = pci_resource_start (pdev, 1);
-	mmio_end = pci_resource_end (pdev, 1);
-	mmio_flags = pci_resource_flags (pdev, 1);
-	mmio_len = pci_resource_len (pdev, 1);
-
-	/* set this immediately, we need to know before
-	 * we talk to the chip directly */
-	pr_debug("PIO region size == 0x%02lX\n", pio_len);
-	pr_debug("MMIO region size == 0x%02lX\n", mmio_len);
-
-retry:
-	if (use_io) {
-		/* make sure PCI base addr 0 is PIO */
-		if (!(pio_flags & IORESOURCE_IO)) {
-			dev_err(&pdev->dev, "region #0 not a PIO resource, aborting\n");
-			rc = -ENODEV;
-			goto err_out;
-		}
-		/* check for weird/broken PCI region reporting */
-		if (pio_len < RTL_MIN_IO_SIZE) {
-			dev_err(&pdev->dev, "Invalid PCI I/O region size(s), aborting\n");
-			rc = -ENODEV;
-			goto err_out;
-		}
-	} else {
-		/* make sure PCI base addr 1 is MMIO */
-		if (!(mmio_flags & IORESOURCE_MEM)) {
-			dev_err(&pdev->dev, "region #1 not an MMIO resource, aborting\n");
-			rc = -ENODEV;
-			goto err_out;
-		}
-		if (mmio_len < RTL_MIN_IO_SIZE) {
-			dev_err(&pdev->dev, "Invalid PCI mem region size(s), aborting\n");
-			rc = -ENODEV;
-			goto err_out;
-		}
-	}
-
-	rc = pci_request_regions (pdev, DRV_NAME);
-	if (rc)
-		goto err_out;
-	disable_dev_on_err = 1;
-
-	/* enable PCI bus-mastering */
-	pci_set_master (pdev);
-
-	if (use_io) {
-		ioaddr = pci_iomap(pdev, 0, 0);
-		if (!ioaddr) {
-			dev_err(&pdev->dev, "cannot map PIO, aborting\n");
-			rc = -EIO;
-			goto err_out;
-		}
-		dev->base_addr = pio_start;
-		tp->regs_len = pio_len;
-	} else {
-		/* ioremap MMIO region */
-		ioaddr = pci_iomap(pdev, 1, 0);
-		if (ioaddr == NULL) {
-			dev_err(&pdev->dev, "cannot remap MMIO, trying PIO\n");
-			pci_release_regions(pdev);
-			use_io = 1;
-			goto retry;
-		}
-		dev->base_addr = (long) ioaddr;
-		tp->regs_len = mmio_len;
-	}
-	tp->mmio_addr = ioaddr;
-
-	/* Bring old chips out of low-power mode. */
-	RTL_W8 (HltClk, 'R');
-
-	/* check for missing/broken hardware */
-	if (RTL_R32 (TxConfig) == 0xFFFFFFFF) {
-		dev_err(&pdev->dev, "Chip not responding, ignoring board\n");
-		rc = -EIO;
-		goto err_out;
-	}
-
-	/* identify chip attached to board */
-	version = RTL_R32 (TxConfig) & HW_REVID_MASK;
-	for (i = 0; i < ARRAY_SIZE (rtl_chip_info); i++)
-		if (version == rtl_chip_info[i].version) {
-			tp->chipset = i;
-			goto match;
-		}
-
-	/* if unknown chip, assume array element #0, original RTL-8139 in this case */
-	i = 0;
-	dev_dbg(&pdev->dev, "unknown chip version, assuming RTL-8139\n");
-	dev_dbg(&pdev->dev, "TxConfig = 0x%x\n", RTL_R32 (TxConfig));
-	tp->chipset = 0;
-
-match:
-	pr_debug("chipset id (%d) == index %d, '%s'\n",
-		 version, i, rtl_chip_info[i].name);
-
-	if (tp->chipset >= CH_8139B) {
-		u8 new_tmp8 = tmp8 = RTL_R8 (Config1);
-		pr_debug("PCI PM wakeup\n");
-		if ((rtl_chip_info[tp->chipset].flags & HasLWake) &&
-		    (tmp8 & LWAKE))
-			new_tmp8 &= ~LWAKE;
-		new_tmp8 |= Cfg1_PM_Enable;
-		if (new_tmp8 != tmp8) {
-			RTL_W8 (Cfg9346, Cfg9346_Unlock);
-			RTL_W8 (Config1, tmp8);
-			RTL_W8 (Cfg9346, Cfg9346_Lock);
-		}
-		if (rtl_chip_info[tp->chipset].flags & HasLWake) {
-			tmp8 = RTL_R8 (Config4);
-			if (tmp8 & LWPTN) {
-				RTL_W8 (Cfg9346, Cfg9346_Unlock);
-				RTL_W8 (Config4, tmp8 & ~LWPTN);
-				RTL_W8 (Cfg9346, Cfg9346_Lock);
-			}
-		}
-	} else {
-		pr_debug("Old chip wakeup\n");
-		tmp8 = RTL_R8 (Config1);
-		tmp8 &= ~(SLEEP | PWRDN);
-		RTL_W8 (Config1, tmp8);
-	}
-
-	rtl8139_chip_reset (ioaddr);
-
-	return dev;
-
-err_out:
-	__rtl8139_cleanup_dev (dev);
-	if (disable_dev_on_err)
-		pci_disable_device (pdev);
-	return ERR_PTR(rc);
-}
-
-static const struct net_device_ops rtl8139_netdev_ops = {
-	.ndo_open		= rtl8139_open,
-	.ndo_stop		= rtl8139_close,
-	.ndo_get_stats		= rtl8139_get_stats,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address 	= rtl8139_set_mac_address,
-	.ndo_start_xmit		= rtl8139_start_xmit,
-	.ndo_set_multicast_list	= rtl8139_set_rx_mode,
-	.ndo_do_ioctl		= netdev_ioctl,
-	.ndo_tx_timeout		= rtl8139_tx_timeout,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= rtl8139_poll_controller,
-#endif
-};
-
-static int __devinit rtl8139_init_one (struct pci_dev *pdev,
-				       const struct pci_device_id *ent)
-{
-	struct net_device *dev = NULL;
-	struct rtl8139_private *tp;
-	int i, addr_len, option;
-	void __iomem *ioaddr;
-	static int board_idx = -1;
-
-	assert (pdev != NULL);
-	assert (ent != NULL);
-
-	board_idx++;
-
-	/* when we're built into the kernel, the driver version message
-	 * is only printed if at least one 8139 board has been found
-	 */
-#ifndef MODULE
-	{
-		static int printed_version;
-		if (!printed_version++)
-			pr_info(RTL8139_DRIVER_NAME "\n");
-	}
-#endif
-
-	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
-	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 && pdev->revision >= 0x20) {
-		dev_info(&pdev->dev,
-			   "This (id %04x:%04x rev %02x) is an enhanced 8139C+ chip, use 8139cp\n",
-		       	   pdev->vendor, pdev->device, pdev->revision);
-		return -ENODEV;
-	}
-
-	if (pdev->vendor == PCI_VENDOR_ID_REALTEK &&
-	    pdev->device == PCI_DEVICE_ID_REALTEK_8139 &&
-	    pdev->subsystem_vendor == PCI_VENDOR_ID_ATHEROS &&
-	    pdev->subsystem_device == PCI_DEVICE_ID_REALTEK_8139) {
-		pr_info("OQO Model 2 detected. Forcing PIO\n");
-		use_io = 1;
-	}
-
-	dev = rtl8139_init_board (pdev);
-	if (IS_ERR(dev))
-		return PTR_ERR(dev);
-
-	assert (dev != NULL);
-	tp = netdev_priv(dev);
-	tp->dev = dev;
-
-	ioaddr = tp->mmio_addr;
-	assert (ioaddr != NULL);
-
-	addr_len = read_eeprom (ioaddr, 0, 8) == 0x8129 ? 8 : 6;
-	for (i = 0; i < 3; i++)
-		((__le16 *) (dev->dev_addr))[i] =
-		    cpu_to_le16(read_eeprom (ioaddr, i + 7, addr_len));
-	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
-
-	/* The Rtl8139-specific entries in the device structure. */
-	dev->netdev_ops = &rtl8139_netdev_ops;
-	dev->ethtool_ops = &rtl8139_ethtool_ops;
-	dev->watchdog_timeo = TX_TIMEOUT;
-	netif_napi_add(dev, &tp->napi, rtl8139_poll, 64);
-
-	/* note: the hardware is not capable of sg/csum/highdma, however
-	 * through the use of skb_copy_and_csum_dev we enable these
-	 * features
-	 */
-	dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA;
-	dev->vlan_features = dev->features;
-
-	dev->irq = pdev->irq;
-
-	/* tp zeroed and aligned in alloc_etherdev */
-	tp = netdev_priv(dev);
-
-	/* note: tp->chipset set in rtl8139_init_board */
-	tp->drv_flags = board_info[ent->driver_data].hw_flags;
-	tp->mmio_addr = ioaddr;
-	tp->msg_enable =
-		(debug < 0 ? RTL8139_DEF_MSG_ENABLE : ((1 << debug) - 1));
-	spin_lock_init (&tp->lock);
-	spin_lock_init (&tp->rx_lock);
-	INIT_DELAYED_WORK(&tp->thread, rtl8139_thread);
-	tp->mii.dev = dev;
-	tp->mii.mdio_read = mdio_read;
-	tp->mii.mdio_write = mdio_write;
-	tp->mii.phy_id_mask = 0x3f;
-	tp->mii.reg_num_mask = 0x1f;
-
-	/* dev is fully set up and ready to use now */
-	pr_debug("about to register device named %s (%p)...\n",
-		 dev->name, dev);
-	i = register_netdev (dev);
-	if (i) goto err_out;
-
-	pci_set_drvdata (pdev, dev);
-
-	netdev_info(dev, "%s at 0x%lx, %pM, IRQ %d\n",
-		    board_info[ent->driver_data].name,
-		    dev->base_addr, dev->dev_addr, dev->irq);
-
-	netdev_dbg(dev, "Identified 8139 chip type '%s'\n",
-		   rtl_chip_info[tp->chipset].name);
-
-	/* Find the connected MII xcvrs.
-	   Doing this in open() would allow detecting external xcvrs later, but
-	   takes too much time. */
-#ifdef CONFIG_8139TOO_8129
-	if (tp->drv_flags & HAS_MII_XCVR) {
-		int phy, phy_idx = 0;
-		for (phy = 0; phy < 32 && phy_idx < sizeof(tp->phys); phy++) {
-			int mii_status = mdio_read(dev, phy, 1);
-			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
-				u16 advertising = mdio_read(dev, phy, 4);
-				tp->phys[phy_idx++] = phy;
-				netdev_info(dev, "MII transceiver %d status 0x%04x advertising %04x\n",
-					    phy, mii_status, advertising);
-			}
-		}
-		if (phy_idx == 0) {
-			netdev_info(dev, "No MII transceivers found! Assuming SYM transceiver\n");
-			tp->phys[0] = 32;
-		}
-	} else
-#endif
-		tp->phys[0] = 32;
-	tp->mii.phy_id = tp->phys[0];
-
-	/* The lower four bits are the media type. */
-	option = (board_idx >= MAX_UNITS) ? 0 : media[board_idx];
-	if (option > 0) {
-		tp->mii.full_duplex = (option & 0x210) ? 1 : 0;
-		tp->default_port = option & 0xFF;
-		if (tp->default_port)
-			tp->mii.force_media = 1;
-	}
-	if (board_idx < MAX_UNITS  &&  full_duplex[board_idx] > 0)
-		tp->mii.full_duplex = full_duplex[board_idx];
-	if (tp->mii.full_duplex) {
-		netdev_info(dev, "Media type forced to Full Duplex\n");
-		/* Changing the MII-advertised media because might prevent
-		   re-connection. */
-		tp->mii.force_media = 1;
-	}
-	if (tp->default_port) {
-		netdev_info(dev, "  Forcing %dMbps %s-duplex operation\n",
-			    (option & 0x20 ? 100 : 10),
-			    (option & 0x10 ? "full" : "half"));
-		mdio_write(dev, tp->phys[0], 0,
-				   ((option & 0x20) ? 0x2000 : 0) | 	/* 100Mbps? */
-				   ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
-	}
-
-	/* Put the chip into low-power mode. */
-	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
-		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
-
-	return 0;
-
-err_out:
-	__rtl8139_cleanup_dev (dev);
-	pci_disable_device (pdev);
-	return i;
-}
-
-
-static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata (pdev);
-	struct rtl8139_private *tp = netdev_priv(dev);
-
-	assert (dev != NULL);
-
-	cancel_delayed_work_sync(&tp->thread);
-
-	unregister_netdev (dev);
-
-	__rtl8139_cleanup_dev (dev);
-	pci_disable_device (pdev);
-}
-
-
-/* Serial EEPROM section. */
-
-/*  EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK	0x04	/* EEPROM shift clock. */
-#define EE_CS			0x08	/* EEPROM chip select. */
-#define EE_DATA_WRITE	0x02	/* EEPROM chip data in. */
-#define EE_WRITE_0		0x00
-#define EE_WRITE_1		0x02
-#define EE_DATA_READ	0x01	/* EEPROM chip data out. */
-#define EE_ENB			(0x80 | EE_CS)
-
-/* Delay between EEPROM clock transitions.
-   No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
- */
-
-#define eeprom_delay()	(void)RTL_R32(Cfg9346)
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD	(5)
-#define EE_READ_CMD		(6)
-#define EE_ERASE_CMD	(7)
-
-static int __devinit read_eeprom (void __iomem *ioaddr, int location, int addr_len)
-{
-	int i;
-	unsigned retval = 0;
-	int read_cmd = location | (EE_READ_CMD << addr_len);
-
-	RTL_W8 (Cfg9346, EE_ENB & ~EE_CS);
-	RTL_W8 (Cfg9346, EE_ENB);
-	eeprom_delay ();
-
-	/* Shift the read command bits out. */
-	for (i = 4 + addr_len; i >= 0; i--) {
-		int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
-		RTL_W8 (Cfg9346, EE_ENB | dataval);
-		eeprom_delay ();
-		RTL_W8 (Cfg9346, EE_ENB | dataval | EE_SHIFT_CLK);
-		eeprom_delay ();
-	}
-	RTL_W8 (Cfg9346, EE_ENB);
-	eeprom_delay ();
-
-	for (i = 16; i > 0; i--) {
-		RTL_W8 (Cfg9346, EE_ENB | EE_SHIFT_CLK);
-		eeprom_delay ();
-		retval =
-		    (retval << 1) | ((RTL_R8 (Cfg9346) & EE_DATA_READ) ? 1 :
-				     0);
-		RTL_W8 (Cfg9346, EE_ENB);
-		eeprom_delay ();
-	}
-
-	/* Terminate the EEPROM access. */
-	RTL_W8 (Cfg9346, ~EE_CS);
-	eeprom_delay ();
-
-	return retval;
-}
-
-/* MII serial management: mostly bogus for now. */
-/* Read and write the MII management registers using software-generated
-   serial MDIO protocol.
-   The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
-   met by back-to-back PCI I/O cycles, but we insert a delay to avoid
-   "overclocking" issues. */
-#define MDIO_DIR		0x80
-#define MDIO_DATA_OUT	0x04
-#define MDIO_DATA_IN	0x02
-#define MDIO_CLK		0x01
-#define MDIO_WRITE0 (MDIO_DIR)
-#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
-
-#define mdio_delay()	RTL_R8(Config4)
-
-
-static const char mii_2_8139_map[8] = {
-	BasicModeCtrl,
-	BasicModeStatus,
-	0,
-	0,
-	NWayAdvert,
-	NWayLPAR,
-	NWayExpansion,
-	0
-};
-
-
-#ifdef CONFIG_8139TOO_8129
-/* Syncronize the MII management interface by shifting 32 one bits out. */
-static void mdio_sync (void __iomem *ioaddr)
-{
-	int i;
-
-	for (i = 32; i >= 0; i--) {
-		RTL_W8 (Config4, MDIO_WRITE1);
-		mdio_delay ();
-		RTL_W8 (Config4, MDIO_WRITE1 | MDIO_CLK);
-		mdio_delay ();
-	}
-}
-#endif
-
-static int mdio_read (struct net_device *dev, int phy_id, int location)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	int retval = 0;
-#ifdef CONFIG_8139TOO_8129
-	void __iomem *ioaddr = tp->mmio_addr;
-	int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
-	int i;
-#endif
-
-	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
-		void __iomem *ioaddr = tp->mmio_addr;
-		return location < 8 && mii_2_8139_map[location] ?
-		    RTL_R16 (mii_2_8139_map[location]) : 0;
-	}
-
-#ifdef CONFIG_8139TOO_8129
-	mdio_sync (ioaddr);
-	/* Shift the read command bits out. */
-	for (i = 15; i >= 0; i--) {
-		int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
-
-		RTL_W8 (Config4, MDIO_DIR | dataval);
-		mdio_delay ();
-		RTL_W8 (Config4, MDIO_DIR | dataval | MDIO_CLK);
-		mdio_delay ();
-	}
-
-	/* Read the two transition, 16 data, and wire-idle bits. */
-	for (i = 19; i > 0; i--) {
-		RTL_W8 (Config4, 0);
-		mdio_delay ();
-		retval = (retval << 1) | ((RTL_R8 (Config4) & MDIO_DATA_IN) ? 1 : 0);
-		RTL_W8 (Config4, MDIO_CLK);
-		mdio_delay ();
-	}
-#endif
-
-	return (retval >> 1) & 0xffff;
-}
-
-
-static void mdio_write (struct net_device *dev, int phy_id, int location,
-			int value)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-#ifdef CONFIG_8139TOO_8129
-	void __iomem *ioaddr = tp->mmio_addr;
-	int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
-	int i;
-#endif
-
-	if (phy_id > 31) {	/* Really a 8139.  Use internal registers. */
-		void __iomem *ioaddr = tp->mmio_addr;
-		if (location == 0) {
-			RTL_W8 (Cfg9346, Cfg9346_Unlock);
-			RTL_W16 (BasicModeCtrl, value);
-			RTL_W8 (Cfg9346, Cfg9346_Lock);
-		} else if (location < 8 && mii_2_8139_map[location])
-			RTL_W16 (mii_2_8139_map[location], value);
-		return;
-	}
-
-#ifdef CONFIG_8139TOO_8129
-	mdio_sync (ioaddr);
-
-	/* Shift the command bits out. */
-	for (i = 31; i >= 0; i--) {
-		int dataval =
-		    (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
-		RTL_W8 (Config4, dataval);
-		mdio_delay ();
-		RTL_W8 (Config4, dataval | MDIO_CLK);
-		mdio_delay ();
-	}
-	/* Clear out extra bits. */
-	for (i = 2; i > 0; i--) {
-		RTL_W8 (Config4, 0);
-		mdio_delay ();
-		RTL_W8 (Config4, MDIO_CLK);
-		mdio_delay ();
-	}
-#endif
-}
-
-
-static int rtl8139_open (struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	int retval;
-	void __iomem *ioaddr = tp->mmio_addr;
-
-	retval = request_irq (dev->irq, rtl8139_interrupt, IRQF_SHARED, dev->name, dev);
-	if (retval)
-		return retval;
-
-	tp->tx_bufs = dma_alloc_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
-					   &tp->tx_bufs_dma, GFP_KERNEL);
-	tp->rx_ring = dma_alloc_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
-					   &tp->rx_ring_dma, GFP_KERNEL);
-	if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
-		free_irq(dev->irq, dev);
-
-		if (tp->tx_bufs)
-			dma_free_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
-					    tp->tx_bufs, tp->tx_bufs_dma);
-		if (tp->rx_ring)
-			dma_free_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
-					    tp->rx_ring, tp->rx_ring_dma);
-
-		return -ENOMEM;
-
-	}
-
-	napi_enable(&tp->napi);
-
-	tp->mii.full_duplex = tp->mii.force_media;
-	tp->tx_flag = (TX_FIFO_THRESH << 11) & 0x003f0000;
-
-	rtl8139_init_ring (dev);
-	rtl8139_hw_start (dev);
-	netif_start_queue (dev);
-
-	netif_dbg(tp, ifup, dev,
-		  "%s() ioaddr %#llx IRQ %d GP Pins %02x %s-duplex\n",
-		  __func__,
-		  (unsigned long long)pci_resource_start (tp->pci_dev, 1),
-		  dev->irq, RTL_R8 (MediaStatus),
-		  tp->mii.full_duplex ? "full" : "half");
-
-	rtl8139_start_thread(tp);
-
-	return 0;
-}
-
-
-static void rtl_check_media (struct net_device *dev, unsigned int init_media)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-
-	if (tp->phys[0] >= 0) {
-		mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
-	}
-}
-
-/* Start the hardware at open or resume. */
-static void rtl8139_hw_start (struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	u32 i;
-	u8 tmp;
-
-	/* Bring old chips out of low-power mode. */
-	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
-		RTL_W8 (HltClk, 'R');
-
-	rtl8139_chip_reset (ioaddr);
-
-	/* unlock Config[01234] and BMCR register writes */
-	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
-	/* Restore our idea of the MAC address. */
-	RTL_W32_F (MAC0 + 0, le32_to_cpu (*(__le32 *) (dev->dev_addr + 0)));
-	RTL_W32_F (MAC0 + 4, le16_to_cpu (*(__le16 *) (dev->dev_addr + 4)));
-
-	tp->cur_rx = 0;
-
-	/* init Rx ring buffer DMA address */
-	RTL_W32_F (RxBuf, tp->rx_ring_dma);
-
-	/* Must enable Tx/Rx before setting transfer thresholds! */
-	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
-
-	tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
-	RTL_W32 (RxConfig, tp->rx_config);
-	RTL_W32 (TxConfig, rtl8139_tx_config);
-
-	rtl_check_media (dev, 1);
-
-	if (tp->chipset >= CH_8139B) {
-		/* Disable magic packet scanning, which is enabled
-		 * when PM is enabled in Config1.  It can be reenabled
-		 * via ETHTOOL_SWOL if desired.  */
-		RTL_W8 (Config3, RTL_R8 (Config3) & ~Cfg3_Magic);
-	}
-
-	netdev_dbg(dev, "init buffer addresses\n");
-
-	/* Lock Config[01234] and BMCR register writes */
-	RTL_W8 (Cfg9346, Cfg9346_Lock);
-
-	/* init Tx buffer DMA addresses */
-	for (i = 0; i < NUM_TX_DESC; i++)
-		RTL_W32_F (TxAddr0 + (i * 4), tp->tx_bufs_dma + (tp->tx_buf[i] - tp->tx_bufs));
-
-	RTL_W32 (RxMissed, 0);
-
-	rtl8139_set_rx_mode (dev);
-
-	/* no early-rx interrupts */
-	RTL_W16 (MultiIntr, RTL_R16 (MultiIntr) & MultiIntrClear);
-
-	/* make sure RxTx has started */
-	tmp = RTL_R8 (ChipCmd);
-	if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
-		RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
-
-	/* Enable all known interrupts by setting the interrupt mask. */
-	RTL_W16 (IntrMask, rtl8139_intr_mask);
-}
-
-
-/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void rtl8139_init_ring (struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	int i;
-
-	tp->cur_rx = 0;
-	tp->cur_tx = 0;
-	tp->dirty_tx = 0;
-
-	for (i = 0; i < NUM_TX_DESC; i++)
-		tp->tx_buf[i] = &tp->tx_bufs[i * TX_BUF_SIZE];
-}
-
-
-/* This must be global for CONFIG_8139TOO_TUNE_TWISTER case */
-static int next_tick = 3 * HZ;
-
-#ifndef CONFIG_8139TOO_TUNE_TWISTER
-static inline void rtl8139_tune_twister (struct net_device *dev,
-				  struct rtl8139_private *tp) {}
-#else
-enum TwisterParamVals {
-	PARA78_default	= 0x78fa8388,
-	PARA7c_default	= 0xcb38de43,	/* param[0][3] */
-	PARA7c_xxx	= 0xcb38de43,
-};
-
-static const unsigned long param[4][4] = {
-	{0xcb39de43, 0xcb39ce43, 0xfb38de03, 0xcb38de43},
-	{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
-	{0xcb39de43, 0xcb39ce43, 0xcb39ce83, 0xcb39ce83},
-	{0xbb39de43, 0xbb39ce43, 0xbb39ce83, 0xbb39ce83}
-};
-
-static void rtl8139_tune_twister (struct net_device *dev,
-				  struct rtl8139_private *tp)
-{
-	int linkcase;
-	void __iomem *ioaddr = tp->mmio_addr;
-
-	/* This is a complicated state machine to configure the "twister" for
-	   impedance/echos based on the cable length.
-	   All of this is magic and undocumented.
-	 */
-	switch (tp->twistie) {
-	case 1:
-		if (RTL_R16 (CSCR) & CSCR_LinkOKBit) {
-			/* We have link beat, let us tune the twister. */
-			RTL_W16 (CSCR, CSCR_LinkDownOffCmd);
-			tp->twistie = 2;	/* Change to state 2. */
-			next_tick = HZ / 10;
-		} else {
-			/* Just put in some reasonable defaults for when beat returns. */
-			RTL_W16 (CSCR, CSCR_LinkDownCmd);
-			RTL_W32 (FIFOTMS, 0x20);	/* Turn on cable test mode. */
-			RTL_W32 (PARA78, PARA78_default);
-			RTL_W32 (PARA7c, PARA7c_default);
-			tp->twistie = 0;	/* Bail from future actions. */
-		}
-		break;
-	case 2:
-		/* Read how long it took to hear the echo. */
-		linkcase = RTL_R16 (CSCR) & CSCR_LinkStatusBits;
-		if (linkcase == 0x7000)
-			tp->twist_row = 3;
-		else if (linkcase == 0x3000)
-			tp->twist_row = 2;
-		else if (linkcase == 0x1000)
-			tp->twist_row = 1;
-		else
-			tp->twist_row = 0;
-		tp->twist_col = 0;
-		tp->twistie = 3;	/* Change to state 2. */
-		next_tick = HZ / 10;
-		break;
-	case 3:
-		/* Put out four tuning parameters, one per 100msec. */
-		if (tp->twist_col == 0)
-			RTL_W16 (FIFOTMS, 0);
-		RTL_W32 (PARA7c, param[(int) tp->twist_row]
-			 [(int) tp->twist_col]);
-		next_tick = HZ / 10;
-		if (++tp->twist_col >= 4) {
-			/* For short cables we are done.
-			   For long cables (row == 3) check for mistune. */
-			tp->twistie =
-			    (tp->twist_row == 3) ? 4 : 0;
-		}
-		break;
-	case 4:
-		/* Special case for long cables: check for mistune. */
-		if ((RTL_R16 (CSCR) &
-		     CSCR_LinkStatusBits) == 0x7000) {
-			tp->twistie = 0;
-			break;
-		} else {
-			RTL_W32 (PARA7c, 0xfb38de03);
-			tp->twistie = 5;
-			next_tick = HZ / 10;
-		}
-		break;
-	case 5:
-		/* Retune for shorter cable (column 2). */
-		RTL_W32 (FIFOTMS, 0x20);
-		RTL_W32 (PARA78, PARA78_default);
-		RTL_W32 (PARA7c, PARA7c_default);
-		RTL_W32 (FIFOTMS, 0x00);
-		tp->twist_row = 2;
-		tp->twist_col = 0;
-		tp->twistie = 3;
-		next_tick = HZ / 10;
-		break;
-
-	default:
-		/* do nothing */
-		break;
-	}
-}
-#endif /* CONFIG_8139TOO_TUNE_TWISTER */
-
-static inline void rtl8139_thread_iter (struct net_device *dev,
-				 struct rtl8139_private *tp,
-				 void __iomem *ioaddr)
-{
-	int mii_lpa;
-
-	mii_lpa = mdio_read (dev, tp->phys[0], MII_LPA);
-
-	if (!tp->mii.force_media && mii_lpa != 0xffff) {
-		int duplex = ((mii_lpa & LPA_100FULL) ||
-			      (mii_lpa & 0x01C0) == 0x0040);
-		if (tp->mii.full_duplex != duplex) {
-			tp->mii.full_duplex = duplex;
-
-			if (mii_lpa) {
-				netdev_info(dev, "Setting %s-duplex based on MII #%d link partner ability of %04x\n",
-					    tp->mii.full_duplex ? "full" : "half",
-					    tp->phys[0], mii_lpa);
-			} else {
-				netdev_info(dev, "media is unconnected, link down, or incompatible connection\n");
-			}
-#if 0
-			RTL_W8 (Cfg9346, Cfg9346_Unlock);
-			RTL_W8 (Config1, tp->mii.full_duplex ? 0x60 : 0x20);
-			RTL_W8 (Cfg9346, Cfg9346_Lock);
-#endif
-		}
-	}
-
-	next_tick = HZ * 60;
-
-	rtl8139_tune_twister (dev, tp);
-
-	netdev_dbg(dev, "Media selection tick, Link partner %04x\n",
-		   RTL_R16(NWayLPAR));
-	netdev_dbg(dev, "Other registers are IntMask %04x IntStatus %04x\n",
-		   RTL_R16(IntrMask), RTL_R16(IntrStatus));
-	netdev_dbg(dev, "Chip config %02x %02x\n",
-		   RTL_R8(Config0), RTL_R8(Config1));
-}
-
-static void rtl8139_thread (struct work_struct *work)
-{
-	struct rtl8139_private *tp =
-		container_of(work, struct rtl8139_private, thread.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
-		rtl8139_thread_iter(dev, tp, tp->mmio_addr);
-
-	if (tp->have_thread)
-		schedule_delayed_work(&tp->thread, thr_delay);
-out_unlock:
-	rtnl_unlock ();
-}
-
-static void rtl8139_start_thread(struct rtl8139_private *tp)
-{
-	tp->twistie = 0;
-	if (tp->chipset == CH_8139_K)
-		tp->twistie = 1;
-	else if (tp->drv_flags & HAS_LNK_CHNG)
-		return;
-
-	tp->have_thread = 1;
-	tp->watchdog_fired = 0;
-
-	schedule_delayed_work(&tp->thread, next_tick);
-}
-
-static inline void rtl8139_tx_clear (struct rtl8139_private *tp)
-{
-	tp->cur_tx = 0;
-	tp->dirty_tx = 0;
-
-	/* XXX account for unsent Tx packets in tp->stats.tx_dropped */
-}
-
-static void rtl8139_tx_timeout_task (struct work_struct *work)
-{
-	struct rtl8139_private *tp =
-		container_of(work, struct rtl8139_private, thread.work);
-	struct net_device *dev = tp->mii.dev;
-	void __iomem *ioaddr = tp->mmio_addr;
-	int i;
-	u8 tmp8;
-
-	netdev_dbg(dev, "Transmit timeout, status %02x %04x %04x media %02x\n",
-		   RTL_R8(ChipCmd), RTL_R16(IntrStatus),
-		   RTL_R16(IntrMask), RTL_R8(MediaStatus));
-	/* Emit info to figure out what went wrong. */
-	netdev_dbg(dev, "Tx queue start entry %ld  dirty entry %ld\n",
-		   tp->cur_tx, tp->dirty_tx);
-	for (i = 0; i < NUM_TX_DESC; i++)
-		netdev_dbg(dev, "Tx descriptor %d is %08x%s\n",
-			   i, RTL_R32(TxStatus0 + (i * 4)),
-			   i == tp->dirty_tx % NUM_TX_DESC ?
-			   " (queue head)" : "");
-
-	tp->xstats.tx_timeouts++;
-
-	/* disable Tx ASAP, if not already */
-	tmp8 = RTL_R8 (ChipCmd);
-	if (tmp8 & CmdTxEnb)
-		RTL_W8 (ChipCmd, CmdRxEnb);
-
-	spin_lock_bh(&tp->rx_lock);
-	/* Disable interrupts by clearing the interrupt mask. */
-	RTL_W16 (IntrMask, 0x0000);
-
-	/* Stop a shared interrupt from scavenging while we are. */
-	spin_lock_irq(&tp->lock);
-	rtl8139_tx_clear (tp);
-	spin_unlock_irq(&tp->lock);
-
-	/* ...and finally, reset everything */
-	if (netif_running(dev)) {
-		rtl8139_hw_start (dev);
-		netif_wake_queue (dev);
-	}
-	spin_unlock_bh(&tp->rx_lock);
-}
-
-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_thread);
-		schedule_delayed_work(&tp->thread, next_tick);
-	}
-}
-
-static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
-					     struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	unsigned int entry;
-	unsigned int len = skb->len;
-	unsigned long flags;
-
-	/* Calculate the next Tx descriptor entry. */
-	entry = tp->cur_tx % NUM_TX_DESC;
-
-	/* Note: the chip doesn't have auto-pad! */
-	if (likely(len < TX_BUF_SIZE)) {
-		if (len < ETH_ZLEN)
-			memset(tp->tx_buf[entry], 0, ETH_ZLEN);
-		skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
-		dev_kfree_skb(skb);
-	} else {
-		dev_kfree_skb(skb);
-		dev->stats.tx_dropped++;
-		return NETDEV_TX_OK;
-	}
-
-	spin_lock_irqsave(&tp->lock, flags);
-	/*
-	 * Writing to TxStatus triggers a DMA transfer of the data
-	 * copied to tp->tx_buf[entry] above. Use a memory barrier
-	 * to make sure that the device sees the updated data.
-	 */
-	wmb();
-	RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
-		   tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
-
-	tp->cur_tx++;
-
-	if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
-		netif_stop_queue (dev);
-	spin_unlock_irqrestore(&tp->lock, flags);
-
-	netif_dbg(tp, tx_queued, dev, "Queued Tx packet size %u to slot %d\n",
-		  len, entry);
-
-	return NETDEV_TX_OK;
-}
-
-
-static void rtl8139_tx_interrupt (struct net_device *dev,
-				  struct rtl8139_private *tp,
-				  void __iomem *ioaddr)
-{
-	unsigned long dirty_tx, tx_left;
-
-	assert (dev != NULL);
-	assert (ioaddr != NULL);
-
-	dirty_tx = tp->dirty_tx;
-	tx_left = tp->cur_tx - dirty_tx;
-	while (tx_left > 0) {
-		int entry = dirty_tx % NUM_TX_DESC;
-		int txstatus;
-
-		txstatus = RTL_R32 (TxStatus0 + (entry * sizeof (u32)));
-
-		if (!(txstatus & (TxStatOK | TxUnderrun | TxAborted)))
-			break;	/* It still hasn't been Txed */
-
-		/* Note: TxCarrierLost is always asserted at 100mbps. */
-		if (txstatus & (TxOutOfWindow | TxAborted)) {
-			/* There was an major error, log it. */
-			netif_dbg(tp, tx_err, dev, "Transmit error, Tx status %08x\n",
-				  txstatus);
-			dev->stats.tx_errors++;
-			if (txstatus & TxAborted) {
-				dev->stats.tx_aborted_errors++;
-				RTL_W32 (TxConfig, TxClearAbt);
-				RTL_W16 (IntrStatus, TxErr);
-				wmb();
-			}
-			if (txstatus & TxCarrierLost)
-				dev->stats.tx_carrier_errors++;
-			if (txstatus & TxOutOfWindow)
-				dev->stats.tx_window_errors++;
-		} else {
-			if (txstatus & TxUnderrun) {
-				/* Add 64 to the Tx FIFO threshold. */
-				if (tp->tx_flag < 0x00300000)
-					tp->tx_flag += 0x00020000;
-				dev->stats.tx_fifo_errors++;
-			}
-			dev->stats.collisions += (txstatus >> 24) & 15;
-			dev->stats.tx_bytes += txstatus & 0x7ff;
-			dev->stats.tx_packets++;
-		}
-
-		dirty_tx++;
-		tx_left--;
-	}
-
-#ifndef RTL8139_NDEBUG
-	if (tp->cur_tx - dirty_tx > NUM_TX_DESC) {
-		netdev_err(dev, "Out-of-sync dirty pointer, %ld vs. %ld\n",
-			   dirty_tx, tp->cur_tx);
-		dirty_tx += NUM_TX_DESC;
-	}
-#endif /* RTL8139_NDEBUG */
-
-	/* only wake the queue if we did work, and the queue is stopped */
-	if (tp->dirty_tx != dirty_tx) {
-		tp->dirty_tx = dirty_tx;
-		mb();
-		netif_wake_queue (dev);
-	}
-}
-
-
-/* TODO: clean this up!  Rx reset need not be this intensive */
-static void rtl8139_rx_err (u32 rx_status, struct net_device *dev,
-			    struct rtl8139_private *tp, void __iomem *ioaddr)
-{
-	u8 tmp8;
-#ifdef CONFIG_8139_OLD_RX_RESET
-	int tmp_work;
-#endif
-
-	netif_dbg(tp, rx_err, dev, "Ethernet frame had errors, status %08x\n",
-		  rx_status);
-	dev->stats.rx_errors++;
-	if (!(rx_status & RxStatusOK)) {
-		if (rx_status & RxTooLong) {
-			netdev_dbg(dev, "Oversized Ethernet frame, status %04x!\n",
-				   rx_status);
-			/* A.C.: The chip hangs here. */
-		}
-		if (rx_status & (RxBadSymbol | RxBadAlign))
-			dev->stats.rx_frame_errors++;
-		if (rx_status & (RxRunt | RxTooLong))
-			dev->stats.rx_length_errors++;
-		if (rx_status & RxCRCErr)
-			dev->stats.rx_crc_errors++;
-	} else {
-		tp->xstats.rx_lost_in_ring++;
-	}
-
-#ifndef CONFIG_8139_OLD_RX_RESET
-	tmp8 = RTL_R8 (ChipCmd);
-	RTL_W8 (ChipCmd, tmp8 & ~CmdRxEnb);
-	RTL_W8 (ChipCmd, tmp8);
-	RTL_W32 (RxConfig, tp->rx_config);
-	tp->cur_rx = 0;
-#else
-	/* Reset the receiver, based on RealTek recommendation. (Bug?) */
-
-	/* disable receive */
-	RTL_W8_F (ChipCmd, CmdTxEnb);
-	tmp_work = 200;
-	while (--tmp_work > 0) {
-		udelay(1);
-		tmp8 = RTL_R8 (ChipCmd);
-		if (!(tmp8 & CmdRxEnb))
-			break;
-	}
-	if (tmp_work <= 0)
-		netdev_warn(dev, "rx stop wait too long\n");
-	/* restart receive */
-	tmp_work = 200;
-	while (--tmp_work > 0) {
-		RTL_W8_F (ChipCmd, CmdRxEnb | CmdTxEnb);
-		udelay(1);
-		tmp8 = RTL_R8 (ChipCmd);
-		if ((tmp8 & CmdRxEnb) && (tmp8 & CmdTxEnb))
-			break;
-	}
-	if (tmp_work <= 0)
-		netdev_warn(dev, "tx/rx enable wait too long\n");
-
-	/* and reinitialize all rx related registers */
-	RTL_W8_F (Cfg9346, Cfg9346_Unlock);
-	/* Must enable Tx/Rx before setting transfer thresholds! */
-	RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
-
-	tp->rx_config = rtl8139_rx_config | AcceptBroadcast | AcceptMyPhys;
-	RTL_W32 (RxConfig, tp->rx_config);
-	tp->cur_rx = 0;
-
-	netdev_dbg(dev, "init buffer addresses\n");
-
-	/* Lock Config[01234] and BMCR register writes */
-	RTL_W8 (Cfg9346, Cfg9346_Lock);
-
-	/* init Rx ring buffer DMA address */
-	RTL_W32_F (RxBuf, tp->rx_ring_dma);
-
-	/* A.C.: Reset the multicast list. */
-	__set_rx_mode (dev);
-#endif
-}
-
-#if RX_BUF_IDX == 3
-static inline void wrap_copy(struct sk_buff *skb, const unsigned char *ring,
-				 u32 offset, unsigned int size)
-{
-	u32 left = RX_BUF_LEN - offset;
-
-	if (size > left) {
-		skb_copy_to_linear_data(skb, ring + offset, left);
-		skb_copy_to_linear_data_offset(skb, left, ring, size - left);
-	} else
-		skb_copy_to_linear_data(skb, ring + offset, size);
-}
-#endif
-
-static void rtl8139_isr_ack(struct rtl8139_private *tp)
-{
-	void __iomem *ioaddr = tp->mmio_addr;
-	u16 status;
-
-	status = RTL_R16 (IntrStatus) & RxAckBits;
-
-	/* Clear out errors and receive interrupts */
-	if (likely(status != 0)) {
-		if (unlikely(status & (RxFIFOOver | RxOverflow))) {
-			tp->dev->stats.rx_errors++;
-			if (status & RxFIFOOver)
-				tp->dev->stats.rx_fifo_errors++;
-		}
-		RTL_W16_F (IntrStatus, RxAckBits);
-	}
-}
-
-static int rtl8139_rx(struct net_device *dev, struct rtl8139_private *tp,
-		      int budget)
-{
-	void __iomem *ioaddr = tp->mmio_addr;
-	int received = 0;
-	unsigned char *rx_ring = tp->rx_ring;
-	unsigned int cur_rx = tp->cur_rx;
-	unsigned int rx_size = 0;
-
-	netdev_dbg(dev, "In %s(), current %04x BufAddr %04x, free to %04x, Cmd %02x\n",
-		   __func__, (u16)cur_rx,
-		   RTL_R16(RxBufAddr), RTL_R16(RxBufPtr), RTL_R8(ChipCmd));
-
-	while (netif_running(dev) && received < budget &&
-	       (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
-		u32 ring_offset = cur_rx % RX_BUF_LEN;
-		u32 rx_status;
-		unsigned int pkt_size;
-		struct sk_buff *skb;
-
-		rmb();
-
-		/* read size+status of next frame from DMA ring buffer */
-		rx_status = le32_to_cpu (*(__le32 *) (rx_ring + ring_offset));
-		rx_size = rx_status >> 16;
-		pkt_size = rx_size - 4;
-
-		netif_dbg(tp, rx_status, dev, "%s() status %04x, size %04x, cur %04x\n",
-			  __func__, rx_status, rx_size, cur_rx);
-#if RTL8139_DEBUG > 2
-		print_hex_dump(KERN_DEBUG, "Frame contents: ",
-			       DUMP_PREFIX_OFFSET, 16, 1,
-			       &rx_ring[ring_offset], 70, true);
-#endif
-
-		/* Packet copy from FIFO still in progress.
-		 * Theoretically, this should never happen
-		 * since EarlyRx is disabled.
-		 */
-		if (unlikely(rx_size == 0xfff0)) {
-			if (!tp->fifo_copy_timeout)
-				tp->fifo_copy_timeout = jiffies + 2;
-			else if (time_after(jiffies, tp->fifo_copy_timeout)) {
-				netdev_dbg(dev, "hung FIFO. Reset\n");
-				rx_size = 0;
-				goto no_early_rx;
-			}
-			netif_dbg(tp, intr, dev, "fifo copy in progress\n");
-			tp->xstats.early_rx++;
-			break;
-		}
-
-no_early_rx:
-		tp->fifo_copy_timeout = 0;
-
-		/* If Rx err or invalid rx_size/rx_status received
-		 * (which happens if we get lost in the ring),
-		 * Rx process gets reset, so we abort any further
-		 * Rx processing.
-		 */
-		if (unlikely((rx_size > (MAX_ETH_FRAME_SIZE+4)) ||
-			     (rx_size < 8) ||
-			     (!(rx_status & RxStatusOK)))) {
-			rtl8139_rx_err (rx_status, dev, tp, ioaddr);
-			received = -1;
-			goto out;
-		}
-
-		/* Malloc up new buffer, compatible with net-2e. */
-		/* Omit the four octet CRC from the length. */
-
-		skb = netdev_alloc_skb_ip_align(dev, pkt_size);
-		if (likely(skb)) {
-#if RX_BUF_IDX == 3
-			wrap_copy(skb, rx_ring, ring_offset+4, pkt_size);
-#else
-			skb_copy_to_linear_data (skb, &rx_ring[ring_offset + 4], pkt_size);
-#endif
-			skb_put (skb, pkt_size);
-
-			skb->protocol = eth_type_trans (skb, dev);
-
-			dev->stats.rx_bytes += pkt_size;
-			dev->stats.rx_packets++;
-
-			netif_receive_skb (skb);
-		} else {
-			if (net_ratelimit())
-				netdev_warn(dev, "Memory squeeze, dropping packet\n");
-			dev->stats.rx_dropped++;
-		}
-		received++;
-
-		cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
-		RTL_W16 (RxBufPtr, (u16) (cur_rx - 16));
-
-		rtl8139_isr_ack(tp);
-	}
-
-	if (unlikely(!received || rx_size == 0xfff0))
-		rtl8139_isr_ack(tp);
-
-	netdev_dbg(dev, "Done %s(), current %04x BufAddr %04x, free to %04x, Cmd %02x\n",
-		   __func__, cur_rx,
-		   RTL_R16(RxBufAddr), RTL_R16(RxBufPtr), RTL_R8(ChipCmd));
-
-	tp->cur_rx = cur_rx;
-
-	/*
-	 * The receive buffer should be mostly empty.
-	 * Tell NAPI to reenable the Rx irq.
-	 */
-	if (tp->fifo_copy_timeout)
-		received = budget;
-
-out:
-	return received;
-}
-
-
-static void rtl8139_weird_interrupt (struct net_device *dev,
-				     struct rtl8139_private *tp,
-				     void __iomem *ioaddr,
-				     int status, int link_changed)
-{
-	netdev_dbg(dev, "Abnormal interrupt, status %08x\n", status);
-
-	assert (dev != NULL);
-	assert (tp != NULL);
-	assert (ioaddr != NULL);
-
-	/* Update the error count. */
-	dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
-	RTL_W32 (RxMissed, 0);
-
-	if ((status & RxUnderrun) && link_changed &&
-	    (tp->drv_flags & HAS_LNK_CHNG)) {
-		rtl_check_media(dev, 0);
-		status &= ~RxUnderrun;
-	}
-
-	if (status & (RxUnderrun | RxErr))
-		dev->stats.rx_errors++;
-
-	if (status & PCSTimeout)
-		dev->stats.rx_length_errors++;
-	if (status & RxUnderrun)
-		dev->stats.rx_fifo_errors++;
-	if (status & PCIErr) {
-		u16 pci_cmd_status;
-		pci_read_config_word (tp->pci_dev, PCI_STATUS, &pci_cmd_status);
-		pci_write_config_word (tp->pci_dev, PCI_STATUS, pci_cmd_status);
-
-		netdev_err(dev, "PCI Bus error %04x\n", pci_cmd_status);
-	}
-}
-
-static int rtl8139_poll(struct napi_struct *napi, int budget)
-{
-	struct rtl8139_private *tp = container_of(napi, struct rtl8139_private, napi);
-	struct net_device *dev = tp->dev;
-	void __iomem *ioaddr = tp->mmio_addr;
-	int work_done;
-
-	spin_lock(&tp->rx_lock);
-	work_done = 0;
-	if (likely(RTL_R16(IntrStatus) & RxAckBits))
-		work_done += rtl8139_rx(dev, tp, budget);
-
-	if (work_done < budget) {
-		unsigned long flags;
-		/*
-		 * Order is important since data can get interrupted
-		 * again when we think we are done.
-		 */
-		spin_lock_irqsave(&tp->lock, flags);
-		__napi_complete(napi);
-		RTL_W16_F(IntrMask, rtl8139_intr_mask);
-		spin_unlock_irqrestore(&tp->lock, flags);
-	}
-	spin_unlock(&tp->rx_lock);
-
-	return work_done;
-}
-
-/* The interrupt handler does all of the Rx thread work and cleans up
-   after the Tx thread. */
-static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
-{
-	struct net_device *dev = (struct net_device *) dev_instance;
-	struct rtl8139_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	u16 status, ackstat;
-	int link_changed = 0; /* avoid bogus "uninit" warning */
-	int handled = 0;
-
-	spin_lock (&tp->lock);
-	status = RTL_R16 (IntrStatus);
-
-	/* shared irq? */
-	if (unlikely((status & rtl8139_intr_mask) == 0))
-		goto out;
-
-	handled = 1;
-
-	/* h/w no longer present (hotplug?) or major error, bail */
-	if (unlikely(status == 0xFFFF))
-		goto out;
-
-	/* close possible race's with dev_close */
-	if (unlikely(!netif_running(dev))) {
-		RTL_W16 (IntrMask, 0);
-		goto out;
-	}
-
-	/* Acknowledge all of the current interrupt sources ASAP, but
-	   an first get an additional status bit from CSCR. */
-	if (unlikely(status & RxUnderrun))
-		link_changed = RTL_R16 (CSCR) & CSCR_LinkChangeBit;
-
-	ackstat = status & ~(RxAckBits | TxErr);
-	if (ackstat)
-		RTL_W16 (IntrStatus, ackstat);
-
-	/* Receive packets are processed by poll routine.
-	   If not running start it now. */
-	if (status & RxAckBits){
-		if (napi_schedule_prep(&tp->napi)) {
-			RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
-			__napi_schedule(&tp->napi);
-		}
-	}
-
-	/* Check uncommon events with one test. */
-	if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
-		rtl8139_weird_interrupt (dev, tp, ioaddr,
-					 status, link_changed);
-
-	if (status & (TxOK | TxErr)) {
-		rtl8139_tx_interrupt (dev, tp, ioaddr);
-		if (status & TxErr)
-			RTL_W16 (IntrStatus, TxErr);
-	}
- out:
-	spin_unlock (&tp->lock);
-
-	netdev_dbg(dev, "exiting interrupt, intr_status=%#4.4x\n",
-		   RTL_R16(IntrStatus));
-	return IRQ_RETVAL(handled);
-}
-
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling receive - used by netconsole and other diagnostic tools
- * to allow network i/o with interrupts disabled.
- */
-static void rtl8139_poll_controller(struct net_device *dev)
-{
-	disable_irq(dev->irq);
-	rtl8139_interrupt(dev->irq, dev);
-	enable_irq(dev->irq);
-}
-#endif
-
-static int rtl8139_set_mac_address(struct net_device *dev, void *p)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	struct sockaddr *addr = p;
-
-	if (!is_valid_ether_addr(addr->sa_data))
-		return -EADDRNOTAVAIL;
-
-	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
-
-	spin_lock_irq(&tp->lock);
-
-	RTL_W8_F(Cfg9346, Cfg9346_Unlock);
-	RTL_W32_F(MAC0 + 0, cpu_to_le32 (*(u32 *) (dev->dev_addr + 0)));
-	RTL_W32_F(MAC0 + 4, cpu_to_le32 (*(u32 *) (dev->dev_addr + 4)));
-	RTL_W8_F(Cfg9346, Cfg9346_Lock);
-
-	spin_unlock_irq(&tp->lock);
-
-	return 0;
-}
-
-static int rtl8139_close (struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	unsigned long flags;
-
-	netif_stop_queue(dev);
-	napi_disable(&tp->napi);
-
-	netif_dbg(tp, ifdown, dev, "Shutting down ethercard, status was 0x%04x\n",
-		  RTL_R16(IntrStatus));
-
-	spin_lock_irqsave (&tp->lock, flags);
-
-	/* Stop the chip's Tx and Rx DMA processes. */
-	RTL_W8 (ChipCmd, 0);
-
-	/* Disable interrupts by clearing the interrupt mask. */
-	RTL_W16 (IntrMask, 0);
-
-	/* Update the error counts. */
-	dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
-	RTL_W32 (RxMissed, 0);
-
-	spin_unlock_irqrestore (&tp->lock, flags);
-
-	free_irq (dev->irq, dev);
-
-	rtl8139_tx_clear (tp);
-
-	dma_free_coherent(&tp->pci_dev->dev, RX_BUF_TOT_LEN,
-			  tp->rx_ring, tp->rx_ring_dma);
-	dma_free_coherent(&tp->pci_dev->dev, TX_BUF_TOT_LEN,
-			  tp->tx_bufs, tp->tx_bufs_dma);
-	tp->rx_ring = NULL;
-	tp->tx_bufs = NULL;
-
-	/* Green! Put the chip in low-power mode. */
-	RTL_W8 (Cfg9346, Cfg9346_Unlock);
-
-	if (rtl_chip_info[tp->chipset].flags & HasHltClk)
-		RTL_W8 (HltClk, 'H');	/* 'R' would leave the clock running. */
-
-	return 0;
-}
-
-
-/* Get the ethtool Wake-on-LAN settings.  Assumes that wol points to
-   kernel memory, *wol has been initialized as {ETHTOOL_GWOL}, and
-   other threads or interrupts aren't messing with the 8139.  */
-static void rtl8139_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-
-	spin_lock_irq(&tp->lock);
-	if (rtl_chip_info[tp->chipset].flags & HasLWake) {
-		u8 cfg3 = RTL_R8 (Config3);
-		u8 cfg5 = RTL_R8 (Config5);
-
-		wol->supported = WAKE_PHY | WAKE_MAGIC
-			| WAKE_UCAST | WAKE_MCAST | WAKE_BCAST;
-
-		wol->wolopts = 0;
-		if (cfg3 & Cfg3_LinkUp)
-			wol->wolopts |= WAKE_PHY;
-		if (cfg3 & Cfg3_Magic)
-			wol->wolopts |= WAKE_MAGIC;
-		/* (KON)FIXME: See how netdev_set_wol() handles the
-		   following constants.  */
-		if (cfg5 & Cfg5_UWF)
-			wol->wolopts |= WAKE_UCAST;
-		if (cfg5 & Cfg5_MWF)
-			wol->wolopts |= WAKE_MCAST;
-		if (cfg5 & Cfg5_BWF)
-			wol->wolopts |= WAKE_BCAST;
-	}
-	spin_unlock_irq(&tp->lock);
-}
-
-
-/* Set the ethtool Wake-on-LAN settings.  Return 0 or -errno.  Assumes
-   that wol points to kernel memory and other threads or interrupts
-   aren't messing with the 8139.  */
-static int rtl8139_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	u32 support;
-	u8 cfg3, cfg5;
-
-	support = ((rtl_chip_info[tp->chipset].flags & HasLWake)
-		   ? (WAKE_PHY | WAKE_MAGIC
-		      | WAKE_UCAST | WAKE_MCAST | WAKE_BCAST)
-		   : 0);
-	if (wol->wolopts & ~support)
-		return -EINVAL;
-
-	spin_lock_irq(&tp->lock);
-	cfg3 = RTL_R8 (Config3) & ~(Cfg3_LinkUp | Cfg3_Magic);
-	if (wol->wolopts & WAKE_PHY)
-		cfg3 |= Cfg3_LinkUp;
-	if (wol->wolopts & WAKE_MAGIC)
-		cfg3 |= Cfg3_Magic;
-	RTL_W8 (Cfg9346, Cfg9346_Unlock);
-	RTL_W8 (Config3, cfg3);
-	RTL_W8 (Cfg9346, Cfg9346_Lock);
-
-	cfg5 = RTL_R8 (Config5) & ~(Cfg5_UWF | Cfg5_MWF | Cfg5_BWF);
-	/* (KON)FIXME: These are untested.  We may have to set the
-	   CRC0, Wakeup0 and LSBCRC0 registers too, but I have no
-	   documentation.  */
-	if (wol->wolopts & WAKE_UCAST)
-		cfg5 |= Cfg5_UWF;
-	if (wol->wolopts & WAKE_MCAST)
-		cfg5 |= Cfg5_MWF;
-	if (wol->wolopts & WAKE_BCAST)
-		cfg5 |= Cfg5_BWF;
-	RTL_W8 (Config5, cfg5);	/* need not unlock via Cfg9346 */
-	spin_unlock_irq(&tp->lock);
-
-	return 0;
-}
-
-static void rtl8139_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	strcpy(info->driver, DRV_NAME);
-	strcpy(info->version, DRV_VERSION);
-	strcpy(info->bus_info, pci_name(tp->pci_dev));
-	info->regdump_len = tp->regs_len;
-}
-
-static int rtl8139_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	spin_lock_irq(&tp->lock);
-	mii_ethtool_gset(&tp->mii, cmd);
-	spin_unlock_irq(&tp->lock);
-	return 0;
-}
-
-static int rtl8139_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	int rc;
-	spin_lock_irq(&tp->lock);
-	rc = mii_ethtool_sset(&tp->mii, cmd);
-	spin_unlock_irq(&tp->lock);
-	return rc;
-}
-
-static int rtl8139_nway_reset(struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	return mii_nway_restart(&tp->mii);
-}
-
-static u32 rtl8139_get_link(struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	return mii_link_ok(&tp->mii);
-}
-
-static u32 rtl8139_get_msglevel(struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	return tp->msg_enable;
-}
-
-static void rtl8139_set_msglevel(struct net_device *dev, u32 datum)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	tp->msg_enable = datum;
-}
-
-static int rtl8139_get_regs_len(struct net_device *dev)
-{
-	struct rtl8139_private *tp;
-	/* TODO: we are too slack to do reg dumping for pio, for now */
-	if (use_io)
-		return 0;
-	tp = netdev_priv(dev);
-	return tp->regs_len;
-}
-
-static void rtl8139_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *regbuf)
-{
-	struct rtl8139_private *tp;
-
-	/* TODO: we are too slack to do reg dumping for pio, for now */
-	if (use_io)
-		return;
-	tp = netdev_priv(dev);
-
-	regs->version = RTL_REGS_VER;
-
-	spin_lock_irq(&tp->lock);
-	memcpy_fromio(regbuf, tp->mmio_addr, regs->len);
-	spin_unlock_irq(&tp->lock);
-}
-
-static int rtl8139_get_sset_count(struct net_device *dev, int sset)
-{
-	switch (sset) {
-	case ETH_SS_STATS:
-		return RTL_NUM_STATS;
-	default:
-		return -EOPNOTSUPP;
-	}
-}
-
-static void rtl8139_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-
-	data[0] = tp->xstats.early_rx;
-	data[1] = tp->xstats.tx_buf_mapped;
-	data[2] = tp->xstats.tx_timeouts;
-	data[3] = tp->xstats.rx_lost_in_ring;
-}
-
-static void rtl8139_get_strings(struct net_device *dev, u32 stringset, u8 *data)
-{
-	memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys));
-}
-
-static const struct ethtool_ops rtl8139_ethtool_ops = {
-	.get_drvinfo		= rtl8139_get_drvinfo,
-	.get_settings		= rtl8139_get_settings,
-	.set_settings		= rtl8139_set_settings,
-	.get_regs_len		= rtl8139_get_regs_len,
-	.get_regs		= rtl8139_get_regs,
-	.nway_reset		= rtl8139_nway_reset,
-	.get_link		= rtl8139_get_link,
-	.get_msglevel		= rtl8139_get_msglevel,
-	.set_msglevel		= rtl8139_set_msglevel,
-	.get_wol		= rtl8139_get_wol,
-	.set_wol		= rtl8139_set_wol,
-	.get_strings		= rtl8139_get_strings,
-	.get_sset_count		= rtl8139_get_sset_count,
-	.get_ethtool_stats	= rtl8139_get_ethtool_stats,
-};
-
-static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	int rc;
-
-	if (!netif_running(dev))
-		return -EINVAL;
-
-	spin_lock_irq(&tp->lock);
-	rc = generic_mii_ioctl(&tp->mii, if_mii(rq), cmd, NULL);
-	spin_unlock_irq(&tp->lock);
-
-	return rc;
-}
-
-
-static struct net_device_stats *rtl8139_get_stats (struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	unsigned long flags;
-
-	if (netif_running(dev)) {
-		spin_lock_irqsave (&tp->lock, flags);
-		dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
-		RTL_W32 (RxMissed, 0);
-		spin_unlock_irqrestore (&tp->lock, flags);
-	}
-
-	return &dev->stats;
-}
-
-/* Set or clear the multicast filter for this adaptor.
-   This routine is not state sensitive and need not be SMP locked. */
-
-static void __set_rx_mode (struct net_device *dev)
-{
-	struct rtl8139_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	u32 mc_filter[2];	/* Multicast hash filter */
-	int rx_mode;
-	u32 tmp;
-
-	netdev_dbg(dev, "rtl8139_set_rx_mode(%04x) done -- Rx config %08x\n",
-		   dev->flags, RTL_R32(RxConfig));
-
-	/* Note: do not reorder, GCC is clever about common statements. */
-	if (dev->flags & IFF_PROMISC) {
-		rx_mode =
-		    AcceptBroadcast | AcceptMulticast | AcceptMyPhys |
-		    AcceptAllPhys;
-		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else if ((netdev_mc_count(dev) > multicast_filter_limit) ||
-		   (dev->flags & IFF_ALLMULTI)) {
-		/* Too many to filter perfectly -- accept all multicasts. */
-		rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
-		mc_filter[1] = mc_filter[0] = 0xffffffff;
-	} else {
-		struct netdev_hw_addr *ha;
-		rx_mode = AcceptBroadcast | AcceptMyPhys;
-		mc_filter[1] = mc_filter[0] = 0;
-		netdev_for_each_mc_addr(ha, dev) {
-			int bit_nr = ether_crc(ETH_ALEN, ha->addr) >> 26;
-
-			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
-			rx_mode |= AcceptMulticast;
-		}
-	}
-
-	/* We can safely update without stopping the chip. */
-	tmp = rtl8139_rx_config | rx_mode;
-	if (tp->rx_config != tmp) {
-		RTL_W32_F (RxConfig, tmp);
-		tp->rx_config = tmp;
-	}
-	RTL_W32_F (MAR0 + 0, mc_filter[0]);
-	RTL_W32_F (MAR0 + 4, mc_filter[1]);
-}
-
-static void rtl8139_set_rx_mode (struct net_device *dev)
-{
-	unsigned long flags;
-	struct rtl8139_private *tp = netdev_priv(dev);
-
-	spin_lock_irqsave (&tp->lock, flags);
-	__set_rx_mode(dev);
-	spin_unlock_irqrestore (&tp->lock, flags);
-}
-
-#ifdef CONFIG_PM
-
-static int rtl8139_suspend (struct pci_dev *pdev, pm_message_t state)
-{
-	struct net_device *dev = pci_get_drvdata (pdev);
-	struct rtl8139_private *tp = netdev_priv(dev);
-	void __iomem *ioaddr = tp->mmio_addr;
-	unsigned long flags;
-
-	pci_save_state (pdev);
-
-	if (!netif_running (dev))
-		return 0;
-
-	netif_device_detach (dev);
-
-	spin_lock_irqsave (&tp->lock, flags);
-
-	/* Disable interrupts, stop Tx and Rx. */
-	RTL_W16 (IntrMask, 0);
-	RTL_W8 (ChipCmd, 0);
-
-	/* Update the error counts. */
-	dev->stats.rx_missed_errors += RTL_R32 (RxMissed);
-	RTL_W32 (RxMissed, 0);
-
-	spin_unlock_irqrestore (&tp->lock, flags);
-
-	pci_set_power_state (pdev, PCI_D3hot);
-
-	return 0;
-}
-
-
-static int rtl8139_resume (struct pci_dev *pdev)
-{
-	struct net_device *dev = pci_get_drvdata (pdev);
-
-	pci_restore_state (pdev);
-	if (!netif_running (dev))
-		return 0;
-	pci_set_power_state (pdev, PCI_D0);
-	rtl8139_init_ring (dev);
-	rtl8139_hw_start (dev);
-	netif_device_attach (dev);
-	return 0;
-}
-
-#endif /* CONFIG_PM */
-
-
-static struct pci_driver rtl8139_pci_driver = {
-	.name		= DRV_NAME,
-	.id_table	= rtl8139_pci_tbl,
-	.probe		= rtl8139_init_one,
-	.remove		= __devexit_p(rtl8139_remove_one),
-#ifdef CONFIG_PM
-	.suspend	= rtl8139_suspend,
-	.resume		= rtl8139_resume,
-#endif /* CONFIG_PM */
-};
-
-
-static int __init rtl8139_init_module (void)
-{
-	/* when we're a module, we always print a version message,
-	 * even if no 8139 board is found.
-	 */
-#ifdef MODULE
-	pr_info(RTL8139_DRIVER_NAME "\n");
-#endif
-
-	return pci_register_driver(&rtl8139_pci_driver);
-}
-
-
-static void __exit rtl8139_cleanup_module (void)
-{
-	pci_unregister_driver (&rtl8139_pci_driver);
-}
-
-
-module_init(rtl8139_init_module);
-module_exit(rtl8139_cleanup_module);

+ 0 - 1632
drivers/net/82596.c

@@ -1,1632 +0,0 @@
-/* 82596.c: A generic 82596 ethernet driver for linux. */
-/*
-   Based on Apricot.c
-   Written 1994 by Mark Evans.
-   This driver is for the Apricot 82596 bus-master interface
-
-   Modularised 12/94 Mark Evans
-
-
-   Modified to support the 82596 ethernet chips on 680x0 VME boards.
-   by Richard Hirst <richard@sleepie.demon.co.uk>
-   Renamed to be 82596.c
-
-   980825:  Changed to receive directly in to sk_buffs which are
-   allocated at open() time.  Eliminates copy on incoming frames
-   (small ones are still copied).  Shared data now held in a
-   non-cached page, so we can run on 68060 in copyback mode.
-
-   TBD:
-   * look at deferring rx frames rather than discarding (as per tulip)
-   * handle tx ring full as per tulip
-   * performance test to tune rx_copybreak
-
-   Most of my modifications relate to the braindead big-endian
-   implementation by Intel.  When the i596 is operating in
-   'big-endian' mode, it thinks a 32 bit value of 0x12345678
-   should be stored as 0x56781234.  This is a real pain, when
-   you have linked lists which are shared by the 680x0 and the
-   i596.
-
-   Driver skeleton
-   Written 1993 by Donald Becker.
-   Copyright 1993 United States Government as represented by the Director,
-   National Security Agency. This software may only be used and distributed
-   according to the terms of the GNU General Public License as modified by SRC,
-   incorporated herein by reference.
-
-   The author may be reached as becker@scyld.com, or C/O
-   Scyld Computing Corporation, 410 Severn Ave., Suite 210, Annapolis MD 21403
-
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-#include <linux/ioport.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-#include <linux/init.h>
-#include <linux/bitops.h>
-#include <linux/gfp.h>
-
-#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";
-
-#define DRV_NAME	"82596"
-
-/* DEBUG flags
- */
-
-#define DEB_INIT	0x0001
-#define DEB_PROBE	0x0002
-#define DEB_SERIOUS	0x0004
-#define DEB_ERRORS	0x0008
-#define DEB_MULTI	0x0010
-#define DEB_TDR		0x0020
-#define DEB_OPEN	0x0040
-#define DEB_RESET	0x0080
-#define DEB_ADDCMD	0x0100
-#define DEB_STATUS	0x0200
-#define DEB_STARTTX	0x0400
-#define DEB_RXADDR	0x0800
-#define DEB_TXADDR	0x1000
-#define DEB_RXFRAME	0x2000
-#define DEB_INTS	0x4000
-#define DEB_STRUCT	0x8000
-#define DEB_ANY		0xffff
-
-
-#define DEB(x,y)	if (i596_debug & (x)) y
-
-
-#if defined(CONFIG_MVME16x_NET) || defined(CONFIG_MVME16x_NET_MODULE)
-#define ENABLE_MVME16x_NET
-#endif
-#if defined(CONFIG_BVME6000_NET) || defined(CONFIG_BVME6000_NET_MODULE)
-#define ENABLE_BVME6000_NET
-#endif
-#if defined(CONFIG_APRICOT) || defined(CONFIG_APRICOT_MODULE)
-#define ENABLE_APRICOT
-#endif
-
-#ifdef ENABLE_MVME16x_NET
-#include <asm/mvme16xhw.h>
-#endif
-#ifdef ENABLE_BVME6000_NET
-#include <asm/bvme6000hw.h>
-#endif
-
-/*
- * Define various macros for Channel Attention, word swapping etc., dependent
- * on architecture.  MVME and BVME are 680x0 based, otherwise it is Intel.
- */
-
-#ifdef __mc68000__
-#define WSWAPrfd(x)  ((struct i596_rfd *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPrbd(x)  ((struct i596_rbd *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPiscp(x) ((struct i596_iscp *)(((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPscb(x)  ((struct i596_scb *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPcmd(x)  ((struct i596_cmd *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPtbd(x)  ((struct i596_tbd *) (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define WSWAPchar(x) ((char *)            (((u32)(x)<<16) | ((((u32)(x)))>>16)))
-#define ISCP_BUSY	0x00010000
-#define MACH_IS_APRICOT	0
-#else
-#define WSWAPrfd(x)     ((struct i596_rfd *)((long)x))
-#define WSWAPrbd(x)     ((struct i596_rbd *)((long)x))
-#define WSWAPiscp(x)    ((struct i596_iscp *)((long)x))
-#define WSWAPscb(x)     ((struct i596_scb *)((long)x))
-#define WSWAPcmd(x)     ((struct i596_cmd *)((long)x))
-#define WSWAPtbd(x)     ((struct i596_tbd *)((long)x))
-#define WSWAPchar(x)    ((char *)((long)x))
-#define ISCP_BUSY	0x0001
-#define MACH_IS_APRICOT	1
-#endif
-
-/*
- * The MPU_PORT command allows direct access to the 82596. With PORT access
- * the following commands are available (p5-18). The 32-bit port command
- * must be word-swapped with the most significant word written first.
- * This only applies to VME boards.
- */
-#define PORT_RESET		0x00	/* reset 82596 */
-#define PORT_SELFTEST		0x01	/* selftest */
-#define PORT_ALTSCP		0x02	/* alternate SCB address */
-#define PORT_ALTDUMP		0x03	/* Alternate DUMP address */
-
-static int i596_debug = (DEB_SERIOUS|DEB_PROBE);
-
-MODULE_AUTHOR("Richard Hirst");
-MODULE_DESCRIPTION("i82596 driver");
-MODULE_LICENSE("GPL");
-
-module_param(i596_debug, int, 0);
-MODULE_PARM_DESC(i596_debug, "i82596 debug mask");
-
-
-/* Copy frames shorter than rx_copybreak, otherwise pass on up in
- * a full sized sk_buff.  Value of 100 stolen from tulip.c (!alpha).
- */
-static int rx_copybreak = 100;
-
-#define PKT_BUF_SZ	1536
-#define MAX_MC_CNT	64
-
-#define I596_TOTAL_SIZE 17
-
-#define I596_NULL ((void *)0xffffffff)
-
-#define CMD_EOL		0x8000	/* The last command of the list, stop. */
-#define CMD_SUSP	0x4000	/* Suspend after doing cmd. */
-#define CMD_INTR	0x2000	/* Interrupt after doing cmd. */
-
-#define CMD_FLEX	0x0008	/* Enable flexible memory model */
-
-enum commands {
-	CmdNOp = 0, CmdSASetup = 1, CmdConfigure = 2, CmdMulticastList = 3,
-	CmdTx = 4, CmdTDR = 5, CmdDump = 6, CmdDiagnose = 7
-};
-
-#define STAT_C		0x8000	/* Set to 0 after execution */
-#define STAT_B		0x4000	/* Command being executed */
-#define STAT_OK		0x2000	/* Command executed ok */
-#define STAT_A		0x1000	/* Command aborted */
-
-#define	 CUC_START	0x0100
-#define	 CUC_RESUME	0x0200
-#define	 CUC_SUSPEND    0x0300
-#define	 CUC_ABORT	0x0400
-#define	 RX_START	0x0010
-#define	 RX_RESUME	0x0020
-#define	 RX_SUSPEND	0x0030
-#define	 RX_ABORT	0x0040
-
-#define TX_TIMEOUT	(HZ/20)
-
-
-struct i596_reg {
-	unsigned short porthi;
-	unsigned short portlo;
-	unsigned long ca;
-};
-
-#define EOF		0x8000
-#define SIZE_MASK	0x3fff
-
-struct i596_tbd {
-	unsigned short size;
-	unsigned short pad;
-	struct i596_tbd *next;
-	char *data;
-};
-
-/* The command structure has two 'next' pointers; v_next is the address of
- * the next command as seen by the CPU, b_next is the address of the next
- * command as seen by the 82596.  The b_next pointer, as used by the 82596
- * always references the status field of the next command, rather than the
- * v_next field, because the 82596 is unaware of v_next.  It may seem more
- * logical to put v_next at the end of the structure, but we cannot do that
- * because the 82596 expects other fields to be there, depending on command
- * type.
- */
-
-struct i596_cmd {
-	struct i596_cmd *v_next;	/* Address from CPUs viewpoint */
-	unsigned short status;
-	unsigned short command;
-	struct i596_cmd *b_next;	/* Address from i596 viewpoint */
-};
-
-struct tx_cmd {
-	struct i596_cmd cmd;
-	struct i596_tbd *tbd;
-	unsigned short size;
-	unsigned short pad;
-	struct sk_buff *skb;	/* So we can free it after tx */
-};
-
-struct tdr_cmd {
-	struct i596_cmd cmd;
-	unsigned short status;
-	unsigned short pad;
-};
-
-struct mc_cmd {
-	struct i596_cmd cmd;
-	short mc_cnt;
-	char mc_addrs[MAX_MC_CNT*6];
-};
-
-struct sa_cmd {
-	struct i596_cmd cmd;
-	char eth_addr[8];
-};
-
-struct cf_cmd {
-	struct i596_cmd cmd;
-	char i596_config[16];
-};
-
-struct i596_rfd {
-	unsigned short stat;
-	unsigned short cmd;
-	struct i596_rfd *b_next;	/* Address from i596 viewpoint */
-	struct i596_rbd *rbd;
-	unsigned short count;
-	unsigned short size;
-	struct i596_rfd *v_next;	/* Address from CPUs viewpoint */
-	struct i596_rfd *v_prev;
-};
-
-struct i596_rbd {
-    unsigned short count;
-    unsigned short zero1;
-    struct i596_rbd *b_next;
-    unsigned char *b_data;		/* Address from i596 viewpoint */
-    unsigned short size;
-    unsigned short zero2;
-    struct sk_buff *skb;
-    struct i596_rbd *v_next;
-    struct i596_rbd *b_addr;		/* This rbd addr from i596 view */
-    unsigned char *v_data;		/* Address from CPUs viewpoint */
-};
-
-#define TX_RING_SIZE 64
-#define RX_RING_SIZE 16
-
-struct i596_scb {
-	unsigned short status;
-	unsigned short command;
-	struct i596_cmd *cmd;
-	struct i596_rfd *rfd;
-	unsigned long crc_err;
-	unsigned long align_err;
-	unsigned long resource_err;
-	unsigned long over_err;
-	unsigned long rcvdt_err;
-	unsigned long short_err;
-	unsigned short t_on;
-	unsigned short t_off;
-};
-
-struct i596_iscp {
-	unsigned long stat;
-	struct i596_scb *scb;
-};
-
-struct i596_scp {
-	unsigned long sysbus;
-	unsigned long pad;
-	struct i596_iscp *iscp;
-};
-
-struct i596_private {
-	volatile struct i596_scp scp;
-	volatile struct i596_iscp iscp;
-	volatile struct i596_scb scb;
-	struct sa_cmd sa_cmd;
-	struct cf_cmd cf_cmd;
-	struct tdr_cmd tdr_cmd;
-	struct mc_cmd mc_cmd;
-	unsigned long stat;
-	int last_restart __attribute__((aligned(4)));
-	struct i596_rfd *rfd_head;
-	struct i596_rbd *rbd_head;
-	struct i596_cmd *cmd_tail;
-	struct i596_cmd *cmd_head;
-	int cmd_backlog;
-	unsigned long last_cmd;
-	struct i596_rfd rfds[RX_RING_SIZE];
-	struct i596_rbd rbds[RX_RING_SIZE];
-	struct tx_cmd tx_cmds[TX_RING_SIZE];
-	struct i596_tbd tbds[TX_RING_SIZE];
-	int next_tx_cmd;
-	spinlock_t lock;
-};
-
-static char init_setup[] =
-{
-	0x8E,			/* length, prefetch on */
-	0xC8,			/* fifo to 8, monitor off */
-#ifdef CONFIG_VME
-	0xc0,			/* don't save bad frames */
-#else
-	0x80,			/* don't save bad frames */
-#endif
-	0x2E,			/* No source address insertion, 8 byte preamble */
-	0x00,			/* priority and backoff defaults */
-	0x60,			/* interframe spacing */
-	0x00,			/* slot time LSB */
-	0xf2,			/* slot time and retries */
-	0x00,			/* promiscuous mode */
-	0x00,			/* collision detect */
-	0x40,			/* minimum frame length */
-	0xff,
-	0x00,
-	0x7f /*  *multi IA */ };
-
-static int i596_open(struct net_device *dev);
-static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
-static irqreturn_t i596_interrupt(int irq, void *dev_id);
-static int i596_close(struct net_device *dev);
-static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
-static void i596_tx_timeout (struct net_device *dev);
-static void print_eth(unsigned char *buf, char *str);
-static void set_multicast_list(struct net_device *dev);
-
-static int rx_ring_size = RX_RING_SIZE;
-static int ticks_limit = 25;
-static int max_cmd_backlog = TX_RING_SIZE-1;
-
-
-static inline void CA(struct net_device *dev)
-{
-#ifdef ENABLE_MVME16x_NET
-	if (MACH_IS_MVME16x) {
-		((struct i596_reg *) dev->base_addr)->ca = 1;
-	}
-#endif
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000) {
-		volatile u32 i;
-
-		i = *(volatile u32 *) (dev->base_addr);
-	}
-#endif
-#ifdef ENABLE_APRICOT
-	if (MACH_IS_APRICOT) {
-		outw(0, (short) (dev->base_addr) + 4);
-	}
-#endif
-}
-
-
-static inline void MPU_PORT(struct net_device *dev, int c, volatile void *x)
-{
-#ifdef ENABLE_MVME16x_NET
-	if (MACH_IS_MVME16x) {
-		struct i596_reg *p = (struct i596_reg *) (dev->base_addr);
-		p->porthi = ((c) | (u32) (x)) & 0xffff;
-		p->portlo = ((c) | (u32) (x)) >> 16;
-	}
-#endif
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000) {
-		u32 v = (u32) (c) | (u32) (x);
-		v = ((u32) (v) << 16) | ((u32) (v) >> 16);
-		*(volatile u32 *) dev->base_addr = v;
-		udelay(1);
-		*(volatile u32 *) dev->base_addr = v;
-	}
-#endif
-}
-
-
-static inline int wait_istat(struct net_device *dev, struct i596_private *lp, int delcnt, char *str)
-{
-	while (--delcnt && lp->iscp.stat)
-		udelay(10);
-	if (!delcnt) {
-		printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n",
-		     dev->name, str, lp->scb.status, lp->scb.command);
-		return -1;
-	}
-	else
-		return 0;
-}
-
-
-static inline int wait_cmd(struct net_device *dev, struct i596_private *lp, int delcnt, char *str)
-{
-	while (--delcnt && lp->scb.command)
-		udelay(10);
-	if (!delcnt) {
-		printk(KERN_ERR "%s: %s, status %4.4x, cmd %4.4x.\n",
-		     dev->name, str, lp->scb.status, lp->scb.command);
-		return -1;
-	}
-	else
-		return 0;
-}
-
-
-static inline int wait_cfg(struct net_device *dev, struct i596_cmd *cmd, int delcnt, char *str)
-{
-	volatile struct i596_cmd *c = cmd;
-
-	while (--delcnt && c->command)
-		udelay(10);
-	if (!delcnt) {
-		printk(KERN_ERR "%s: %s.\n", dev->name, str);
-		return -1;
-	}
-	else
-		return 0;
-}
-
-
-static void i596_display_data(struct net_device *dev)
-{
-	struct i596_private *lp = dev->ml_priv;
-	struct i596_cmd *cmd;
-	struct i596_rfd *rfd;
-	struct i596_rbd *rbd;
-
-	printk(KERN_ERR "lp and scp at %p, .sysbus = %08lx, .iscp = %p\n",
-	       &lp->scp, lp->scp.sysbus, lp->scp.iscp);
-	printk(KERN_ERR "iscp at %p, iscp.stat = %08lx, .scb = %p\n",
-	       &lp->iscp, lp->iscp.stat, lp->iscp.scb);
-	printk(KERN_ERR "scb at %p, scb.status = %04x, .command = %04x,"
-		" .cmd = %p, .rfd = %p\n",
-	       &lp->scb, lp->scb.status, lp->scb.command,
-		lp->scb.cmd, lp->scb.rfd);
-	printk(KERN_ERR "   errors: crc %lx, align %lx, resource %lx,"
-               " over %lx, rcvdt %lx, short %lx\n",
-		lp->scb.crc_err, lp->scb.align_err, lp->scb.resource_err,
-		lp->scb.over_err, lp->scb.rcvdt_err, lp->scb.short_err);
-	cmd = lp->cmd_head;
-	while (cmd != I596_NULL) {
-		printk(KERN_ERR "cmd at %p, .status = %04x, .command = %04x, .b_next = %p\n",
-		  cmd, cmd->status, cmd->command, cmd->b_next);
-		cmd = cmd->v_next;
-	}
-	rfd = lp->rfd_head;
-	printk(KERN_ERR "rfd_head = %p\n", rfd);
-	do {
-		printk(KERN_ERR "   %p .stat %04x, .cmd %04x, b_next %p, rbd %p,"
-                        " count %04x\n",
-			rfd, rfd->stat, rfd->cmd, rfd->b_next, rfd->rbd,
-			rfd->count);
-		rfd = rfd->v_next;
-	} while (rfd != lp->rfd_head);
-	rbd = lp->rbd_head;
-	printk(KERN_ERR "rbd_head = %p\n", rbd);
-	do {
-		printk(KERN_ERR "   %p .count %04x, b_next %p, b_data %p, size %04x\n",
-			rbd, rbd->count, rbd->b_next, rbd->b_data, rbd->size);
-		rbd = rbd->v_next;
-	} while (rbd != lp->rbd_head);
-}
-
-
-#if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET)
-static irqreturn_t i596_error(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-#ifdef ENABLE_MVME16x_NET
-	if (MACH_IS_MVME16x) {
-		volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
-
-		pcc2[0x28] = 1;
-		pcc2[0x2b] = 0x1d;
-	}
-#endif
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000) {
-		volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG;
-
-		*ethirq = 1;
-		*ethirq = 3;
-	}
-#endif
-	printk(KERN_ERR "%s: Error interrupt\n", dev->name);
-	i596_display_data(dev);
-	return IRQ_HANDLED;
-}
-#endif
-
-static inline void remove_rx_bufs(struct net_device *dev)
-{
-	struct i596_private *lp = dev->ml_priv;
-	struct i596_rbd *rbd;
-	int i;
-
-	for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) {
-		if (rbd->skb == NULL)
-			break;
-		dev_kfree_skb(rbd->skb);
-		rbd->skb = NULL;
-	}
-}
-
-static inline int init_rx_bufs(struct net_device *dev)
-{
-	struct i596_private *lp = dev->ml_priv;
-	int i;
-	struct i596_rfd *rfd;
-	struct i596_rbd *rbd;
-
-	/* First build the Receive Buffer Descriptor List */
-
-	for (i = 0, rbd = lp->rbds; i < rx_ring_size; i++, rbd++) {
-		struct sk_buff *skb = dev_alloc_skb(PKT_BUF_SZ);
-
-		if (skb == NULL) {
-			remove_rx_bufs(dev);
-			return -ENOMEM;
-		}
-
-		skb->dev = dev;
-		rbd->v_next = rbd+1;
-		rbd->b_next = WSWAPrbd(virt_to_bus(rbd+1));
-		rbd->b_addr = WSWAPrbd(virt_to_bus(rbd));
-		rbd->skb = skb;
-		rbd->v_data = skb->data;
-		rbd->b_data = WSWAPchar(virt_to_bus(skb->data));
-		rbd->size = PKT_BUF_SZ;
-#ifdef __mc68000__
-		cache_clear(virt_to_phys(skb->data), PKT_BUF_SZ);
-#endif
-	}
-	lp->rbd_head = lp->rbds;
-	rbd = lp->rbds + rx_ring_size - 1;
-	rbd->v_next = lp->rbds;
-	rbd->b_next = WSWAPrbd(virt_to_bus(lp->rbds));
-
-	/* Now build the Receive Frame Descriptor List */
-
-	for (i = 0, rfd = lp->rfds; i < rx_ring_size; i++, rfd++) {
-		rfd->rbd = I596_NULL;
-		rfd->v_next = rfd+1;
-		rfd->v_prev = rfd-1;
-		rfd->b_next = WSWAPrfd(virt_to_bus(rfd+1));
-		rfd->cmd = CMD_FLEX;
-	}
-	lp->rfd_head = lp->rfds;
-	lp->scb.rfd = WSWAPrfd(virt_to_bus(lp->rfds));
-	rfd = lp->rfds;
-	rfd->rbd = lp->rbd_head;
-	rfd->v_prev = lp->rfds + rx_ring_size - 1;
-	rfd = lp->rfds + rx_ring_size - 1;
-	rfd->v_next = lp->rfds;
-	rfd->b_next = WSWAPrfd(virt_to_bus(lp->rfds));
-	rfd->cmd = CMD_EOL|CMD_FLEX;
-
-	return 0;
-}
-
-
-static void rebuild_rx_bufs(struct net_device *dev)
-{
-	struct i596_private *lp = dev->ml_priv;
-	int i;
-
-	/* Ensure rx frame/buffer descriptors are tidy */
-
-	for (i = 0; i < rx_ring_size; i++) {
-		lp->rfds[i].rbd = I596_NULL;
-		lp->rfds[i].cmd = CMD_FLEX;
-	}
-	lp->rfds[rx_ring_size-1].cmd = CMD_EOL|CMD_FLEX;
-	lp->rfd_head = lp->rfds;
-	lp->scb.rfd = WSWAPrfd(virt_to_bus(lp->rfds));
-	lp->rbd_head = lp->rbds;
-	lp->rfds[0].rbd = WSWAPrbd(virt_to_bus(lp->rbds));
-}
-
-
-static int init_i596_mem(struct net_device *dev)
-{
-	struct i596_private *lp = dev->ml_priv;
-#if !defined(ENABLE_MVME16x_NET) && !defined(ENABLE_BVME6000_NET) || defined(ENABLE_APRICOT)
-	short ioaddr = dev->base_addr;
-#endif
-	unsigned long flags;
-
-	MPU_PORT(dev, PORT_RESET, NULL);
-
-	udelay(100);		/* Wait 100us - seems to help */
-
-#if defined(ENABLE_MVME16x_NET) || defined(ENABLE_BVME6000_NET)
-#ifdef ENABLE_MVME16x_NET
-	if (MACH_IS_MVME16x) {
-		volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
-
-		/* Disable all ints for now */
-		pcc2[0x28] = 1;
-		pcc2[0x2a] = 0x48;
-		/* Following disables snooping.  Snooping is not required
-		 * as we make appropriate use of non-cached pages for
-		 * shared data, and cache_push/cache_clear.
-		 */
-		pcc2[0x2b] = 0x08;
-	}
-#endif
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000) {
-		volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG;
-
-		*ethirq = 1;
-	}
-#endif
-
-	/* change the scp address */
-
-	MPU_PORT(dev, PORT_ALTSCP, (void *)virt_to_bus((void *)&lp->scp));
-
-#elif defined(ENABLE_APRICOT)
-
-	{
-		u32 scp = virt_to_bus(&lp->scp);
-
-		/* change the scp address */
-		outw(0, ioaddr);
-		outw(0, ioaddr);
-		outb(4, ioaddr + 0xf);
-		outw(scp | 2, ioaddr);
-		outw(scp >> 16, ioaddr);
-	}
-#endif
-
-	lp->last_cmd = jiffies;
-
-#ifdef ENABLE_MVME16x_NET
-	if (MACH_IS_MVME16x)
-		lp->scp.sysbus = 0x00000054;
-#endif
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000)
-		lp->scp.sysbus = 0x0000004c;
-#endif
-#ifdef ENABLE_APRICOT
-	if (MACH_IS_APRICOT)
-		lp->scp.sysbus = 0x00440000;
-#endif
-
-	lp->scp.iscp = WSWAPiscp(virt_to_bus((void *)&lp->iscp));
-	lp->iscp.scb = WSWAPscb(virt_to_bus((void *)&lp->scb));
-	lp->iscp.stat = ISCP_BUSY;
-	lp->cmd_backlog = 0;
-
-	lp->cmd_head = lp->scb.cmd = I596_NULL;
-
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000) {
-		lp->scb.t_on  = 7 * 25;
-		lp->scb.t_off = 1 * 25;
-	}
-#endif
-
-	DEB(DEB_INIT,printk(KERN_DEBUG "%s: starting i82596.\n", dev->name));
-
-#if defined(ENABLE_APRICOT)
-	(void) inb(ioaddr + 0x10);
-	outb(4, ioaddr + 0xf);
-#endif
-	CA(dev);
-
-	if (wait_istat(dev,lp,1000,"initialization timed out"))
-		goto failed;
-	DEB(DEB_INIT,printk(KERN_DEBUG "%s: i82596 initialization successful\n", dev->name));
-
-	/* Ensure rx frame/buffer descriptors are tidy */
-	rebuild_rx_bufs(dev);
-	lp->scb.command = 0;
-
-#ifdef ENABLE_MVME16x_NET
-	if (MACH_IS_MVME16x) {
-		volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
-
-		/* Enable ints, etc. now */
-		pcc2[0x2a] = 0x55;	/* Edge sensitive */
-		pcc2[0x2b] = 0x15;
-	}
-#endif
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000) {
-		volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG;
-
-		*ethirq = 3;
-	}
-#endif
-
-
-	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdConfigure\n", dev->name));
-	memcpy(lp->cf_cmd.i596_config, init_setup, 14);
-	lp->cf_cmd.cmd.command = CmdConfigure;
-	i596_add_cmd(dev, &lp->cf_cmd.cmd);
-
-	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdSASetup\n", dev->name));
-	memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6);
-	lp->sa_cmd.cmd.command = CmdSASetup;
-	i596_add_cmd(dev, &lp->sa_cmd.cmd);
-
-	DEB(DEB_INIT,printk(KERN_DEBUG "%s: queuing CmdTDR\n", dev->name));
-	lp->tdr_cmd.cmd.command = CmdTDR;
-	i596_add_cmd(dev, &lp->tdr_cmd.cmd);
-
-	spin_lock_irqsave (&lp->lock, flags);
-
-	if (wait_cmd(dev,lp,1000,"timed out waiting to issue RX_START")) {
-		spin_unlock_irqrestore (&lp->lock, flags);
-		goto failed;
-	}
-	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Issuing RX_START\n", dev->name));
-	lp->scb.command = RX_START;
-	CA(dev);
-
-	spin_unlock_irqrestore (&lp->lock, flags);
-
-	if (wait_cmd(dev,lp,1000,"RX_START not processed"))
-		goto failed;
-	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Receive unit started OK\n", dev->name));
-	return 0;
-
-failed:
-	printk(KERN_CRIT "%s: Failed to initialise 82596\n", dev->name);
-	MPU_PORT(dev, PORT_RESET, NULL);
-	return -1;
-}
-
-static inline int i596_rx(struct net_device *dev)
-{
-	struct i596_private *lp = dev->ml_priv;
-	struct i596_rfd *rfd;
-	struct i596_rbd *rbd;
-	int frames = 0;
-
-	DEB(DEB_RXFRAME,printk(KERN_DEBUG "i596_rx(), rfd_head %p, rbd_head %p\n",
-			lp->rfd_head, lp->rbd_head));
-
-	rfd = lp->rfd_head;		/* Ref next frame to check */
-
-	while ((rfd->stat) & STAT_C) {	/* Loop while complete frames */
-		if (rfd->rbd == I596_NULL)
-			rbd = I596_NULL;
-		else if (rfd->rbd == lp->rbd_head->b_addr)
-			rbd = lp->rbd_head;
-		else {
-			printk(KERN_CRIT "%s: rbd chain broken!\n", dev->name);
-			/* XXX Now what? */
-			rbd = I596_NULL;
-		}
-		DEB(DEB_RXFRAME, printk(KERN_DEBUG "  rfd %p, rfd.rbd %p, rfd.stat %04x\n",
-			rfd, rfd->rbd, rfd->stat));
-
-		if (rbd != I596_NULL && ((rfd->stat) & STAT_OK)) {
-			/* a good frame */
-			int pkt_len = rbd->count & 0x3fff;
-			struct sk_buff *skb = rbd->skb;
-			int rx_in_place = 0;
-
-			DEB(DEB_RXADDR,print_eth(rbd->v_data, "received"));
-			frames++;
-
-			/* Check if the packet is long enough to just accept
-			 * without copying to a properly sized skbuff.
-			 */
-
-			if (pkt_len > rx_copybreak) {
-				struct sk_buff *newskb;
-
-				/* Get fresh skbuff to replace filled one. */
-				newskb = dev_alloc_skb(PKT_BUF_SZ);
-				if (newskb == NULL) {
-					skb = NULL;	/* drop pkt */
-					goto memory_squeeze;
-				}
-				/* Pass up the skb already on the Rx ring. */
-				skb_put(skb, pkt_len);
-				rx_in_place = 1;
-				rbd->skb = newskb;
-				newskb->dev = dev;
-				rbd->v_data = newskb->data;
-				rbd->b_data = WSWAPchar(virt_to_bus(newskb->data));
-#ifdef __mc68000__
-				cache_clear(virt_to_phys(newskb->data), PKT_BUF_SZ);
-#endif
-			}
-			else
-				skb = dev_alloc_skb(pkt_len + 2);
-memory_squeeze:
-			if (skb == NULL) {
-				/* XXX tulip.c can defer packets here!! */
-				printk(KERN_WARNING "%s: i596_rx Memory squeeze, dropping packet.\n", dev->name);
-				dev->stats.rx_dropped++;
-			}
-			else {
-				if (!rx_in_place) {
-					/* 16 byte align the data fields */
-					skb_reserve(skb, 2);
-					memcpy(skb_put(skb,pkt_len), rbd->v_data, pkt_len);
-				}
-				skb->protocol=eth_type_trans(skb,dev);
-				skb->len = pkt_len;
-#ifdef __mc68000__
-				cache_clear(virt_to_phys(rbd->skb->data),
-						pkt_len);
-#endif
-				netif_rx(skb);
-				dev->stats.rx_packets++;
-				dev->stats.rx_bytes+=pkt_len;
-			}
-		}
-		else {
-			DEB(DEB_ERRORS, printk(KERN_DEBUG "%s: Error, rfd.stat = 0x%04x\n",
-					dev->name, rfd->stat));
-			dev->stats.rx_errors++;
-			if ((rfd->stat) & 0x0001)
-				dev->stats.collisions++;
-			if ((rfd->stat) & 0x0080)
-				dev->stats.rx_length_errors++;
-			if ((rfd->stat) & 0x0100)
-				dev->stats.rx_over_errors++;
-			if ((rfd->stat) & 0x0200)
-				dev->stats.rx_fifo_errors++;
-			if ((rfd->stat) & 0x0400)
-				dev->stats.rx_frame_errors++;
-			if ((rfd->stat) & 0x0800)
-				dev->stats.rx_crc_errors++;
-			if ((rfd->stat) & 0x1000)
-				dev->stats.rx_length_errors++;
-		}
-
-		/* Clear the buffer descriptor count and EOF + F flags */
-
-		if (rbd != I596_NULL && (rbd->count & 0x4000)) {
-			rbd->count = 0;
-			lp->rbd_head = rbd->v_next;
-		}
-
-		/* Tidy the frame descriptor, marking it as end of list */
-
-		rfd->rbd = I596_NULL;
-		rfd->stat = 0;
-		rfd->cmd = CMD_EOL|CMD_FLEX;
-		rfd->count = 0;
-
-		/* Remove end-of-list from old end descriptor */
-
-		rfd->v_prev->cmd = CMD_FLEX;
-
-		/* Update record of next frame descriptor to process */
-
-		lp->scb.rfd = rfd->b_next;
-		lp->rfd_head = rfd->v_next;
-		rfd = lp->rfd_head;
-	}
-
-	DEB(DEB_RXFRAME,printk(KERN_DEBUG "frames %d\n", frames));
-
-	return 0;
-}
-
-
-static void i596_cleanup_cmd(struct net_device *dev, struct i596_private *lp)
-{
-	struct i596_cmd *ptr;
-
-	while (lp->cmd_head != I596_NULL) {
-		ptr = lp->cmd_head;
-		lp->cmd_head = ptr->v_next;
-		lp->cmd_backlog--;
-
-		switch ((ptr->command) & 0x7) {
-		case CmdTx:
-			{
-				struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
-				struct sk_buff *skb = tx_cmd->skb;
-
-				dev_kfree_skb(skb);
-
-				dev->stats.tx_errors++;
-				dev->stats.tx_aborted_errors++;
-
-				ptr->v_next = ptr->b_next = I596_NULL;
-				tx_cmd->cmd.command = 0;  /* Mark as free */
-				break;
-			}
-		default:
-			ptr->v_next = ptr->b_next = I596_NULL;
-		}
-	}
-
-	wait_cmd(dev,lp,100,"i596_cleanup_cmd timed out");
-	lp->scb.cmd = I596_NULL;
-}
-
-static void i596_reset(struct net_device *dev, struct i596_private *lp,
-			int ioaddr)
-{
-	unsigned long flags;
-
-	DEB(DEB_RESET,printk(KERN_DEBUG "i596_reset\n"));
-
-	spin_lock_irqsave (&lp->lock, flags);
-
-	wait_cmd(dev,lp,100,"i596_reset timed out");
-
-	netif_stop_queue(dev);
-
-	lp->scb.command = CUC_ABORT | RX_ABORT;
-	CA(dev);
-
-	/* wait for shutdown */
-	wait_cmd(dev,lp,1000,"i596_reset 2 timed out");
-	spin_unlock_irqrestore (&lp->lock, flags);
-
-	i596_cleanup_cmd(dev,lp);
-	i596_rx(dev);
-
-	netif_start_queue(dev);
-	init_i596_mem(dev);
-}
-
-static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd)
-{
-	struct i596_private *lp = dev->ml_priv;
-	int ioaddr = dev->base_addr;
-	unsigned long flags;
-
-	DEB(DEB_ADDCMD,printk(KERN_DEBUG "i596_add_cmd\n"));
-
-	cmd->status = 0;
-	cmd->command |= (CMD_EOL | CMD_INTR);
-	cmd->v_next = cmd->b_next = I596_NULL;
-
-	spin_lock_irqsave (&lp->lock, flags);
-
-	if (lp->cmd_head != I596_NULL) {
-		lp->cmd_tail->v_next = cmd;
-		lp->cmd_tail->b_next = WSWAPcmd(virt_to_bus(&cmd->status));
-	} else {
-		lp->cmd_head = cmd;
-		wait_cmd(dev,lp,100,"i596_add_cmd timed out");
-		lp->scb.cmd = WSWAPcmd(virt_to_bus(&cmd->status));
-		lp->scb.command = CUC_START;
-		CA(dev);
-	}
-	lp->cmd_tail = cmd;
-	lp->cmd_backlog++;
-
-	spin_unlock_irqrestore (&lp->lock, flags);
-
-	if (lp->cmd_backlog > max_cmd_backlog) {
-		unsigned long tickssofar = jiffies - lp->last_cmd;
-
-		if (tickssofar < ticks_limit)
-			return;
-
-		printk(KERN_NOTICE "%s: command unit timed out, status resetting.\n", dev->name);
-
-		i596_reset(dev, lp, ioaddr);
-	}
-}
-
-static int i596_open(struct net_device *dev)
-{
-	int res = 0;
-
-	DEB(DEB_OPEN,printk(KERN_DEBUG "%s: i596_open() irq %d.\n", dev->name, dev->irq));
-
-	if (request_irq(dev->irq, i596_interrupt, 0, "i82596", dev)) {
-		printk(KERN_ERR "%s: IRQ %d not free\n", dev->name, dev->irq);
-		return -EAGAIN;
-	}
-#ifdef ENABLE_MVME16x_NET
-	if (MACH_IS_MVME16x) {
-		if (request_irq(0x56, i596_error, 0, "i82596_error", dev)) {
-			res = -EAGAIN;
-			goto err_irq_dev;
-		}
-	}
-#endif
-	res = init_rx_bufs(dev);
-	if (res)
-		goto err_irq_56;
-
-	netif_start_queue(dev);
-
-	if (init_i596_mem(dev)) {
-		res = -EAGAIN;
-		goto err_queue;
-	}
-
-	return 0;
-
-err_queue:
-	netif_stop_queue(dev);
-	remove_rx_bufs(dev);
-err_irq_56:
-#ifdef ENABLE_MVME16x_NET
-	free_irq(0x56, dev);
-err_irq_dev:
-#endif
-	free_irq(dev->irq, dev);
-
-	return res;
-}
-
-static void i596_tx_timeout (struct net_device *dev)
-{
-	struct i596_private *lp = dev->ml_priv;
-	int ioaddr = dev->base_addr;
-
-	/* Transmitter timeout, serious problems. */
-	DEB(DEB_ERRORS,printk(KERN_ERR "%s: transmit timed out, status resetting.\n",
-			dev->name));
-
-	dev->stats.tx_errors++;
-
-	/* Try to restart the adaptor */
-	if (lp->last_restart == dev->stats.tx_packets) {
-		DEB(DEB_ERRORS,printk(KERN_ERR "Resetting board.\n"));
-		/* Shutdown and restart */
-		i596_reset (dev, lp, ioaddr);
-	} else {
-		/* Issue a channel attention signal */
-		DEB(DEB_ERRORS,printk(KERN_ERR "Kicking board.\n"));
-		lp->scb.command = CUC_START | RX_START;
-		CA (dev);
-		lp->last_restart = dev->stats.tx_packets;
-	}
-
-	dev->trans_start = jiffies; /* prevent tx timeout */
-	netif_wake_queue (dev);
-}
-
-static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	struct i596_private *lp = dev->ml_priv;
-	struct tx_cmd *tx_cmd;
-	struct i596_tbd *tbd;
-	short length = skb->len;
-
-	DEB(DEB_STARTTX,printk(KERN_DEBUG "%s: i596_start_xmit(%x,%p) called\n",
-				dev->name, skb->len, skb->data));
-
-	if (skb->len < ETH_ZLEN) {
-		if (skb_padto(skb, ETH_ZLEN))
-			return NETDEV_TX_OK;
-		length = ETH_ZLEN;
-	}
-	netif_stop_queue(dev);
-
-	tx_cmd = lp->tx_cmds + lp->next_tx_cmd;
-	tbd = lp->tbds + lp->next_tx_cmd;
-
-	if (tx_cmd->cmd.command) {
-		printk(KERN_NOTICE "%s: xmit ring full, dropping packet.\n",
-				dev->name);
-		dev->stats.tx_dropped++;
-
-		dev_kfree_skb(skb);
-	} else {
-		if (++lp->next_tx_cmd == TX_RING_SIZE)
-			lp->next_tx_cmd = 0;
-		tx_cmd->tbd = WSWAPtbd(virt_to_bus(tbd));
-		tbd->next = I596_NULL;
-
-		tx_cmd->cmd.command = CMD_FLEX | CmdTx;
-		tx_cmd->skb = skb;
-
-		tx_cmd->pad = 0;
-		tx_cmd->size = 0;
-		tbd->pad = 0;
-		tbd->size = EOF | length;
-
-		tbd->data = WSWAPchar(virt_to_bus(skb->data));
-
-#ifdef __mc68000__
-		cache_push(virt_to_phys(skb->data), length);
-#endif
-		DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued"));
-		i596_add_cmd(dev, &tx_cmd->cmd);
-
-		dev->stats.tx_packets++;
-		dev->stats.tx_bytes += length;
-	}
-
-	netif_start_queue(dev);
-
-	return NETDEV_TX_OK;
-}
-
-static void print_eth(unsigned char *add, char *str)
-{
-	printk(KERN_DEBUG "i596 0x%p, %pM --> %pM %02X%02X, %s\n",
-	       add, add + 6, add, add[12], add[13], str);
-}
-
-static int io = 0x300;
-static int irq = 10;
-
-static const struct net_device_ops i596_netdev_ops = {
-	.ndo_open 		= i596_open,
-	.ndo_stop		= i596_close,
-	.ndo_start_xmit		= i596_start_xmit,
-	.ndo_set_multicast_list = set_multicast_list,
-	.ndo_tx_timeout		= i596_tx_timeout,
-	.ndo_change_mtu		= eth_change_mtu,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_validate_addr	= eth_validate_addr,
-};
-
-struct net_device * __init i82596_probe(int unit)
-{
-	struct net_device *dev;
-	int i;
-	struct i596_private *lp;
-	char eth_addr[8];
-	static int probed;
-	int err;
-
-	if (probed)
-		return ERR_PTR(-ENODEV);
-	probed++;
-
-	dev = alloc_etherdev(0);
-	if (!dev)
-		return ERR_PTR(-ENOMEM);
-
-	if (unit >= 0) {
-		sprintf(dev->name, "eth%d", unit);
-		netdev_boot_setup_check(dev);
-	} else {
-		dev->base_addr = io;
-		dev->irq = irq;
-	}
-
-#ifdef ENABLE_MVME16x_NET
-	if (MACH_IS_MVME16x) {
-		if (mvme16x_config & MVME16x_CONFIG_NO_ETHERNET) {
-			printk(KERN_NOTICE "Ethernet probe disabled - chip not present\n");
-			err = -ENODEV;
-			goto out;
-		}
-		memcpy(eth_addr, (void *) 0xfffc1f2c, 6);	/* YUCK! Get addr from NOVRAM */
-		dev->base_addr = MVME_I596_BASE;
-		dev->irq = (unsigned) MVME16x_IRQ_I596;
-		goto found;
-	}
-#endif
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000) {
-		volatile unsigned char *rtc = (unsigned char *) BVME_RTC_BASE;
-		unsigned char msr = rtc[3];
-		int i;
-
-		rtc[3] |= 0x80;
-		for (i = 0; i < 6; i++)
-			eth_addr[i] = rtc[i * 4 + 7];	/* Stored in RTC RAM at offset 1 */
-		rtc[3] = msr;
-		dev->base_addr = BVME_I596_BASE;
-		dev->irq = (unsigned) BVME_IRQ_I596;
-		goto found;
-	}
-#endif
-#ifdef ENABLE_APRICOT
-	{
-		int checksum = 0;
-		int ioaddr = 0x300;
-
-		/* this is easy the ethernet interface can only be at 0x300 */
-		/* first check nothing is already registered here */
-
-		if (!request_region(ioaddr, I596_TOTAL_SIZE, DRV_NAME)) {
-			printk(KERN_ERR "82596: IO address 0x%04x in use\n", ioaddr);
-			err = -EBUSY;
-			goto out;
-		}
-
-		dev->base_addr = ioaddr;
-
-		for (i = 0; i < 8; i++) {
-			eth_addr[i] = inb(ioaddr + 8 + i);
-			checksum += eth_addr[i];
-		}
-
-		/* checksum is a multiple of 0x100, got this wrong first time
-		   some machines have 0x100, some 0x200. The DOS driver doesn't
-		   even bother with the checksum.
-		   Some other boards trip the checksum.. but then appear as
-		   ether address 0. Trap these - AC */
-
-		if ((checksum % 0x100) ||
-		    (memcmp(eth_addr, "\x00\x00\x49", 3) != 0)) {
-			err = -ENODEV;
-			goto out1;
-		}
-
-		dev->irq = 10;
-		goto found;
-	}
-#endif
-	err = -ENODEV;
-	goto out;
-
-found:
-	dev->mem_start = (int)__get_free_pages(GFP_ATOMIC, 0);
-	if (!dev->mem_start) {
-		err = -ENOMEM;
-		goto out1;
-	}
-
-	DEB(DEB_PROBE,printk(KERN_INFO "%s: 82596 at %#3lx,", dev->name, dev->base_addr));
-
-	for (i = 0; i < 6; i++)
-		DEB(DEB_PROBE,printk(" %2.2X", dev->dev_addr[i] = eth_addr[i]));
-
-	DEB(DEB_PROBE,printk(" IRQ %d.\n", dev->irq));
-
-	DEB(DEB_PROBE,printk(KERN_INFO "%s", version));
-
-	/* The 82596-specific entries in the device structure. */
-	dev->netdev_ops = &i596_netdev_ops;
-	dev->watchdog_timeo = TX_TIMEOUT;
-
-	dev->ml_priv = (void *)(dev->mem_start);
-
-	lp = dev->ml_priv;
-	DEB(DEB_INIT,printk(KERN_DEBUG "%s: lp at 0x%08lx (%zd bytes), "
-			"lp->scb at 0x%08lx\n",
-			dev->name, (unsigned long)lp,
-			sizeof(struct i596_private), (unsigned long)&lp->scb));
-	memset((void *) lp, 0, sizeof(struct i596_private));
-
-#ifdef __mc68000__
-	cache_push(virt_to_phys((void *)(dev->mem_start)), 4096);
-	cache_clear(virt_to_phys((void *)(dev->mem_start)), 4096);
-	kernel_set_cachemode((void *)(dev->mem_start), 4096, IOMAP_NOCACHE_SER);
-#endif
-	lp->scb.command = 0;
-	lp->scb.cmd = I596_NULL;
-	lp->scb.rfd = I596_NULL;
-	spin_lock_init(&lp->lock);
-
-	err = register_netdev(dev);
-	if (err)
-		goto out2;
-	return dev;
-out2:
-#ifdef __mc68000__
-	/* XXX This assumes default cache mode to be IOMAP_FULL_CACHING,
-	 * XXX which may be invalid (CONFIG_060_WRITETHROUGH)
-	 */
-	kernel_set_cachemode((void *)(dev->mem_start), 4096,
-			IOMAP_FULL_CACHING);
-#endif
-	free_page ((u32)(dev->mem_start));
-out1:
-#ifdef ENABLE_APRICOT
-	release_region(dev->base_addr, I596_TOTAL_SIZE);
-#endif
-out:
-	free_netdev(dev);
-	return ERR_PTR(err);
-}
-
-static irqreturn_t i596_interrupt(int irq, void *dev_id)
-{
-	struct net_device *dev = dev_id;
-	struct i596_private *lp;
-	short ioaddr;
-	unsigned short status, ack_cmd = 0;
-	int handled = 0;
-
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000) {
-		if (*(char *) BVME_LOCAL_IRQ_STAT & BVME_ETHERR) {
-			i596_error(irq, dev_id);
-			return IRQ_HANDLED;
-		}
-	}
-#endif
-	if (dev == NULL) {
-		printk(KERN_ERR "i596_interrupt(): irq %d for unknown device.\n", irq);
-		return IRQ_NONE;
-	}
-
-	ioaddr = dev->base_addr;
-	lp = dev->ml_priv;
-
-	spin_lock (&lp->lock);
-
-	wait_cmd(dev,lp,100,"i596 interrupt, timeout");
-	status = lp->scb.status;
-
-	DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt, IRQ %d, status %4.4x.\n",
-			dev->name, irq, status));
-
-	ack_cmd = status & 0xf000;
-
-	if ((status & 0x8000) || (status & 0x2000)) {
-		struct i596_cmd *ptr;
-
-		handled = 1;
-		if ((status & 0x8000))
-			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt completed command.\n", dev->name));
-		if ((status & 0x2000))
-			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700));
-
-		while ((lp->cmd_head != I596_NULL) && (lp->cmd_head->status & STAT_C)) {
-			ptr = lp->cmd_head;
-
-			DEB(DEB_STATUS,printk(KERN_DEBUG "cmd_head->status = %04x, ->command = %04x\n",
-				       lp->cmd_head->status, lp->cmd_head->command));
-			lp->cmd_head = ptr->v_next;
-			lp->cmd_backlog--;
-
-			switch ((ptr->command) & 0x7) {
-			case CmdTx:
-			    {
-				struct tx_cmd *tx_cmd = (struct tx_cmd *) ptr;
-				struct sk_buff *skb = tx_cmd->skb;
-
-				if ((ptr->status) & STAT_OK) {
-					DEB(DEB_TXADDR,print_eth(skb->data, "tx-done"));
-				} else {
-					dev->stats.tx_errors++;
-					if ((ptr->status) & 0x0020)
-						dev->stats.collisions++;
-					if (!((ptr->status) & 0x0040))
-						dev->stats.tx_heartbeat_errors++;
-					if ((ptr->status) & 0x0400)
-						dev->stats.tx_carrier_errors++;
-					if ((ptr->status) & 0x0800)
-						dev->stats.collisions++;
-					if ((ptr->status) & 0x1000)
-						dev->stats.tx_aborted_errors++;
-				}
-
-				dev_kfree_skb_irq(skb);
-
-				tx_cmd->cmd.command = 0; /* Mark free */
-				break;
-			    }
-			case CmdTDR:
-			    {
-				unsigned short status = ((struct tdr_cmd *)ptr)->status;
-
-				if (status & 0x8000) {
-					DEB(DEB_TDR,printk(KERN_INFO "%s: link ok.\n", dev->name));
-				} else {
-					if (status & 0x4000)
-						printk(KERN_ERR "%s: Transceiver problem.\n", dev->name);
-					if (status & 0x2000)
-						printk(KERN_ERR "%s: Termination problem.\n", dev->name);
-					if (status & 0x1000)
-						printk(KERN_ERR "%s: Short circuit.\n", dev->name);
-
-					DEB(DEB_TDR,printk(KERN_INFO "%s: Time %d.\n", dev->name, status & 0x07ff));
-				}
-				break;
-			    }
-			case CmdConfigure:
-			case CmdMulticastList:
-				/* Zap command so set_multicast_list() knows it is free */
-				ptr->command = 0;
-				break;
-			}
-			ptr->v_next = ptr->b_next = I596_NULL;
-			lp->last_cmd = jiffies;
-		}
-
-		ptr = lp->cmd_head;
-		while ((ptr != I596_NULL) && (ptr != lp->cmd_tail)) {
-			ptr->command &= 0x1fff;
-			ptr = ptr->v_next;
-		}
-
-		if ((lp->cmd_head != I596_NULL))
-			ack_cmd |= CUC_START;
-		lp->scb.cmd = WSWAPcmd(virt_to_bus(&lp->cmd_head->status));
-	}
-	if ((status & 0x1000) || (status & 0x4000)) {
-		if ((status & 0x4000))
-			DEB(DEB_INTS,printk(KERN_DEBUG "%s: i596 interrupt received a frame.\n", dev->name));
-		i596_rx(dev);
-		/* Only RX_START if stopped - RGH 07-07-96 */
-		if (status & 0x1000) {
-			if (netif_running(dev)) {
-				DEB(DEB_ERRORS,printk(KERN_ERR "%s: i596 interrupt receive unit inactive, status 0x%x\n", dev->name, status));
-				ack_cmd |= RX_START;
-				dev->stats.rx_errors++;
-				dev->stats.rx_fifo_errors++;
-				rebuild_rx_bufs(dev);
-			}
-		}
-	}
-	wait_cmd(dev,lp,100,"i596 interrupt, timeout");
-	lp->scb.command = ack_cmd;
-
-#ifdef ENABLE_MVME16x_NET
-	if (MACH_IS_MVME16x) {
-		/* Ack the interrupt */
-
-		volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
-
-		pcc2[0x2a] |= 0x08;
-	}
-#endif
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000) {
-		volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG;
-
-		*ethirq = 1;
-		*ethirq = 3;
-	}
-#endif
-#ifdef ENABLE_APRICOT
-	(void) inb(ioaddr + 0x10);
-	outb(4, ioaddr + 0xf);
-#endif
-	CA(dev);
-
-	DEB(DEB_INTS,printk(KERN_DEBUG "%s: exiting interrupt.\n", dev->name));
-
-	spin_unlock (&lp->lock);
-	return IRQ_RETVAL(handled);
-}
-
-static int i596_close(struct net_device *dev)
-{
-	struct i596_private *lp = dev->ml_priv;
-	unsigned long flags;
-
-	netif_stop_queue(dev);
-
-	DEB(DEB_INIT,printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
-		       dev->name, lp->scb.status));
-
-	spin_lock_irqsave(&lp->lock, flags);
-
-	wait_cmd(dev,lp,100,"close1 timed out");
-	lp->scb.command = CUC_ABORT | RX_ABORT;
-	CA(dev);
-
-	wait_cmd(dev,lp,100,"close2 timed out");
-
-	spin_unlock_irqrestore(&lp->lock, flags);
-	DEB(DEB_STRUCT,i596_display_data(dev));
-	i596_cleanup_cmd(dev,lp);
-
-#ifdef ENABLE_MVME16x_NET
-	if (MACH_IS_MVME16x) {
-		volatile unsigned char *pcc2 = (unsigned char *) 0xfff42000;
-
-		/* Disable all ints */
-		pcc2[0x28] = 1;
-		pcc2[0x2a] = 0x40;
-		pcc2[0x2b] = 0x40;	/* Set snooping bits now! */
-	}
-#endif
-#ifdef ENABLE_BVME6000_NET
-	if (MACH_IS_BVME6000) {
-		volatile unsigned char *ethirq = (unsigned char *) BVME_ETHIRQ_REG;
-
-		*ethirq = 1;
-	}
-#endif
-
-#ifdef ENABLE_MVME16x_NET
-	free_irq(0x56, dev);
-#endif
-	free_irq(dev->irq, dev);
-	remove_rx_bufs(dev);
-
-	return 0;
-}
-
-/*
- *    Set or clear the multicast filter for this adaptor.
- */
-
-static void set_multicast_list(struct net_device *dev)
-{
-	struct i596_private *lp = dev->ml_priv;
-	int config = 0, cnt;
-
-	DEB(DEB_MULTI,printk(KERN_DEBUG "%s: set multicast list, %d entries, promisc %s, allmulti %s\n",
-		dev->name, netdev_mc_count(dev),
-		dev->flags & IFF_PROMISC  ? "ON" : "OFF",
-		dev->flags & IFF_ALLMULTI ? "ON" : "OFF"));
-
-	if (wait_cfg(dev, &lp->cf_cmd.cmd, 1000, "config change request timed out"))
-		return;
-
-	if ((dev->flags & IFF_PROMISC) && !(lp->cf_cmd.i596_config[8] & 0x01)) {
-		lp->cf_cmd.i596_config[8] |= 0x01;
-		config = 1;
-	}
-	if (!(dev->flags & IFF_PROMISC) && (lp->cf_cmd.i596_config[8] & 0x01)) {
-		lp->cf_cmd.i596_config[8] &= ~0x01;
-		config = 1;
-	}
-	if ((dev->flags & IFF_ALLMULTI) && (lp->cf_cmd.i596_config[11] & 0x20)) {
-		lp->cf_cmd.i596_config[11] &= ~0x20;
-		config = 1;
-	}
-	if (!(dev->flags & IFF_ALLMULTI) && !(lp->cf_cmd.i596_config[11] & 0x20)) {
-		lp->cf_cmd.i596_config[11] |= 0x20;
-		config = 1;
-	}
-	if (config) {
-		lp->cf_cmd.cmd.command = CmdConfigure;
-		i596_add_cmd(dev, &lp->cf_cmd.cmd);
-	}
-
-	cnt = netdev_mc_count(dev);
-	if (cnt > MAX_MC_CNT)
-	{
-		cnt = MAX_MC_CNT;
-		printk(KERN_ERR "%s: Only %d multicast addresses supported",
-			dev->name, cnt);
-	}
-
-	if (!netdev_mc_empty(dev)) {
-		struct netdev_hw_addr *ha;
-		unsigned char *cp;
-		struct mc_cmd *cmd;
-
-		if (wait_cfg(dev, &lp->mc_cmd.cmd, 1000, "multicast list change request timed out"))
-			return;
-		cmd = &lp->mc_cmd;
-		cmd->cmd.command = CmdMulticastList;
-		cmd->mc_cnt = cnt * ETH_ALEN;
-		cp = cmd->mc_addrs;
-		netdev_for_each_mc_addr(ha, dev) {
-			if (!cnt--)
-				break;
-			memcpy(cp, ha->addr, ETH_ALEN);
-			if (i596_debug > 1)
-				DEB(DEB_MULTI,printk(KERN_INFO "%s: Adding address %pM\n",
-						dev->name, cp));
-			cp += ETH_ALEN;
-		}
-		i596_add_cmd(dev, &cmd->cmd);
-	}
-}
-
-#ifdef MODULE
-static struct net_device *dev_82596;
-
-#ifdef ENABLE_APRICOT
-module_param(irq, int, 0);
-MODULE_PARM_DESC(irq, "Apricot IRQ number");
-#endif
-
-static int debug = -1;
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug, "i82596 debug mask");
-
-int __init init_module(void)
-{
-	if (debug >= 0)
-		i596_debug = debug;
-	dev_82596 = i82596_probe(-1);
-	if (IS_ERR(dev_82596))
-		return PTR_ERR(dev_82596);
-	return 0;
-}
-
-void __exit cleanup_module(void)
-{
-	unregister_netdev(dev_82596);
-#ifdef __mc68000__
-	/* XXX This assumes default cache mode to be IOMAP_FULL_CACHING,
-	 * XXX which may be invalid (CONFIG_060_WRITETHROUGH)
-	 */
-
-	kernel_set_cachemode((void *)(dev_82596->mem_start), 4096,
-			IOMAP_FULL_CACHING);
-#endif
-	free_page ((u32)(dev_82596->mem_start));
-#ifdef ENABLE_APRICOT
-	/* If we don't do this, we can't re-insmod it later. */
-	release_region(dev_82596->base_addr, I596_TOTAL_SIZE);
-#endif
-	free_netdev(dev_82596);
-}
-
-#endif				/* MODULE */

+ 0 - 103
drivers/net/8390.c

@@ -1,103 +0,0 @@
-/* 8390 core for usual drivers */
-
-static const char version[] =
-    "8390.c:v1.10cvs 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
-
-#include "lib8390.c"
-
-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);
-
-netdev_tx_t ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	return __ei_start_xmit(skb, dev);
-}
-EXPORT_SYMBOL(ei_start_xmit);
-
-struct net_device_stats *ei_get_stats(struct net_device *dev)
-{
-	return __ei_get_stats(dev);
-}
-EXPORT_SYMBOL(ei_get_stats);
-
-void ei_set_multicast_list(struct net_device *dev)
-{
-	__ei_set_multicast_list(dev);
-}
-EXPORT_SYMBOL(ei_set_multicast_list);
-
-void ei_tx_timeout(struct net_device *dev)
-{
-	__ei_tx_timeout(dev);
-}
-EXPORT_SYMBOL(ei_tx_timeout);
-
-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
-
-const struct net_device_ops ei_netdev_ops = {
-	.ndo_open		= ei_open,
-	.ndo_stop		= ei_close,
-	.ndo_start_xmit		= ei_start_xmit,
-	.ndo_tx_timeout		= ei_tx_timeout,
-	.ndo_get_stats		= ei_get_stats,
-	.ndo_set_multicast_list = ei_set_multicast_list,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_change_mtu		= eth_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= ei_poll,
-#endif
-};
-EXPORT_SYMBOL(ei_netdev_ops);
-
-struct net_device *__alloc_ei_netdev(int size)
-{
-	struct net_device *dev = ____alloc_ei_netdev(size);
-	if (dev)
-		dev->netdev_ops = &ei_netdev_ops;
-	return dev;
-}
-EXPORT_SYMBOL(__alloc_ei_netdev);
-
-void NS8390_init(struct net_device *dev, int startp)
-{
-	__NS8390_init(dev, startp);
-}
-EXPORT_SYMBOL(NS8390_init);
-
-#if defined(MODULE)
-
-static int __init ns8390_module_init(void)
-{
-	return 0;
-}
-
-static void __exit ns8390_module_exit(void)
-{
-}
-
-module_init(ns8390_module_init);
-module_exit(ns8390_module_exit);
-#endif /* MODULE */
-MODULE_LICENSE("GPL");

+ 0 - 105
drivers/net/8390p.c

@@ -1,105 +0,0 @@
-/* 8390 core for ISA devices needing bus delays */
-
-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_inb_p(_p)	inb_p(_p)
-#define ei_outb_p(_v, _p) outb_p(_v, _p)
-
-#include "lib8390.c"
-
-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);
-
-netdev_tx_t eip_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
-	return __ei_start_xmit(skb, dev);
-}
-EXPORT_SYMBOL(eip_start_xmit);
-
-struct net_device_stats *eip_get_stats(struct net_device *dev)
-{
-	return __ei_get_stats(dev);
-}
-EXPORT_SYMBOL(eip_get_stats);
-
-void eip_set_multicast_list(struct net_device *dev)
-{
-	__ei_set_multicast_list(dev);
-}
-EXPORT_SYMBOL(eip_set_multicast_list);
-
-void eip_tx_timeout(struct net_device *dev)
-{
-	__ei_tx_timeout(dev);
-}
-EXPORT_SYMBOL(eip_tx_timeout);
-
-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
-
-const struct net_device_ops eip_netdev_ops = {
-	.ndo_open		= eip_open,
-	.ndo_stop		= eip_close,
-	.ndo_start_xmit		= eip_start_xmit,
-	.ndo_tx_timeout		= eip_tx_timeout,
-	.ndo_get_stats		= eip_get_stats,
-	.ndo_set_multicast_list = eip_set_multicast_list,
-	.ndo_validate_addr	= eth_validate_addr,
-	.ndo_set_mac_address 	= eth_mac_addr,
-	.ndo_change_mtu		= eth_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	= eip_poll,
-#endif
-};
-EXPORT_SYMBOL(eip_netdev_ops);
-
-struct net_device *__alloc_eip_netdev(int size)
-{
-	struct net_device *dev = ____alloc_ei_netdev(size);
-	if (dev)
-		dev->netdev_ops = &eip_netdev_ops;
-	return dev;
-}
-EXPORT_SYMBOL(__alloc_eip_netdev);
-
-void NS8390p_init(struct net_device *dev, int startp)
-{
-	__NS8390_init(dev, startp);
-}
-EXPORT_SYMBOL(NS8390p_init);
-
-static int __init NS8390p_init_module(void)
-{
-	return 0;
-}
-
-static void __exit NS8390p_cleanup_module(void)
-{
-}
-
-module_init(NS8390p_init_module);
-module_exit(NS8390p_cleanup_module);
-MODULE_LICENSE("GPL");

+ 166 - 3281
drivers/net/Kconfig

@@ -2,9 +2,6 @@
 # Network device configuration
 #
 
-config HAVE_NET_MACB
-	bool
-
 menuconfig NETDEVICES
 	default y if UML
 	depends on NET
@@ -28,18 +25,32 @@ menuconfig NETDEVICES
 # that for each of the symbols.
 if NETDEVICES
 
-config IFB
-	tristate "Intermediate Functional Block support"
-	depends on NET_CLS_ACT
+config NET_CORE
+	default y
+	bool "Network core driver support"
 	---help---
-	  This is an intermediate driver that allows sharing of
-	  resources.
+	  You can say N here if you do not intend to use any of the
+	  networking core drivers (i.e. VLAN, bridging, bonding, etc.)
+
+if NET_CORE
+
+config BONDING
+	tristate "Bonding driver support"
+	depends on INET
+	depends on IPV6 || IPV6=n
+	---help---
+	  Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet
+	  Channels together. This is called 'Etherchannel' by Cisco,
+	  'Trunking' by Sun, 802.3ad by the IEEE, and 'Bonding' in Linux.
+
+	  The driver supports multiple bonding modes to allow for both high
+	  performance and high availability operation.
+
+	  Refer to <file:Documentation/networking/bonding.txt> for more
+	  information.
+
 	  To compile this driver as a module, choose M here: the module
-	  will be called ifb.  If you want to use more than one ifb
-	  device at a time, you need to compile this driver as a module.
-	  Instead of 'ifb', the devices will then be called 'ifb0',
-	  'ifb1' etc.
-	  Look at the iproute2 documentation directory for usage etc
+	  will be called bonding.
 
 config DUMMY
 	tristate "Dummy net driver support"
@@ -60,23 +71,59 @@ config DUMMY
 	  Instead of 'dummy', the devices will then be called 'dummy0',
 	  'dummy1' etc.
 
-config BONDING
-	tristate "Bonding driver support"
-	depends on INET
-	depends on IPV6 || IPV6=n
+config EQUALIZER
+	tristate "EQL (serial line load balancing) support"
 	---help---
-	  Say 'Y' or 'M' if you wish to be able to 'bond' multiple Ethernet
-	  Channels together. This is called 'Etherchannel' by Cisco,
-	  'Trunking' by Sun, 802.3ad by the IEEE, and 'Bonding' in Linux.
+	  If you have two serial connections to some other computer (this
+	  usually requires two modems and two telephone lines) and you use
+	  SLIP (the protocol for sending Internet traffic over telephone
+	  lines) or PPP (a better SLIP) on them, you can make them behave like
+	  one double speed connection using this driver.  Naturally, this has
+	  to be supported at the other end as well, either with a similar EQL
+	  Linux driver or with a Livingston Portmaster 2e.
 
-	  The driver supports multiple bonding modes to allow for both high
-	  performance and high availability operation.
+	  Say Y if you want this and read
+	  <file:Documentation/networking/eql.txt>.  You may also want to read
+	  section 6.2 of the NET-3-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>.
 
-	  Refer to <file:Documentation/networking/bonding.txt> for more
-	  information.
+	  To compile this driver as a module, choose M here: the module
+	  will be called eql.  If unsure, say N.
+
+config NET_FC
+	bool "Fibre Channel driver support"
+	depends on SCSI && PCI
+	help
+	  Fibre Channel is a high speed serial protocol mainly used to connect
+	  large storage devices to the computer; it is compatible with and
+	  intended to replace SCSI.
 
+	  If you intend to use Fibre Channel, you need to have a Fibre channel
+	  adaptor card in your computer; say Y here and to the driver for your
+	  adaptor below. You also should have said Y to "SCSI support" and
+	  "SCSI generic support".
+
+config MII
+	tristate "Generic Media Independent Interface device support"
+	help
+	  Most ethernet controllers have MII transceiver either as an external
+	  or internal device.  It is safe to say Y or M here even if your
+	  ethernet card lacks MII.
+
+source "drivers/ieee802154/Kconfig"
+
+config IFB
+	tristate "Intermediate Functional Block support"
+	depends on NET_CLS_ACT
+	---help---
+	  This is an intermediate driver that allows sharing of
+	  resources.
 	  To compile this driver as a module, choose M here: the module
-	  will be called bonding.
+	  will be called ifb.  If you want to use more than one ifb
+	  device at a time, you need to compile this driver as a module.
+	  Instead of 'ifb', the devices will then be called 'ifb0',
+	  'ifb1' etc.
+	  Look at the iproute2 documentation directory for usage etc
 
 config MACVLAN
 	tristate "MAC-VLAN support (EXPERIMENTAL)"
@@ -105,24 +152,46 @@ config MACVTAP
 	  To compile this driver as a module, choose M here: the module
 	  will be called macvtap.
 
-config EQUALIZER
-	tristate "EQL (serial line load balancing) support"
+config NETCONSOLE
+	tristate "Network console logging support"
 	---help---
-	  If you have two serial connections to some other computer (this
-	  usually requires two modems and two telephone lines) and you use
-	  SLIP (the protocol for sending Internet traffic over telephone
-	  lines) or PPP (a better SLIP) on them, you can make them behave like
-	  one double speed connection using this driver.  Naturally, this has
-	  to be supported at the other end as well, either with a similar EQL
-	  Linux driver or with a Livingston Portmaster 2e.
+	If you want to log kernel messages over the network, enable this.
+	See <file:Documentation/networking/netconsole.txt> for details.
 
-	  Say Y if you want this and read
-	  <file:Documentation/networking/eql.txt>.  You may also want to read
-	  section 6.2 of the NET-3-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
+config NETCONSOLE_DYNAMIC
+	bool "Dynamic reconfiguration of logging targets"
+	depends on NETCONSOLE && SYSFS && CONFIGFS_FS && \
+			!(NETCONSOLE=y && CONFIGFS_FS=m)
+	help
+	  This option enables the ability to dynamically reconfigure target
+	  parameters (interface, IP addresses, port numbers, MAC addresses)
+	  at runtime through a userspace interface exported using configfs.
+	  See <file:Documentation/networking/netconsole.txt> for details.
 
-	  To compile this driver as a module, choose M here: the module
-	  will be called eql.  If unsure, say N.
+config NETPOLL
+	def_bool NETCONSOLE
+
+config NETPOLL_TRAP
+	bool "Netpoll traffic trapping"
+	default n
+	depends on NETPOLL
+
+config NET_POLL_CONTROLLER
+	def_bool NETPOLL
+
+config RIONET
+	tristate "RapidIO Ethernet over messaging driver support"
+	depends on RAPIDIO
+
+config RIONET_TX_SIZE
+	int "Number of outbound queue entries"
+	depends on RIONET
+	default "128"
+
+config RIONET_RX_SIZE
+	int "Number of inbound queue entries"
+	depends on RIONET
+	default "128"
 
 config TUN
 	tristate "Universal TUN/TAP device driver support"
@@ -154,6 +223,28 @@ config VETH
 	  When one end receives the packet it appears on its pair and vice
 	  versa.
 
+config VIRTIO_NET
+	tristate "Virtio network driver (EXPERIMENTAL)"
+	depends on EXPERIMENTAL && VIRTIO
+	---help---
+	  This is the virtual network driver for virtio.  It can be used with
+	  lguest or QEMU based VMMs (like KVM or Xen).  Say Y or M.
+
+endif # NET_CORE
+
+config SUNGEM_PHY
+	tristate
+
+source "drivers/net/arcnet/Kconfig"
+
+source "drivers/atm/Kconfig"
+
+source "drivers/net/caif/Kconfig"
+
+source "drivers/net/ethernet/Kconfig"
+
+source "drivers/net/fddi/Kconfig"
+
 config NET_SB1000
 	tristate "General Instruments Surfboard 1000"
 	depends on PNP
@@ -178,3271 +269,65 @@ config NET_SB1000
 
 	  If you don't have this card, of course say N.
 
-source "drivers/net/arcnet/Kconfig"
-
-config MII
-	tristate "Generic Media Independent Interface device support"
-	help
-	  Most ethernet controllers have MII transceiver either as an external
-	  or internal device.  It is safe to say Y or M here even if your
-	  ethernet card lacks MII.
-
 source "drivers/net/phy/Kconfig"
 
-#
-#	Ethernet
-#
-
-menuconfig NET_ETHERNET
-	bool "Ethernet (10 or 100Mbit)"
-	depends on !UML
-	---help---
-	  Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
-	  type of Local Area Network (LAN) in universities and companies.
-
-	  Common varieties of Ethernet are: 10BASE-2 or Thinnet (10 Mbps over
-	  coaxial cable, linking computers in a chain), 10BASE-T or twisted
-	  pair (10 Mbps over twisted pair cable, linking computers to central
-	  hubs), 10BASE-F (10 Mbps over optical fiber links, using hubs),
-	  100BASE-TX (100 Mbps over two twisted pair cables, using hubs),
-	  100BASE-T4 (100 Mbps over 4 standard voice-grade twisted pair
-	  cables, using hubs), 100BASE-FX (100 Mbps over optical fiber links)
-	  [the 100BASE varieties are also known as Fast Ethernet], and Gigabit
-	  Ethernet (1 Gbps over optical fiber or short copper links).
-
-	  If your Linux machine will be connected to an Ethernet and you have
-	  an Ethernet network interface card (NIC) installed in your computer,
-	  say Y here and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. You will then also have
-	  to say Y to the driver for your particular NIC.
-
-	  Note that the answer to this question won't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about Ethernet network cards. If unsure, say N.
-
-if NET_ETHERNET
-
-config MACB
-	tristate "Atmel MACB support"
-	depends on HAVE_NET_MACB
-	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.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called macb.
-
-source "drivers/net/arm/Kconfig"
-
-config AX88796
-	tristate "ASIX AX88796 NE2000 clone support"
-	depends on ARM || MIPS || SUPERH
-	select PHYLIB
-	select MDIO_BITBANG
-	help
-	  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
-	select CRC32
-	help
-	  Power Macintoshes and clones with Ethernet built-in on the
-	  motherboard will usually use a MACE (Medium Access Control for
-	  Ethernet) interface. Say Y to include support for the MACE chip.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called mace.
+source "drivers/net/plip/Kconfig"
 
-config MACE_AAUI_PORT
-	bool "Use AAUI port instead of TP by default"
-	depends on MACE
-	help
-	  Some Apple machines (notably the Apple Network Server) which use the
-	  MACE ethernet chip have an Apple AUI port (small 15-pin connector),
-	  instead of an 8-pin RJ45 connector for twisted-pair ethernet.  Say
-	  Y here if you have such a machine.  If unsure, say N.
-	  The driver will default to AAUI on ANS anyway, and if you use it as
-	  a module, you can provide the port_aaui=0|1 to force the driver.
-
-config BMAC
-	tristate "BMAC (G3 ethernet) support"
-	depends on PPC_PMAC && PPC32
-	select CRC32
-	help
-	  Say Y for support of BMAC Ethernet interfaces. These are used on G3
-	  computers.
+source "drivers/net/ppp/Kconfig"
 
-	  To compile this driver as a module, choose M here: the module
-	  will be called bmac.
+source "drivers/net/slip/Kconfig"
 
-config ARIADNE
-	tristate "Ariadne support"
-	depends on ZORRO
-	help
-	  If you have a Village Tronic Ariadne Ethernet adapter, say Y.
-	  Otherwise, say N.
+source "drivers/s390/net/Kconfig"
 
-	  To compile this driver as a module, choose M here: the module
-	  will be called ariadne.
+source "drivers/net/tokenring/Kconfig"
 
-config A2065
-	tristate "A2065 support"
-	depends on ZORRO
-	select CRC32
-	help
-	  If you have a Commodore A2065 Ethernet adapter, say Y. Otherwise,
-	  say N.
+source "drivers/net/usb/Kconfig"
 
-	  To compile this driver as a module, choose M here: the module
-	  will be called a2065.
+source "drivers/net/wireless/Kconfig"
 
-config HYDRA
-	tristate "Hydra support"
-	depends on ZORRO
-	select CRC32
-	help
-	  If you have a Hydra Ethernet adapter, say Y. Otherwise, say N.
+source "drivers/net/wimax/Kconfig"
 
-	  To compile this driver as a module, choose M here: the module
-	  will be called hydra.
+source "drivers/net/wan/Kconfig"
 
-config ZORRO8390
-	tristate "Zorro NS8390-based Ethernet support"
-	depends on ZORRO
-	select CRC32
+config XEN_NETDEV_FRONTEND
+	tristate "Xen network device frontend driver"
+	depends on XEN
+	select XEN_XENBUS_FRONTEND
+	default y
 	help
-	  This driver is for Zorro Ethernet cards using an NS8390-compatible
-	  chipset, like the Village Tronic Ariadne II and the Individual
-	  Computers X-Surf Ethernet cards. If you have such a card, say Y.
-	  Otherwise, say N.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called zorro8390.
+	  This driver provides support for Xen paravirtual network
+	  devices exported by a Xen network driver domain (often
+	  domain 0).
 
-config APNE
-	tristate "PCMCIA NE2000 support"
-	depends on AMIGA_PCMCIA
-	select CRC32
-	help
-	  If you have a PCMCIA NE2000 compatible adapter, say Y.  Otherwise,
-	  say N.
+	  The corresponding Linux backend driver is enabled by the
+	  CONFIG_XEN_NETDEV_BACKEND option.
 
-	  To compile this driver as a module, choose M here: the module
-	  will be called apne.
+	  If you are compiling a kernel for use as Xen guest, you
+	  should say Y here. To compile this driver as a module, chose
+	  M here: the module will be called xen-netfront.
 
-config MAC8390
-	bool "Macintosh NS 8390 based ethernet cards"
-	depends on MAC
-	select CRC32
+config XEN_NETDEV_BACKEND
+	tristate "Xen backend network device"
+	depends on XEN_BACKEND
 	help
-	  If you want to include a driver to support Nubus or LC-PDS
-	  Ethernet cards using an NS8390 chipset or its equivalent, say Y
-	  and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-config MAC89x0
-	tristate "Macintosh CS89x0 based ethernet cards"
-	depends on MAC
-	---help---
-	  Support for CS89x0 chipset based Ethernet cards.  If you have a
-	  Nubus or LC-PDS network (Ethernet) card of this type, say Y and
-	  read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. This module will
-	  be called mac89x0.
-
-config MACSONIC
-	tristate "Macintosh SONIC based ethernet (onboard, NuBus, LC, CS)"
-	depends on MAC
-	---help---
-	  Support for NatSemi SONIC based Ethernet devices.  This includes
-	  the onboard Ethernet in many Quadras as well as some LC-PDS,
-	  a few Nubus and all known Comm Slot Ethernet cards.  If you have
-	  one of these say Y and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. This module will
-	  be called macsonic.
+	  This driver allows the kernel to act as a Xen network driver
+	  domain which exports paravirtual network devices to other
+	  Xen domains. These devices can be accessed by any operating
+	  system that implements a compatible front end.
 
-config MACMACE
-	bool "Macintosh (AV) onboard MACE ethernet"
-	depends on MAC
-	select CRC32
-	help
-	  Support for the onboard AMD 79C940 MACE Ethernet controller used in
-	  the 660AV and 840AV Macintosh.  If you have one of these Macintoshes
-	  say Y and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
+	  The corresponding Linux frontend driver is enabled by the
+	  CONFIG_XEN_NETDEV_FRONTEND configuration option.
 
-config MVME147_NET
-	tristate "MVME147 (Lance) Ethernet support"
-	depends on MVME147
-	select CRC32
-	help
-	  Support for the on-board Ethernet interface on the Motorola MVME147
-	  single-board computer.  Say Y here to include the
-	  driver for this chip in your kernel.
-	  To compile this driver as a module, choose M here.
-
-config MVME16x_NET
-	tristate "MVME16x Ethernet support"
-	depends on MVME16x
-	help
-	  This is the driver for the Ethernet interface on the Motorola
-	  MVME162, 166, 167, 172 and 177 boards.  Say Y here to include the
-	  driver for this chip in your kernel.
-	  To compile this driver as a module, choose M here.
-
-config BVME6000_NET
-	tristate "BVME6000 Ethernet support"
-	depends on BVME6000
-	help
-	  This is the driver for the Ethernet interface on BVME4000 and
-	  BVME6000 VME boards.  Say Y here to include the driver for this chip
-	  in your kernel.
-	  To compile this driver as a module, choose M here.
-
-config ATARILANCE
-	tristate "Atari Lance support"
-	depends on ATARI
-	help
-	  Say Y to include support for several Atari Ethernet adapters based
-	  on the AMD Lance chipset: RieblCard (with or without battery), or
-	  PAMCard VME (also the version by Rhotron, with different addresses).
-
-config SUN3LANCE
-	tristate "Sun3/Sun3x on-board LANCE support"
-	depends on SUN3 || SUN3X
-	help
-	  Most Sun3 and Sun3x motherboards (including the 3/50, 3/60 and 3/80)
-	  featured an AMD Lance 10Mbit Ethernet controller on board; say Y
-	  here to compile in the Linux driver for this and enable Ethernet.
-	  General Linux information on the Sun 3 and 3x series (now
-	  discontinued) is at
-	  <http://www.angelfire.com/ca2/tech68k/sun3.html>.
-
-	  If you're not building a kernel for a Sun 3, say N.
-
-config SUN3_82586
-	bool "Sun3 on-board Intel 82586 support"
-	depends on SUN3
-	help
-	  This driver enables support for the on-board Intel 82586 based
-	  Ethernet adapter found on Sun 3/1xx and 3/2xx motherboards.  Note
-	  that this driver does not support 82586-based adapters on additional
-	  VME boards.
-
-config HPLANCE
-	bool "HP on-board LANCE support"
-	depends on DIO
-	select CRC32
-	help
-	  If you want to use the builtin "LANCE" Ethernet controller on an
-	  HP300 machine, say Y here.
-
-config LASI_82596
-	tristate "Lasi ethernet"
-	depends on GSC
-	help
-	  Say Y here to support the builtin Intel 82596 ethernet controller
-	  found in Hewlett-Packard PA-RISC machines with 10Mbit ethernet.
-
-config SNI_82596
-	tristate "SNI RM ethernet"
-	depends on NET_ETHERNET && SNI_RM
-	help
-	  Say Y here to support the on-board Intel 82596 ethernet controller
-	  built into SNI RM machines.
-
-config KORINA
-	tristate "Korina (IDT RC32434) Ethernet support"
-	depends on NET_ETHERNET && MIKROTIK_RB532
-	help
-	  If you have a Mikrotik RouterBoard 500 or IDT RC32434
-	  based system say Y. Otherwise say N.
-
-config MIPS_JAZZ_SONIC
-	tristate "MIPS JAZZ onboard SONIC Ethernet support"
-	depends on MACH_JAZZ
-	help
-	  This is the driver for the onboard card of MIPS Magnum 4000,
-	  Acer PICA, Olivetti M700-10 and a few other identical OEM systems.
-
-config XTENSA_XT2000_SONIC
-	tristate "Xtensa XT2000 onboard SONIC Ethernet support"
-	depends on XTENSA_PLATFORM_XT2000
-	help
-	  This is the driver for the onboard card of the Xtensa XT2000 board.
-
-config MIPS_AU1X00_ENET
-	tristate "MIPS AU1000 Ethernet support"
-	depends on MIPS_ALCHEMY
-	select PHYLIB
-	select CRC32
-	help
-	  If you have an Alchemy Semi AU1X00 based system
-	  say Y.  Otherwise, say N.
-
-config SGI_IOC3_ETH
-	bool "SGI IOC3 Ethernet"
-	depends on PCI && SGI_IP27
-	select CRC32
-	select MII
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-config MIPS_SIM_NET
-	tristate "MIPS simulator Network device"
-	depends on MIPS_SIM
-	help
-	  The MIPSNET device is a simple Ethernet network device which is
-	  emulated by the MIPS Simulator.
-	  If you are not using a MIPSsim or are unsure, say N.
-
-config SGI_O2MACE_ETH
-	tristate "SGI O2 MACE Fast Ethernet support"
-	depends on SGI_IP32=y
-
-config STNIC
-	tristate "National DP83902AV  support"
-	depends on SUPERH
-	select CRC32
-	help
-	  Support for cards based on the National Semiconductor DP83902AV
-	  ST-NIC Serial Network Interface Controller for Twisted Pair.  This
-	  is a 10Mbit/sec Ethernet controller.  Product overview and specs at
-	  <http://www.national.com/pf/DP/DP83902A.html>.
-
-	  If unsure, say N.
-
-config SH_ETH
-	tristate "Renesas SuperH Ethernet support"
-	depends on SUPERH && \
-		(CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \
-		 CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \
-		 CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7757)
-	select CRC32
-	select MII
-	select MDIO_BITBANG
-	select PHYLIB
-	help
-	  Renesas SuperH Ethernet device driver.
-	  This driver supporting CPUs are:
-		- SH7710, SH7712, SH7763, SH7619, SH7724, and SH7757.
-
-config SUNLANCE
-	tristate "Sun LANCE support"
-	depends on SBUS
-	select CRC32
-	help
-	  This driver supports the "le" interface present on all 32-bit Sparc
-	  systems, on some older Ultra systems and as an Sbus option.  These
-	  cards are based on the AMD Lance chipset, which is better known
-	  via the NE2100 cards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called sunlance.
-
-config HAPPYMEAL
-	tristate "Sun Happy Meal 10/100baseT support"
-	depends on SBUS || PCI
-	select CRC32
-	help
-	  This driver supports the "hme" interface present on most Ultra
-	  systems and as an option on older Sbus systems. This driver supports
-	  both PCI and Sbus devices. This driver also supports the "qfe" quad
-	  100baseT device available in both PCI and Sbus configurations.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called sunhme.
-
-config SUNBMAC
-	tristate "Sun BigMAC 10/100baseT support (EXPERIMENTAL)"
-	depends on SBUS && EXPERIMENTAL
-	select CRC32
-	help
-	  This driver supports the "be" interface available as an Sbus option.
-	  This is Sun's older 100baseT Ethernet device.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called sunbmac.
-
-config SUNQE
-	tristate "Sun QuadEthernet support"
-	depends on SBUS
-	select CRC32
-	help
-	  This driver supports the "qe" 10baseT Ethernet device, available as
-	  an Sbus option. Note that this is not the same as Quad FastEthernet
-	  "qfe" which is supported by the Happy Meal driver instead.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called sunqe.
-
-config SUNGEM
-	tristate "Sun GEM support"
-	depends on PCI
-	select CRC32
-	help
-	  Support for the Sun GEM chip, aka Sun GigabitEthernet/P 2.0.  See also
-	  <http://www.sun.com/products-n-solutions/hardware/docs/pdf/806-3985-10.pdf>.
-
-config CASSINI
-	tristate "Sun Cassini support"
-	depends on PCI
-	select CRC32
-	help
-	  Support for the Sun Cassini chip, aka Sun GigaSwift Ethernet. See also
-	  <http://www.sun.com/products-n-solutions/hardware/docs/pdf/817-4341-10.pdf>
-
-config SUNVNET
-	tristate "Sun Virtual Network support"
-	depends on SUN_LDOMS
-	help
-	  Support for virtual network devices under Sun Logical Domains.
-
-config NET_VENDOR_3COM
-	bool "3COM cards"
-	depends on ISA || EISA || MCA || PCI
-	help
-	  If you have a network (Ethernet) card belonging to this class, say Y
-	  and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about 3COM cards. If you say Y, you will be asked for
-	  your specific card in the following questions.
-
-config EL1
-	tristate "3c501 \"EtherLink\" support"
-	depends on NET_VENDOR_3COM && ISA
-	---help---
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.  Also, consider buying a
-	  new card, since the 3c501 is slow, broken, and obsolete: you will
-	  have problems.  Some people suggest to ping ("man ping") a nearby
-	  machine every minute ("man cron") when using this card.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called 3c501.
-
-config EL2
-	tristate "3c503 \"EtherLink II\" support"
-	depends on NET_VENDOR_3COM && ISA
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called 3c503.
-
-config ELPLUS
-	tristate "3c505 \"EtherLink Plus\" support"
-	depends on NET_VENDOR_3COM && ISA && ISA_DMA_API
-	---help---
-	  Information about this network (Ethernet) card can be found in
-	  <file:Documentation/networking/3c505.txt>.  If you have a card of
-	  this type, say Y and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called 3c505.
-
-config EL16
-	tristate "3c507 \"EtherLink 16\" support (EXPERIMENTAL)"
-	depends on NET_VENDOR_3COM && ISA && EXPERIMENTAL
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called 3c507.
-
-config EL3
-	tristate "3c509/3c529 (MCA)/3c579 \"EtherLink III\" support"
-	depends on NET_VENDOR_3COM && (ISA || EISA || MCA)
-	---help---
-	  If you have a network (Ethernet) card belonging to the 3Com
-	  EtherLinkIII series, say Y and read the Ethernet-HOWTO, available
-	  from <http://www.tldp.org/docs.html#howto>.
-
-	  If your card is not working you may need to use the DOS
-	  setup disk to disable Plug & Play mode, and to select the default
-	  media type.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called 3c509.
-
-config 3C515
-	tristate "3c515 ISA \"Fast EtherLink\""
-	depends on NET_VENDOR_3COM && (ISA || EISA) && ISA_DMA_API
-	help
-	  If you have a 3Com ISA EtherLink XL "Corkscrew" 3c515 Fast Ethernet
-	  network card, say Y and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called 3c515.
-
-config ELMC
-	tristate "3c523 \"EtherLink/MC\" support"
-	depends on NET_VENDOR_3COM && MCA_LEGACY
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called 3c523.
-
-config ELMC_II
-	tristate "3c527 \"EtherLink/MC 32\" support (EXPERIMENTAL)"
-	depends on NET_VENDOR_3COM && MCA && MCA_LEGACY
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called 3c527.
-
-config VORTEX
-	tristate "3c590/3c900 series (592/595/597) \"Vortex/Boomerang\" support"
-	depends on NET_VENDOR_3COM && (PCI || EISA)
-	select MII
-	---help---
-	  This option enables driver support for a large number of 10Mbps and
-	  10/100Mbps EISA, PCI and PCMCIA 3Com network cards:
-
-	  "Vortex"    (Fast EtherLink 3c590/3c592/3c595/3c597) EISA and PCI
-	  "Boomerang" (EtherLink XL 3c900 or 3c905)            PCI
-	  "Cyclone"   (3c540/3c900/3c905/3c980/3c575/3c656)    PCI and Cardbus
-	  "Tornado"   (3c905)                                  PCI
-	  "Hurricane" (3c555/3cSOHO)                           PCI
-
-	  If you have such a card, say Y and read the Ethernet-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>. More
-	  specific information is in
-	  <file:Documentation/networking/vortex.txt> and in the comments at
-	  the beginning of <file:drivers/net/3c59x.c>.
-
-	  To compile this support as a module, choose M here.
-
-config TYPHOON
-	tristate "3cr990 series \"Typhoon\" support"
-	depends on NET_VENDOR_3COM && PCI
-	select CRC32
-	---help---
-	  This option enables driver support for the 3cr990 series of cards:
-
-	  3C990-TX, 3CR990-TX-95, 3CR990-TX-97, 3CR990-FX-95, 3CR990-FX-97,
-	  3CR990SVR, 3CR990SVR95, 3CR990SVR97, 3CR990-FX-95 Server,
-	  3CR990-FX-97 Server, 3C990B-TX-M, 3C990BSVR
-
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called typhoon.
-
-config LANCE
-	tristate "AMD LANCE and PCnet (AT1500 and NE2100) support"
-	depends on ISA && ISA_DMA_API
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. Some LinkSys cards are
-	  of this type.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called lance.  This is recommended.
-
-config NET_VENDOR_SMC
-	bool "Western Digital/SMC cards"
-	depends on ISA || MCA || EISA || MAC
-	help
-	  If you have a network (Ethernet) card belonging to this class, say Y
-	  and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about Western Digital cards. If you say Y, you will be
-	  asked for your specific card in the following questions.
-
-config WD80x3
-	tristate "WD80*3 support"
-	depends on NET_VENDOR_SMC && ISA
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called wd.
-
-config ULTRAMCA
-	tristate "SMC Ultra MCA support"
-	depends on NET_VENDOR_SMC && MCA
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type and are running
-	  an MCA based system (PS/2), say Y and read the Ethernet-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called smc-mca.
-
-config ULTRA
-	tristate "SMC Ultra support"
-	depends on NET_VENDOR_SMC && ISA
-	select CRC32
-	---help---
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Important: There have been many reports that, with some motherboards
-	  mixing an SMC Ultra and an Adaptec AHA154x SCSI card (or compatible,
-	  such as some BusLogic models) causes corruption problems with many
-	  operating systems. The Linux smc-ultra driver has a work-around for
-	  this but keep it in mind if you have such a SCSI card and have
-	  problems.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called smc-ultra.
-
-config ULTRA32
-	tristate "SMC Ultra32 EISA support"
-	depends on NET_VENDOR_SMC && EISA
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called smc-ultra32.
-
-config BFIN_MAC
-	tristate "Blackfin on-chip MAC support"
-	depends on NET_ETHERNET && (BF516 || BF518 || BF526 || BF527 || BF536 || BF537)
-	select CRC32
-	select MII
-	select PHYLIB
-	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 && (BF527 || BF537)
-	default y
-	help
-	  To get maximum network performance, 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_USE_HWSTAMP
-	bool "Use IEEE 1588 hwstamp"
-	depends on BFIN_MAC && BF518
-	default y
-	help
-	  To support the IEEE 1588 Precision Time Protocol (PTP), select y here
-
-config SMC9194
-	tristate "SMC 9194 support"
-	depends on NET_VENDOR_SMC && (ISA || MAC && BROKEN)
-	select CRC32
-	---help---
-	  This is support for the SMC9xxx based Ethernet cards. Choose this
-	  option if you have a DELL laptop with the docking station, or
-	  another SMC9192/9194 based chipset.  Say Y if you want it compiled
-	  into the kernel, and read the file
-	  <file:Documentation/networking/smc9.txt> and the Ethernet-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called smc9194.
-
-config SMC91X
-	tristate "SMC 91C9x/91C1xxx support"
-	select CRC32
-	select MII
-	depends on ARM || M32R || SUPERH || \
-		MIPS || BLACKFIN || MN10300 || COLDFIRE
-	help
-	  This is a driver for SMC's 91x series of Ethernet chipsets,
-	  including the SMC91C94 and the SMC91C111. Say Y if you want it
-	  compiled into the kernel, and read the file
-	  <file:Documentation/networking/smc9.txt>  and the Ethernet-HOWTO,
-	  available from  <http://www.tldp.org/docs.html#howto>.
-
-	  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 smc91x.  If you want to compile it as a
-	  module, say M here and read <file:Documentation/kbuild/modules.txt>.
-
-config PXA168_ETH
-	tristate "Marvell pxa168 ethernet support"
-	depends on CPU_PXA168
-	select PHYLIB
-	help
-	  This driver supports the pxa168 Ethernet ports.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called pxa168_eth.
-
-config NET_NETX
-	tristate "NetX Ethernet support"
-	select MII
-	depends on ARCH_NETX
-	help
-	  This is support for the Hilscher netX builtin Ethernet ports
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called netx-eth.
-
-config TI_DAVINCI_EMAC
-	tristate "TI DaVinci EMAC Support"
-	depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
-	select TI_DAVINCI_MDIO
-	select TI_DAVINCI_CPDMA
-	select PHYLIB
-	help
-	  This driver supports TI's DaVinci Ethernet .
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called davinci_emac_driver.  This is recommended.
-
-config TI_DAVINCI_MDIO
-	tristate "TI DaVinci MDIO Support"
-	depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
-	select PHYLIB
-	help
-	  This driver supports TI's DaVinci MDIO module.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called davinci_mdio.  This is recommended.
-
-config TI_DAVINCI_CPDMA
-	tristate "TI DaVinci CPDMA Support"
-	depends on ARM && ( ARCH_DAVINCI || ARCH_OMAP3 )
-	help
-	  This driver supports TI's DaVinci CPDMA dma engine.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called davinci_cpdma.  This is recommended.
-
-config DM9000
-	tristate "DM9000 support"
-	depends on ARM || BLACKFIN || MIPS
-	select CRC32
-	select MII
-	---help---
-	  Support for DM9000 chipset.
-
-	  To compile this driver as a module, choose M here.  The module
-	  will be called dm9000.
-
-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 DM9000_FORCE_SIMPLE_PHY_POLL
-	bool "Force simple NSR based PHY polling"
-	depends on DM9000
-	---help---
-	  This configuration forces the DM9000 to use the NSR's LinkStatus
-	  bit to determine if the link is up or down instead of the more
-	  costly MII PHY reads. Note, this will not work if the chip is
-	  operating with an external PHY.
-
-config ENC28J60
-	tristate "ENC28J60 support"
-	depends on EXPERIMENTAL && SPI && NET_ETHERNET
-	select CRC32
-	---help---
-	  Support for the Microchip EN28J60 ethernet chip.
-
-	  To compile this driver as a module, choose M here. The module will be
-	  called enc28j60.
-
-config ENC28J60_WRITEVERIFY
-	bool "Enable write verify"
-	depends on ENC28J60
-	---help---
-	  Enable the verify after the buffer write useful for debugging purpose.
-	  If unsure, say N.
-
-config ETHOC
-	tristate "OpenCores 10/100 Mbps Ethernet MAC support"
-	depends on NET_ETHERNET && HAS_IOMEM && HAS_DMA
-	select MII
-	select PHYLIB
-	select CRC32
-	select BITREVERSE
-	help
-	  Say Y here if you want to use the OpenCores 10/100 Mbps Ethernet MAC.
-
-config GRETH
-	tristate "Aeroflex Gaisler GRETH Ethernet MAC support"
-	depends on SPARC
-	select PHYLIB
-	select CRC32
-	help
-	  Say Y here if you want to use the Aeroflex Gaisler GRETH Ethernet MAC.
-
-config SMC911X
-	tristate "SMSC LAN911[5678] support"
-	select CRC32
-	select MII
-	depends on ARM || SUPERH || MN10300
-	help
-	  This is a driver for SMSC's LAN911x series of Ethernet chipsets
-	  including the new LAN9115, LAN9116, LAN9117, and LAN9118.
-	  Say Y if you want it compiled into the kernel, 
-	  and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  This driver is also available as a module. The module will be 
-	  called smc911x.  If you want to compile it as a module, say M 
-	  here and read <file:Documentation/kbuild/modules.txt>
-
-config SMSC911X
-	tristate "SMSC LAN911x/LAN921x families embedded ethernet support"
-	depends on ARM || SUPERH || BLACKFIN || MIPS || MN10300
-	select CRC32
-	select MII
-	select PHYLIB
-	---help---
-	  Say Y here if you want support for SMSC LAN911x and LAN921x families
-	  of ethernet controllers.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called smsc911x.
-
-config SMSC911X_ARCH_HOOKS
-	def_bool n
-	depends on SMSC911X
-	help
-	  If the arch enables this, it allows the arch to implement various
-	  hooks for more comprehensive interrupt control and also to override
-	  the source of the MAC address.
-
-config NET_VENDOR_RACAL
-	bool "Racal-Interlan (Micom) NI cards"
-	depends on ISA
-	help
-	  If you have a network (Ethernet) card belonging to this class, such
-	  as the NI5010, NI5210 or NI6210, say Y and read the Ethernet-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about NI cards. If you say Y, you will be asked for
-	  your specific card in the following questions.
-
-config NI5010
-	tristate "NI5010 support (EXPERIMENTAL)"
-	depends on NET_VENDOR_RACAL && ISA && EXPERIMENTAL && BROKEN_ON_SMP
-	---help---
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. Note that this is still
-	  experimental code.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ni5010.
-
-config NI52
-	tristate "NI5210 support"
-	depends on NET_VENDOR_RACAL && ISA
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ni52.
-
-config NI65
-	tristate "NI6510 support"
-	depends on NET_VENDOR_RACAL && ISA && ISA_DMA_API
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ni65.
-
-config DNET
-	tristate "Dave ethernet support (DNET)"
-	depends on NET_ETHERNET && HAS_IOMEM
-	select PHYLIB
-	help
-	  The Dave ethernet interface (DNET) is found on Qong Board FPGA.
-	  Say Y to include support for the DNET chip.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called dnet.
-
-source "drivers/net/tulip/Kconfig"
-
-config AT1700
-	tristate "AT1700/1720 support (EXPERIMENTAL)"
-	depends on (ISA || MCA_LEGACY) && EXPERIMENTAL
-	select CRC32
-	---help---
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called at1700.
-
-config DEPCA
-	tristate "DEPCA, DE10x, DE200, DE201, DE202, DE422 support"
-	depends on ISA || EISA || MCA
-	select CRC32
-	---help---
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto> as well as
-	  <file:drivers/net/depca.c>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called depca.
-
-config HP100
-	tristate "HP 10/100VG PCLAN (ISA, EISA, PCI) support"
-	depends on ISA || EISA || PCI
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called hp100.
-
-config NET_ISA
-	bool "Other ISA cards"
-	depends on ISA
-	---help---
-	  If your network (Ethernet) card hasn't been mentioned yet and its
-	  bus system (that's the way the cards talks to the other components
-	  of your computer) is ISA (as opposed to EISA, VLB or PCI), say Y.
-	  Make sure you know the name of your card. Read the Ethernet-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>.
-
-	  If unsure, say Y.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the remaining ISA network card questions. If you say Y, you will be
-	  asked for your specific card in the following questions.
-
-config E2100
-	tristate "Cabletron E21xx support"
-	depends on NET_ISA
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called e2100.
-
-config EWRK3
-	tristate "EtherWORKS 3 (DE203, DE204, DE205) support"
-	depends on NET_ISA
-	select CRC32
-	---help---
-	  This driver supports the DE203, DE204 and DE205 network (Ethernet)
-	  cards. If this is for you, say Y and read
-	  <file:Documentation/networking/ewrk3.txt> in the kernel source as
-	  well as the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ewrk3.
-
-config EEXPRESS
-	tristate "EtherExpress 16 support"
-	depends on NET_ISA
-	---help---
-	  If you have an EtherExpress16 network (Ethernet) card, say Y and
-	  read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.  Note that the Intel
-	  EtherExpress16 card used to be regarded as a very poor choice
-	  because the driver was very unreliable. We now have a new driver
-	  that should do better.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called eexpress.
-
-config EEXPRESS_PRO
-	tristate "EtherExpressPro support/EtherExpress 10 (i82595) support"
-	depends on NET_ISA
-	---help---
-	  If you have a network (Ethernet) card of this type, say Y. This
-	  driver supports Intel i82595{FX,TX} based boards. Note however
-	  that the EtherExpress PRO/100 Ethernet card has its own separate
-	  driver.  Please read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called eepro.
-
-config HPLAN_PLUS
-	tristate "HP PCLAN+ (27247B and 27252A) support"
-	depends on NET_ISA
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called hp-plus.
-
-config HPLAN
-	tristate "HP PCLAN (27245 and other 27xxx series) support"
-	depends on NET_ISA
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called hp.
-
-config LP486E
-	tristate "LP486E on board Ethernet"
-	depends on NET_ISA
-	help
-	  Say Y here to support the 82596-based on-board Ethernet controller
-	  for the Panther motherboard, which is one of the two shipped in the
-	  Intel Professional Workstation.
-
-config ETH16I
-	tristate "ICL EtherTeam 16i/32 support"
-	depends on NET_ISA
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called eth16i.
-
-config NE2000
-	tristate "NE2000/NE1000 support"
-	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
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.  Many Ethernet cards
-	  without a specific driver are compatible with NE2000.
-
-	  If you have a PCI NE2000 card however, say N here and Y to "PCI
-	  NE2000 and clone support" under "EISA, VLB, PCI and on board
-	  controllers" below. If you have a NE2000 card and are running on
-	  an MCA system (a bus system used on some IBM PS/2 computers and
-	  laptops), say N here and Y to "NE/2 (ne2000 MCA version) support",
-	  below.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ne.
-
-config ZNET
-	tristate "Zenith Z-Note support (EXPERIMENTAL)"
-	depends on NET_ISA && EXPERIMENTAL && ISA_DMA_API
-	help
-	  The Zenith Z-Note notebook computer has a built-in network
-	  (Ethernet) card, and this is the Linux driver for it. Note that the
-	  IBM Thinkpad 300 is compatible with the Z-Note and is also supported
-	  by this driver. Read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-config SEEQ8005
-	tristate "SEEQ8005 support (EXPERIMENTAL)"
-	depends on NET_ISA && EXPERIMENTAL
-	help
-	  This is a driver for the SEEQ 8005 network (Ethernet) card.  If this
-	  is for you, read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called seeq8005.
-
-config NE2_MCA
-	tristate "NE/2 (ne2000 MCA version) support"
-	depends on MCA_LEGACY
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ne2.
-
-config IBMLANA
-	tristate "IBM LAN Adapter/A support"
-	depends on MCA
-	---help---
-	  This is a Micro Channel Ethernet adapter.  You need to set
-	  CONFIG_MCA to use this driver.  It is both available as an in-kernel
-	  driver and as a module.
-
-	  To compile this driver as a module, choose M here. The only
-	  currently supported card is the IBM LAN Adapter/A for Ethernet.  It
-	  will both support 16K and 32K memory windows, however a 32K window
-	  gives a better security against packet losses.  Usage of multiple
-	  boards with this driver should be possible, but has not been tested
-	  up to now due to lack of hardware.
-
-config IBMVETH
-	tristate "IBM LAN Virtual Ethernet support"
-	depends on PPC_PSERIES
-	---help---
-	  This driver supports virtual ethernet adapters on newer IBM iSeries
-	  and pSeries systems.
-
-	  To compile this driver as a module, choose M here. The module will
-	  be called ibmveth.
-
-source "drivers/net/ibm_newemac/Kconfig"
-
-config NET_PCI
-	bool "EISA, VLB, PCI and on board controllers"
-	depends on ISA || EISA || PCI
-	help
-	  This is another class of network cards which attach directly to the
-	  bus. If you have one of those, say Y and read the Ethernet-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about this class of network cards. If you say Y, you
-	  will be asked for your specific card in the following questions. If
-	  you are unsure, say Y.
-
-config PCNET32
-	tristate "AMD PCnet32 PCI support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select MII
-	help
-	  If you have a PCnet32 or PCnetPCI based network (Ethernet) card,
-	  answer Y here and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called pcnet32.
-
-config AMD8111_ETH
-	tristate "AMD 8111 (new PCI lance) support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select MII
-	help
-	  If you have an AMD 8111-based PCI lance ethernet card,
-	  answer Y here and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called amd8111e.
-
-config ADAPTEC_STARFIRE
-	tristate "Adaptec Starfire/DuraLAN support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select MII
-	help
-	  Say Y here if you have an Adaptec Starfire (or DuraLAN) PCI network
-	  adapter. The DuraLAN chip is used on the 64 bit PCI boards from
-	  Adaptec e.g. the ANA-6922A. The older 32 bit boards use the tulip
-	  driver.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called starfire.  This is recommended.
-
-config AC3200
-	tristate "Ansel Communications EISA 3200 support (EXPERIMENTAL)"
-	depends on NET_PCI && (ISA || EISA) && EXPERIMENTAL
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ac3200.
-
-config KSZ884X_PCI
-	tristate "Micrel KSZ8841/2 PCI"
-	depends on NET_PCI && PCI
-	select MII
-	select CRC32
-	help
-	  This PCI driver is for Micrel KSZ8841/KSZ8842 PCI Ethernet chip.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ksz884x.
-
-config APRICOT
-	tristate "Apricot Xen-II on board Ethernet"
-	depends on NET_PCI && ISA
-	help
-	  If you have a network (Ethernet) controller of this type, say Y and
-	  read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called apricot.
-
-config B44
-	tristate "Broadcom 440x/47xx ethernet support"
-	depends on SSB_POSSIBLE && HAS_DMA
-	select SSB
-	select MII
-	help
-	  If you have a network (Ethernet) controller of this type, say Y
-	  or M and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called b44.
-
-# Auto-select SSB PCI-HOST support, if possible
-config B44_PCI_AUTOSELECT
-	bool
-	depends on B44 && SSB_PCIHOST_POSSIBLE
-	select SSB_PCIHOST
-	default y
-
-# Auto-select SSB PCICORE driver, if possible
-config B44_PCICORE_AUTOSELECT
-	bool
-	depends on B44 && SSB_DRIVER_PCICORE_POSSIBLE
-	select SSB_DRIVER_PCICORE
-	default y
-
-config B44_PCI
-	bool
-	depends on B44_PCI_AUTOSELECT && B44_PCICORE_AUTOSELECT
-	default y
-
-config FORCEDETH
-	tristate "nForce Ethernet support"
-	depends on NET_PCI && PCI
-	help
-	  If you have a network (Ethernet) controller of this type, say Y and
-	  read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called forcedeth.
-
-config CS89x0
-	tristate "CS89x0 support"
-	depends on NET_ETHERNET && (ISA || EISA || MACH_IXDP2351 \
-		|| ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440)
-	---help---
-	  Support for CS89x0 chipset based Ethernet cards. If you have a
-	  network (Ethernet) card of this type, say Y and read the
-	  Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto> as well as
-	  <file:Documentation/networking/cs89x0.txt>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called cs89x0.
-
-config CS89x0_NONISA_IRQ
-	def_bool y
-	depends on CS89x0 != n
-	depends on MACH_IXDP2351 || ARCH_IXDP2X01 || MACH_MX31ADS || MACH_QQ2440
-
-config TC35815
-	tristate "TOSHIBA TC35815 Ethernet support"
-	depends on NET_PCI && PCI && MIPS
-	select PHYLIB
-
-config E100
-	tristate "Intel(R) PRO/100+ support"
-	depends on NET_PCI && PCI
-	select MII
-	---help---
-	  This driver supports Intel(R) PRO/100 family of adapters.
-	  To verify that your adapter is supported, find the board ID number 
-	  on the adapter. Look for a label that has a barcode and a number 
-	  in the format 123456-001 (six digits hyphen three digits). 
-
-	  Use the above information and the Adapter & Driver ID Guide at:
-
-	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-	  to identify the adapter.
-
-	  For the latest Intel PRO/100 network driver for Linux, see:
-
-	  <http://www.intel.com/p/en_US/support/highlights/network/pro100plus>
-
-	  More specific information on configuring the driver is in 
-	  <file:Documentation/networking/e100.txt>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called e100.
-
-config LNE390
-	tristate "Mylex EISA LNE390A/B support (EXPERIMENTAL)"
-	depends on NET_PCI && EISA && EXPERIMENTAL
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called lne390.
-
-config FEALNX
-	tristate "Myson MTD-8xx PCI Ethernet support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select MII
-	help
-	  Say Y here to support the Myson MTD-800 family of PCI-based Ethernet 
-	  cards. <http://www.myson.com.tw/>
-
-config NATSEMI
-	tristate "National Semiconductor DP8381x series PCI Ethernet support"
-	depends on NET_PCI && PCI
-	select CRC32
-	help
-	  This driver is for the National Semiconductor DP83810 series,
-	  which is used in cards from PureData, NetGear, Linksys
-	  and others, including the 83815 chip.
-	  More specific information and updates are available from
-	  <http://www.scyld.com/network/natsemi.html>.
-
-config NE2K_PCI
-	tristate "PCI NE2000 and clones support (see help)"
-	depends on NET_PCI && PCI
-	select CRC32
-	---help---
-	  This driver is for NE2000 compatible PCI cards. It will not work
-	  with ISA NE2000 cards (they have their own driver, "NE2000/NE1000
-	  support" below). If you have a PCI NE2000 network (Ethernet) card,
-	  say Y and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  This driver also works for the following NE2000 clone cards:
-	  RealTek RTL-8029  Winbond 89C940  Compex RL2000  KTI ET32P2
-	  NetVin NV5000SC   Via 86C926      SureCom NE34   Winbond
-	  Holtek HT80232    Holtek HT80229
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ne2k-pci.
-
-config NE3210
-	tristate "Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)"
-	depends on NET_PCI && EISA && EXPERIMENTAL
-	select CRC32
-	---help---
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.  Note that this driver
-	  will NOT WORK for NE3200 cards as they are completely different.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ne3210.
-
-config ES3210
-	tristate "Racal-Interlan EISA ES3210 support (EXPERIMENTAL)"
-	depends on NET_PCI && EISA && EXPERIMENTAL
-	select CRC32
-	help
-	  If you have a network (Ethernet) card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called es3210.
-
-config 8139CP
-	tristate "RealTek RTL-8139 C+ PCI Fast Ethernet Adapter support (EXPERIMENTAL)"
-	depends on NET_PCI && PCI && EXPERIMENTAL
-	select CRC32
-	select MII
-	help
-	  This is a driver for the Fast Ethernet PCI network cards based on
-	  the RTL8139C+ chips. If you have one of those, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called 8139cp.  This is recommended.
-
-config 8139TOO
-	tristate "RealTek RTL-8129/8130/8139 PCI Fast Ethernet Adapter support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select MII
-	---help---
-	  This is a driver for the Fast Ethernet PCI network cards based on
-	  the RTL 8129/8130/8139 chips. If you have one of those, say Y and
-	  read the Ethernet-HOWTO <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called 8139too.  This is recommended.
-
-config 8139TOO_PIO
-	bool "Use PIO instead of MMIO"
-	default y
-	depends on 8139TOO
-	help
-	  This instructs the driver to use programmed I/O ports (PIO) instead
-	  of PCI shared memory (MMIO).  This can possibly solve some problems
-	  in case your mainboard has memory consistency issues.  If unsure,
-	  say N.
-
-config 8139TOO_TUNE_TWISTER
-	bool "Support for uncommon RTL-8139 rev. K (automatic channel equalization)"
-	depends on 8139TOO
-	help
-	  This implements a function which might come in handy in case you
-	  are using low quality on long cabling. It is required for RealTek
-	  RTL-8139 revision K boards, and totally unused otherwise.  It tries
-	  to match the transceiver to the cable characteristics. This is
-	  experimental since hardly documented by the manufacturer.
-	  If unsure, say Y.
-
-config 8139TOO_8129
-	bool "Support for older RTL-8129/8130 boards"
-	depends on 8139TOO
-	help
-	  This enables support for the older and uncommon RTL-8129 and
-	  RTL-8130 chips, which support MII via an external transceiver,
-	  instead of an internal one.  Disabling this option will save some
-	  memory by making the code size smaller.  If unsure, say Y.
-
-config 8139_OLD_RX_RESET
-	bool "Use older RX-reset method"
-	depends on 8139TOO
-	help
-	  The 8139too driver was recently updated to contain a more rapid
-	  reset sequence, in the face of severe receive errors.  This "new"
-	  RX-reset method should be adequate for all boards.  But if you
-	  experience problems, you can enable this option to restore the
-	  old RX-reset behavior.  If unsure, say N.
-
-config R6040
-	tristate "RDC R6040 Fast Ethernet Adapter support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select MII
-	select PHYLIB
-	help
-	  This is a driver for the R6040 Fast Ethernet MACs found in the
-	  the RDC R-321x System-on-chips.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called r6040. This is recommended.
-
-config SIS900
-	tristate "SiS 900/7016 PCI Fast Ethernet Adapter support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select MII
-	---help---
-	  This is a driver for the Fast Ethernet PCI network cards based on
-	  the SiS 900 and SiS 7016 chips. The SiS 900 core is also embedded in
-	  SiS 630 and SiS 540 chipsets.
-
-	  This driver also supports AMD 79C901 HomePNA so that you can use
-	  your phone line as a network cable.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called sis900.  This is recommended.
-
-config EPIC100
-	tristate "SMC EtherPower II"
-	depends on NET_PCI && PCI
-	select CRC32
-	select MII
-	help
-	  This driver is for the SMC EtherPower II 9432 PCI Ethernet NIC,
-	  which is based on the SMC83c17x (EPIC/100).
-	  More specific information and updates are available from
-	  <http://www.scyld.com/network/epic100.html>.
-
-config SMSC9420
-	tristate "SMSC LAN9420 PCI ethernet adapter support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select PHYLIB
-	select SMSC_PHY
-	help
-	  This is a driver for SMSC's LAN9420 PCI ethernet adapter.
-	  Say Y if you want it compiled into the kernel,
-	  and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  This driver is also available as a module. The module will be
-	  called smsc9420.  If you want to compile it as a module, say M
-	  here and read <file:Documentation/kbuild/modules.txt>
-
-config SUNDANCE
-	tristate "Sundance Alta support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select MII
-	help
-	  This driver is for the Sundance "Alta" chip.
-	  More specific information and updates are available from
-	  <http://www.scyld.com/network/sundance.html>.
-
-config SUNDANCE_MMIO
-	bool "Use MMIO instead of PIO"
-	depends on SUNDANCE
-	help
-	  Enable memory-mapped I/O for interaction with Sundance NIC registers.
-	  Do NOT enable this by default, PIO (enabled when MMIO is disabled)
-	  is known to solve bugs on certain chips.
-
-	  If unsure, say N.
-
-config TLAN
-	tristate "TI ThunderLAN support"
-	depends on NET_PCI && (PCI || EISA)
-	---help---
-	  If you have a PCI Ethernet network card based on the ThunderLAN chip
-	  which is supported by this driver, say Y and read the
-	  Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  Devices currently supported by this driver are Compaq Netelligent,
-	  Compaq NetFlex and Olicom cards.  Please read the file
-	  <file:Documentation/networking/tlan.txt> for more details.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called tlan.
-
-	  Please email feedback to <torben.mathiasen@compaq.com>.
-
-config KS8842
-	tristate "Micrel KSZ8841/42 with generic bus interface"
-	depends on HAS_IOMEM && DMA_ENGINE
-	help
-	  This platform driver is for KSZ8841(1-port) / KS8842(2-port)
-	  ethernet switch chip (managed, VLAN, QoS) from Micrel or
-	  Timberdale(FPGA).
-
-config KS8851
-	tristate "Micrel KS8851 SPI"
-	depends on SPI
-	select MII
-	select CRC32
-	help
-	  SPI driver for Micrel KS8851 SPI attached network chip.
-
-config KS8851_MLL
-	tristate "Micrel KS8851 MLL"
-	depends on HAS_IOMEM
-	select MII
-	help
-	  This platform driver is for Micrel KS8851 Address/data bus
-	  multiplexed network chip.
-
-config VIA_RHINE
-	tristate "VIA Rhine support"
-	depends on NET_PCI && PCI
-	select CRC32
-	select MII
-	help
-	  If you have a VIA "Rhine" based network card (Rhine-I (VT86C100A),
-	  Rhine-II (VT6102), or Rhine-III (VT6105)), say Y here. Rhine-type
-	  Ethernet functions can also be found integrated on South Bridges
-	  (e.g. VT8235).
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called via-rhine.
-
-config VIA_RHINE_MMIO
-	bool "Use MMIO instead of PIO"
-	depends on VIA_RHINE
-	help
-	  This instructs the driver to use PCI shared memory (MMIO) instead of
-	  programmed I/O ports (PIO). Enabling this gives an improvement in
-	  processing time in parts of the driver.
-
-	  If unsure, say Y.
-
-config SC92031
-	tristate "Silan SC92031 PCI Fast Ethernet Adapter driver (EXPERIMENTAL)"
-	depends on NET_PCI && PCI && EXPERIMENTAL
-	select CRC32
-	---help---
-	  This is a driver for the Fast Ethernet PCI network cards based on
-	  the Silan SC92031 chip (sometimes also called Rsltek 8139D). If you
-	  have one of these, say Y here.
-
-	  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
-	help
-	  TI AR7 CPMAC Ethernet support
-
-config NET_POCKET
-	bool "Pocket and portable adapters"
-	depends on PARPORT
-	---help---
-	  Cute little network (Ethernet) devices which attach to the parallel
-	  port ("pocket adapters"), commonly used with laptops. If you have
-	  one of those, say Y and read the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you want to plug a network (or some other) card into the PCMCIA
-	  (or PC-card) slot of your laptop instead (PCMCIA is the standard for
-	  credit card size extension cards used by all modern laptops), you
-	  need the pcmcia-cs package (location contained in the file
-	  <file:Documentation/Changes>) and you can say N here.
-
-	  Laptop users should read the Linux Laptop home page at
-	  <http://www.linux-on-laptops.com/> or
-	  Tuxmobil - Linux on Mobile Computers at <http://www.tuxmobil.org/>.
-
-	  Note that the answer to this question doesn't directly affect the
-	  kernel: saying N will just cause the configurator to skip all
-	  the questions about this class of network devices. If you say Y, you
-	  will be asked for your specific device in the following questions.
-
-config ATP
-	tristate "AT-LAN-TEC/RealTek pocket adapter support"
-	depends on NET_POCKET && PARPORT && X86
-	select CRC32
-	---help---
-	  This is a network (Ethernet) device which attaches to your parallel
-	  port. Read <file:drivers/net/atp.c> as well as the Ethernet-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>, if you
-	  want to use this.  If you intend to use this driver, you should have
-	  said N to the "Parallel printer support", because the two drivers
-	  don't like each other.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called atp.
-
-config DE600
-	tristate "D-Link DE600 pocket adapter support"
-	depends on NET_POCKET && PARPORT
-	---help---
-	  This is a network (Ethernet) device which attaches to your parallel
-	  port. Read <file:Documentation/networking/DLINK.txt> as well as the
-	  Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, if you want to use
-	  this. It is possible to have several devices share a single parallel
-	  port and it is safe to compile the corresponding drivers into the
-	  kernel.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called de600.
-
-config DE620
-	tristate "D-Link DE620 pocket adapter support"
-	depends on NET_POCKET && PARPORT
-	---help---
-	  This is a network (Ethernet) device which attaches to your parallel
-	  port. Read <file:Documentation/networking/DLINK.txt> as well as the
-	  Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, if you want to use
-	  this. It is possible to have several devices share a single parallel
-	  port and it is safe to compile the corresponding drivers into the
-	  kernel.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called de620.
-
-config SGISEEQ
-	tristate "SGI Seeq ethernet controller support"
-	depends on SGI_HAS_SEEQ
-	help
-	  Say Y here if you have an Seeq based Ethernet network card. This is
-	  used in many Silicon Graphics machines.
-
-config DECLANCE
-	tristate "DEC LANCE ethernet controller support"
-	depends on MACH_DECSTATION
-	select CRC32
-	help
-	  This driver is for the series of Ethernet controllers produced by
-	  DEC (now Compaq) based on the AMD Lance chipset, including the
-	  DEPCA series.  (This chipset is better known via the NE2100 cards.)
-
-config FEC
-	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
-	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
-		IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC
-	default IMX_HAVE_PLATFORM_FEC || MXS_HAVE_PLATFORM_FEC if ARM
-	select PHYLIB
-	help
-	  Say Y here if you want to use the built-in 10/100 Fast ethernet
-	  controller on some Motorola ColdFire and Freescale i.MX processors.
-
-config FEC_MPC52xx
-	tristate "MPC52xx FEC driver"
-	depends on PPC_MPC52xx && PPC_BESTCOMM
-	select CRC32
-	select PHYLIB
-	select PPC_BESTCOMM_FEC
-	---help---
-	  This option enables support for the MPC5200's on-chip
-	  Fast Ethernet Controller
-	  If compiled as module, it will be called fec_mpc52xx.
-
-config FEC_MPC52xx_MDIO
-	bool "MPC52xx FEC MDIO bus driver"
-	depends on FEC_MPC52xx
-	default y
-	---help---
-	  The MPC5200's FEC can connect to the Ethernet either with
-	  an external MII PHY chip or 10 Mbps 7-wire interface
-	  (Motorola? industry standard).
-	  If your board uses an external PHY connected to FEC, enable this.
-	  If not sure, enable.
-	  If compiled as module, it will be called fec_mpc52xx_phy.
-
-config NE_H8300
-	tristate "NE2000 compatible support for H8/300"
-	depends on H8300
-	help
-	  Say Y here if you want to use the NE2000 compatible
-	  controller on the Renesas H8/300 processor.
-
-config ATL2
-	tristate "Atheros L2 Fast Ethernet support"
-	depends on PCI
-	select CRC32
-	select MII
-	help
-	  This driver supports the Atheros L2 fast ethernet adapter.
-
-	  To compile this driver as a module, choose M here.  The module
-	  will be called atl2.
-
-config XILINX_EMACLITE
-	tristate "Xilinx 10/100 Ethernet Lite support"
-	depends on PPC32 || MICROBLAZE
-	select PHYLIB
-	help
-	  This driver supports the 10/100 Ethernet Lite from Xilinx.
-
-config BCM63XX_ENET
-	tristate "Broadcom 63xx internal mac support"
-	depends on BCM63XX
-	select MII
-	select PHYLIB
-	help
-	  This driver supports the ethernet MACs in the Broadcom 63xx
-	  MIPS chipset family (BCM63XX).
-
-config FTMAC100
-	tristate "Faraday FTMAC100 10/100 Ethernet support"
-	depends on ARM
-	select MII
-	help
-	  This driver supports the FTMAC100 10/100 Ethernet controller
-	  from Faraday. It is used on Faraday A320, Andes AG101 and some
-	  other ARM/NDS32 SoC's.
-
-config LANTIQ_ETOP
-	tristate "Lantiq SoC ETOP driver"
-	depends on SOC_TYPE_XWAY
-	help
-	  Support for the MII0 inside the Lantiq SoC
-
-
-source "drivers/net/fs_enet/Kconfig"
-
-source "drivers/net/octeon/Kconfig"
-
-endif # NET_ETHERNET
-
-#
-#	Gigabit Ethernet
-#
-
-menuconfig NETDEV_1000
-	bool "Ethernet (1000 Mbit)"
-	depends on !UML
-	default y
-	---help---
-	  Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
-	  type of Local Area Network (LAN) in universities and companies.
-
-	  Say Y here to get to see options for Gigabit Ethernet drivers.
-	  This option alone does not add any kernel code.
-	  Note that drivers supporting both 100 and 1000 MBit may be listed
-	  under "Ethernet (10 or 100MBit)" instead.
-
-	  If you say N, all options in this submenu will be skipped and disabled.
-
-if NETDEV_1000
-
-config ACENIC
-	tristate "Alteon AceNIC/3Com 3C985/NetGear GA620 Gigabit support"
-	depends on PCI
-	---help---
-	  Say Y here if you have an Alteon AceNIC, 3Com 3C985(B), NetGear
-	  GA620, SGI Gigabit or Farallon PN9000-SX PCI Gigabit Ethernet
-	  adapter. The driver allows for using the Jumbo Frame option (9000
-	  bytes/frame) however it requires that your switches can handle this
-	  as well. To enable Jumbo Frames, add `mtu 9000' to your ifconfig
-	  line.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called acenic.
-
-config ACENIC_OMIT_TIGON_I
-	bool "Omit support for old Tigon I based AceNICs"
-	depends on ACENIC
-	help
-	  Say Y here if you only have Tigon II based AceNICs and want to leave
-	  out support for the older Tigon I based cards which are no longer
-	  being sold (ie. the original Alteon AceNIC and 3Com 3C985 (non B
-	  version)).  This will reduce the size of the driver object by
-	  app. 100KB.  If you are not sure whether your card is a Tigon I or a
-	  Tigon II, say N here.
-
-	  The safe and default value for this is N.
-
-config DL2K
-	tristate "DL2000/TC902x-based Gigabit Ethernet support"
-	depends on PCI
-	select CRC32
-	help
-	  This driver supports DL2000/TC902x-based Gigabit ethernet cards,
-	  which includes
-	  D-Link DGE-550T Gigabit Ethernet Adapter.
-	  D-Link DL2000-based Gigabit Ethernet Adapter.
-	  Sundance/Tamarack TC902x Gigabit Ethernet Adapter.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called dl2k.
-
-config E1000
-	tristate "Intel(R) PRO/1000 Gigabit Ethernet support"
-	depends on PCI
-	---help---
-	  This driver supports Intel(R) PRO/1000 gigabit ethernet family of
-	  adapters.  For more information on how to identify your adapter, go 
-	  to the Adapter & Driver ID Guide at:
-
-	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-	  For general information and support, go to the Intel support
-	  website at:
-
-	  <http://support.intel.com>
-
-	  More specific information on configuring the driver is in 
-	  <file:Documentation/networking/e1000.txt>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called e1000.
-
-config E1000E
-	tristate "Intel(R) PRO/1000 PCI-Express Gigabit Ethernet support"
-	depends on PCI && (!SPARC32 || BROKEN)
-	select CRC32
-	---help---
-	  This driver supports the PCI-Express Intel(R) PRO/1000 gigabit
-	  ethernet family of adapters. For PCI or PCI-X e1000 adapters,
-	  use the regular e1000 driver For more information on how to
-	  identify your adapter, go to the Adapter & Driver ID Guide at:
-
-	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-	  For general information and support, go to the Intel support
-	  website at:
-
-	  <http://support.intel.com>
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called e1000e.
-
-config IP1000
-	tristate "IP1000 Gigabit Ethernet support"
-	depends on PCI && EXPERIMENTAL
-	select MII
-	---help---
-	  This driver supports IP1000 gigabit Ethernet cards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called ipg.  This is recommended.
-
-config IGB
-	tristate "Intel(R) 82575/82576 PCI-Express Gigabit Ethernet support"
-	depends on PCI
-	---help---
-	  This driver supports Intel(R) 82575/82576 gigabit ethernet family of
-	  adapters.  For more information on how to identify your adapter, go
-	  to the Adapter & Driver ID Guide at:
-
-	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-	  For general information and support, go to the Intel support
-	  website at:
-
-	  <http://support.intel.com>
-
-	  More specific information on configuring the driver is in
-	  <file:Documentation/networking/e1000.txt>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called igb.
-
-config IGB_DCA
-	bool "Direct Cache Access (DCA) Support"
-	default y
-	depends on IGB && DCA && !(IGB=y && DCA=m)
-	---help---
-	  Say Y here if you want to use Direct Cache Access (DCA) in the
-	  driver.  DCA is a method for warming the CPU cache before data
-	  is used, with the intent of lessening the impact of cache misses.
-
-config IGBVF
-	tristate "Intel(R) 82576 Virtual Function Ethernet support"
-	depends on PCI
-	---help---
-	  This driver supports Intel(R) 82576 virtual functions.  For more
-	  information on how to identify your adapter, go to the Adapter &
-	  Driver ID Guide at:
-
-	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-	  For general information and support, go to the Intel support
-	  website at:
-
-	  <http://support.intel.com>
-
-	  More specific information on configuring the driver is in
-	  <file:Documentation/networking/e1000.txt>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called igbvf.
-
-source "drivers/net/ixp2000/Kconfig"
-
-config NS83820
-	tristate "National Semiconductor DP83820 support"
-	depends on PCI
-	help
-	  This is a driver for the National Semiconductor DP83820 series
-	  of gigabit ethernet MACs.  Cards using this chipset include
-	  the D-Link DGE-500T, PureData's PDP8023Z-TG, SMC's SMC9462TX,
-	  SOHO-GA2000T, SOHO-GA2500T.  The driver supports the use of
-	  zero copy.
-
-config HAMACHI
-	tristate "Packet Engines Hamachi GNIC-II support"
-	depends on PCI
-	select MII
-	help
-	  If you have a Gigabit Ethernet card of this type, say Y and read
-	  the Ethernet-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  To compile this driver as a module, choose M here. The module will be
-	  called hamachi.
-
-config YELLOWFIN
-	tristate "Packet Engines Yellowfin Gigabit-NIC support (EXPERIMENTAL)"
-	depends on PCI && EXPERIMENTAL
-	select CRC32
-	---help---
-	  Say Y here if you have a Packet Engines G-NIC PCI Gigabit Ethernet
-	  adapter or the SYM53C885 Ethernet controller. The Gigabit adapter is
-	  used by the Beowulf Linux cluster project.  See
-	  <http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html> for more
-	  information about this driver in particular and Beowulf in general.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called yellowfin.  This is recommended.
-
-config R8169
-	tristate "Realtek 8169 gigabit ethernet support"
-	depends on PCI
-	select FW_LOADER
-	select CRC32
-	select MII
-	---help---
-	  Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called r8169.  This is recommended.
-
-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
-	  the BCM1120, BCM1125, BCM1125H, BCM1250, BCM1255, BCM1280, BCM1455
-	  and BCM1480 chips.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called sb1250-mac.
-
-config SIS190
-	tristate "SiS190/SiS191 gigabit ethernet support"
-	depends on PCI
-	select CRC32
-	select MII
-	---help---
-	  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.
-
-config SKGE
-	tristate "Marvell Yukon Gigabit Ethernet support"
-	depends on PCI
-	select CRC32
-	---help---
-	  This driver support the Marvell Yukon or SysKonnect SK-98xx/SK-95xx
-	  and related Gigabit Ethernet adapters. It is a new smaller driver
-	  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.
-
-	  This driver supports adapters based on the original Yukon chipset:
-	  Marvell 88E8001, Belkin F5D5005, CNet GigaCard, DLink DGE-530T,
-	  Linksys EG1032/EG1064, 3Com 3C940/3C940B, SysKonnect SK-9871/9872.
-
-	  It does not support the newer Yukon2 chipset: a separate driver,
-	  sky2, is provided for these adapters.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called skge.  This is recommended.
-
-config SKGE_DEBUG
-	bool "Debugging interface"
-	depends on SKGE && DEBUG_FS
-	help
-	  This option adds the ability to dump driver state for debugging.
-	  The file /sys/kernel/debug/skge/ethX displays the state of the internal
-	  transmit and receive rings.
-
-	  If unsure, say N.
-
-config SKGE_GENESIS
-       bool "Support for older SysKonnect Genesis boards"
-       depends on SKGE
-       help
-         This enables support for the older and uncommon SysKonnect Genesis
-	 chips, which support MII via an external transceiver, instead of
-	 an internal one. Disabling this option will save some memory
-	 by making code smaller. If unsure say Y.
-
-config SKY2
-	tristate "Marvell Yukon 2 support"
-	depends on PCI
-	select CRC32
-	---help---
-	  This driver supports Gigabit Ethernet adapters based on the
-	  Marvell Yukon 2 chipset:
-	  Marvell 88E8021/88E8022/88E8035/88E8036/88E8038/88E8050/88E8052/
-	  88E8053/88E8055/88E8061/88E8062, SysKonnect SK-9E21D/SK-9S21
-
-	  There is companion driver for the older Marvell Yukon and
-	  SysKonnect Genesis based adapters: skge.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called sky2.  This is recommended.
-
-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 /sys/kernel/debug/sky2/ethX displays the state of the internal
-	  transmit and receive rings.
-
-	  If unsure, say N.
-
-config VIA_VELOCITY
-	tristate "VIA Velocity support"
-	depends on PCI
-	select CRC32
-	select CRC_CCITT
-	select MII
-	help
-	  If you have a VIA "Velocity" based network card say Y here.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called via-velocity.
-
-config TIGON3
-	tristate "Broadcom Tigon3 support"
-	depends on PCI
-	select PHYLIB
-	help
-	  This driver supports Broadcom Tigon3 based gigabit Ethernet cards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called tg3.  This is recommended.
-
-config BNX2
-	tristate "Broadcom NetXtremeII support"
-	depends on PCI
-	select CRC32
-	select FW_LOADER
-	help
-	  This driver supports Broadcom NetXtremeII gigabit Ethernet cards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called bnx2.  This is recommended.
-
-config CNIC
-	tristate "Broadcom CNIC support"
-	depends on PCI
-	select BNX2
-	select UIO
-	help
-	  This driver supports offload features of Broadcom NetXtremeII
-	  gigabit Ethernet cards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called cnic.  This is recommended.
-
-config SPIDER_NET
-	tristate "Spider Gigabit Ethernet driver"
-	depends on PCI && (PPC_IBM_CELL_BLADE || PPC_CELLEB)
-	select FW_LOADER
-	help
-	  This driver supports the Gigabit Ethernet chips present on the
-	  Cell Processor-Based Blades from IBM.
-
-config TSI108_ETH
-	tristate "Tundra TSI108 gigabit Ethernet support"
-	depends on TSI108_BRIDGE
-	help
-	  This driver supports Tundra TSI108 gigabit Ethernet ports.
-	  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
-	select PS3_SYS_MANAGER
-	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 GELIC_WIRELESS
-	bool "PS3 Wireless support"
-	depends on WLAN
-	depends on GELIC_NET
-	select WIRELESS_EXT
-	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 FSL_PQ_MDIO
-	tristate "Freescale PQ MDIO"
-	depends on FSL_SOC
-	select PHYLIB
-	help
-	  This driver supports the MDIO bus used by the gianfar and UCC drivers.
-
-config GIANFAR
-	tristate "Gianfar Ethernet"
-	depends on FSL_SOC
-	select FSL_PQ_MDIO
-	select PHYLIB
-	select CRC32
-	help
-	  This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
-	  and MPC86xx family of chips, and the FEC on the 8540.
-
-config UCC_GETH
-	tristate "Freescale QE Gigabit Ethernet"
-	depends on QUICC_ENGINE
-	select FSL_PQ_MDIO
-	select PHYLIB
-	help
-	  This driver supports the Gigabit Ethernet mode of the QUICC Engine,
-	  which is available on some Freescale SOCs.
-
-config UGETH_TX_ON_DEMAND
-	bool "Transmit on Demand support"
-	depends on UCC_GETH
-
-config MV643XX_ETH
-	tristate "Marvell Discovery (643XX) and Orion ethernet support"
-	depends on (MV64X60 || PPC32 || PLAT_ORION) && INET
-	select INET_LRO
-	select PHYLIB
-	help
-	  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 XILINX_LL_TEMAC
-	tristate "Xilinx LL TEMAC (LocalLink Tri-mode Ethernet MAC) driver"
-	depends on PPC || MICROBLAZE
-	select PHYLIB
-	help
-	  This driver supports the Xilinx 10/100/1000 LocalLink TEMAC
-	  core used in Xilinx Spartan and Virtex FPGAs
-
-config QLA3XXX
-	tristate "QLogic QLA3XXX Network Driver Support"
-	depends on PCI
-	help
-	  This driver supports QLogic ISP3XXX gigabit Ethernet cards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called qla3xxx.
-
-config ATL1
-	tristate "Atheros/Attansic L1 Gigabit Ethernet support"
-	depends on PCI
-	select CRC32
-	select MII
-	help
-	  This driver supports the Atheros/Attansic L1 gigabit ethernet
-	  adapter.
-
-	  To compile this driver as a module, choose M here.  The module
-	  will be called atl1.
-
-config ATL1E
-	tristate "Atheros L1E Gigabit Ethernet support (EXPERIMENTAL)"
-	depends on PCI && EXPERIMENTAL
-	select CRC32
-	select MII
-	help
-	  This driver supports the Atheros L1E gigabit ethernet adapter.
-
-	  To compile this driver as a module, choose M here.  The module
-	  will be called atl1e.
-
-config ATL1C
-	tristate "Atheros L1C Gigabit Ethernet support (EXPERIMENTAL)"
-	depends on PCI && EXPERIMENTAL
-	select CRC32
-	select MII
-	help
-	  This driver supports the Atheros L1C gigabit ethernet adapter.
-
-	  To compile this driver as a module, choose M here.  The module
-	  will be called atl1c.
-
-config JME
-	tristate "JMicron(R) PCI-Express Gigabit Ethernet support"
-	depends on PCI
-	select CRC32
-	select MII
-	---help---
-	  This driver supports the PCI-Express gigabit ethernet adapters
-	  based on JMicron JMC250 chipset.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called jme.
-
-config S6GMAC
-	tristate "S6105 GMAC ethernet support"
-	depends on XTENSA_VARIANT_S6000
-	select PHYLIB
-	help
-	  This driver supports the on chip ethernet device on the
-	  S6105 xtensa processor.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called s6gmac.
-
-source "drivers/net/stmmac/Kconfig"
-
-config PCH_GBE
-	tristate "Intel EG20T PCH/OKI SEMICONDUCTOR IOH(ML7223/ML7831) GbE"
-	depends on PCI
-	select MII
-	---help---
-	  This is a gigabit ethernet driver for EG20T PCH.
-	  EG20T PCH is the platform controller hub that is used in Intel's
-	  general embedded platform.
-	  EG20T PCH has Gigabit Ethernet interface.
-	  Using this interface, it is able to access system devices connected
-	  to Gigabit Ethernet.
-	  This driver enables Gigabit Ethernet function.
-
-	  This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
-	  Output Hub), ML7223/ML7831.
-	  ML7223 IOH is for MP(Media Phone) use. ML7831 IOH is for general
-	  purpose use.
-	  ML7223/ML7831 is companion chip for Intel Atom E6xx series.
-	  ML7223/ML7831 is completely compatible for Intel EG20T PCH.
-
-config FTGMAC100
-	tristate "Faraday FTGMAC100 Gigabit Ethernet support"
-	depends on ARM
-	select PHYLIB
-	help
-	  This driver supports the FTGMAC100 Gigabit Ethernet controller
-	  from Faraday. It is used on Faraday A369, Andes AG102 and some
-	  other ARM/NDS32 SoC's.
-
-endif # NETDEV_1000
-
-#
-#	10 Gigabit Ethernet
-#
-
-menuconfig NETDEV_10000
-	bool "Ethernet (10000 Mbit)"
-	depends on !UML
-	default y
-	---help---
-	  Say Y here to get to see options for 10 Gigabit Ethernet drivers.
-	  This option alone does not add any kernel code.
-
-	  If you say N, all options in this submenu will be skipped and disabled.
-
-if NETDEV_10000
-
-config MDIO
-	tristate
-
-config CHELSIO_T1
-	tristate "Chelsio 10Gb Ethernet support"
-	depends on PCI
-	select CRC32
-	select MDIO
-	help
-	  This driver supports Chelsio gigabit and 10-gigabit
-	  Ethernet cards. More information about adapter features and
-	  performance tuning is in <file:Documentation/networking/cxgb.txt>.
-
-	  For general information about Chelsio and our products, visit
-	  our website at <http://www.chelsio.com>.
-
-	  For customer support, please visit our customer support page at
-	  <http://www.chelsio.com/support.html>.
-
-	  Please send feedback to <linux-bugs@chelsio.com>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called cxgb.
-
-config CHELSIO_T1_1G
-	bool "Chelsio gigabit Ethernet support"
-	depends on CHELSIO_T1
-	help
-	  Enables support for Chelsio's gigabit Ethernet PCI cards.  If you
-	  are using only 10G cards say 'N' here.
-
-config CHELSIO_T3
-	tristate "Chelsio Communications T3 10Gb Ethernet support"
-	depends on PCI && INET
-	select FW_LOADER
-	select MDIO
-	help
-	  This driver supports Chelsio T3-based gigabit and 10Gb Ethernet
-	  adapters.
-
-	  For general information about Chelsio and our products, visit
-	  our website at <http://www.chelsio.com>.
-
-	  For customer support, please visit our customer support page at
-	  <http://www.chelsio.com/support.html>.
-
-	  Please send feedback to <linux-bugs@chelsio.com>.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called cxgb3.
-
-config CHELSIO_T4
-	tristate "Chelsio Communications T4 Ethernet support"
-	depends on PCI
-	select FW_LOADER
-	select MDIO
-	help
-	  This driver supports Chelsio T4-based gigabit and 10Gb Ethernet
-	  adapters.
-
-	  For general information about Chelsio and our products, visit
-	  our website at <http://www.chelsio.com>.
-
-	  For customer support, please visit our customer support page at
-	  <http://www.chelsio.com/support.html>.
-
-	  Please send feedback to <linux-bugs@chelsio.com>.
-
-	  To compile this driver as a module choose M here; the module
-	  will be called cxgb4.
-
-config CHELSIO_T4VF
-	tristate "Chelsio Communications T4 Virtual Function Ethernet support"
-	depends on PCI
-	help
-	  This driver supports Chelsio T4-based gigabit and 10Gb Ethernet
-	  adapters with PCI-E SR-IOV Virtual Functions.
-
-	  For general information about Chelsio and our products, visit
-	  our website at <http://www.chelsio.com>.
-
-	  For customer support, please visit our customer support page at
-	  <http://www.chelsio.com/support.html>.
-
-	  Please send feedback to <linux-bugs@chelsio.com>.
-
-	  To compile this driver as a module choose M here; the module
-	  will be called cxgb4vf.
-
-config EHEA
-	tristate "eHEA Ethernet support"
-	depends on IBMEBUS && INET && SPARSEMEM
-	select INET_LRO
-	---help---
-	  This driver supports the IBM pSeries eHEA ethernet adapter.
-
-	  To compile the driver as a module, choose M here. The module
-	  will be called ehea.
-
-config ENIC
-	tristate "Cisco VIC Ethernet NIC Support"
-	depends on PCI && INET
-	help
-	  This enables the support for the Cisco VIC Ethernet card.
-
-config IXGBE
-	tristate "Intel(R) 10GbE PCI Express adapters support"
-	depends on PCI && INET
-	select MDIO
-	---help---
-	  This driver supports Intel(R) 10GbE PCI Express family of
-	  adapters.  For more information on how to identify your adapter, go
-	  to the Adapter & Driver ID Guide at:
-
-	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-	  For general information and support, go to the Intel support
-	  website at:
-
-	  <http://support.intel.com>
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ixgbe.
-
-config IXGBE_DCA
-	bool "Direct Cache Access (DCA) Support"
-	default y
-	depends on IXGBE && DCA && !(IXGBE=y && DCA=m)
-	---help---
-	  Say Y here if you want to use Direct Cache Access (DCA) in the
-	  driver.  DCA is a method for warming the CPU cache before data
-	  is used, with the intent of lessening the impact of cache misses.
-
-config IXGBE_DCB
-	bool "Data Center Bridging (DCB) Support"
-	default n
-	depends on IXGBE && DCB
-	---help---
-	  Say Y here if you want to use Data Center Bridging (DCB) in the
-	  driver.
-
-	  If unsure, say N.
-
-config IXGBEVF
-	tristate "Intel(R) 82599 Virtual Function Ethernet support"
-	depends on PCI_MSI
-	---help---
-	  This driver supports Intel(R) 82599 virtual functions.  For more
-	  information on how to identify your adapter, go to the Adapter &
-	  Driver ID Guide at:
-
-	  <http://support.intel.com/support/network/sb/CS-008441.htm>
-
-	  For general information and support, go to the Intel support
-	  website at:
-
-	  <http://support.intel.com>
-
-	  More specific information on configuring the driver is in
-	  <file:Documentation/networking/ixgbevf.txt>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ixgbevf.  MSI-X interrupt support is required
-	  for this driver to work correctly.
-
-config IXGB
-	tristate "Intel(R) PRO/10GbE support"
-	depends on PCI
-	---help---
-	  This driver supports Intel(R) PRO/10GbE family of adapters for
-	  PCI-X type cards. For PCI-E type cards, use the "ixgbe" driver
-	  instead. For more information on how to identify your adapter, go
-	  to the Adapter & Driver ID Guide at:
-
-	  <http://support.intel.com/support/network/adapter/pro100/21397.htm>
-
-	  For general information and support, go to the Intel support
-	  website at:
-
-	  <http://support.intel.com>
-
-	  More specific information on configuring the driver is in 
-	  <file:Documentation/networking/ixgb.txt>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called ixgb.
-
-config S2IO
-	tristate "Exar Xframe 10Gb Ethernet Adapter"
-	depends on PCI
-	---help---
-	  This driver supports Exar Corp's Xframe Series 10Gb Ethernet Adapters.
-
-	  More specific information on configuring the driver is in 
-	  <file:Documentation/networking/s2io.txt>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called s2io.
-
-config VXGE
-	tristate "Exar X3100 Series 10GbE PCIe Server Adapter"
-	depends on PCI && INET
-	---help---
-	  This driver supports Exar Corp's X3100 Series 10 GbE PCIe
-	  I/O Virtualized Server Adapter.
-
-	  More specific information on configuring the driver is in
-	  <file:Documentation/networking/vxge.txt>.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called vxge.
-
-config VXGE_DEBUG_TRACE_ALL
-	bool "Enabling All Debug trace statments in driver"
-	default n
-	depends on VXGE
-	---help---
-	  Say Y here if you want to enabling all the debug trace statements in
-	  the vxge driver. By default only few debug trace statements are
-	  enabled.
-
-config MYRI10GE
-	tristate "Myricom Myri-10G Ethernet support"
-	depends on PCI && INET
-	select FW_LOADER
-	select CRC32
-	select INET_LRO
-	---help---
-	  This driver supports Myricom Myri-10G Dual Protocol interface in
-	  Ethernet mode. If the eeprom on your board is not recent enough,
-	  you will need a newer firmware image.
-	  You may get this image or more information, at:
-
-	  <http://www.myri.com/scs/download-Myri10GE.html>
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called myri10ge.
-
-config MYRI10GE_DCA
-	bool "Direct Cache Access (DCA) Support"
-	default y
-	depends on MYRI10GE && DCA && !(MYRI10GE=y && DCA=m)
-	---help---
-	  Say Y here if you want to use Direct Cache Access (DCA) in the
-	  driver.  DCA is a method for warming the CPU cache before data
-	  is used, with the intent of lessening the impact of cache misses.
-
-config NETXEN_NIC
-	tristate "NetXen Multi port (1/10) Gigabit Ethernet NIC"
-	depends on PCI
-	select FW_LOADER
-	help
-	  This enables the support for NetXen's Gigabit Ethernet card.
-
-config NIU
-	tristate "Sun Neptune 10Gbit Ethernet support"
-	depends on PCI
-	select CRC32
-	help
-	  This enables support for cards based upon Sun's
-	  Neptune chipset.
-
-config PASEMI_MAC
-	tristate "PA Semi 1/10Gbit MAC"
-	depends on PPC_PASEMI && PCI && INET
-	select PHYLIB
-	select INET_LRO
-	help
-	  This driver supports the on-chip 1/10Gbit Ethernet controller on
-	  PA Semi's PWRficient line of chips.
-
-config MLX4_EN
-	tristate "Mellanox Technologies 10Gbit Ethernet support"
-	depends on PCI && INET
-	select MLX4_CORE
-	select INET_LRO
-	help
-	  This driver supports Mellanox Technologies ConnectX Ethernet
-	  devices.
-
-config MLX4_CORE
-	tristate
-	depends on PCI
-	default n
-
-config MLX4_DEBUG
-	bool "Verbose debugging output" if (MLX4_CORE && EXPERT)
-	depends on MLX4_CORE
-	default y
-	---help---
-	  This option causes debugging code to be compiled into the
-	  mlx4_core driver.  The output can be turned on via the
-	  debug_level module parameter (which can also be set after
-	  the driver is loaded through sysfs).
-
-config TEHUTI
-	tristate "Tehuti Networks 10G Ethernet"
-	depends on PCI
-	help
-	  Tehuti Networks 10G Ethernet NIC
-
-config BNX2X
-	tristate "Broadcom NetXtremeII 10Gb support"
-	depends on PCI
-	select FW_LOADER
-	select ZLIB_INFLATE
-	select LIBCRC32C
-	select MDIO
-	help
-	  This driver supports Broadcom NetXtremeII 10 gigabit Ethernet cards.
-	  To compile this driver as a module, choose M here: the module
-	  will be called bnx2x.  This is recommended.
-
-config QLCNIC
-	tristate "QLOGIC QLCNIC 1/10Gb Converged Ethernet NIC Support"
-	depends on PCI
-	select FW_LOADER
-	help
-	  This driver supports QLogic QLE8240 and QLE8242 Converged Ethernet
-	  devices.
-
-config QLGE
-	tristate "QLogic QLGE 10Gb Ethernet Driver Support"
-	depends on PCI
-	help
-	  This driver supports QLogic ISP8XXX 10Gb Ethernet cards.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called qlge.
-
-config BNA
-	tristate "Brocade 1010/1020 10Gb Ethernet Driver support"
-	depends on PCI
-	---help---
-	  This driver supports Brocade 1010/1020 10Gb CEE capable Ethernet
-	  cards.
-	  To compile this driver as a module, choose M here: the module
-	  will be called bna.
-
-	  For general information and support, go to the Brocade support
-	  website at:
-
-	  <http://support.brocade.com>
-
-source "drivers/net/sfc/Kconfig"
-
-source "drivers/net/benet/Kconfig"
-
-endif # NETDEV_10000
-
-source "drivers/net/tokenring/Kconfig"
-
-source "drivers/net/wireless/Kconfig"
-
-source "drivers/net/wimax/Kconfig"
-
-source "drivers/net/usb/Kconfig"
-
-source "drivers/net/pcmcia/Kconfig"
-
-source "drivers/net/wan/Kconfig"
-
-source "drivers/atm/Kconfig"
-
-source "drivers/ieee802154/Kconfig"
-
-source "drivers/s390/net/Kconfig"
-
-source "drivers/net/caif/Kconfig"
-
-config TILE_NET
-	tristate "Tilera GBE/XGBE network driver support"
-	depends on TILE
-	default y
-	select CRC32
-	help
-	  This is a standard Linux network device driver for the
-	  on-chip Tilera Gigabit Ethernet and XAUI interfaces.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called tile_net.
-
-config XEN_NETDEV_FRONTEND
-	tristate "Xen network device frontend driver"
-	depends on XEN
-	select XEN_XENBUS_FRONTEND
-	default y
-	help
-	  This driver provides support for Xen paravirtual network
-	  devices exported by a Xen network driver domain (often
-	  domain 0).
-
-	  The corresponding Linux backend driver is enabled by the
-	  CONFIG_XEN_NETDEV_BACKEND option.
-
-	  If you are compiling a kernel for use as Xen guest, you
-	  should say Y here. To compile this driver as a module, chose
-	  M here: the module will be called xen-netfront.
-
-config XEN_NETDEV_BACKEND
-	tristate "Xen backend network device"
-	depends on XEN_BACKEND
-	help
-	  This driver allows the kernel to act as a Xen network driver
-	  domain which exports paravirtual network devices to other
-	  Xen domains. These devices can be accessed by any operating
-	  system that implements a compatible front end.
-
-	  The corresponding Linux frontend driver is enabled by the
-	  CONFIG_XEN_NETDEV_FRONTEND configuration option.
-
-	  The backend driver presents a standard network device
-	  endpoint for each paravirtual network device to the driver
-	  domain network stack. These can then be bridged or routed
-	  etc in order to provide full network connectivity.
+	  The backend driver presents a standard network device
+	  endpoint for each paravirtual network device to the driver
+	  domain network stack. These can then be bridged or routed
+	  etc in order to provide full network connectivity.
 
 	  If you are compiling a kernel to run in a Xen network driver
 	  domain (often this is domain 0) you should say Y here. To
 	  compile this driver as a module, chose M here: the module
 	  will be called xen-netback.
 
-config ISERIES_VETH
-	tristate "iSeries Virtual Ethernet driver support"
-	depends on PPC_ISERIES
-
-config RIONET
-	tristate "RapidIO Ethernet over messaging driver support"
-	depends on RAPIDIO
-
-config RIONET_TX_SIZE
-	int "Number of outbound queue entries"
-	depends on RIONET
-	default "128"
-
-config RIONET_RX_SIZE
-	int "Number of inbound queue entries"
-	depends on RIONET
-	default "128"
-
-config FDDI
-	tristate "FDDI driver support"
-	depends on (PCI || EISA || TC)
-	help
-	  Fiber Distributed Data Interface is a high speed local area network
-	  design; essentially a replacement for high speed Ethernet. FDDI can
-	  run over copper or fiber. If you are connected to such a network and
-	  want a driver for the FDDI card in your computer, say Y here (and
-	  then also Y to the driver for your FDDI card, below). Most people
-	  will say N.
-
-config DEFXX
-	tristate "Digital DEFTA/DEFEA/DEFPA adapter support"
-	depends on FDDI && (PCI || EISA || TC)
-	---help---
-	  This is support for the DIGITAL series of TURBOchannel (DEFTA),
-	  EISA (DEFEA) and PCI (DEFPA) controllers which can connect you
-	  to a local FDDI network.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called defxx.  If unsure, say N.
-
-config DEFXX_MMIO
-	bool
-	prompt "Use MMIO instead of PIO" if PCI || EISA
-	depends on DEFXX
-	default n if PCI || EISA
-	default y
-	---help---
-	  This instructs the driver to use EISA or PCI memory-mapped I/O
-	  (MMIO) as appropriate instead of programmed I/O ports (PIO).
-	  Enabling this gives an improvement in processing time in parts
-	  of the driver, but it may cause problems with EISA (DEFEA)
-	  adapters.  TURBOchannel does not have the concept of I/O ports,
-	  so MMIO is always used for these (DEFTA) adapters.
-
-	  If unsure, say N.
-
-config SKFP
-	tristate "SysKonnect FDDI PCI support"
-	depends on FDDI && PCI
-	select BITREVERSE
-	---help---
-	  Say Y here if you have a SysKonnect FDDI PCI adapter.
-	  The following adapters are supported by this driver:
-	  - SK-5521 (SK-NET FDDI-UP)
-	  - SK-5522 (SK-NET FDDI-UP DAS)
-	  - SK-5541 (SK-NET FDDI-FP)
-	  - SK-5543 (SK-NET FDDI-LP)
-	  - SK-5544 (SK-NET FDDI-LP DAS)
-	  - SK-5821 (SK-NET FDDI-UP64)
-	  - SK-5822 (SK-NET FDDI-UP64 DAS)
-	  - SK-5841 (SK-NET FDDI-FP64)
-	  - SK-5843 (SK-NET FDDI-LP64)
-	  - SK-5844 (SK-NET FDDI-LP64 DAS)
-	  - Netelligent 100 FDDI DAS Fibre SC
-	  - Netelligent 100 FDDI SAS Fibre SC
-	  - Netelligent 100 FDDI DAS UTP
-	  - Netelligent 100 FDDI SAS UTP
-	  - Netelligent 100 FDDI SAS Fibre MIC
-
-	  Read <file:Documentation/networking/skfp.txt> for information about
-	  the driver.
-
-	  Questions concerning this driver can be addressed to:
-	  <linux@syskonnect.de>
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called skfp.  This is recommended.
-
-config HIPPI
-	bool "HIPPI driver support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && INET && PCI
-	help
-	  HIgh Performance Parallel Interface (HIPPI) is a 800Mbit/sec and
-	  1600Mbit/sec dual-simplex switched or point-to-point network. HIPPI
-	  can run over copper (25m) or fiber (300m on multi-mode or 10km on
-	  single-mode). HIPPI networks are commonly used for clusters and to
-	  connect to super computers. If you are connected to a HIPPI network
-	  and have a HIPPI network card in your computer that you want to use
-	  under Linux, say Y here (you must also remember to enable the driver
-	  for your HIPPI card below). Most people will say N here.
-
-config ROADRUNNER
-	tristate "Essential RoadRunner HIPPI PCI adapter support (EXPERIMENTAL)"
-	depends on HIPPI && PCI
-	help
-	  Say Y here if this is your PCI HIPPI network card.
-
-	  To compile this driver as a module, choose M here: the module
-	  will be called rrunner.  If unsure, say N.
-
-config ROADRUNNER_LARGE_RINGS
-	bool "Use large TX/RX rings (EXPERIMENTAL)"
-	depends on ROADRUNNER
-	help
-	  If you say Y here, the RoadRunner driver will preallocate up to 2 MB
-	  of additional memory to allow for fastest operation, both for
-	  transmitting and receiving. This memory cannot be used by any other
-	  kernel code or by user space programs. Say Y here only if you have
-	  the memory.
-
-config PLIP
-	tristate "PLIP (parallel port) support"
-	depends on PARPORT
-	---help---
-	  PLIP (Parallel Line Internet Protocol) is used to create a
-	  reasonably fast mini network consisting of two (or, rarely, more)
-	  local machines.  A PLIP link from a Linux box is a popular means to
-	  install a Linux distribution on a machine which doesn't have a
-	  CD-ROM drive (a minimal system has to be transferred with floppies
-	  first). The kernels on both machines need to have this PLIP option
-	  enabled for this to work.
-
-	  The PLIP driver has two modes, mode 0 and mode 1.  The parallel
-	  ports (the connectors at the computers with 25 holes) are connected
-	  with "null printer" or "Turbo Laplink" cables which can transmit 4
-	  bits at a time (mode 0) or with special PLIP cables, to be used on
-	  bidirectional parallel ports only, which can transmit 8 bits at a
-	  time (mode 1); you can find the wiring of these cables in
-	  <file:Documentation/networking/PLIP.txt>.  The cables can be up to
-	  15m long.  Mode 0 works also if one of the machines runs DOS/Windows
-	  and has some PLIP software installed, e.g. the Crynwr PLIP packet
-	  driver (<http://oak.oakland.edu/simtel.net/msdos/pktdrvr-pre.html>)
-	  and winsock or NCSA's telnet.
-
-	  If you want to use PLIP, say Y and read the PLIP mini-HOWTO as well
-	  as the NET-3-HOWTO, both available from
-	  <http://www.tldp.org/docs.html#howto>.  Note that the PLIP
-	  protocol has been changed and this PLIP driver won't work together
-	  with the PLIP support in Linux versions 1.0.x.  This option enlarges
-	  your kernel by about 8 KB.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called plip. If unsure, say Y or M, in case you buy
-	  a laptop later.
-
-config PPP
-	tristate "PPP (point-to-point protocol) support"
-	select SLHC
-	---help---
-	  PPP (Point to Point Protocol) is a newer and better SLIP.  It serves
-	  the same purpose: sending Internet traffic over telephone (and other
-	  serial) lines.  Ask your access provider if they support it, because
-	  otherwise you can't use it; most Internet access providers these
-	  days support PPP rather than SLIP.
-
-	  To use PPP, you need an additional program called pppd as described
-	  in the PPP-HOWTO, available at
-	  <http://www.tldp.org/docs.html#howto>.  Make sure that you have
-	  the version of pppd recommended in <file:Documentation/Changes>.
-	  The PPP option enlarges your kernel by about 16 KB.
-
-	  There are actually two versions of PPP: the traditional PPP for
-	  asynchronous lines, such as regular analog phone lines, and
-	  synchronous PPP which can be used over digital ISDN lines for
-	  example.  If you want to use PPP over phone lines or other
-	  asynchronous serial lines, you need to say Y (or M) here and also to
-	  the next option, "PPP support for async serial ports".  For PPP over
-	  synchronous lines, you should say Y (or M) here and to "Support
-	  synchronous PPP", below.
-
-	  If you said Y to "Version information on all symbols" above, then
-	  you cannot compile the PPP driver into the kernel; you can then only
-	  compile it as a module. To compile this driver as a module, choose M
-	  here. The module will be called ppp_generic.
-
-config PPP_MULTILINK
-	bool "PPP multilink support (EXPERIMENTAL)"
-	depends on PPP && EXPERIMENTAL
-	help
-	  PPP multilink is a protocol (defined in RFC 1990) which allows you
-	  to combine several (logical or physical) lines into one logical PPP
-	  connection, so that you can utilize your full bandwidth.
-
-	  This has to be supported at the other end as well and you need a
-	  version of the pppd daemon which understands the multilink protocol.
-
-	  If unsure, say N.
-
-config PPP_FILTER
-	bool "PPP filtering"
-	depends on PPP
-	help
-	  Say Y here if you want to be able to filter the packets passing over
-	  PPP interfaces.  This allows you to control which packets count as
-	  activity (i.e. which packets will reset the idle timer or bring up
-	  a demand-dialed link) and which packets are to be dropped entirely.
-	  You need to say Y here if you wish to use the pass-filter and
-	  active-filter options to pppd.
-
-	  If unsure, say N.
-
-config PPP_ASYNC
-	tristate "PPP support for async serial ports"
-	depends on PPP
-	select CRC_CCITT
-	---help---
-	  Say Y (or M) here if you want to be able to use PPP over standard
-	  asynchronous serial ports, such as COM1 or COM2 on a PC.  If you use
-	  a modem (not a synchronous or ISDN modem) to contact your ISP, you
-	  need this option.
-
-	  To compile this driver as a module, choose M here.
-
-	  If unsure, say Y.
-
-config PPP_SYNC_TTY
-	tristate "PPP support for sync tty ports"
-	depends on PPP
-	help
-	  Say Y (or M) here if you want to be able to use PPP over synchronous
-	  (HDLC) tty devices, such as the SyncLink adapter. These devices
-	  are often used for high-speed leased lines like T1/E1.
-
-	  To compile this driver as a module, choose M here.
-
-config PPP_DEFLATE
-	tristate "PPP Deflate compression"
-	depends on PPP
-	select ZLIB_INFLATE
-	select ZLIB_DEFLATE
-	---help---
-	  Support for the Deflate compression method for PPP, which uses the
-	  Deflate algorithm (the same algorithm that gzip uses) to compress
-	  each PPP packet before it is sent over the wire.  The machine at the
-	  other end of the PPP link (usually your ISP) has to support the
-	  Deflate compression method as well for this to be useful.  Even if
-	  they don't support it, it is safe to say Y here.
-
-	  To compile this driver as a module, choose M here.
-
-config PPP_BSDCOMP
-	tristate "PPP BSD-Compress compression"
-	depends on PPP
-	---help---
-	  Support for the BSD-Compress compression method for PPP, which uses
-	  the LZW compression method to compress each PPP packet before it is
-	  sent over the wire. The machine at the other end of the PPP link
-	  (usually your ISP) has to support the BSD-Compress compression
-	  method as well for this to be useful. Even if they don't support it,
-	  it is safe to say Y here.
-
-	  The PPP Deflate compression method ("PPP Deflate compression",
-	  above) is preferable to BSD-Compress, because it compresses better
-	  and is patent-free.
-
-	  Note that the BSD compression code will always be compiled as a
-	  module; it is called bsd_comp and will show up in the directory
-	  modules once you have said "make modules". If unsure, say N.
-
-config PPP_MPPE
-	tristate "PPP MPPE compression (encryption) (EXPERIMENTAL)"
-	depends on PPP && EXPERIMENTAL
-	select CRYPTO
-	select CRYPTO_SHA1
-	select CRYPTO_ARC4
-	select CRYPTO_ECB
-	---help---
-	  Support for the MPPE Encryption protocol, as employed by the
-	  Microsoft Point-to-Point Tunneling Protocol.
-
-	  See http://pptpclient.sourceforge.net/ for information on
-	  configuring PPTP clients and servers to utilize this method.
-
-config PPPOE
-	tristate "PPP over Ethernet (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && PPP
-	help
-	  Support for PPP over Ethernet.
-
-	  This driver requires the latest version of pppd from the CVS
-	  repository at cvs.samba.org.  Alternatively, see the 
-	  RoaringPenguin package (<http://www.roaringpenguin.com/pppoe>)
-	  which contains instruction on how to use this driver (under 
-	  the heading "Kernel mode PPPoE").
-
-config PPTP
-	tristate "PPP over IPv4 (PPTP) (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && PPP && NET_IPGRE_DEMUX
-	help
-	  Support for PPP over IPv4.(Point-to-Point Tunneling Protocol)
-
-	  This driver requires pppd plugin to work in client mode or
-	  modified pptpd (poptop) to work in server mode.
-	  See http://accel-pptp.sourceforge.net/ for information how to
-	  utilize this module.
-
-config PPPOATM
-	tristate "PPP over ATM"
-	depends on ATM && PPP
-	help
-	  Support PPP (Point to Point Protocol) encapsulated in ATM frames.
-	  This implementation does not yet comply with section 8 of RFC2364,
-	  which can lead to bad results if the ATM peer loses state and
-	  changes its encapsulation unilaterally.
-
-config PPPOL2TP
-	tristate "PPP over L2TP (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && L2TP && PPP
-	help
-	  Support for PPP-over-L2TP socket family. L2TP is a protocol
-	  used by ISPs and enterprises to tunnel PPP traffic over UDP
-	  tunnels. L2TP is replacing PPTP for VPN uses.
-
-config SLIP
-	tristate "SLIP (serial line) support"
-	---help---
-	  Say Y if you intend to use SLIP or CSLIP (compressed SLIP) to
-	  connect to your Internet service provider or to connect to some
-	  other local Unix box or if you want to configure your Linux box as a
-	  Slip/CSlip server for other people to dial in. SLIP (Serial Line
-	  Internet Protocol) is a protocol used to send Internet traffic over
-	  serial connections such as telephone lines or null modem cables;
-	  nowadays, the protocol PPP is more commonly used for this same
-	  purpose.
-
-	  Normally, your access provider has to support SLIP in order for you
-	  to be able to use it, but there is now a SLIP emulator called SLiRP
-	  around (available from
-	  <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
-	  allows you to use SLIP over a regular dial up shell connection. If
-	  you plan to use SLiRP, make sure to say Y to CSLIP, below. The
-	  NET-3-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, explains how to
-	  configure SLIP. Note that you don't need this option if you just
-	  want to run term (term is a program which gives you almost full
-	  Internet connectivity if you have a regular dial up shell account on
-	  some Internet connected Unix computer. Read
-	  <http://www.bart.nl/~patrickr/term-howto/Term-HOWTO.html>). SLIP
-	  support will enlarge your kernel by about 4 KB. If unsure, say N.
-
-	  To compile this driver as a module, choose M here. The module
-	  will be called slip.
-
-config SLIP_COMPRESSED
-	bool "CSLIP compressed headers"
-	depends on SLIP
-	select SLHC
-	---help---
-	  This protocol is faster than SLIP because it uses compression on the
-	  TCP/IP headers (not on the data itself), but it has to be supported
-	  on both ends. Ask your access provider if you are not sure and
-	  answer Y, just in case. You will still be able to use plain SLIP. If
-	  you plan to use SLiRP, the SLIP emulator (available from
-	  <ftp://ibiblio.org/pub/Linux/system/network/serial/>) which
-	  allows you to use SLIP over a regular dial up shell connection, you
-	  definitely want to say Y here. The NET-3-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, explains how to configure
-	  CSLIP. This won't enlarge your kernel.
-
-config SLHC
-	tristate
-	help
-	  This option enables Van Jacobsen serial line header compression
-	  routines.
-
-config SLIP_SMART
-	bool "Keepalive and linefill"
-	depends on SLIP
-	help
-	  Adds additional capabilities to the SLIP driver to support the
-	  RELCOM line fill and keepalive monitoring. Ideal on poor quality
-	  analogue lines.
-
-config SLIP_MODE_SLIP6
-	bool "Six bit SLIP encapsulation"
-	depends on SLIP
-	help
-	  Just occasionally you may need to run IP over hostile serial
-	  networks that don't pass all control characters or are only seven
-	  bit. Saying Y here adds an extra mode you can use with SLIP:
-	  "slip6". In this mode, SLIP will only send normal ASCII symbols over
-	  the serial device. Naturally, this has to be supported at the other
-	  end of the link as well. It's good enough, for example, to run IP
-	  over the async ports of a Camtec JNT Pad. If unsure, say N.
-
-config NET_FC
-	bool "Fibre Channel driver support"
-	depends on SCSI && PCI
-	help
-	  Fibre Channel is a high speed serial protocol mainly used to connect
-	  large storage devices to the computer; it is compatible with and
-	  intended to replace SCSI.
-
-	  If you intend to use Fibre Channel, you need to have a Fibre channel
-	  adaptor card in your computer; say Y here and to the driver for your
-	  adaptor below. You also should have said Y to "SCSI support" and
-	  "SCSI generic support".
-
-config NETCONSOLE
-	tristate "Network console logging support"
-	---help---
-	If you want to log kernel messages over the network, enable this.
-	See <file:Documentation/networking/netconsole.txt> for details.
-
-config NETCONSOLE_DYNAMIC
-	bool "Dynamic reconfiguration of logging targets"
-	depends on NETCONSOLE && SYSFS && CONFIGFS_FS && \
-			!(NETCONSOLE=y && CONFIGFS_FS=m)
-	help
-	  This option enables the ability to dynamically reconfigure target
-	  parameters (interface, IP addresses, port numbers, MAC addresses)
-	  at runtime through a userspace interface exported using configfs.
-	  See <file:Documentation/networking/netconsole.txt> for details.
-
-config NETPOLL
-	def_bool NETCONSOLE
-
-config NETPOLL_TRAP
-	bool "Netpoll traffic trapping"
-	default n
-	depends on NETPOLL
-
-config NET_POLL_CONTROLLER
-	def_bool NETPOLL
-
-config VIRTIO_NET
-	tristate "Virtio network driver (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && VIRTIO
-	---help---
-	  This is the virtual network driver for virtio.  It can be used with
-	  lguest or QEMU based VMMs (like KVM or Xen).  Say Y or M.
-
 config VMXNET3
 	tristate "VMware VMXNET3 ethernet driver"
 	depends on PCI && INET

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است