Patchwork [1/1] via-rhine: Split driver into .c and .h files.

login
register
mail settings
Submitter Bjarke Istrup Pedersen
Date Jan. 1, 2012, 9:15 p.m.
Message ID <1325452525-23476-1-git-send-email-gurligebis@gentoo.org>
Download mbox | patch
Permalink /patch/133767/
State Rejected
Delegated to: David Miller
Headers show

Comments

Bjarke Istrup Pedersen - Jan. 1, 2012, 9:15 p.m.
Split the driver into via-rhine.c and via-rhine.h like it should be.

There is also a bit of cleanup of checkpatch warnings, other than that,
there is no changes to how the code works, it is plain refactoring.

Signed-off-by: Bjarke Istrup Pedersen <gurligebis@gentoo.org>
---
 drivers/net/ethernet/via/via-rhine.c |  449 ++--------------------------------
 drivers/net/ethernet/via/via-rhine.h |  440 +++++++++++++++++++++++++++++++++
 2 files changed, 466 insertions(+), 423 deletions(-)
 create mode 100644 drivers/net/ethernet/via/via-rhine.h
françois romieu - Jan. 1, 2012, 10:49 p.m.
Bjarke Istrup Pedersen <gurligebis@gentoo.org> :
> Split the driver into via-rhine.c and via-rhine.h like it should be.
> There is also a bit of cleanup of checkpatch warnings, other than that,
> there is no changes to how the code works, it is plain refactoring.

Please don't do that. The .h won't be used elsewhere. It's useless
(and register definitions stay barely readable).

Roger, any comment regarding patches #1 .. #3 ?

rhine_task_{enable / disable} should be balanced in open / close and
suspend / resume, ok.
Bjarke Istrup Pedersen - Jan. 2, 2012, 8:44 a.m.
2012/1/1 Francois Romieu <romieu@fr.zoreil.com>:
> Bjarke Istrup Pedersen <gurligebis@gentoo.org> :
>> Split the driver into via-rhine.c and via-rhine.h like it should be.
>> There is also a bit of cleanup of checkpatch warnings, other than that,
>> there is no changes to how the code works, it is plain refactoring.
>
> Please don't do that. The .h won't be used elsewhere. It's useless
> (and register definitions stay barely readable).

Hmm, I see your point, was just trying to make the two via drivers more alike :)

> Roger, any comment regarding patches #1 .. #3 ?
>
> rhine_task_{enable / disable} should be balanced in open / close and
> suspend / resume, ok.
>
> --
> Ueimor
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch

diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 89ced1b..6c1651e 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -68,25 +68,6 @@  static bool avoid_D3;
    The Rhine has a 64 element 8390-like hash table. */
 static const int multicast_filter_limit = 32;
 
-
-/* Operational parameters that are set at compile time. */
-
-/* Keep the ring sizes a power of two for compile efficiency.
-   The compiler will convert <unsigned>'%'<2^N> into a bit mask.
-   Making the Tx ring too large decreases the effectiveness of channel
-   bonding and packet priority.
-   There are no ill effects from too-large receive rings. */
-#define TX_RING_SIZE	16
-#define TX_QUEUE_LEN	10	/* Limit ring entries actually used. */
-#define RX_RING_SIZE	64
-
-/* Operational parameters that usually are not changed. */
-
-/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT	(2*HZ)
-
-#define PKT_BUF_SZ	1536	/* Size of each temporary Rx buffer.*/
-
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/kernel.h>
@@ -114,16 +95,7 @@  static const int multicast_filter_limit = 32;
 #include <asm/uaccess.h>
 #include <linux/dmi.h>
 
-/* These identify the driver base version and may not be removed. */
-static const char version[] __devinitconst =
-	"v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker";
-
-/* This driver was written to use PCI memory space. Some early versions
-   of the Rhine may only work correctly with I/O space accesses. */
-#ifdef CONFIG_VIA_RHINE_MMIO
-#define USE_MMIO
-#else
-#endif
+#include "via-rhine.h"
 
 MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
 MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver");
