View | Details | Raw Unified
Collapse All | Expand All

(-) linux-2.6.18-rc6/drivers/net/r8169.c (-275 / +374 lines)
 Lines 6-31    Link Here 
 History:
 History:
 Feb  4 2002	- created initially by ShuChen <shuchen@realtek.com.tw>.
 Feb  4 2002	- created initially by ShuChen <shuchen@realtek.com.tw>.
 May 20 2002	- Add link status force-mode and TBI mode support.
 May 20 2002	- Add link status force-mode and TBI mode support.
        2004	- Massive updates. See kernel SCM system for details.
	2004	- Massive updates. See kernel SCM system for details.
=========================================================================
=========================================================================
  1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes.
  1. [DEPRECATED: use ethtool instead] The media can be forced in 5 modes.
	 Command: 'insmod r8169 media = SET_MEDIA'
	 Command: 'insmod r8169 media = SET_MEDIA'
	 Ex:	  'insmod r8169 media = 0x04' will force PHY to operate in 100Mpbs Half-duplex.
	 Ex:	  'insmod r8169 media = 0x04' will force PHY to operate in 100Mpbs Half-duplex.
	
	 SET_MEDIA can be:
	 SET_MEDIA can be:
 		_10_Half	= 0x01
 		_10_Half	= 0x01
 		_10_Full	= 0x02
 		_10_Full	= 0x02
 		_100_Half	= 0x04
 		_100_Half	= 0x04
 		_100_Full	= 0x08
 		_100_Full	= 0x08
 		_1000_Full	= 0x10
 		_1000_Full	= 0x10
  
  2. Support TBI mode.
  2. Support TBI mode.
=========================================================================
=========================================================================
VERSION 1.1	<2002/10/4>
VERSION 1.1	<2002/10/4>
	The bit4:0 of MII register 4 is called "selector field", and have to be
	The bit4:0 of MII register 4 is called "selector field", and have to be
	00001b to indicate support of IEEE std 802.3 during NWay process of
	00001b to indicate support of IEEE std 802.3 during NWay process of
	exchanging Link Code Word (FLP). 
	exchanging Link Code Word (FLP).
VERSION 1.2	<2002/11/30>
VERSION 1.2	<2002/11/30>
 Lines 81-90   VERSION 2.2LK <2005/01/25> Link Here 