@@ -136,9 +108,6 @@  MODULE_PARM_DESC(debug, "VIA Rhine debug level (0-7)");
 MODULE_PARM_DESC(rx_copybreak, "VIA Rhine copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(avoid_D3, "Avoid power state D3 (work-around for broken BIOSes)");
 
-#define MCAM_SIZE	32
-#define VCAM_SIZE	32
-
 /*
 		Theory of Operation
 
@@ -232,290 +201,6 @@  The chip does not pad to minimum transmit length.
 
 */
 
-
-/* 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.
-   Note the matching code -- the first table entry matchs all 56** cards but
-   second only the 1234 card.
-*/
-
-enum rhine_revs {
-	VT86C100A	= 0x00,
-	VTunknown0	= 0x20,
-	VT6102		= 0x40,
-	VT8231		= 0x50,	/* Integrated MAC */
-	VT8233		= 0x60,	/* Integrated MAC */
-	VT8235		= 0x74,	/* Integrated MAC */
-	VT8237		= 0x78,	/* Integrated MAC */
-	VTunknown1	= 0x7C,
-	VT6105		= 0x80,
-	VT6105_B0	= 0x83,
-	VT6105L		= 0x8A,
-	VT6107		= 0x8C,
-	VTunknown2	= 0x8E,
-	VT6105M		= 0x90,	/* Management adapter */
-};
-
-enum rhine_quirks {
-	rqWOL		= 0x0001,	/* Wake-On-LAN support */
-	rqForceReset	= 0x0002,
-	rq6patterns	= 0x0040,	/* 6 instead of 4 patterns for WOL */
-	rqStatusWBRace	= 0x0080,	/* Tx Status Writeback Error possible */
-	rqRhineI	= 0x0100,	/* See comment below */
-};
-/*
- * rqRhineI: VT86C100A (aka Rhine-I) uses different bits to enable
- * MMIO as well as for the collision counter and the Tx FIFO underflow
- * indicator. In addition, Tx and Rx buffers need to 4 byte aligned.
- */
-
-/* Beware of PCI posted writes */
-#define IOSYNC	do { ioread8(ioaddr + StationAddr); } while (0)
-
-static DEFINE_PCI_DEVICE_TABLE(rhine_pci_tbl) = {
-	{ 0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, },	/* VT86C100A */
-	{ 0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, },	/* VT6102 */
-	{ 0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, },	/* 6105{,L,LOM} */
-	{ 0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, },	/* VT6105M */
-	{ }	/* terminate list */
-};
-MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
-
-
-/* Offsets to the device registers. */
-enum register_offsets {
-	StationAddr=0x00, RxConfig=0x06, TxConfig=0x07, ChipCmd=0x08,
-	ChipCmd1=0x09, TQWake=0x0A,
-	IntrStatus=0x0C, IntrEnable=0x0E,
-	MulticastFilter0=0x10, MulticastFilter1=0x14,
-	RxRingPtr=0x18, TxRingPtr=0x1C, GFIFOTest=0x54,
-	MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E, PCIBusConfig1=0x6F,
-	MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
-	ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
-	RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81,
-	StickyHW=0x83, IntrStatus2=0x84,
-	CamMask=0x88, CamCon=0x92, CamAddr=0x93,
-	WOLcrSet=0xA0, PwcfgSet=0xA1, WOLcgSet=0xA3, WOLcrClr=0xA4,
-	WOLcrClr1=0xA6, WOLcgClr=0xA7,
-	PwrcsrSet=0xA8, PwrcsrSet1=0xA9, PwrcsrClr=0xAC, PwrcsrClr1=0xAD,
-};
-
-/* Bits in ConfigD */
-enum backoff_bits {
-	BackOptional=0x01, BackModify=0x02,
-	BackCaptureEffect=0x04, BackRandom=0x08
-};
-
-/* Bits in the TxConfig (TCR) register */
-enum tcr_bits {
-	TCR_PQEN=0x01,
-	TCR_LB0=0x02,		/* loopback[0] */
-	TCR_LB1=0x04,		/* loopback[1] */
-	TCR_OFSET=0x08,
-	TCR_RTGOPT=0x10,
-	TCR_RTFT0=0x20,
-	TCR_RTFT1=0x40,
-	TCR_RTSF=0x80,
-};
-
-/* Bits in the CamCon (CAMC) register */
-enum camcon_bits {
-	CAMC_CAMEN=0x01,
-	CAMC_VCAMSL=0x02,
-	CAMC_CAMWR=0x04,
-	CAMC_CAMRD=0x08,
-};
-
-/* Bits in the PCIBusConfig1 (BCR1) register */
-enum bcr1_bits {
-	BCR1_POT0=0x01,
-	BCR1_POT1=0x02,
-	BCR1_POT2=0x04,
-	BCR1_CTFT0=0x08,
-	BCR1_CTFT1=0x10,
-	BCR1_CTSF=0x20,
-	BCR1_TXQNOBK=0x40,	/* for VT6105 */
-	BCR1_VIDFR=0x80,	/* for VT6105 */
-	BCR1_MED0=0x40,		/* for VT6102 */
-	BCR1_MED1=0x80,		/* for VT6102 */
-};
-
-#ifdef USE_MMIO
-/* Registers we check that mmio and reg are the same. */
-static const int mmio_verify_registers[] = {
-	RxConfig, TxConfig, IntrEnable, ConfigA, ConfigB, ConfigC, ConfigD,
-	0
-};
-#endif
-
-/* Bits in the interrupt status/mask registers. */
-enum intr_status_bits {
-	IntrRxDone	= 0x0001,
-	IntrTxDone	= 0x0002,
-	IntrRxErr	= 0x0004,
-	IntrTxError	= 0x0008,
-	IntrRxEmpty	= 0x0020,
-	IntrPCIErr	= 0x0040,
-	IntrStatsMax	= 0x0080,
-	IntrRxEarly	= 0x0100,
-	IntrTxUnderrun	= 0x0210,
-	IntrRxOverflow	= 0x0400,
-	IntrRxDropped	= 0x0800,
-	IntrRxNoBuf	= 0x1000,
-	IntrTxAborted	= 0x2000,
-	IntrLinkChange	= 0x4000,
-	IntrRxWakeUp	= 0x8000,
-	IntrTxDescRace		= 0x080000,	/* mapped from IntrStatus2 */
-	IntrNormalSummary	= IntrRxDone | IntrTxDone,
-	IntrTxErrSummary	= IntrTxDescRace | IntrTxAborted | IntrTxError |
-				  IntrTxUnderrun,
-};
-
-/* Bits in WOLcrSet/WOLcrClr and PwrcsrSet/PwrcsrClr */
-enum wol_bits {
-	WOLucast	= 0x10,
-	WOLmagic	= 0x20,
-	WOLbmcast	= 0x30,
-	WOLlnkon	= 0x40,
-	WOLlnkoff	= 0x80,
-};
-
-/* The Rx and Tx buffer descriptors. */
-struct rx_desc {
-	__le32 rx_status;
-	__le32 desc_length; /* Chain flag, Buffer/frame length */
-	__le32 addr;
-	__le32 next_desc;
-};
-struct tx_desc {
-	__le32 tx_status;
-	__le32 desc_length; /* Chain flag, Tx Config, Frame length */
-	__le32 addr;
-	__le32 next_desc;
-};
-
-/* Initial value for tx_desc.desc_length, Buffer size goes to bits 0-10 */
-#define TXDESC		0x00e08000
-
-enum rx_status_bits {
-	RxOK=0x8000, RxWholePkt=0x0300, RxErr=0x008F
-};
-
-/* Bits in *_desc.*_status */
-enum desc_status_bits {
-	DescOwn=0x80000000
-};
-
-/* Bits in *_desc.*_length */
-enum desc_length_bits {
-	DescTag=0x00010000
-};
-
-/* Bits in ChipCmd. */
-enum chip_cmd_bits {
-	CmdInit=0x01, CmdStart=0x02, CmdStop=0x04, CmdRxOn=0x08,
-	CmdTxOn=0x10, Cmd1TxDemand=0x20, CmdRxDemand=0x40,
-	Cmd1EarlyRx=0x01, Cmd1EarlyTx=0x02, Cmd1FDuplex=0x04,
-	Cmd1NoTxPoll=0x08, Cmd1Reset=0x80,
-};
-
-struct rhine_private {
-	/* Bit mask for configured VLAN ids */
-	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
-
-	/* Descriptor rings */
-	struct rx_desc *rx_ring;
-	struct tx_desc *tx_ring;
-	dma_addr_t rx_ring_dma;
-	dma_addr_t tx_ring_dma;
-
-	/* The addresses of receive-in-place skbuffs. */
-	struct sk_buff *rx_skbuff[RX_RING_SIZE];
-	dma_addr_t rx_skbuff_dma[RX_RING_SIZE];
-
-	/* The saved address of a sent-in-place packet/buffer, for later free(). */
-	struct sk_buff *tx_skbuff[TX_RING_SIZE];
-	dma_addr_t tx_skbuff_dma[TX_RING_SIZE];
-
-	/* Tx bounce buffers (Rhine-I only) */
-	unsigned char *tx_buf[TX_RING_SIZE];
-	unsigned char *tx_bufs;
-	dma_addr_t tx_bufs_dma;
-
-	struct pci_dev *pdev;
-	long pioaddr;
-	struct net_device *dev;
-	struct napi_struct napi;
-	spinlock_t lock;
-	struct mutex task_lock;
-	bool task_enable;
-	struct work_struct slow_event_task;
-	struct work_struct reset_task;
-
-	u32 msg_enable;
-
-	/* Frequently used values: keep some adjacent for cache effect. */
-	u32 quirks;
-	struct rx_desc *rx_head_desc;
-	unsigned int cur_rx, dirty_rx;	/* Producer/consumer ring indices */
-	unsigned int cur_tx, dirty_tx;
-	unsigned int rx_buf_sz;		/* Based on MTU+slack. */
-	u8 wolopts;
-
-	u8 tx_thresh, rx_thresh;
-
-	struct mii_if_info mii_if;
-	void __iomem *base;
-};
-
-#define BYTE_REG_BITS_ON(x, p)      do { iowrite8((ioread8((p))|(x)), (p)); } while (0)
-#define WORD_REG_BITS_ON(x, p)      do { iowrite16((ioread16((p))|(x)), (p)); } while (0)
-#define DWORD_REG_BITS_ON(x, p)     do { iowrite32((ioread32((p))|(x)), (p)); } while (0)
-
-#define BYTE_REG_BITS_IS_ON(x, p)   (ioread8((p)) & (x))
-#define WORD_REG_BITS_IS_ON(x, p)   (ioread16((p)) & (x))
-#define DWORD_REG_BITS_IS_ON(x, p)  (ioread32((p)) & (x))
-
-#define BYTE_REG_BITS_OFF(x, p)     do { iowrite8(ioread8((p)) & (~(x)), (p)); } while (0)
-#define WORD_REG_BITS_OFF(x, p)     do { iowrite16(ioread16((p)) & (~(x)), (p)); } while (0)
-#define DWORD_REG_BITS_OFF(x, p)    do { iowrite32(ioread32((p)) & (~(x)), (p)); } while (0)
-
-#define BYTE_REG_BITS_SET(x, m, p)   do { iowrite8((ioread8((p)) & (~(m)))|(x), (p)); } while (0)
-#define WORD_REG_BITS_SET(x, m, p)   do { iowrite16((ioread16((p)) & (~(m)))|(x), (p)); } while (0)
-#define DWORD_REG_BITS_SET(x, m, p)  do { iowrite32((ioread32((p)) & (~(m)))|(x), (p)); } while (0)
-
-
-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 value);
-static int  rhine_open(struct net_device *dev);
-static void rhine_reset_task(struct work_struct *work);
-static void rhine_slow_event_task(struct work_struct *work);
-static void rhine_tx_timeout(struct net_device *dev);
-static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
-				  struct net_device *dev);
-static irqreturn_t rhine_interrupt(int irq, void *dev_instance);
-static void rhine_tx(struct net_device *dev);
-static int rhine_rx(struct net_device *dev, int limit);
-static void rhine_set_rx_mode(struct net_device *dev);
-static struct net_device_stats *rhine_get_stats(struct net_device *dev);
-static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-static const struct ethtool_ops netdev_ethtool_ops;
-static int  rhine_close(struct net_device *dev);
-static void rhine_shutdown (struct pci_dev *pdev);
-static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid);
-static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
-static void rhine_restart_tx(struct net_device *dev);
-
-#define RHINE_WAIT_FOR(condition)				\
-do {								\
-	int i = 1024;						\
-	while (!(condition) && --i)				\
-		;						\
-	if (debug > 1 && i < 512)				\
-		pr_info("%4d cycles used @ %s:%d\n",		\
-			1024 - i, __func__, __LINE__);		\
-} while (0)
-
 static u32 rhine_get_events(struct rhine_private *rp)
 {
 	void __iomem *ioaddr = rp->base;
@@ -731,26 +416,6 @@  static void rhine_update_rx_crc_and_missed_errord(struct rhine_private *rp)
 	ioread16(ioaddr + RxMissed);
 }
 
-#define RHINE_EVENT_NAPI_RX	(IntrRxDone | \
-				 IntrRxErr | \
-				 IntrRxEmpty | \
-				 IntrRxOverflow	| \
-				 IntrRxDropped | \
-				 IntrRxNoBuf | \
-				 IntrRxWakeUp)
-
-#define RHINE_EVENT_NAPI_TX_ERR	(IntrTxError | \
-				 IntrTxAborted | \
-				 IntrTxUnderrun | \
-				 IntrTxDescRace)
-#define RHINE_EVENT_NAPI_TX	(IntrTxDone | RHINE_EVENT_NAPI_TX_ERR)
-
-#define RHINE_EVENT_NAPI	(RHINE_EVENT_NAPI_RX | \
-				 RHINE_EVENT_NAPI_TX | \
-				 IntrStatsMax)
-#define RHINE_EVENT_SLOW	(IntrPCIErr | IntrLinkChange)
-#define RHINE_EVENT		(RHINE_EVENT_NAPI | RHINE_EVENT_SLOW)
-
 static int rhine_napipoll(struct napi_struct *napi, int budget)
 {
 	struct rhine_private *rp = container_of(napi, struct rhine_private, napi);
@@ -814,24 +479,6 @@  static void __devinit rhine_hw_init(struct net_device *dev, long pioaddr)
 	rhine_reload_eeprom(pioaddr, dev);
 }
 