#ifdef RTL8169_DEBUG
#ifdef RTL8169_DEBUG
#define assert(expr) \
#define assert(expr) \
        if(!(expr)) {					\
	if (!(expr)) {					\
	        printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
		printk( "Assertion failed! %s,%s,%s,line=%d\n",	\
        	#expr,__FILE__,__FUNCTION__,__LINE__);		\
		#expr,__FILE__,__FUNCTION__,__LINE__);		\
        }
	}
#define dprintk(fmt, args...)	do { printk(PFX fmt, ## args); } while (0)
#define dprintk(fmt, args...)	do { printk(PFX fmt, ## args); } while (0)
#else
#else
#define assert(expr) do {} while (0)
#define assert(expr) do {} while (0)
 Lines 150-160   static const int multicast_filter_limit Link Here 
#define RTL_R32(reg)		((unsigned long) readl (ioaddr + (reg)))
#define RTL_R32(reg)		((unsigned long) readl (ioaddr + (reg)))
enum mac_version {
enum mac_version {
	RTL_GIGA_MAC_VER_B = 0x00,
	RTL_GIGA_MAC_VER_01 = 0x00,
	/* RTL_GIGA_MAC_VER_C = 0x03, */
	RTL_GIGA_MAC_VER_02 = 0x01,
	RTL_GIGA_MAC_VER_D = 0x01,
	RTL_GIGA_MAC_VER_03 = 0x02,
	RTL_GIGA_MAC_VER_E = 0x02,
	RTL_GIGA_MAC_VER_04 = 0x03,
	RTL_GIGA_MAC_VER_X = 0x04	/* Greater than RTL_GIGA_MAC_VER_E */
	RTL_GIGA_MAC_VER_05 = 0x04,
	RTL_GIGA_MAC_VER_11 = 0x0b,
	RTL_GIGA_MAC_VER_12 = 0x0c,
	RTL_GIGA_MAC_VER_13 = 0x0d,
	RTL_GIGA_MAC_VER_14 = 0x0e,
	RTL_GIGA_MAC_VER_15 = 0x0f
};
};
enum phy_version {
enum phy_version {
 Lines 166-172   enum phy_version { Link Here 
	RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */
	RTL_GIGA_PHY_VER_H = 0x08, /* PHY Reg 0x03 bit0-3 == 0x0003 */
};
};
#define _R(NAME,MAC,MASK) \
#define _R(NAME,MAC,MASK) \
	{ .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
	{ .name = NAME, .mac_version = MAC, .RxConfigMask = MASK }
 Lines 175-193   static const struct { Link Here 
	u8 mac_version;
	u8 mac_version;
	u32 RxConfigMask;	/* Clears the bits supported by this chip */
	u32 RxConfigMask;	/* Clears the bits supported by this chip */
} rtl_chip_info[] = {
} rtl_chip_info[] = {
	_R("RTL8169",		RTL_GIGA_MAC_VER_B, 0xff7e1880),
	_R("RTL8169",		RTL_GIGA_MAC_VER_01, 0xff7e1880),
	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_D, 0xff7e1880),
	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_02, 0xff7e1880),
	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_E, 0xff7e1880),
	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_03, 0xff7e1880),
	_R("RTL8169s/8110s",	RTL_GIGA_MAC_VER_X, 0xff7e1880),
	_R("RTL8169sb/8110sb",	RTL_GIGA_MAC_VER_04, 0xff7e1880),
	_R("RTL8169sc/8110sc",	RTL_GIGA_MAC_VER_05, 0xff7e1880),
	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
	_R("RTL8168b/8111b",	RTL_GIGA_MAC_VER_12, 0xff7e1880), // PCI-E
	_R("RTL8101e",		RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
	_R("RTL8100e",		RTL_GIGA_MAC_VER_14, 0xff7e1880), // PCI-E 8139
	_R("RTL8100e",		RTL_GIGA_MAC_VER_15, 0xff7e1880)  // PCI-E 8139
};
};
#undef _R
#undef _R
enum cfg_version {
	RTL_CFG_0 = 0x00,
	RTL_CFG_1,
	RTL_CFG_2
};
static const struct {
	unsigned int region;
	unsigned int align;
} rtl_cfg_info[] = {
	[RTL_CFG_0] = { 1, NET_IP_ALIGN },
	[RTL_CFG_1] = { 2, NET_IP_ALIGN },
	[RTL_CFG_2] = { 2, 8 }
};
static struct pci_device_id rtl8169_pci_tbl[] = {
static struct pci_device_id rtl8169_pci_tbl[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), },
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), 0, 0, RTL_CFG_0 },
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8129), },
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8136), 0, 0, RTL_CFG_2 },
	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), },
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8167), 0, 0, RTL_CFG_1 },
	{ PCI_DEVICE(0x16ec,			0x0116), },
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8168), 0, 0, RTL_CFG_2 },
	{ PCI_VENDOR_ID_LINKSYS,		0x1032, PCI_ANY_ID, 0x0024, },
	{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK,	0x8169), 0, 0, RTL_CFG_0 },
	{ PCI_DEVICE(PCI_VENDOR_ID_DLINK,	0x4300), 0, 0, RTL_CFG_0 },
	{ PCI_DEVICE(0x16ec,			0x0116), 0, 0, RTL_CFG_0 },
	{ PCI_VENDOR_ID_LINKSYS,		0x1032,
		PCI_ANY_ID, 0x0024, 0, 0, RTL_CFG_0 },
	{0,},
	{0,},
};
};
 Lines 257-266   enum RTL8169_register_content { Link Here 
	RxOK = 0x01,
	RxOK = 0x01,
	/* RxStatusDesc */
	/* RxStatusDesc */
	RxRES = 0x00200000,
	RxFOVF	= (1 << 23),
	RxCRC = 0x00080000,
	RxRWT	= (1 << 22),
	RxRUNT = 0x00100000,
	RxRES	= (1 << 21),
	RxRWT = 0x00400000,
	RxRUNT	= (1 << 20),
	RxCRC	= (1 << 19),
	/* ChipCmdBits */
	/* ChipCmdBits */
	CmdReset = 0x10,
	CmdReset = 0x10,
 Lines 326-355   enum RTL8169_register_content { Link Here 
	LinkStatus = 0x02,
	LinkStatus = 0x02,
	FullDup = 0x01,
	FullDup = 0x01,
	/* GIGABIT_PHY_registers */
	PHY_CTRL_REG = 0,
	PHY_STAT_REG = 1,
	PHY_AUTO_NEGO_REG = 4,
	PHY_1000_CTRL_REG = 9,
	/* GIGABIT_PHY_REG_BIT */
	PHY_Restart_Auto_Nego = 0x0200,
	PHY_Enable_Auto_Nego = 0x1000,
	/* PHY_STAT_REG = 1 */
	PHY_Auto_Neco_Comp = 0x0020,
	/* PHY_AUTO_NEGO_REG = 4 */
	PHY_Cap_10_Half = 0x0020,
	PHY_Cap_10_Full = 0x0040,
	PHY_Cap_100_Half = 0x0080,
	PHY_Cap_100_Full = 0x0100,
	/* PHY_1000_CTRL_REG = 9 */
	PHY_Cap_1000_Full = 0x0200,
	PHY_Cap_Null = 0x0,
	/* _MediaType */
	/* _MediaType */
	_10_Half = 0x01,
	_10_Half = 0x01,
	_10_Full = 0x02,
	_10_Full = 0x02,
 Lines 433-438   struct rtl8169_private { Link Here 
	dma_addr_t RxPhyAddr;
	dma_addr_t RxPhyAddr;
	struct sk_buff *Rx_skbuff[NUM_RX_DESC];	/* Rx data buffers */
	struct sk_buff *Rx_skbuff[NUM_RX_DESC];	/* Rx data buffers */
	struct ring_info tx_skb[NUM_TX_DESC];	/* Tx data buffers */
	struct ring_info tx_skb[NUM_TX_DESC];	/* Tx data buffers */
	unsigned align;
	unsigned rx_buf_sz;
	unsigned rx_buf_sz;
	struct timer_list timer;
	struct timer_list timer;
	u16 cp_cmd;
	u16 cp_cmd;
 Lines 488-499   static const u16 rtl8169_intr_mask = Link Here 
static const u16 rtl8169_napi_event =
static const u16 rtl8169_napi_event =
	RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr;
	RxOK | RxOverflow | RxFIFOOver | TxOK | TxErr;
static const unsigned int rtl8169_rx_config =
static const unsigned int rtl8169_rx_config =
    (RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
	(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
#define PHY_Cap_10_Half_Or_Less PHY_Cap_10_Half
#define PHY_Cap_10_Full_Or_Less PHY_Cap_10_Full | PHY_Cap_10_Half_Or_Less
#define PHY_Cap_100_Half_Or_Less PHY_Cap_100_Half | PHY_Cap_10_Full_Or_Less
#define PHY_Cap_100_Full_Or_Less PHY_Cap_100_Full | PHY_Cap_100_Half_Or_Less
static void mdio_write(void __iomem *ioaddr, int RegAddr, int value)
static void mdio_write(void __iomem *ioaddr, int RegAddr, int value)
{
{
 Lines 503-509   static void mdio_write(void __iomem *ioa Link Here 
	for (i = 20; i > 0; i--) {
	for (i = 20; i > 0; i--) {
		/* Check if the RTL8169 has completed writing to the specified MII register */
		/* Check if the RTL8169 has completed writing to the specified MII register */
		if (!(RTL_R32(PHYAR) & 0x80000000)) 
		if (!(RTL_R32(PHYAR) & 0x80000000))
			break;
			break;
		udelay(25);
		udelay(25);
	}
	}
 Lines 547-553   static unsigned int rtl8169_tbi_reset_pe Link Here 
static unsigned int rtl8169_xmii_reset_pending(void __iomem *ioaddr)
static unsigned int rtl8169_xmii_reset_pending(void __iomem *ioaddr)
{
{
	return mdio_read(ioaddr, 0) & 0x8000;
	return mdio_read(ioaddr, MII_BMCR) & BMCR_RESET;
}
}
static unsigned int rtl8169_tbi_link_ok(void __iomem *ioaddr)
static unsigned int rtl8169_tbi_link_ok(void __iomem *ioaddr)
 Lines 569-576   static void rtl8169_xmii_reset_enable(vo Link Here 
{
{
	unsigned int val;
	unsigned int val;
	val = (mdio_read(ioaddr, PHY_CTRL_REG) | 0x8000) & 0xffff;
	val = (mdio_read(ioaddr, MII_BMCR) | BMCR_RESET) & 0xffff;
	mdio_write(ioaddr, PHY_CTRL_REG, val);
	mdio_write(ioaddr, MII_BMCR, val);
}
}
static void rtl8169_check_link_status(struct net_device *dev,
static void rtl8169_check_link_status(struct net_device *dev,
 Lines 608-614   static void rtl8169_link_option(int idx, Link Here 
		{ SPEED_1000,	DUPLEX_FULL, AUTONEG_ENABLE,	0xff }
		{ SPEED_1000,	DUPLEX_FULL, AUTONEG_ENABLE,	0xff }
	}, *p;
	}, *p;
	unsigned char option;
	unsigned char option;
	
	option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff;
	option = ((idx < MAX_UNITS) && (idx >= 0)) ? media[idx] : 0xff;
	if ((option != 0xff) && !idx && netif_msg_drv(&debug))
	if ((option != 0xff) && !idx && netif_msg_drv(&debug))
 Lines 650-658   static void rtl8169_get_wol(struct net_d Link Here 
	if (options & UWF)
	if (options & UWF)
		wol->wolopts |= WAKE_UCAST;
		wol->wolopts |= WAKE_UCAST;
	if (options & BWF)
	if (options & BWF)
	        wol->wolopts |= WAKE_BCAST;
		wol->wolopts |= WAKE_BCAST;
	if (options & MWF)
	if (options & MWF)
	        wol->wolopts |= WAKE_MCAST;
		wol->wolopts |= WAKE_MCAST;
out_unlock:
out_unlock:
	spin_unlock_irq(&tp->lock);
	spin_unlock_irq(&tp->lock);
 Lines 745-782   static int rtl8169_set_speed_xmii(struct Link Here 
	void __iomem *ioaddr = tp->mmio_addr;
	void __iomem *ioaddr = tp->mmio_addr;
	int auto_nego, giga_ctrl;
	int auto_nego, giga_ctrl;
	auto_nego = mdio_read(ioaddr, PHY_AUTO_NEGO_REG);
	auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
	auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_10_Full |
	auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
		       PHY_Cap_100_Half | PHY_Cap_100_Full);
		       ADVERTISE_100HALF | ADVERTISE_100FULL);
	giga_ctrl = mdio_read(ioaddr, PHY_1000_CTRL_REG);
	giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
	giga_ctrl &= ~(PHY_Cap_1000_Full | PHY_Cap_Null);
	giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
	if (autoneg == AUTONEG_ENABLE) {
	if (autoneg == AUTONEG_ENABLE) {
		auto_nego |= (PHY_Cap_10_Half | PHY_Cap_10_Full |
		auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
			      PHY_Cap_100_Half | PHY_Cap_100_Full);
			      ADVERTISE_100HALF | ADVERTISE_100FULL);
		giga_ctrl |= PHY_Cap_1000_Full;
		giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
	} else {
	} else {
		if (speed == SPEED_10)
		if (speed == SPEED_10)
			auto_nego |= PHY_Cap_10_Half | PHY_Cap_10_Full;
			auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL;
		else if (speed == SPEED_100)
		else if (speed == SPEED_100)
			auto_nego |= PHY_Cap_100_Half | PHY_Cap_100_Full;
			auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL;
		else if (speed == SPEED_1000)
		else if (speed == SPEED_1000)
			giga_ctrl |= PHY_Cap_1000_Full;
			giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
		if (duplex == DUPLEX_HALF)
		if (duplex == DUPLEX_HALF)
			auto_nego &= ~(PHY_Cap_10_Full | PHY_Cap_100_Full);
			auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL);
		if (duplex == DUPLEX_FULL)
		if (duplex == DUPLEX_FULL)
			auto_nego &= ~(PHY_Cap_10_Half | PHY_Cap_100_Half);
			auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_100HALF);
		/* This tweak comes straight from Realtek's driver. */
		if ((speed == SPEED_100) && (duplex == DUPLEX_HALF) &&
		    (tp->mac_version == RTL_GIGA_MAC_VER_13)) {
			auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA;
		}
	}
	}
	/* The 8100e/8101e do Fast Ethernet only. */
	if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
	    (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
	    (tp->mac_version == RTL_GIGA_MAC_VER_15)) {
		if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
		    netif_msg_link(tp)) {
			printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
			       dev->name);
		}
		giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
	}
	auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
	tp->phy_auto_nego_reg = auto_nego;
	tp->phy_auto_nego_reg = auto_nego;
	tp->phy_1000_ctrl_reg = giga_ctrl;
	tp->phy_1000_ctrl_reg = giga_ctrl;
	mdio_write(ioaddr, PHY_AUTO_NEGO_REG, auto_nego);
	mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
	mdio_write(ioaddr, PHY_1000_CTRL_REG, giga_ctrl);
	mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
	mdio_write(ioaddr, PHY_CTRL_REG, PHY_Enable_Auto_Nego |
	mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
					 PHY_Restart_Auto_Nego);
	return 0;
	return 0;
}
}
 Lines 788-794   static int rtl8169_set_speed(struct net_ Link Here 
	ret = tp->set_speed(dev, autoneg, speed, duplex);
	ret = tp->set_speed(dev, autoneg, speed, duplex);
	if (netif_running(dev) && (tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full))
	if (netif_running(dev) && (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL))
		mod_timer(&tp->timer, jiffies + RTL8169_PHY_TIMEOUT);
		mod_timer(&tp->timer, jiffies + RTL8169_PHY_TIMEOUT);
	return ret;
	return ret;
 Lines 803-809   static int rtl8169_set_settings(struct n Link Here 
	spin_lock_irqsave(&tp->lock, flags);
	spin_lock_irqsave(&tp->lock, flags);
	ret = rtl8169_set_speed(dev, cmd->autoneg, cmd->speed, cmd->duplex);
	ret = rtl8169_set_speed(dev, cmd->autoneg, cmd->speed, cmd->duplex);
	spin_unlock_irqrestore(&tp->lock, flags);
	spin_unlock_irqrestore(&tp->lock, flags);
	
	return ret;
	return ret;
}
}
 Lines 936-955   static void rtl8169_gset_xmii(struct net Link Here 
			 SUPPORTED_100baseT_Full |
			 SUPPORTED_100baseT_Full |
			 SUPPORTED_1000baseT_Full |
			 SUPPORTED_1000baseT_Full |
			 SUPPORTED_Autoneg |
			 SUPPORTED_Autoneg |
		         SUPPORTED_TP;
			 SUPPORTED_TP;
	cmd->autoneg = 1;
	cmd->autoneg = 1;
	cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
	cmd->advertising = ADVERTISED_TP | ADVERTISED_Autoneg;
	if (tp->phy_auto_nego_reg & PHY_Cap_10_Half)
	if (tp->phy_auto_nego_reg & ADVERTISE_10HALF)
		cmd->advertising |= ADVERTISED_10baseT_Half;
		cmd->advertising |= ADVERTISED_10baseT_Half;
	if (tp->phy_auto_nego_reg & PHY_Cap_10_Full)
	if (tp->phy_auto_nego_reg & ADVERTISE_10FULL)
		cmd->advertising |= ADVERTISED_10baseT_Full;
		cmd->advertising |= ADVERTISED_10baseT_Full;
	if (tp->phy_auto_nego_reg & PHY_Cap_100_Half)
	if (tp->phy_auto_nego_reg & ADVERTISE_100HALF)
		cmd->advertising |= ADVERTISED_100baseT_Half;
		cmd->advertising |= ADVERTISED_100baseT_Half;
	if (tp->phy_auto_nego_reg & PHY_Cap_100_Full)
	if (tp->phy_auto_nego_reg & ADVERTISE_100FULL)
		cmd->advertising |= ADVERTISED_100baseT_Full;
		cmd->advertising |= ADVERTISED_100baseT_Full;
	if (tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full)
	if (tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL)
		cmd->advertising |= ADVERTISED_1000baseT_Full;
		cmd->advertising |= ADVERTISED_1000baseT_Full;
	status = RTL_R8(PHYstatus);
	status = RTL_R8(PHYstatus);
 Lines 961-966   static void rtl8169_gset_xmii(struct net Link Here 
	else if (status & _10bps)
	else if (status & _10bps)
		cmd->speed = SPEED_10;
		cmd->speed = SPEED_10;
	if (status & TxFlowCtrl)
		cmd->advertising |= ADVERTISED_Asym_Pause;
	if (status & RxFlowCtrl)
		cmd->advertising |= ADVERTISED_Pause;
	cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
	cmd->duplex = ((status & _1000bpsF) || (status & FullDup)) ?
		      DUPLEX_FULL : DUPLEX_HALF;
		      DUPLEX_FULL : DUPLEX_HALF;
}
}
 Lines 981-995   static int rtl8169_get_settings(struct n Link Here 
static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs,
			     void *p)
			     void *p)
{
{
        struct rtl8169_private *tp = netdev_priv(dev);
	struct rtl8169_private *tp = netdev_priv(dev);
        unsigned long flags;
	unsigned long flags;
        if (regs->len > R8169_REGS_SIZE)
	if (regs->len > R8169_REGS_SIZE)
        	regs->len = R8169_REGS_SIZE;
		regs->len = R8169_REGS_SIZE;
        spin_lock_irqsave(&tp->lock, flags);
	spin_lock_irqsave(&tp->lock, flags);
        memcpy_fromio(p, tp->mmio_addr, regs->len);
	memcpy_fromio(p, tp->mmio_addr, regs->len);
        spin_unlock_irqrestore(&tp->lock, flags);
	spin_unlock_irqrestore(&tp->lock, flags);
}
}
static u32 rtl8169_get_msglevel(struct net_device *dev)
static u32 rtl8169_get_msglevel(struct net_device *dev)
 Lines 1071-1077   static void rtl8169_get_ethtool_stats(st Link Here 
	RTL_W32(CounterAddrLow, 0);
	RTL_W32(CounterAddrLow, 0);
	RTL_W32(CounterAddrHigh, 0);
	RTL_W32(CounterAddrHigh, 0);
	data[0]	= le64_to_cpu(counters->tx_packets);
	data[0] = le64_to_cpu(counters->tx_packets);
	data[1] = le64_to_cpu(counters->rx_packets);
	data[1] = le64_to_cpu(counters->rx_packets);
	data[2] = le64_to_cpu(counters->tx_errors);
	data[2] = le64_to_cpu(counters->tx_errors);
	data[3] = le32_to_cpu(counters->rx_errors);
	data[3] = le32_to_cpu(counters->rx_errors);
 Lines 1131-1137   static void rtl8169_write_gmii_reg_bit(v Link Here 
	val = mdio_read(ioaddr, reg);
	val = mdio_read(ioaddr, reg);
	val = (bitval == 1) ?
	val = (bitval == 1) ?
		val | (bitval << bitnum) :  val & ~(0x0001 << bitnum);
		val | (bitval << bitnum) :  val & ~(0x0001 << bitnum);
	mdio_write(ioaddr, reg, val & 0xffff); 
	mdio_write(ioaddr, reg, val & 0xffff);
}
}
static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr)
static void rtl8169_get_mac_version(struct rtl8169_private *tp, void __iomem *ioaddr)
 Lines 1140-1149   static void rtl8169_get_mac_version(stru Link Here 
		u32 mask;
		u32 mask;
		int mac_version;
		int mac_version;
	} mac_info[] = {
	} mac_info[] = {
		{ 0x1 << 28,	RTL_GIGA_MAC_VER_X },
		{ 0x38800000,	RTL_GIGA_MAC_VER_15 },
		{ 0x1 << 26,	RTL_GIGA_MAC_VER_E },
		{ 0x38000000,	RTL_GIGA_MAC_VER_12 },
		{ 0x1 << 23,	RTL_GIGA_MAC_VER_D }, 
		{ 0x34000000,	RTL_GIGA_MAC_VER_13 },
		{ 0x00000000,	RTL_GIGA_MAC_VER_B } /* Catch-all */
		{ 0x30800000,	RTL_GIGA_MAC_VER_14 },
		{ 0x30000000,	RTL_GIGA_MAC_VER_11 },
		{ 0x18000000,	RTL_GIGA_MAC_VER_05 },
		{ 0x10000000,	RTL_GIGA_MAC_VER_04 },
		{ 0x04000000,	RTL_GIGA_MAC_VER_03 },
		{ 0x00800000,	RTL_GIGA_MAC_VER_02 },
		{ 0x00000000,	RTL_GIGA_MAC_VER_01 }	/* Catch-all */
	}, *p = mac_info;
	}, *p = mac_info;
	u32 reg;
	u32 reg;
 Lines 1155-1178   static void rtl8169_get_mac_version(stru Link Here 
static void rtl8169_print_mac_version(struct rtl8169_private *tp)
static void rtl8169_print_mac_version(struct rtl8169_private *tp)
{
{
	struct {
	dprintk("mac_version = 0x%02x\n", tp->mac_version);
		int version;
		char *msg;
	} mac_print[] = {
		{ RTL_GIGA_MAC_VER_E, "RTL_GIGA_MAC_VER_E" },
		{ RTL_GIGA_MAC_VER_D, "RTL_GIGA_MAC_VER_D" },
		{ RTL_GIGA_MAC_VER_B, "RTL_GIGA_MAC_VER_B" },
		{ 0, NULL }
	}, *p;
	for (p = mac_print; p->msg; p++) {
		if (tp->mac_version == p->version) {
			dprintk("mac_version == %s (%04d)\n", p->msg,
				  p->version);
			return;
		}
	}
	dprintk("mac_version == Unknown\n");
}
}
static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr)
static void rtl8169_get_phy_version(struct rtl8169_private *tp, void __iomem *ioaddr)
 Lines 1189-1195   static void rtl8169_get_phy_version(stru Link Here 
	}, *p = phy_info;
	}, *p = phy_info;
	u16 reg;
	u16 reg;
	reg = mdio_read(ioaddr, 3) & 0xffff;
	reg = mdio_read(ioaddr, MII_PHYSID2) & 0xffff;
	while ((reg & p->mask) != p->set)
	while ((reg & p->mask) != p->set)
		p++;
		p++;
	tp->phy_version = p->phy_version;
	tp->phy_version = p->phy_version;
 Lines 1257-1263   static void rtl8169_hw_phy_config(struct Link Here 
	rtl8169_print_mac_version(tp);
	rtl8169_print_mac_version(tp);
	rtl8169_print_phy_version(tp);
	rtl8169_print_phy_version(tp);
	if (tp->mac_version <= RTL_GIGA_MAC_VER_B)
	if (tp->mac_version <= RTL_GIGA_MAC_VER_01)
		return;
		return;
	if (tp->phy_version >= RTL_GIGA_PHY_VER_H)
	if (tp->phy_version >= RTL_GIGA_PHY_VER_H)
		return;
		return;
 Lines 1267-1273   static void rtl8169_hw_phy_config(struct Link Here 
	/* Shazam ! */
	/* Shazam ! */
	if (tp->mac_version == RTL_GIGA_MAC_VER_X) {
	if (tp->mac_version == RTL_GIGA_MAC_VER_04) {
		mdio_write(ioaddr, 31, 0x0001);
		mdio_write(ioaddr, 31, 0x0001);
		mdio_write(ioaddr,  9, 0x273a);
		mdio_write(ioaddr,  9, 0x273a);
		mdio_write(ioaddr, 14, 0x7bfb);
		mdio_write(ioaddr, 14, 0x7bfb);
 Lines 1306-1321   static void rtl8169_phy_timer(unsigned l Link Here 
	void __iomem *ioaddr = tp->mmio_addr;
	void __iomem *ioaddr = tp->mmio_addr;
	unsigned long timeout = RTL8169_PHY_TIMEOUT;
	unsigned long timeout = RTL8169_PHY_TIMEOUT;
	assert(tp->mac_version > RTL_GIGA_MAC_VER_B);
	assert(tp->mac_version > RTL_GIGA_MAC_VER_01);
	assert(tp->phy_version < RTL_GIGA_PHY_VER_H);
	assert(tp->phy_version < RTL_GIGA_PHY_VER_H);
	if (!(tp->phy_1000_ctrl_reg & PHY_Cap_1000_Full))
	if (!(tp->phy_1000_ctrl_reg & ADVERTISE_1000FULL))
		return;
		return;
	spin_lock_irq(&tp->lock);
	spin_lock_irq(&tp->lock);
	if (tp->phy_reset_pending(ioaddr)) {
	if (tp->phy_reset_pending(ioaddr)) {
		/* 
		/*
		 * A busy loop could burn quite a few cycles on nowadays CPU.
		 * A busy loop could burn quite a few cycles on nowadays CPU.
		 * Let's delay the execution of the timer for a few ticks.
		 * Let's delay the execution of the timer for a few ticks.
		 */
		 */
 Lines 1342-1348   static inline void rtl8169_delete_timer( Link Here 
	struct rtl8169_private *tp = netdev_priv(dev);
	struct rtl8169_private *tp = netdev_priv(dev);
	struct timer_list *timer = &tp->timer;
	struct timer_list *timer = &tp->timer;
	if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
	if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
		return;
		return;
 Lines 1354-1360   static inline void rtl8169_request_timer Link Here 
	struct rtl8169_private *tp = netdev_priv(dev);
	struct rtl8169_private *tp = netdev_priv(dev);
	struct timer_list *timer = &tp->timer;
	struct timer_list *timer = &tp->timer;
	if ((tp->mac_version <= RTL_GIGA_MAC_VER_B) ||
	if ((tp->mac_version <= RTL_GIGA_MAC_VER_01) ||
	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
	    (tp->phy_version >= RTL_GIGA_PHY_VER_H))
		return;
		return;
 Lines 1382-1387   static void rtl8169_netpoll(struct net_d Link Here 
}
}
#endif
#endif
static void __rtl8169_set_mac_addr(struct net_device *dev, void __iomem *ioaddr)
{
	unsigned int i, j;
	RTL_W8(Cfg9346, Cfg9346_Unlock);
	for (i = 0; i < 2; i++) {
		__le32 l = 0;
		for (j = 0; j < 4; j++) {
			l <<= 8;
			l |= dev->dev_addr[4*i + j];
		}
		RTL_W32(MAC0 + 4*i, cpu_to_be32(l));
	}
	RTL_W8(Cfg9346, Cfg9346_Lock);
}
static int rtl8169_set_mac_addr(struct net_device *dev, void *p)
{
	struct rtl8169_private *tp = netdev_priv(dev);
	struct sockaddr *addr = p;
	if (!is_valid_ether_addr(addr->sa_data))
		return -EINVAL;
	memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
	if (netif_running(dev)) {
		spin_lock_irq(&tp->lock);
		__rtl8169_set_mac_addr(dev, tp->mmio_addr);
		spin_unlock_irq(&tp->lock);
	}
	return 0;
}
static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev,
				  void __iomem *ioaddr)
				  void __iomem *ioaddr)
{
{
 Lines 1391-1413   static void rtl8169_release_board(struct Link Here 
	free_netdev(dev);
	free_netdev(dev);
}
}
static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
{
	void __iomem *ioaddr = tp->mmio_addr;
	static int board_idx = -1;
	u8 autoneg, duplex;
	u16 speed;
	board_idx++;
	rtl8169_hw_phy_config(dev);
	dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
	RTL_W8(0x82, 0x01);
	if (tp->mac_version < RTL_GIGA_MAC_VER_03) {
		dprintk("Set PCI Latency=0x40\n");
		pci_write_config_byte(tp->pci_dev, PCI_LATENCY_TIMER, 0x40);
	}
	if (tp->mac_version == RTL_GIGA_MAC_VER_02) {
		dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
		RTL_W8(0x82, 0x01);
		dprintk("Set PHY Reg 0x0bh = 0x00h\n");
		mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
	}
	rtl8169_link_option(board_idx, &autoneg, &speed, &duplex);
	rtl8169_set_speed(dev, autoneg, speed, duplex);
	if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
		printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
}
static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct rtl8169_private *tp = netdev_priv(dev);
	struct mii_ioctl_data *data = if_mii(ifr);
	if (!netif_running(dev))
		return -ENODEV;
	switch (cmd) {
	case SIOCGMIIPHY:
		data->phy_id = 32; /* Internal PHY */
		return 0;
	case SIOCGMIIREG:
		data->val_out = mdio_read(tp->mmio_addr, data->reg_num & 0x1f);
		return 0;
	case SIOCSMIIREG:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;
		mdio_write(tp->mmio_addr, data->reg_num & 0x1f, data->val_in);
		return 0;
	}
	return -EOPNOTSUPP;
}
static int __devinit
static int __devinit
rtl8169_init_board(struct pci_dev *pdev, struct net_device **dev_out,
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
		   void __iomem **ioaddr_out)
{
{
	void __iomem *ioaddr;
	const unsigned int region = rtl_cfg_info[ent->driver_data].region;
	struct net_device *dev;
	struct rtl8169_private *tp;
	struct rtl8169_private *tp;
	int rc = -ENOMEM, i, acpi_idle_state = 0, pm_cap;
	struct net_device *dev;
	void __iomem *ioaddr;
	unsigned int i, pm_cap;
	int rc;
	assert(ioaddr_out != NULL);
	if (netif_msg_drv(&debug)) {
		printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
		       MODULENAME, RTL8169_VERSION);
	}
	/* dev zeroed in alloc_etherdev */
	dev = alloc_etherdev(sizeof (*tp));
	dev = alloc_etherdev(sizeof (*tp));
	if (dev == NULL) {
	if (!dev) {
		if (netif_msg_drv(&debug))
		if (netif_msg_drv(&debug))
			dev_err(&pdev->dev, "unable to alloc new ethernet\n");
			dev_err(&pdev->dev, "unable to alloc new ethernet\n");
		goto err_out;
		rc = -ENOMEM;
		goto out;
	}
	}
	SET_MODULE_OWNER(dev);
	SET_MODULE_OWNER(dev);
 Lines 1420-1467   rtl8169_init_board(struct pci_dev *pdev, Link Here 
	if (rc < 0) {
	if (rc < 0) {
		if (netif_msg_probe(tp))
		if (netif_msg_probe(tp))
			dev_err(&pdev->dev, "enable failure\n");
			dev_err(&pdev->dev, "enable failure\n");
		goto err_out_free_dev;
		goto err_out_free_dev_1;
	}
	}
	rc = pci_set_mwi(pdev);
	rc = pci_set_mwi(pdev);
	if (rc < 0)
	if (rc < 0)
		goto err_out_disable;
		goto err_out_disable_2;
	/* save power state before pci_enable_device overwrites it */
	/* save power state before pci_enable_device overwrites it */
	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
	pm_cap = pci_find_capability(pdev, PCI_CAP_ID_PM);
	if (pm_cap) {
	if (pm_cap) {
		u16 pwr_command;
		u16 pwr_command, acpi_idle_state;
		pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
		pci_read_config_word(pdev, pm_cap + PCI_PM_CTRL, &pwr_command);
		acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
		acpi_idle_state = pwr_command & PCI_PM_CTRL_STATE_MASK;
	} else {
	} else {
		if (netif_msg_probe(tp))
		if (netif_msg_probe(tp)) {
			dev_err(&pdev->dev,
			dev_err(&pdev->dev,
			       "PowerManagement capability not found.\n");
				"PowerManagement capability not found.\n");
		}
	}
	}
	/* make sure PCI base addr 1 is MMIO */
	/* make sure PCI base addr 1 is MMIO */
	if (!(pci_resource_flags(pdev, 1) & IORESOURCE_MEM)) {
	if (!(pci_resource_flags(pdev, region) & IORESOURCE_MEM)) {
		if (netif_msg_probe(tp))
		if (netif_msg_probe(tp)) {
			dev_err(&pdev->dev,
			dev_err(&pdev->dev,
			       "region #1 not an MMIO resource, aborting\n");
				"region #%d not an MMIO resource, aborting\n",
				region);
		}
		rc = -ENODEV;
		rc = -ENODEV;
		goto err_out_mwi;
		goto err_out_mwi_3;
	}
	}
	/* check for weird/broken PCI region reporting */
	/* check for weird/broken PCI region reporting */
	if (pci_resource_len(pdev, 1) < R8169_REGS_SIZE) {
	if (pci_resource_len(pdev, region) < R8169_REGS_SIZE) {
		if (netif_msg_probe(tp))
		if (netif_msg_probe(tp)) {
			dev_err(&pdev->dev,
			dev_err(&pdev->dev,
			       "Invalid PCI region size(s), aborting\n");
				"Invalid PCI region size(s), aborting\n");
		}
		rc = -ENODEV;
		rc = -ENODEV;
		goto err_out_mwi;
		goto err_out_mwi_3;
	}
	}
	rc = pci_request_regions(pdev, MODULENAME);
	rc = pci_request_regions(pdev, MODULENAME);
	if (rc < 0) {
	if (rc < 0) {
		if (netif_msg_probe(tp))
		if (netif_msg_probe(tp))
			dev_err(&pdev->dev, "could not request regions.\n");
			dev_err(&pdev->dev, "could not request regions.\n");
		goto err_out_mwi;
		goto err_out_mwi_3;
	}
	}
	tp->cp_cmd = PCIMulRW | RxChkSum;
	tp->cp_cmd = PCIMulRW | RxChkSum;
 Lines 1473-1494   rtl8169_init_board(struct pci_dev *pdev, Link Here 
	} else {
	} else {
		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
		rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
		if (rc < 0) {
		if (rc < 0) {
			if (netif_msg_probe(tp))
			if (netif_msg_probe(tp)) {
				dev_err(&pdev->dev,
				dev_err(&pdev->dev,
				       "DMA configuration failed.\n");
					"DMA configuration failed.\n");
			goto err_out_free_res;
			}
			goto err_out_free_res_4;
		}
		}
	}
	}
	pci_set_master(pdev);
	pci_set_master(pdev);
	/* ioremap MMIO region */
	/* ioremap MMIO region */
	ioaddr = ioremap(pci_resource_start(pdev, 1), R8169_REGS_SIZE);
	ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE);
	if (ioaddr == NULL) {
	if (!ioaddr) {
		if (netif_msg_probe(tp))
		if (netif_msg_probe(tp))
			dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
			dev_err(&pdev->dev, "cannot remap MMIO, aborting\n");
		rc = -EIO;
		rc = -EIO;
		goto err_out_free_res;
		goto err_out_free_res_4;
	}
	}
	/* Unneeded ? Don't mess with Mrs. Murphy. */
	/* Unneeded ? Don't mess with Mrs. Murphy. */
 Lines 1498-1507   rtl8169_init_board(struct pci_dev *pdev, Link Here 
	RTL_W8(ChipCmd, CmdReset);
	RTL_W8(ChipCmd, CmdReset);
	/* Check that the chip has finished the reset. */
	/* Check that the chip has finished the reset. */
	for (i = 1000; i > 0; i--) {
	for (i = 100; i > 0; i--) {
		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
			break;
			break;
		udelay(10);
		msleep_interruptible(1);
	}
	}
	/* Identify chip attached to board */
	/* Identify chip attached to board */
 Lines 1519-1526   rtl8169_init_board(struct pci_dev *pdev, Link Here 
		/* Unknown chip: assume array element #0, original RTL-8169 */
		/* Unknown chip: assume array element #0, original RTL-8169 */
		if (netif_msg_probe(tp)) {
		if (netif_msg_probe(tp)) {
			dev_printk(KERN_DEBUG, &pdev->dev,
			dev_printk(KERN_DEBUG, &pdev->dev,
			       "unknown chip version, assuming %s\n",
				"unknown chip version, assuming %s\n",
			       rtl_chip_info[0].name);
				rtl_chip_info[0].name);
		}
		}
		i++;
		i++;
	}
	}
 Lines 1531-1586   rtl8169_init_board(struct pci_dev *pdev, Link Here 
	RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
	RTL_W8(Config5, RTL_R8(Config5) & PMEStatus);
	RTL_W8(Cfg9346, Cfg9346_Lock);
	RTL_W8(Cfg9346, Cfg9346_Lock);
	*ioaddr_out = ioaddr;
	*dev_out = dev;
out:
	return rc;
err_out_free_res:
	pci_release_regions(pdev);
err_out_mwi:
	pci_clear_mwi(pdev);
err_out_disable:
	pci_disable_device(pdev);
err_out_free_dev:
	free_netdev(dev);
err_out:
	*ioaddr_out = NULL;
	*dev_out = NULL;
	goto out;
}
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct net_device *dev = NULL;
	struct rtl8169_private *tp;
	void __iomem *ioaddr = NULL;
	static int board_idx = -1;
	u8 autoneg, duplex;
	u16 speed;
	int i, rc;
	assert(pdev != NULL);
	assert(ent != NULL);
	board_idx++;
	if (netif_msg_drv(&debug)) {
		printk(KERN_INFO "%s Gigabit Ethernet driver %s loaded\n",
		       MODULENAME, RTL8169_VERSION);
	}
	rc = rtl8169_init_board(pdev, &dev, &ioaddr);
	if (rc)
		return rc;
	tp = netdev_priv(dev);
	assert(ioaddr != NULL);
	if (RTL_R8(PHYstatus) & TBI_Enable) {
	if (RTL_R8(PHYstatus) & TBI_Enable) {
		tp->set_speed = rtl8169_set_speed_tbi;
		tp->set_speed = rtl8169_set_speed_tbi;
		tp->get_settings = rtl8169_gset_tbi;
		tp->get_settings = rtl8169_gset_tbi;
 Lines 1588-1600   rtl8169_init_one(struct pci_dev *pdev, c Link Here 
		tp->phy_reset_pending = rtl8169_tbi_reset_pending;
		tp->phy_reset_pending = rtl8169_tbi_reset_pending;
		tp->link_ok = rtl8169_tbi_link_ok;
		tp->link_ok = rtl8169_tbi_link_ok;
		tp->phy_1000_ctrl_reg = PHY_Cap_1000_Full; /* Implied by TBI */
		tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */
	} else {
	} else {
		tp->set_speed = rtl8169_set_speed_xmii;
		tp->set_speed = rtl8169_set_speed_xmii;
		tp->get_settings = rtl8169_gset_xmii;
		tp->get_settings = rtl8169_gset_xmii;
		tp->phy_reset_enable = rtl8169_xmii_reset_enable;
		tp->phy_reset_enable = rtl8169_xmii_reset_enable;
		tp->phy_reset_pending = rtl8169_xmii_reset_pending;
		tp->phy_reset_pending = rtl8169_xmii_reset_pending;
		tp->link_ok = rtl8169_xmii_link_ok;
		tp->link_ok = rtl8169_xmii_link_ok;
		dev->do_ioctl = rtl8169_ioctl;
	}
	}
	/* Get MAC address.  FIXME: read EEPROM */
	/* Get MAC address.  FIXME: read EEPROM */
 Lines 1609-1614   rtl8169_init_one(struct pci_dev *pdev, c Link Here 
	dev->stop = rtl8169_close;
	dev->stop = rtl8169_close;
	dev->tx_timeout = rtl8169_tx_timeout;
	dev->tx_timeout = rtl8169_tx_timeout;
	dev->set_multicast_list = rtl8169_set_rx_mode;
	dev->set_multicast_list = rtl8169_set_rx_mode;
	dev->set_mac_address = rtl8169_set_mac_addr;
	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
	dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
	dev->irq = pdev->irq;
	dev->irq = pdev->irq;
	dev->base_addr = (unsigned long) ioaddr;
	dev->base_addr = (unsigned long) ioaddr;
 Lines 1632-1650   rtl8169_init_one(struct pci_dev *pdev, c Link Here 
	tp->intr_mask = 0xffff;
	tp->intr_mask = 0xffff;
	tp->pci_dev = pdev;
	tp->pci_dev = pdev;
	tp->mmio_addr = ioaddr;
	tp->mmio_addr = ioaddr;
	tp->align = rtl_cfg_info[ent->driver_data].align;
	spin_lock_init(&tp->lock);
	spin_lock_init(&tp->lock);
	rc = register_netdev(dev);
	rc = register_netdev(dev);
	if (rc) {
	if (rc < 0)
		rtl8169_release_board(pdev, dev, ioaddr);
		goto err_out_unmap_5;
		return rc;
	}
	if (netif_msg_probe(tp)) {
		printk(KERN_DEBUG "%s: Identified chip type is '%s'.\n",
		       dev->name, rtl_chip_info[tp->chipset].name);
	}
	pci_set_drvdata(pdev, dev);
	pci_set_drvdata(pdev, dev);
 Lines 1653-1690   rtl8169_init_one(struct pci_dev *pdev, c Link Here 
		       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
		       "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
		       "IRQ %d\n",
		       "IRQ %d\n",
		       dev->name,
		       dev->name,
		       rtl_chip_info[ent->driver_data].name,
		       rtl_chip_info[tp->chipset].name,
		       dev->base_addr,
		       dev->base_addr,
		       dev->dev_addr[0], dev->dev_addr[1],
		       dev->dev_addr[0], dev->dev_addr[1],
		       dev->dev_addr[2], dev->dev_addr[3],
		       dev->dev_addr[2], dev->dev_addr[3],
		       dev->dev_addr[4], dev->dev_addr[5], dev->irq);
		       dev->dev_addr[4], dev->dev_addr[5], dev->irq);
	}
	}
	rtl8169_hw_phy_config(dev);
	rtl8169_init_phy(dev, tp);
	dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
out:
	RTL_W8(0x82, 0x01);
	return rc;
	if (tp->mac_version < RTL_GIGA_MAC_VER_E) {
		dprintk("Set PCI Latency=0x40\n");
		pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
	}
	if (tp->mac_version == RTL_GIGA_MAC_VER_D) {
		dprintk("Set MAC Reg C+CR Offset 0x82h = 0x01h\n");
		RTL_W8(0x82, 0x01);
		dprintk("Set PHY Reg 0x0bh = 0x00h\n");
		mdio_write(ioaddr, 0x0b, 0x0000); //w 0x0b 15 0 0
	}
	rtl8169_link_option(board_idx, &autoneg, &speed, &duplex);
	rtl8169_set_speed(dev, autoneg, speed, duplex);
	
	if ((RTL_R8(PHYstatus) & TBI_Enable) && netif_msg_link(tp))
		printk(KERN_INFO PFX "%s: TBI auto-negotiating\n", dev->name);
	return 0;
err_out_unmap_5:
	iounmap(ioaddr);
err_out_free_res_4:
	pci_release_regions(pdev);
err_out_mwi_3:
	pci_clear_mwi(pdev);
err_out_disable_2:
	pci_disable_device(pdev);
err_out_free_dev_1:
	free_netdev(dev);
	goto out;
}
}
static void __devexit
static void __devexit
 Lines 1780-1799   rtl8169_hw_start(struct net_device *dev) Link Here 
{
{
	struct rtl8169_private *tp = netdev_priv(dev);
	struct rtl8169_private *tp = netdev_priv(dev);
	void __iomem *ioaddr = tp->mmio_addr;
	void __iomem *ioaddr = tp->mmio_addr;
	struct pci_dev *pdev = tp->pci_dev;
	u32 i;
	u32 i;
	/* Soft reset the chip. */
	/* Soft reset the chip. */
	RTL_W8(ChipCmd, CmdReset);
	RTL_W8(ChipCmd, CmdReset);
	/* Check that the chip has finished the reset. */
	/* Check that the chip has finished the reset. */
	for (i = 1000; i > 0; i--) {
	for (i = 100; i > 0; i--) {
		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
		if ((RTL_R8(ChipCmd) & CmdReset) == 0)
			break;
			break;
		udelay(10);
		msleep_interruptible(1);
	}
	}
	if (tp->mac_version == RTL_GIGA_MAC_VER_13) {
		pci_write_config_word(pdev, 0x68, 0x00);
		pci_write_config_word(pdev, 0x69, 0x08);
	}
	/* Undocumented stuff. */
	if (tp->mac_version == RTL_GIGA_MAC_VER_05) {
		u16 cmd;
		/* Realtek's r1000_n.c driver uses '&& 0x01' here. Well... */
		if ((RTL_R8(Config2) & 0x07) & 0x01)
			RTL_W32(0x7c, 0x0007ffff);
		RTL_W32(0x7c, 0x0007ff00);
		pci_read_config_word(pdev, PCI_COMMAND, &cmd);
		cmd = cmd & 0xef;
		pci_write_config_word(pdev, PCI_COMMAND, cmd);
	}
	RTL_W8(Cfg9346, Cfg9346_Unlock);
	RTL_W8(Cfg9346, Cfg9346_Unlock);
	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
	RTL_W8(EarlyTxThres, EarlyTxThld);
	RTL_W8(EarlyTxThres, EarlyTxThld);
	/* Low hurts. Let's disable the filtering. */
	/* Low hurts. Let's disable the filtering. */
 Lines 1805-1824   rtl8169_hw_start(struct net_device *dev) Link Here 
	RTL_W32(RxConfig, i);
	RTL_W32(RxConfig, i);
	/* Set DMA burst size and Interframe Gap Time */
	/* Set DMA burst size and Interframe Gap Time */
	RTL_W32(TxConfig,
	RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) |
		(TX_DMA_BURST << TxDMAShift) | (InterFrameGap <<
		(InterFrameGap << TxInterFrameGapShift));
						TxInterFrameGapShift));
	tp->cp_cmd |= RTL_R16(CPlusCmd);
	RTL_W16(CPlusCmd, tp->cp_cmd);
	if ((tp->mac_version == RTL_GIGA_MAC_VER_D) ||
	tp->cp_cmd |= RTL_R16(CPlusCmd) | PCIMulRW;
	    (tp->mac_version == RTL_GIGA_MAC_VER_E)) {
	if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
	    (tp->mac_version == RTL_GIGA_MAC_VER_03)) {
		dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. "
		dprintk(KERN_INFO PFX "Set MAC Reg C+CR Offset 0xE0. "
			"Bit-3 and bit-14 MUST be 1\n");
			"Bit-3 and bit-14 MUST be 1\n");
		tp->cp_cmd |= (1 << 14) | PCIMulRW;
		tp->cp_cmd |= (1 << 14);
		RTL_W16(CPlusCmd, tp->cp_cmd);
	}
	}
	RTL_W16(CPlusCmd, tp->cp_cmd);
	/*
	/*
	 * Undocumented corner. Supposedly:
	 * Undocumented corner. Supposedly:
	 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
	 * (TxTimer << 12) | (TxPackets << 8) | (RxTimer << 4) | RxPackets
 Lines 1829-1836   rtl8169_hw_start(struct net_device *dev) Link Here 
	RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
	RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr >> 32));
	RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
	RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr & DMA_32BIT_MASK));
	RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
	RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr >> 32));
	RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
	RTL_W8(Cfg9346, Cfg9346_Lock);
	RTL_W8(Cfg9346, Cfg9346_Lock);
	udelay(10);
	/* Initially a 10 us delay. Turned it into a PCI commit. - FR */
	RTL_R8(IntrMask);
	RTL_W32(RxMissed, 0);
	RTL_W32(RxMissed, 0);
 Lines 1842-1847   rtl8169_hw_start(struct net_device *dev) Link Here 
	/* Enable all known interrupts by setting the interrupt mask. */
	/* Enable all known interrupts by setting the interrupt mask. */
	RTL_W16(IntrMask, rtl8169_intr_mask);
	RTL_W16(IntrMask, rtl8169_intr_mask);
	__rtl8169_set_mac_addr(dev, ioaddr);
	netif_start_queue(dev);
	netif_start_queue(dev);
}
}
 Lines 1910-1926   static inline void rtl8169_map_to_asic(s Link Here 
}
}
static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
static int rtl8169_alloc_rx_skb(struct pci_dev *pdev, struct sk_buff **sk_buff,
				struct RxDesc *desc, int rx_buf_sz)
				struct RxDesc *desc, int rx_buf_sz,
				unsigned int align)
{
{
	struct sk_buff *skb;
	struct sk_buff *skb;
	dma_addr_t mapping;
	dma_addr_t mapping;
	int ret = 0;
	int ret = 0;
	skb = dev_alloc_skb(rx_buf_sz + NET_IP_ALIGN);
	skb = dev_alloc_skb(rx_buf_sz + align);
	if (!skb)
	if (!skb)
		goto err_out;
		goto err_out;
	skb_reserve(skb, NET_IP_ALIGN);
	skb_reserve(skb, align);
	*sk_buff = skb;
	*sk_buff = skb;
	mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
	mapping = pci_map_single(pdev, skb->data, rx_buf_sz,
 Lines 1953-1967   static u32 rtl8169_rx_fill(struct rtl816 Link Here 
			   u32 start, u32 end)
			   u32 start, u32 end)
{
{
	u32 cur;
	u32 cur;
	
	for (cur = start; end - cur > 0; cur++) {
	for (cur = start; end - cur > 0; cur++) {
		int ret, i = cur % NUM_RX_DESC;
		int ret, i = cur % NUM_RX_DESC;
		if (tp->Rx_skbuff[i])
		if (tp->Rx_skbuff[i])
			continue;
			continue;
			
		ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
		ret = rtl8169_alloc_rx_skb(tp->pci_dev, tp->Rx_skbuff + i,
					   tp->RxDescArray + i, tp->rx_buf_sz);
			tp->RxDescArray + i, tp->rx_buf_sz, tp->align);
		if (ret < 0)
		if (ret < 0)
			break;
			break;
	}
	}
 Lines 2190-2197   static int rtl8169_start_xmit(struct sk_ Link Here 
	dma_addr_t mapping;
	dma_addr_t mapping;
	u32 status, len;
	u32 status, len;
	u32 opts1;
	u32 opts1;
	int ret = 0;
	int ret = NETDEV_TX_OK;
	
	if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
	if (unlikely(TX_BUFFS_AVAIL(tp) < skb_shinfo(skb)->nr_frags)) {
		if (netif_msg_drv(tp)) {
		if (netif_msg_drv(tp)) {
			printk(KERN_ERR
			printk(KERN_ERR
 Lines 2255-2261   out: Link Here 
err_stop:
err_stop:
	netif_stop_queue(dev);
	netif_stop_queue(dev);
	ret = 1;
	ret = NETDEV_TX_BUSY;
err_update_stats:
err_update_stats:
	tp->stats.tx_dropped++;
	tp->stats.tx_dropped++;
	goto out;
	goto out;
 Lines 2372-2387   static inline void rtl8169_rx_csum(struc Link Here 
}
}
static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
static inline int rtl8169_try_rx_copy(struct sk_buff **sk_buff, int pkt_size,
				      struct RxDesc *desc, int rx_buf_sz)
				      struct RxDesc *desc, int rx_buf_sz,
				      unsigned int align)
{
{
	int ret = -1;
	int ret = -1;
	if (pkt_size < rx_copybreak) {
	if (pkt_size < rx_copybreak) {
		struct sk_buff *skb;
		struct sk_buff *skb;
		skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
		skb = dev_alloc_skb(pkt_size + align);
		if (skb) {
		if (skb) {
			skb_reserve(skb, NET_IP_ALIGN);
			skb_reserve(skb, align);
			eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
			eth_copy_and_sum(skb, sk_buff[0]->data, pkt_size, 0);
			*sk_buff = skb;
			*sk_buff = skb;
			rtl8169_mark_to_asic(desc, rx_buf_sz);
			rtl8169_mark_to_asic(desc, rx_buf_sz);
 Lines 2427-2432   rtl8169_rx_interrupt(struct net_device * Link Here 
				tp->stats.rx_length_errors++;
				tp->stats.rx_length_errors++;
			if (status & RxCRC)
			if (status & RxCRC)
				tp->stats.rx_crc_errors++;
				tp->stats.rx_crc_errors++;
			if (status & RxFOVF) {
				rtl8169_schedule_work(dev, rtl8169_reset_task);
				tp->stats.rx_fifo_errors++;
			}
			rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
			rtl8169_mark_to_asic(desc, tp->rx_buf_sz);
		} else {
		} else {
			struct sk_buff *skb = tp->Rx_skbuff[entry];
			struct sk_buff *skb = tp->Rx_skbuff[entry];
 Lines 2447-2459   rtl8169_rx_interrupt(struct net_device * Link Here 
			}
			}
			rtl8169_rx_csum(skb, desc);
			rtl8169_rx_csum(skb, desc);
			
			pci_dma_sync_single_for_cpu(tp->pci_dev,
			pci_dma_sync_single_for_cpu(tp->pci_dev,
				le64_to_cpu(desc->addr), tp->rx_buf_sz,
				le64_to_cpu(desc->addr), tp->rx_buf_sz,
				PCI_DMA_FROMDEVICE);
				PCI_DMA_FROMDEVICE);
			if (rtl8169_try_rx_copy(&skb, pkt_size, desc,
			if (rtl8169_try_rx_copy(&skb, pkt_size, desc,
						tp->rx_buf_sz)) {
						tp->rx_buf_sz, tp->align)) {
				pci_action = pci_unmap_single;
				pci_action = pci_unmap_single;
				tp->Rx_skbuff[entry] = NULL;
				tp->Rx_skbuff[entry] = NULL;
			}
			}
 Lines 2543-2549   rtl8169_interrupt(int irq, void *dev_ins Link Here 
			__netif_rx_schedule(dev);
			__netif_rx_schedule(dev);
		else if (netif_msg_intr(tp)) {
		else if (netif_msg_intr(tp)) {
			printk(KERN_INFO "%s: interrupt %04x taken in poll\n",
			printk(KERN_INFO "%s: interrupt %04x taken in poll\n",
			       dev->name, status);	
			       dev->name, status);
		}
		}
		break;
		break;
#else
#else
 Lines 2716-2721   rtl8169_set_rx_mode(struct net_device *d Link Here 
	tmp = rtl8169_rx_config | rx_mode |
	tmp = rtl8169_rx_config | rx_mode |
	      (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
	      (RTL_R32(RxConfig) & rtl_chip_info[tp->chipset].RxConfigMask);
	if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
	    (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
	    (tp->mac_version == RTL_GIGA_MAC_VER_13) ||
	    (tp->mac_version == RTL_GIGA_MAC_VER_14) ||
	    (tp->mac_version == RTL_GIGA_MAC_VER_15)) {
		mc_filter[0] = 0xffffffff;
		mc_filter[1] = 0xffffffff;
	}
	RTL_W32(RxConfig, tmp);
	RTL_W32(RxConfig, tmp);
	RTL_W32(MAR0 + 0, mc_filter[0]);
	RTL_W32(MAR0 + 0, mc_filter[0]);
	RTL_W32(MAR0 + 4, mc_filter[1]);
	RTL_W32(MAR0 + 4, mc_filter[1]);
 Lines 2741-2747   static struct net_device_stats *rtl8169_ Link Here 
		RTL_W32(RxMissed, 0);
		RTL_W32(RxMissed, 0);
		spin_unlock_irqrestore(&tp->lock, flags);
		spin_unlock_irqrestore(&tp->lock, flags);
	}
	}
		
	return &tp->stats;
	return &tp->stats;
}
}
 Lines 2809-2815   static struct pci_driver rtl8169_pci_dri Link Here 
static int __init
static int __init
rtl8169_init_module(void)
rtl8169_init_module(void)
{
{
	return pci_module_init(&rtl8169_pci_driver);
	return pci_register_driver(&rtl8169_pci_driver);
}
}
static void __exit
static void __exit