-static const struct net_device_ops rhine_netdev_ops = {
-	.ndo_open		 = rhine_open,
-	.ndo_stop		 = rhine_close,
-	.ndo_start_xmit		 = rhine_start_tx,
-	.ndo_get_stats		 = rhine_get_stats,
-	.ndo_set_rx_mode	 = rhine_set_rx_mode,
-	.ndo_change_mtu		 = eth_change_mtu,
-	.ndo_validate_addr	 = eth_validate_addr,
-	.ndo_set_mac_address 	 = eth_mac_addr,
-	.ndo_do_ioctl		 = netdev_ioctl,
-	.ndo_tx_timeout 	 = rhine_tx_timeout,
-	.ndo_vlan_rx_add_vid	 = rhine_vlan_rx_add_vid,
-	.ndo_vlan_rx_kill_vid	 = rhine_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-	.ndo_poll_controller	 = rhine_poll,
-#endif
-};
-
 static int __devinit rhine_init_one(struct pci_dev *pdev,
 				    const struct pci_device_id *ent)
 {
@@ -1774,21 +1421,6 @@  static void rhine_tx(struct net_device *dev)
 		netif_wake_queue(dev);
 }
 
-/**
- * rhine_get_vlan_tci - extract TCI from Rx data buffer
- * @skb: pointer to sk_buff
- * @data_size: used data area of the buffer including CRC
- *
- * If hardware VLAN tag extraction is enabled and the chip indicates a 802.1Q
- * packet, the extracted 802.1Q header (2 bytes TPID + 2 bytes TCI) is 4-byte
- * aligned following the CRC.
- */
-static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size)
-{
-	u8 *trailer = (u8 *)skb->data + ((data_size + 3) & ~3) + 2;
-	return be16_to_cpup((__be16 *)trailer);
-}
-
 /* Process up to limit frames from receive ring */
 static int rhine_rx(struct net_device *dev, int limit)
 {
@@ -1992,17 +1624,6 @@  out_unlock:
 	mutex_unlock(&rp->task_lock);
 }
 
-static struct net_device_stats *rhine_get_stats(struct net_device *dev)
-{
-	struct rhine_private *rp = netdev_priv(dev);
-
-	spin_lock_bh(&rp->lock);
-	rhine_update_rx_crc_and_missed_errord(rp);
-	spin_unlock_bh(&rp->lock);
-
-	return &dev->stats;
-}
-
 static void rhine_set_rx_mode(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
@@ -2142,18 +1763,6 @@  static int rhine_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 	return 0;
 }
 
-static const struct ethtool_ops netdev_ethtool_ops = {
-	.get_drvinfo		= netdev_get_drvinfo,
-	.get_settings		= netdev_get_settings,
-	.set_settings		= netdev_set_settings,
-	.nway_reset		= netdev_nway_reset,
-	.get_link		= netdev_get_link,
-	.get_msglevel		= netdev_get_msglevel,
-	.set_msglevel		= netdev_set_msglevel,
-	.get_wol		= rhine_get_wol,
-	.set_wol		= rhine_set_wol,
-};
-
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct rhine_private *rp = netdev_priv(dev);
@@ -2339,36 +1948,6 @@  static int rhine_resume(struct pci_dev *pdev)
 }
 #endif /* CONFIG_PM */
 
-static struct pci_driver rhine_driver = {
-	.name		= DRV_NAME,
-	.id_table	= rhine_pci_tbl,
-	.probe		= rhine_init_one,
-	.remove		= __devexit_p(rhine_remove_one),
-#ifdef CONFIG_PM
-	.suspend	= rhine_suspend,
-	.resume		= rhine_resume,
-#endif /* CONFIG_PM */
-	.shutdown =	rhine_shutdown,
-};
-
-static struct dmi_system_id __initdata rhine_dmi_table[] = {
-	{
-		.ident = "EPIA-M",
-		.matches = {
-			DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
-			DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
-		},
-	},
-	{
-		.ident = "KV7",
-		.matches = {
-			DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
-			DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
-		},
-	},
-	{ NULL }
-};
-
 static int __init rhine_init(void)
 {
 /* when a module, this is printed whether or not devices are found in probe */
@@ -2386,12 +1965,36 @@  static int __init rhine_init(void)
 	return pci_register_driver(&rhine_driver);
 }
 
-
 static void __exit rhine_cleanup(void)
 {
 	pci_unregister_driver(&rhine_driver);
 }
 
+static struct net_device_stats *rhine_get_stats(struct net_device *dev)
+{
+	struct rhine_private *rp = netdev_priv(dev);
+
+	spin_lock_bh(&rp->lock);
+	rhine_update_rx_crc_and_missed_errord(rp);
+	spin_unlock_bh(&rp->lock);
+
+	return &dev->stats;
+}
+
+/**
+ * rhine_get_vlan_tci - extract TCI from Rx data buffer
+ * @skb: pointer to sk_buff
+ * @data_size: used data area of the buffer including CRC
+ *
+ * If hardware VLAN tag extraction is enabled and the chip indicates a 802.1Q
+ * packet, the extracted 802.1Q header (2 bytes TPID + 2 bytes TCI) is 4-byte
+ * aligned following the CRC.
+ */
+static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size)
+{
+	u8 *trailer = (u8 *)skb->data + ((data_size + 3) & ~3) + 2;
+	return be16_to_cpup((__be16 *)trailer);
+}
 
 module_init(rhine_init);
 module_exit(rhine_cleanup);
diff --git a/drivers/net/ethernet/via/via-rhine.h b/drivers/net/ethernet/via/via-rhine.h
new file mode 100644
index 0000000..6add270
--- /dev/null
+++ b/drivers/net/ethernet/via/via-rhine.h
@@ -0,0 +1,440 @@ 
+/* via-rhine.c: A Linux Ethernet device driver for VIA Rhine family chips. */
+/*
+	Written 1998-2001 by Donald Becker.
+
+	Current Maintainer: Roger Luethi <rl@hellgate.ch>
+
+	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 designed for the VIA VT86C100A Rhine-I.
+	It also works with the Rhine-II (6102) and Rhine-III (6105/6105L/6105LOM
+	and management NIC 6105M).
+
+	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 contains some changes from the original Donald Becker
+	version. He may or may not be interested in bug reports on this
+	code. You can find his versions at:
+	http://www.scyld.com/network/via-rhine.html
+	[link no longer provides useful info -jgarzik]
+
+*/
+
+/* Operational parameters that are set at compile time. */
+
+/* Keep the ring sizes a power of two for compile efficiency.
+   The compiler will convert <unsigned>'%'<2^N> into a bit mask.
+   Making the Tx ring too large decreases the effectiveness of channel
+   bonding and packet priority.
+   There are no ill effects from too-large receive rings. */
+#define TX_RING_SIZE	16
+#define TX_QUEUE_LEN	10	/* Limit ring entries actually used. */
+#define RX_RING_SIZE	64
+
+/* Operational parameters that usually are not changed. */
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT	(2*HZ)
+
+#define PKT_BUF_SZ	1536	/* Size of each temporary Rx buffer.*/
+
+/* These identify the driver base version and may not be removed. */
+static const char version[] __devinitconst =
+	"v1.10-LK" DRV_VERSION " " DRV_RELDATE " Written by Donald Becker";
+
+/* This driver was written to use PCI memory space. Some early versions
+   of the Rhine may only work correctly with I/O space accesses. */
+#ifdef CONFIG_VIA_RHINE_MMIO
+#define USE_MMIO
+#else
+#endif
+
+#define MCAM_SIZE	32
+#define VCAM_SIZE	32
+
+/* 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.
+   Note the matching code -- the first table entry matchs all 56** cards but
+   second only the 1234 card.
+*/
+
+enum rhine_revs {
+	VT86C100A	= 0x00,
+	VTunknown0	= 0x20,
+	VT6102		= 0x40,
+	VT8231		= 0x50,	/* Integrated MAC */
+	VT8233		= 0x60,	/* Integrated MAC */
+	VT8235		= 0x74,	/* Integrated MAC */
+	VT8237		= 0x78,	/* Integrated MAC */
+	VTunknown1	= 0x7C,
+	VT6105		= 0x80,
+	VT6105_B0	= 0x83,
+	VT6105L		= 0x8A,
+	VT6107		= 0x8C,
+	VTunknown2	= 0x8E,
+	VT6105M		= 0x90,	/* Management adapter */
+};
+
+enum rhine_quirks {
+	rqWOL		= 0x0001,	/* Wake-On-LAN support */
+	rqForceReset	= 0x0002,
+	rq6patterns	= 0x0040,	/* 6 instead of 4 patterns for WOL */
+	rqStatusWBRace	= 0x0080,	/* Tx Status Writeback Error possible */
+	rqRhineI	= 0x0100,	/* See comment below */
+};
+/*
+ * rqRhineI: VT86C100A (aka Rhine-I) uses different bits to enable
+ * MMIO as well as for the collision counter and the Tx FIFO underflow
+ * indicator. In addition, Tx and Rx buffers need to 4 byte aligned.
+ */
+
+/* Beware of PCI posted writes */
+#define IOSYNC	do { ioread8(ioaddr + StationAddr); } while (0)
+
+static DEFINE_PCI_DEVICE_TABLE(rhine_pci_tbl) = {
+	{ 0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, },	/* VT86C100A */
+	{ 0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, },	/* VT6102 */
+	{ 0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, },	/* 6105{,L,LOM} */
+	{ 0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, },	/* VT6105M */
+	{ }	/* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
+
+
+/* Offsets to the device registers. */
+enum register_offsets {
+	StationAddr = 0x00, RxConfig = 0x06, TxConfig = 0x07, ChipCmd = 0x08,
+	ChipCmd1 = 0x09, TQWake = 0x0A,
+	IntrStatus = 0x0C, IntrEnable = 0x0E,
+	MulticastFilter0 = 0x10, MulticastFilter1 = 0x14,
+	RxRingPtr = 0x18, TxRingPtr = 0x1C, GFIFOTest = 0x54,
+	MIIPhyAddr = 0x6C, MIIStatus = 0x6D, PCIBusConfig = 0x6E, PCIBusConfig1 = 0x6F,
+	MIICmd = 0x70, MIIRegAddr = 0x71, MIIData = 0x72, MACRegEEcsr = 0x74,
+	ConfigA = 0x78, ConfigB = 0x79, ConfigC = 0x7A, ConfigD = 0x7B,
+	RxMissed = 0x7C, RxCRCErrs = 0x7E, MiscCmd = 0x81,
+	StickyHW = 0x83, IntrStatus2 = 0x84,
+	CamMask = 0x88, CamCon = 0x92, CamAddr = 0x93,
+	WOLcrSet = 0xA0, PwcfgSet = 0xA1, WOLcgSet = 0xA3, WOLcrClr = 0xA4,
+	WOLcrClr1 = 0xA6, WOLcgClr = 0xA7,
+	PwrcsrSet = 0xA8, PwrcsrSet1 = 0xA9, PwrcsrClr = 0xAC, PwrcsrClr1 = 0xAD,
+};
+
+/* Bits in ConfigD */
+enum backoff_bits {
+	BackOptional = 0x01, BackModify = 0x02,
+	BackCaptureEffect = 0x04, BackRandom = 0x08
+};
+
+/* Bits in the TxConfig (TCR) register */
+enum tcr_bits {
+	TCR_PQEN = 0x01,
+	TCR_LB0 = 0x02,		/* loopback[0] */
+	TCR_LB1 = 0x04,		/* loopback[1] */
+	TCR_OFSET = 0x08,
+	TCR_RTGOPT = 0x10,
+	TCR_RTFT0 = 0x20,
+	TCR_RTFT1 = 0x40,
+	TCR_RTSF = 0x80,
+};
+
+/* Bits in the CamCon (CAMC) register */
+enum camcon_bits {
+	CAMC_CAMEN = 0x01,
+	CAMC_VCAMSL = 0x02,
+	CAMC_CAMWR = 0x04,
+	CAMC_CAMRD = 0x08,
+};
+
+/* Bits in the PCIBusConfig1 (BCR1) register */
+enum bcr1_bits {
+	BCR1_POT0 = 0x01,
+	BCR1_POT1 = 0x02,
+	BCR1_POT2 = 0x04,
+	BCR1_CTFT0 = 0x08,
+	BCR1_CTFT1 = 0x10,
+	BCR1_CTSF = 0x20,
+	BCR1_TXQNOBK = 0x40,	/* for VT6105 */
+	BCR1_VIDFR = 0x80,	/* for VT6105 */
+	BCR1_MED0 = 0x40,		/* for VT6102 */
+	BCR1_MED1 = 0x80,		/* for VT6102 */
+};
+
+#ifdef USE_MMIO
+/* Registers we check that mmio and reg are the same. */
+static const int mmio_verify_registers[] = {
+	RxConfig, TxConfig, IntrEnable, ConfigA, ConfigB, ConfigC, ConfigD,
+	0
+};
+#endif
+
+/* Bits in the interrupt status/mask registers. */
+enum intr_status_bits {
+	IntrRxDone	= 0x0001,
+	IntrTxDone	= 0x0002,
+	IntrRxErr	= 0x0004,
+	IntrTxError	= 0x0008,
+	IntrRxEmpty	= 0x0020,
+	IntrPCIErr	= 0x0040,
+	IntrStatsMax	= 0x0080,
+	IntrRxEarly	= 0x0100,
+	IntrTxUnderrun	= 0x0210,
+	IntrRxOverflow	= 0x0400,
+	IntrRxDropped	= 0x0800,
+	IntrRxNoBuf	= 0x1000,
+	IntrTxAborted	= 0x2000,
+	IntrLinkChange	= 0x4000,
+	IntrRxWakeUp	= 0x8000,
+	IntrTxDescRace		= 0x080000,	/* mapped from IntrStatus2 */
+	IntrNormalSummary	= IntrRxDone | IntrTxDone,
+	IntrTxErrSummary	= IntrTxDescRace | IntrTxAborted | IntrTxError |
+				  IntrTxUnderrun,
+};
+
+/* Bits in WOLcrSet/WOLcrClr and PwrcsrSet/PwrcsrClr */
+enum wol_bits {
+	WOLucast	= 0x10,
+	WOLmagic	= 0x20,
+	WOLbmcast	= 0x30,
+	WOLlnkon	= 0x40,
+	WOLlnkoff	= 0x80,
+};
+
+/* The Rx and Tx buffer descriptors. */
+struct rx_desc {
+	__le32 rx_status;
+	__le32 desc_length; /* Chain flag, Buffer/frame length */
+	__le32 addr;
+	__le32 next_desc;
+};
+struct tx_desc {
+	__le32 tx_status;
+	__le32 desc_length; /* Chain flag, Tx Config, Frame length */
+	__le32 addr;
+	__le32 next_desc;
+};
+
+/* Initial value for tx_desc.desc_length, Buffer size goes to bits 0-10 */
+#define TXDESC		0x00e08000
+
+enum rx_status_bits {
+	RxOK = 0x8000, RxWholePkt = 0x0300, RxErr = 0x008F
+};
+
+/* Bits in *_desc.*_status */
+enum desc_status_bits {
+	DescOwn = 0x80000000
+};
+
+/* Bits in *_desc.*_length */
+enum desc_length_bits {
+	DescTag = 0x00010000
+};
+
+/* Bits in ChipCmd. */
+enum chip_cmd_bits {
+	CmdInit = 0x01, CmdStart = 0x02, CmdStop = 0x04, CmdRxOn = 0x08,
+	CmdTxOn = 0x10, Cmd1TxDemand = 0x20, CmdRxDemand = 0x40,
+	Cmd1EarlyRx = 0x01, Cmd1EarlyTx = 0x02, Cmd1FDuplex = 0x04,
+	Cmd1NoTxPoll = 0x08, Cmd1Reset = 0x80,
+};
+
+struct rhine_private {
+	/* Bit mask for configured VLAN ids */
+	unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
+
+	/* Descriptor rings */
+	struct rx_desc *rx_ring;
+	struct tx_desc *tx_ring;
+	dma_addr_t rx_ring_dma;
+	dma_addr_t tx_ring_dma;
+
+	/* The addresses of receive-in-place skbuffs. */
+	struct sk_buff *rx_skbuff[RX_RING_SIZE];
+	dma_addr_t rx_skbuff_dma[RX_RING_SIZE];
+
+	/* The saved address of a sent-in-place packet/buffer, for later free(). */
+	struct sk_buff *tx_skbuff[TX_RING_SIZE];
+	dma_addr_t tx_skbuff_dma[TX_RING_SIZE];
+
+	/* Tx bounce buffers (Rhine-I only) */
+	unsigned char *tx_buf[TX_RING_SIZE];
+	unsigned char *tx_bufs;
+	dma_addr_t tx_bufs_dma;
+
+	struct pci_dev *pdev;
+	long pioaddr;
+	struct net_device *dev;
+	struct napi_struct napi;
+	spinlock_t lock;
+	struct mutex task_lock;
+	bool task_enable;
+	struct work_struct slow_event_task;
+	struct work_struct reset_task;
+
+	u32 msg_enable;
+
+	/* Frequently used values: keep some adjacent for cache effect. */
+	u32 quirks;
+	struct rx_desc *rx_head_desc;
+	unsigned int cur_rx, dirty_rx;	/* Producer/consumer ring indices */
+	unsigned int cur_tx, dirty_tx;
+	unsigned int rx_buf_sz;		/* Based on MTU+slack. */
+	u8 wolopts;
+
+	u8 tx_thresh, rx_thresh;
+
+	struct mii_if_info mii_if;
+	void __iomem *base;
+};
+
+static struct dmi_system_id __initdata rhine_dmi_table[] = {
+	{
+		.ident = "EPIA-M",
+		.matches = {
+			DMI_MATCH(DMI_BIOS_VENDOR, "Award Software International, Inc."),
+			DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+		},
+	},
+	{
+		.ident = "KV7",
+		.matches = {
+			DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies, LTD"),
+			DMI_MATCH(DMI_BIOS_VERSION, "6.00 PG"),
+		},
+	},
+	{ NULL }
+};
+
+#define BYTE_REG_BITS_ON(x, p)      do { iowrite8((ioread8((p))|(x)), (p)); } while (0)
+#define WORD_REG_BITS_ON(x, p)      do { iowrite16((ioread16((p))|(x)), (p)); } while (0)
+#define DWORD_REG_BITS_ON(x, p)     do { iowrite32((ioread32((p))|(x)), (p)); } while (0)
+
+#define BYTE_REG_BITS_IS_ON(x, p)   (ioread8((p)) & (x))
+#define WORD_REG_BITS_IS_ON(x, p)   (ioread16((p)) & (x))
+#define DWORD_REG_BITS_IS_ON(x, p)  (ioread32((p)) & (x))
+
+#define BYTE_REG_BITS_OFF(x, p)     do { iowrite8(ioread8((p)) & (~(x)), (p)); } while (0)
+#define WORD_REG_BITS_OFF(x, p)     do { iowrite16(ioread16((p)) & (~(x)), (p)); } while (0)
+#define DWORD_REG_BITS_OFF(x, p)    do { iowrite32(ioread32((p)) & (~(x)), (p)); } while (0)
+
+#define BYTE_REG_BITS_SET(x, m, p)   do { iowrite8((ioread8((p)) & (~(m)))|(x), (p)); } while (0)
+#define WORD_REG_BITS_SET(x, m, p)   do { iowrite16((ioread16((p)) & (~(m)))|(x), (p)); } while (0)
+#define DWORD_REG_BITS_SET(x, m, p)  do { iowrite32((ioread32((p)) & (~(m)))|(x), (p)); } while (0)
+
+#define RHINE_WAIT_FOR(condition)				\
+do {								\
+	int i = 1024;						\
+	while (!(condition) && --i)				\
+		;						\
+	if (debug > 1 && i < 512)				\
+		pr_info("%4d cycles used @ %s:%d\n",		\
+			1024 - i, __func__, __LINE__);		\
+} while (0)
+
+#define RHINE_EVENT_NAPI_RX	(IntrRxDone | \
+				 IntrRxErr | \
+				 IntrRxEmpty | \
+				 IntrRxOverflow	| \
+				 IntrRxDropped | \
+				 IntrRxNoBuf | \
+				 IntrRxWakeUp)
+
+#define RHINE_EVENT_NAPI_TX_ERR	(IntrTxError | \
+				 IntrTxAborted | \
+				 IntrTxUnderrun | \
+				 IntrTxDescRace)
+#define RHINE_EVENT_NAPI_TX	(IntrTxDone | RHINE_EVENT_NAPI_TX_ERR)
+
+#define RHINE_EVENT_NAPI	(RHINE_EVENT_NAPI_RX | \
+				 RHINE_EVENT_NAPI_TX | \
+				 IntrStatsMax)
+#define RHINE_EVENT_SLOW	(IntrPCIErr | IntrLinkChange)
+#define RHINE_EVENT		(RHINE_EVENT_NAPI | RHINE_EVENT_SLOW)
+
+static const struct ethtool_ops netdev_ethtool_ops;
+
+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 value);
+static int rhine_open(struct net_device *dev);
+static void rhine_update_rx_crc_and_missed_errord(struct rhine_private *rp);
+static int __devinit rhine_init_one(struct pci_dev *pdev,
+				    const struct pci_device_id *ent);
+static void __devexit rhine_remove_one(struct pci_dev *pdev);
+static void rhine_reset_task(struct work_struct *work);
+static void rhine_slow_event_task(struct work_struct *work);
+static void rhine_tx_timeout(struct net_device *dev);
+static netdev_tx_t rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
+static irqreturn_t rhine_interrupt(int irq, void *dev_instance);
+static void rhine_tx(struct net_device *dev);
+static int rhine_rx(struct net_device *dev, int limit);
+static void rhine_set_rx_mode(struct net_device *dev);
+static struct net_device_stats *rhine_get_stats(struct net_device *dev);
+static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info);
+static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
+static int netdev_set_settings(struct net_device *dev, struct ethtool_cmd *cmd);
+static int netdev_nway_reset(struct net_device *dev);
+static u32 netdev_get_link(struct net_device *dev);
+static u32 netdev_get_msglevel(struct net_device *dev);
+static void netdev_set_msglevel(struct net_device *dev, u32 value);
+static void rhine_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
+static int rhine_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol);
+static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static void rhine_task_enable(struct rhine_private *rp);
+static int rhine_close(struct net_device *dev);
+static void rhine_shutdown(struct pci_dev *pdev);
+static int rhine_vlan_rx_add_vid(struct net_device *dev, unsigned short vid);
+static int rhine_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid);
+static void rhine_restart_tx(struct net_device *dev);
+static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size);
+
+static const struct net_device_ops rhine_netdev_ops = {
+	.ndo_open		 = rhine_open,
+	.ndo_stop		 = rhine_close,
+	.ndo_start_xmit		 = rhine_start_tx,
+	.ndo_get_stats		 = rhine_get_stats,
+	.ndo_set_rx_mode	 = rhine_set_rx_mode,
+	.ndo_change_mtu		 = eth_change_mtu,
+	.ndo_validate_addr	 = eth_validate_addr,
+	.ndo_set_mac_address	 = eth_mac_addr,
+	.ndo_do_ioctl		 = netdev_ioctl,
+	.ndo_tx_timeout		 = rhine_tx_timeout,
+	.ndo_vlan_rx_add_vid	 = rhine_vlan_rx_add_vid,
+	.ndo_vlan_rx_kill_vid	 = rhine_vlan_rx_kill_vid,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	.ndo_poll_controller	 = rhine_poll,
+#endif
+};
+
+static const struct ethtool_ops netdev_ethtool_ops = {
+	.get_drvinfo		= netdev_get_drvinfo,
+	.get_settings		= netdev_get_settings,
+	.set_settings		= netdev_set_settings,
+	.nway_reset		= netdev_nway_reset,
+	.get_link		= netdev_get_link,
+	.get_msglevel		= netdev_get_msglevel,
+	.set_msglevel		= netdev_set_msglevel,
+	.get_wol		= rhine_get_wol,
+	.set_wol		= rhine_set_wol,
+};
+
+static struct pci_driver rhine_driver = {
+	.name		= DRV_NAME,
+	.id_table	= rhine_pci_tbl,
+	.probe		= rhine_init_one,
+	.remove		= __devexit_p(rhine_remove_one),
+#ifdef CONFIG_PM
+	.suspend	= rhine_suspend,
+	.resume		= rhine_resume,
+#endif /* CONFIG_PM */
+	.shutdown =	rhine_shutdown,
+};