Added r8169 port based on 2.6.31.13 by M. Lüscher.

This commit is contained in:
Florian Pose 2010-05-20 11:16:37 +02:00
parent 541ca41d52
commit b351036b1e
2 changed files with 614 additions and 477 deletions

View File

@ -56,9 +56,6 @@
#define TX_BUFFS_AVAIL(tp) \
(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static const int max_interrupt_work = 20;
/* 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 const int multicast_filter_limit = 32;
@ -71,7 +68,6 @@ static const int multicast_filter_limit = 32;
#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */
#define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */
#define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */
#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
@ -99,6 +95,7 @@ static const int multicast_filter_limit = 32;
#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
enum mac_version {
RTL_GIGA_MAC_NONE = 0x00,
RTL_GIGA_MAC_VER_01 = 0x01, // 8169
RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
@ -443,6 +440,22 @@ enum features {
RTL_FEATURE_GMII = (1 << 2),
};
struct rtl8169_counters {
__le64 tx_packets;
__le64 rx_packets;
__le64 tx_errors;
__le32 rx_errors;
__le16 rx_missed;
__le16 align_errors;
__le32 tx_one_collision;
__le32 tx_multi_collision;
__le64 rx_unicast;
__le64 rx_broadcast;
__le32 rx_multicast;
__le16 tx_aborted;
__le16 tx_underun;
};
struct rtl8169_private {
void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; /* Index of PCI device */
@ -469,7 +482,6 @@ struct rtl8169_private {
u16 intr_event;
u16 napi_event;
u16 intr_mask;
int phy_auto_nego_reg;
int phy_1000_ctrl_reg;
#ifdef CONFIG_R8169_VLAN
struct vlan_group *vlgrp;
@ -480,11 +492,13 @@ struct rtl8169_private {
void (*hw_start)(struct net_device *);
unsigned int (*phy_reset_pending)(void __iomem *);
unsigned int (*link_ok)(void __iomem *);
int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
int pcie_cap;
struct delayed_work task;
unsigned features;
struct mii_if_info mii;
struct rtl8169_counters counters;
ec_device_t *ecdev;
unsigned long ec_watchdog_jiffies;
@ -840,76 +854,81 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
int auto_nego, giga_ctrl;
auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
ADVERTISE_100HALF | ADVERTISE_100FULL);
giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
int giga_ctrl, bmcr;
if (autoneg == AUTONEG_ENABLE) {
int auto_nego;
auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
ADVERTISE_100HALF | ADVERTISE_100FULL);
giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
} else {
if (speed == SPEED_10)
auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL;
else if (speed == SPEED_100)
auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL;
else if (speed == SPEED_1000)
auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
/* The 8100e/8101e/8102e do Fast Ethernet only. */
if ((tp->mac_version != RTL_GIGA_MAC_VER_07) &&
(tp->mac_version != RTL_GIGA_MAC_VER_08) &&
(tp->mac_version != RTL_GIGA_MAC_VER_09) &&
(tp->mac_version != RTL_GIGA_MAC_VER_10) &&
(tp->mac_version != RTL_GIGA_MAC_VER_13) &&
(tp->mac_version != RTL_GIGA_MAC_VER_14) &&
(tp->mac_version != RTL_GIGA_MAC_VER_15) &&
(tp->mac_version != RTL_GIGA_MAC_VER_16)) {
giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
if (duplex == DUPLEX_HALF)
auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL);
if (duplex == DUPLEX_FULL)
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) ||
(tp->mac_version == RTL_GIGA_MAC_VER_16))) {
auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA;
}
}
/* The 8100e/8101e/8102e do Fast Ethernet only. */
if ((tp->mac_version == RTL_GIGA_MAC_VER_07) ||
(tp->mac_version == RTL_GIGA_MAC_VER_08) ||
(tp->mac_version == RTL_GIGA_MAC_VER_09) ||
(tp->mac_version == RTL_GIGA_MAC_VER_10) ||
(tp->mac_version == RTL_GIGA_MAC_VER_13) ||
(tp->mac_version == RTL_GIGA_MAC_VER_14) ||
(tp->mac_version == RTL_GIGA_MAC_VER_15) ||
(tp->mac_version == RTL_GIGA_MAC_VER_16)) {
if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
netif_msg_link(tp)) {
} else if (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;
bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
(tp->mac_version == RTL_GIGA_MAC_VER_12) ||
(tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
/*
* Wake up the PHY.
* Vendor specific (0x1f) and reserved (0x0e) MII
* registers.
*/
mdio_write(ioaddr, 0x1f, 0x0000);
mdio_write(ioaddr, 0x0e, 0x0000);
}
mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
} else {
giga_ctrl = 0;
if (speed == SPEED_10)
bmcr = 0;
else if (speed == SPEED_100)
bmcr = BMCR_SPEED100;
else
return -EINVAL;
if (duplex == DUPLEX_FULL)
bmcr |= BMCR_FULLDPLX;
if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
(tp->mac_version == RTL_GIGA_MAC_VER_12) ||
(tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
/*
* Wake up the PHY.
* Vendor specific (0x1f) and reserved (0x0e) MII registers.
*/
mdio_write(ioaddr, 0x1f, 0x0000);
mdio_write(ioaddr, 0x0e, 0x0000);
}
tp->phy_auto_nego_reg = auto_nego;
tp->phy_1000_ctrl_reg = giga_ctrl;
mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
mdio_write(ioaddr, MII_BMCR, bmcr);
if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
(tp->mac_version == RTL_GIGA_MAC_VER_03)) {
if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) {
mdio_write(ioaddr, 0x17, 0x2138);
mdio_write(ioaddr, 0x0e, 0x0260);
} else {
mdio_write(ioaddr, 0x17, 0x2108);
mdio_write(ioaddr, 0x0e, 0x0000);
}
}
return 0;
}
@ -1113,22 +1132,6 @@ static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = {
"tx_underrun",
};
struct rtl8169_counters {
__le64 tx_packets;
__le64 rx_packets;
__le64 tx_errors;
__le32 rx_errors;
__le16 rx_missed;
__le16 align_errors;
__le32 tx_one_collision;
__le32 tx_multi_collision;
__le64 rx_unicast;
__le64 rx_broadcast;
__le32 rx_multicast;
__le16 tx_aborted;
__le16 tx_underun;
};
static int rtl8169_get_sset_count(struct net_device *dev, int sset)
{
switch (sset) {
@ -1139,51 +1142,70 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset)
}
}
static void rtl8169_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
static void rtl8169_update_counters(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
struct rtl8169_counters *counters;
dma_addr_t paddr;
u32 cmd;
int wait = 1000;
ASSERT_RTNL();
/*
* Some chips are unable to dump tally counters when the receiver
* is disabled.
*/
if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0)
return;
counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr);
if (!counters)
return;
RTL_W32(CounterAddrHigh, (u64)paddr >> 32);
cmd = (u64)paddr & DMA_32BIT_MASK;
cmd = (u64)paddr & DMA_BIT_MASK(32);
RTL_W32(CounterAddrLow, cmd);
RTL_W32(CounterAddrLow, cmd | CounterDump);
while (RTL_R32(CounterAddrLow) & CounterDump) {
if (msleep_interruptible(1))
while (wait--) {
if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) {
/* copy updated counters */
memcpy(&tp->counters, counters, sizeof(*counters));
break;
}
udelay(10);
}
RTL_W32(CounterAddrLow, 0);
RTL_W32(CounterAddrHigh, 0);
data[0] = le64_to_cpu(counters->tx_packets);
data[1] = le64_to_cpu(counters->rx_packets);
data[2] = le64_to_cpu(counters->tx_errors);
data[3] = le32_to_cpu(counters->rx_errors);
data[4] = le16_to_cpu(counters->rx_missed);
data[5] = le16_to_cpu(counters->align_errors);
data[6] = le32_to_cpu(counters->tx_one_collision);
data[7] = le32_to_cpu(counters->tx_multi_collision);
data[8] = le64_to_cpu(counters->rx_unicast);
data[9] = le64_to_cpu(counters->rx_broadcast);
data[10] = le32_to_cpu(counters->rx_multicast);
data[11] = le16_to_cpu(counters->tx_aborted);
data[12] = le16_to_cpu(counters->tx_underun);
pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);
}
static void rtl8169_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
struct rtl8169_private *tp = netdev_priv(dev);
ASSERT_RTNL();
rtl8169_update_counters(dev);
data[0] = le64_to_cpu(tp->counters.tx_packets);
data[1] = le64_to_cpu(tp->counters.rx_packets);
data[2] = le64_to_cpu(tp->counters.tx_errors);
data[3] = le32_to_cpu(tp->counters.rx_errors);
data[4] = le16_to_cpu(tp->counters.rx_missed);
data[5] = le16_to_cpu(tp->counters.align_errors);
data[6] = le32_to_cpu(tp->counters.tx_one_collision);
data[7] = le32_to_cpu(tp->counters.tx_multi_collision);
data[8] = le64_to_cpu(tp->counters.rx_unicast);
data[9] = le64_to_cpu(tp->counters.rx_broadcast);
data[10] = le32_to_cpu(tp->counters.rx_multicast);
data[11] = le16_to_cpu(tp->counters.tx_aborted);
data[12] = le16_to_cpu(tp->counters.tx_underun);
}
static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
switch(stringset) {
@ -1289,7 +1311,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
{ 0xfc800000, 0x00800000, RTL_GIGA_MAC_VER_02 },
{ 0xfc800000, 0x00000000, RTL_GIGA_MAC_VER_01 },
{ 0x00000000, 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */
/* Catch-all */
{ 0x00000000, 0x00000000, RTL_GIGA_MAC_NONE }
}, *p = mac_info;
u32 reg;
@ -1297,12 +1320,6 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
while ((reg & p->mask) != p->val)
p++;
tp->mac_version = p->mac_version;
if (p->mask == 0x00000000) {
struct pci_dev *pdev = tp->pci_dev;
dev_info(&pdev->dev, "unknown MAC (%08x)\n", reg);
}
}
static void rtl8169_print_mac_version(struct rtl8169_private *tp)
@ -1846,9 +1863,11 @@ 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;
return netif_running(dev) ? tp->do_ioctl(tp, data, cmd) : -ENODEV;
}
static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
{
switch (cmd) {
case SIOCGMIIPHY:
data->phy_id = 32; /* Internal PHY */
@ -1867,6 +1886,11 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EOPNOTSUPP;
}
static int rtl_tbi_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
{
return -EOPNOTSUPP;
}
static const struct rtl_cfg_info {
void (*hw_start)(struct net_device *);
unsigned int region;
@ -1874,6 +1898,7 @@ static const struct rtl_cfg_info {
u16 intr_event;
u16 napi_event;
unsigned features;
u8 default_ver;
} rtl_cfg_infos [] = {
[RTL_CFG_0] = {
.hw_start = rtl_hw_start_8169,
@ -1882,7 +1907,8 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
.features = RTL_FEATURE_GMII
.features = RTL_FEATURE_GMII,
.default_ver = RTL_GIGA_MAC_VER_01,
},
[RTL_CFG_1] = {
.hw_start = rtl_hw_start_8168,
@ -1891,7 +1917,8 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow |
TxErr | TxOK | RxOK | RxErr,
.napi_event = TxErr | TxOK | RxOK | RxOverflow,
.features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
.features = RTL_FEATURE_GMII | RTL_FEATURE_MSI,
.default_ver = RTL_GIGA_MAC_VER_11,
},
[RTL_CFG_2] = {
.hw_start = rtl_hw_start_8101,
@ -1900,7 +1927,8 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
.features = RTL_FEATURE_MSI
.features = RTL_FEATURE_MSI,
.default_ver = RTL_GIGA_MAC_VER_13,
}
};
@ -1932,6 +1960,26 @@ static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
}
}
static const struct net_device_ops rtl8169_netdev_ops = {
.ndo_open = rtl8169_open,
.ndo_stop = rtl8169_close,
.ndo_get_stats = rtl8169_get_stats,
.ndo_start_xmit = rtl8169_start_xmit,
.ndo_tx_timeout = rtl8169_tx_timeout,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = rtl8169_change_mtu,
.ndo_set_mac_address = rtl_set_mac_address,
.ndo_do_ioctl = rtl8169_ioctl,
.ndo_set_multicast_list = rtl_set_rx_mode,
#ifdef CONFIG_R8169_VLAN
.ndo_vlan_rx_register = rtl8169_vlan_rx_register,
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = rtl8169_netpoll,
#endif
};
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@ -1958,6 +2006,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
SET_NETDEV_DEV(dev, &pdev->dev);
dev->netdev_ops = &rtl8169_netdev_ops;
tp = netdev_priv(dev);
tp->dev = dev;
tp->pci_dev = pdev;
@ -2014,11 +2063,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->cp_cmd = PCIMulRW | RxChkSum;
if ((sizeof(dma_addr_t) > 4) &&
!pci_set_dma_mask(pdev, DMA_64BIT_MASK) && use_dac) {
!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) {
tp->cp_cmd |= PCIDAC;
dev->features |= NETIF_F_HIGHDMA;
} else {
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc < 0) {
if (netif_msg_probe(tp)) {
dev_err(&pdev->dev,
@ -2028,8 +2077,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
pci_set_master(pdev);
/* ioremap MMIO region */
ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE);
if (!ioaddr) {
@ -2057,9 +2104,20 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
RTL_W16(IntrStatus, 0xffff);
pci_set_master(pdev);
/* Identify chip attached to board */
rtl8169_get_mac_version(tp, ioaddr);
/* Use appropriate default if unknown */
if (tp->mac_version == RTL_GIGA_MAC_NONE) {
if (netif_msg_probe(tp)) {
dev_notice(&pdev->dev,
"unknown MAC, using family default\n");
}
tp->mac_version = cfg->default_ver;
}
rtl8169_print_mac_version(tp);
for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) {
@ -2067,13 +2125,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
if (i == ARRAY_SIZE(rtl_chip_info)) {
/* Unknown chip: assume array element #0, original RTL-8169 */
if (netif_msg_probe(tp)) {
dev_printk(KERN_DEBUG, &pdev->dev,
"unknown chip version, assuming %s\n",
rtl_chip_info[0].name);
}
i = 0;
dev_err(&pdev->dev,
"driver bug, MAC version not found in rtl_chip_info\n");
goto err_out_msi_5;
}
tp->chipset = i;
@ -2094,6 +2148,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->phy_reset_enable = rtl8169_tbi_reset_enable;
tp->phy_reset_pending = rtl8169_tbi_reset_pending;
tp->link_ok = rtl8169_tbi_link_ok;
tp->do_ioctl = rtl_tbi_ioctl;
tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */
} else {
@ -2102,8 +2157,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->phy_reset_enable = rtl8169_xmii_reset_enable;
tp->phy_reset_pending = rtl8169_xmii_reset_pending;
tp->link_ok = rtl8169_xmii_link_ok;
dev->do_ioctl = rtl8169_ioctl;
tp->do_ioctl = rtl_xmii_ioctl;
}
spin_lock_init(&tp->lock);
@ -2115,28 +2169,15 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->dev_addr[i] = RTL_R8(MAC0 + i);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->open = rtl8169_open;
dev->hard_start_xmit = rtl8169_start_xmit;
dev->get_stats = rtl8169_get_stats;
SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
dev->stop = rtl8169_close;
dev->tx_timeout = rtl8169_tx_timeout;
dev->set_multicast_list = rtl_set_rx_mode;
dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
dev->irq = pdev->irq;
dev->base_addr = (unsigned long) ioaddr;
dev->change_mtu = rtl8169_change_mtu;
dev->set_mac_address = rtl_set_mac_address;
netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
#ifdef CONFIG_R8169_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_rx_register = rtl8169_vlan_rx_register;
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = rtl8169_netpoll;
#endif
tp->intr_mask = 0xffff;
@ -2176,12 +2217,12 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rtl8169_init_phy(dev, tp);
device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL);
if (tp->ecdev && ecdev_open(tp->ecdev)) {
ecdev_withdraw(tp->ecdev);
goto err_out_msi_5;
}
out:
return rc;
@ -2264,8 +2305,8 @@ static int rtl8169_open(struct net_device *dev)
goto err_release_ring_2;
napi_enable(&tp->napi);
}
}
rtl_hw_start(dev);
rtl8169_request_timer(dev);
@ -2342,9 +2383,9 @@ static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
* Switching from MMIO to I/O access fixes the issue as well.
*/
RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_32BIT_MASK);
RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32));
RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_32BIT_MASK);
RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32));
}
static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
@ -2356,10 +2397,10 @@ static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
return cmd;
}
static void rtl_set_rx_max_size(void __iomem *ioaddr)
static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz)
{
/* Low hurts. Let's disable the filtering. */
RTL_W16(RxMaxSize, 16383);
RTL_W16(RxMaxSize, rx_buf_sz);
}
static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
@ -2406,7 +2447,7 @@ static void rtl_hw_start_8169(struct net_device *dev)
RTL_W8(EarlyTxThres, EarlyTxThld);
rtl_set_rx_max_size(ioaddr);
rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
(tp->mac_version == RTL_GIGA_MAC_VER_02) ||
@ -2668,7 +2709,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
RTL_W8(EarlyTxThres, EarlyTxThld);
rtl_set_rx_max_size(ioaddr);
rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
@ -2847,7 +2888,7 @@ static void rtl_hw_start_8101(struct net_device *dev)
RTL_W8(EarlyTxThres, EarlyTxThld);
rtl_set_rx_max_size(ioaddr);
rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
@ -3260,13 +3301,6 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
opts1 |= FirstFrag;
} else {
len = skb->len;
if (unlikely(len < ETH_ZLEN)) {
if (skb_padto(skb, ETH_ZLEN))
goto err_update_stats;
len = ETH_ZLEN;
}
opts1 |= FirstFrag | LastFrag;
tp->tx_skb[entry].skb = skb;
}
@ -3283,8 +3317,6 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
txd->opts1 = cpu_to_le32(status);
dev->trans_start = jiffies;
tp->cur_tx += frags + 1;
smp_wmb();
@ -3307,7 +3339,6 @@ err_stop:
if (!tp->ecdev)
netif_stop_queue(dev);
ret = NETDEV_TX_BUSY;
err_update_stats:
dev->stats.tx_dropped++;
goto out;
}
@ -3390,7 +3421,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
if (status & LastFrag) {
if (!tp->ecdev)
dev_kfree_skb_irq(tx_skb->skb);
dev_kfree_skb(tx_skb->skb);
tx_skb->skb = NULL;
}
dirty_tx++;
@ -3547,7 +3578,6 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
netif_receive_skb(skb);
}
dev->last_rx = jiffies;
dev->stats.rx_bytes += pkt_size;
dev->stats.rx_packets++;
}
@ -3594,54 +3624,64 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
int handled = 0;
int status;
/* loop handling interrupts until we have no new ones or
* we hit a invalid/hotplug case.
*/
status = RTL_R16(IntrStatus);
while (status && status != 0xffff) {
handled = 1;
/* hotplug/major error/no more work/shared irq */
if ((status == 0xffff) || !status)
goto out;
handled = 1;
if (unlikely(!tp->ecdev && !netif_running(dev))) {
rtl8169_asic_down(ioaddr);
goto out;
}
status &= tp->intr_mask;
RTL_W16(IntrStatus,
(status & RxFIFOOver) ? (status | RxOverflow) : status);
if (!(status & tp->intr_event))
goto out;
/* Work around for rx fifo overflow */
if (unlikely(status & RxFIFOOver) &&
(tp->mac_version == RTL_GIGA_MAC_VER_11)) {
netif_stop_queue(dev);
rtl8169_tx_timeout(dev);
goto out;
}
if (unlikely(status & SYSErr)) {
rtl8169_pcierr_interrupt(dev);
goto out;
}
if (status & LinkChg)
rtl8169_check_link_status(dev, tp, ioaddr);
if (status & tp->napi_event) {
RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
tp->intr_mask = ~tp->napi_event;
if (likely(netif_rx_schedule_prep(dev, &tp->napi)))
__netif_rx_schedule(dev, &tp->napi);
else if (netif_msg_intr(tp)) {
printk(KERN_INFO "%s: interrupt %04x in poll\n",
dev->name, status);
/* Handle all of the error cases first. These will reset
* the chip, so just exit the loop.
*/
if (unlikely(!tp->ecdev && !netif_running(dev))) {
rtl8169_asic_down(ioaddr);
break;
}
/* Work around for rx fifo overflow */
if (unlikely(status & RxFIFOOver) &&
(tp->mac_version == RTL_GIGA_MAC_VER_11)) {
netif_stop_queue(dev);
rtl8169_tx_timeout(dev);
break;
}
if (unlikely(status & SYSErr)) {
rtl8169_pcierr_interrupt(dev);
break;
}
if (status & LinkChg)
rtl8169_check_link_status(dev, tp, ioaddr);
/* We need to see the lastest version of tp->intr_mask to
* avoid ignoring an MSI interrupt and having to wait for
* another event which may never come.
*/
smp_rmb();
if (status & tp->intr_mask & tp->napi_event) {
RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
tp->intr_mask = ~tp->napi_event;
if (likely(napi_schedule_prep(&tp->napi)))
__napi_schedule(&tp->napi);
else if (netif_msg_intr(tp)) {
printk(KERN_INFO "%s: interrupt %04x in poll\n",
dev->name, status);
}
}
/* We only get a new MSI interrupt when all active irq
* sources on the chip have been acknowledged. So, ack
* everything we've seen and check if new sources have become
* active to avoid blocking all interrupts from the chip.
*/
RTL_W16(IntrStatus,
(status & RxFIFOOver) ? (status | RxOverflow) : status);
status = RTL_R16(IntrStatus);
}
out:
return IRQ_RETVAL(handled);
}
@ -3671,14 +3711,16 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
rtl8169_tx_interrupt(dev, tp, ioaddr);
if (work_done < budget) {
netif_rx_complete(dev, napi);
tp->intr_mask = 0xffff;
/*
* 20040426: the barrier is not strictly required but the
* behavior of the irq handler could be less predictable
* without it. Btw, the lack of flush for the posted pci
* write is safe - FR
napi_complete(napi);
/* We need for force the visibility of tp->intr_mask
* for other CPUs, as we can loose an MSI interrupt
* and potentially wait for a retransmit timeout if we don't.
* The posted write to IntrMask is safe, as it will
* eventually make it to the chip and we won't loose anything
* until it does.
*/
tp->intr_mask = 0xffff;
smp_wmb();
RTL_W16(IntrMask, tp->intr_event);
}
@ -3709,8 +3751,8 @@ static void rtl8169_down(struct net_device *dev)
netif_stop_queue(dev);
napi_disable(&tp->napi);
}
}
core_down:
if (!tp->ecdev)
spin_lock_irq(&tp->lock);
@ -3755,6 +3797,9 @@ static int rtl8169_close(struct net_device *dev)
struct rtl8169_private *tp = netdev_priv(dev);
struct pci_dev *pdev = tp->pci_dev;
/* update counters before going down */
rtl8169_update_counters(dev);
rtl8169_down(dev);
if (!tp->ecdev)
@ -3849,52 +3894,40 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
return &dev->stats;
}
#ifdef CONFIG_PM
static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
static void rtl8169_net_suspend(struct net_device *dev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
if (tp->ecdev)
return -EBUSY;
if (!netif_running(dev))
goto out_pci_suspend;
return;
netif_device_detach(dev);
netif_stop_queue(dev);
}
spin_lock_irq(&tp->lock);
#ifdef CONFIG_PM
rtl8169_asic_down(ioaddr);
static int rtl8169_suspend(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
if (tp->ecdev)
return -EBUSY;
rtl8169_rx_missed(dev, ioaddr);
spin_unlock_irq(&tp->lock);
out_pci_suspend:
pci_save_state(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev, state),
(tp->features & RTL_FEATURE_WOL) ? 1 : 0);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
rtl8169_net_suspend(dev);
return 0;
}
static int rtl8169_resume(struct pci_dev *pdev)
static int rtl8169_resume(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
if (tp->ecdev)
return -EBUSY;
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_enable_wake(pdev, PCI_D0, 0);
if (!netif_running(dev))
goto out;
@ -3905,23 +3938,59 @@ out:
return 0;
}
static struct dev_pm_ops rtl8169_pm_ops = {
.suspend = rtl8169_suspend,
.resume = rtl8169_resume,
.freeze = rtl8169_suspend,
.thaw = rtl8169_resume,
.poweroff = rtl8169_suspend,
.restore = rtl8169_resume,
};
#define RTL8169_PM_OPS (&rtl8169_pm_ops)
#else /* !CONFIG_PM */
#define RTL8169_PM_OPS NULL
#endif /* !CONFIG_PM */
static void rtl_shutdown(struct pci_dev *pdev)
{
rtl8169_suspend(pdev, PMSG_SUSPEND);
}
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
#endif /* CONFIG_PM */
rtl8169_net_suspend(dev);
spin_lock_irq(&tp->lock);
rtl8169_asic_down(ioaddr);
spin_unlock_irq(&tp->lock);
if (system_state == SYSTEM_POWER_OFF) {
/* WoL fails with some 8168 when the receiver is disabled. */
if (tp->features & RTL_FEATURE_WOL) {
pci_clear_master(pdev);
RTL_W8(ChipCmd, CmdRxEnb);
/* PCI commit */
RTL_R8(ChipCmd);
}
pci_wake_from_d3(pdev, true);
pci_set_power_state(pdev, PCI_D3hot);
}
}
static struct pci_driver rtl8169_pci_driver = {
.name = MODULENAME,
.id_table = rtl8169_pci_tbl,
.probe = rtl8169_init_one,
.remove = __devexit_p(rtl8169_remove_one),
#ifdef CONFIG_PM
.suspend = rtl8169_suspend,
.resume = rtl8169_resume,
.shutdown = rtl_shutdown,
#endif
.driver.pm = RTL8169_PM_OPS,
};
static int __init rtl8169_init_module(void)

View File

@ -51,9 +51,6 @@
#define TX_BUFFS_AVAIL(tp) \
(tp->dirty_tx + NUM_TX_DESC - tp->cur_tx - 1)
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static const int max_interrupt_work = 20;
/* 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 const int multicast_filter_limit = 32;
@ -66,7 +63,6 @@ static const int multicast_filter_limit = 32;
#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
#define EarlyTxThld 0x3F /* 0x3F means NO early transmit */
#define RxPacketMaxSize 0x3FE8 /* 16K - 1 - ETH_HLEN - VLAN - CRC... */
#define SafeMtu 0x1c20 /* ... actually life sucks beyond ~7k */
#define InterFrameGap 0x03 /* 3 means InterFrameGap = the shortest one */
@ -94,6 +90,7 @@ static const int multicast_filter_limit = 32;
#define RTL_R32(reg) ((unsigned long) readl (ioaddr + (reg)))
enum mac_version {
RTL_GIGA_MAC_NONE = 0x00,
RTL_GIGA_MAC_VER_01 = 0x01, // 8169
RTL_GIGA_MAC_VER_02 = 0x02, // 8169S
RTL_GIGA_MAC_VER_03 = 0x03, // 8110S
@ -437,6 +434,22 @@ enum features {
RTL_FEATURE_GMII = (1 << 2),
};
struct rtl8169_counters {
__le64 tx_packets;
__le64 rx_packets;
__le64 tx_errors;
__le32 rx_errors;
__le16 rx_missed;
__le16 align_errors;
__le32 tx_one_collision;
__le32 tx_multi_collision;
__le64 rx_unicast;
__le64 rx_broadcast;
__le32 rx_multicast;
__le16 tx_aborted;
__le16 tx_underun;
};
struct rtl8169_private {
void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; /* Index of PCI device */
@ -463,7 +476,6 @@ struct rtl8169_private {
u16 intr_event;
u16 napi_event;
u16 intr_mask;
int phy_auto_nego_reg;
int phy_1000_ctrl_reg;
#ifdef CONFIG_R8169_VLAN
struct vlan_group *vlgrp;
@ -474,11 +486,13 @@ struct rtl8169_private {
void (*hw_start)(struct net_device *);
unsigned int (*phy_reset_pending)(void __iomem *);
unsigned int (*link_ok)(void __iomem *);
int (*do_ioctl)(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd);
int pcie_cap;
struct delayed_work task;
unsigned features;
struct mii_if_info mii;
struct rtl8169_counters counters;
};
MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>");
@ -826,76 +840,81 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
int auto_nego, giga_ctrl;
auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
auto_nego &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
ADVERTISE_100HALF | ADVERTISE_100FULL);
giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
int giga_ctrl, bmcr;
if (autoneg == AUTONEG_ENABLE) {
int auto_nego;
auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
ADVERTISE_100HALF | ADVERTISE_100FULL);
giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
} else {
if (speed == SPEED_10)
auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL;
else if (speed == SPEED_100)
auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL;
else if (speed == SPEED_1000)
auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
/* The 8100e/8101e/8102e do Fast Ethernet only. */
if ((tp->mac_version != RTL_GIGA_MAC_VER_07) &&
(tp->mac_version != RTL_GIGA_MAC_VER_08) &&
(tp->mac_version != RTL_GIGA_MAC_VER_09) &&
(tp->mac_version != RTL_GIGA_MAC_VER_10) &&
(tp->mac_version != RTL_GIGA_MAC_VER_13) &&
(tp->mac_version != RTL_GIGA_MAC_VER_14) &&
(tp->mac_version != RTL_GIGA_MAC_VER_15) &&
(tp->mac_version != RTL_GIGA_MAC_VER_16)) {
giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
if (duplex == DUPLEX_HALF)
auto_nego &= ~(ADVERTISE_10FULL | ADVERTISE_100FULL);
if (duplex == DUPLEX_FULL)
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) ||
(tp->mac_version == RTL_GIGA_MAC_VER_16))) {
auto_nego = ADVERTISE_100HALF | ADVERTISE_CSMA;
}
}
/* The 8100e/8101e/8102e do Fast Ethernet only. */
if ((tp->mac_version == RTL_GIGA_MAC_VER_07) ||
(tp->mac_version == RTL_GIGA_MAC_VER_08) ||
(tp->mac_version == RTL_GIGA_MAC_VER_09) ||
(tp->mac_version == RTL_GIGA_MAC_VER_10) ||
(tp->mac_version == RTL_GIGA_MAC_VER_13) ||
(tp->mac_version == RTL_GIGA_MAC_VER_14) ||
(tp->mac_version == RTL_GIGA_MAC_VER_15) ||
(tp->mac_version == RTL_GIGA_MAC_VER_16)) {
if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
netif_msg_link(tp)) {
} else if (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;
bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
(tp->mac_version == RTL_GIGA_MAC_VER_12) ||
(tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
/*
* Wake up the PHY.
* Vendor specific (0x1f) and reserved (0x0e) MII
* registers.
*/
mdio_write(ioaddr, 0x1f, 0x0000);
mdio_write(ioaddr, 0x0e, 0x0000);
}
mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
} else {
giga_ctrl = 0;
if (speed == SPEED_10)
bmcr = 0;
else if (speed == SPEED_100)
bmcr = BMCR_SPEED100;
else
return -EINVAL;
if (duplex == DUPLEX_FULL)
bmcr |= BMCR_FULLDPLX;
if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
(tp->mac_version == RTL_GIGA_MAC_VER_12) ||
(tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
/*
* Wake up the PHY.
* Vendor specific (0x1f) and reserved (0x0e) MII registers.
*/
mdio_write(ioaddr, 0x1f, 0x0000);
mdio_write(ioaddr, 0x0e, 0x0000);
}
tp->phy_auto_nego_reg = auto_nego;
tp->phy_1000_ctrl_reg = giga_ctrl;
mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
mdio_write(ioaddr, MII_BMCR, bmcr);
if ((tp->mac_version == RTL_GIGA_MAC_VER_02) ||
(tp->mac_version == RTL_GIGA_MAC_VER_03)) {
if ((speed == SPEED_100) && (autoneg != AUTONEG_ENABLE)) {
mdio_write(ioaddr, 0x17, 0x2138);
mdio_write(ioaddr, 0x0e, 0x0260);
} else {
mdio_write(ioaddr, 0x17, 0x2108);
mdio_write(ioaddr, 0x0e, 0x0000);
}
}
return 0;
}
@ -1099,22 +1118,6 @@ static const char rtl8169_gstrings[][ETH_GSTRING_LEN] = {
"tx_underrun",
};
struct rtl8169_counters {
__le64 tx_packets;
__le64 rx_packets;
__le64 tx_errors;
__le32 rx_errors;
__le16 rx_missed;
__le16 align_errors;
__le32 tx_one_collision;
__le32 tx_multi_collision;
__le64 rx_unicast;
__le64 rx_broadcast;
__le32 rx_multicast;
__le16 tx_aborted;
__le16 tx_underun;
};
static int rtl8169_get_sset_count(struct net_device *dev, int sset)
{
switch (sset) {
@ -1125,51 +1128,70 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset)
}
}
static void rtl8169_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
static void rtl8169_update_counters(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
struct rtl8169_counters *counters;
dma_addr_t paddr;
u32 cmd;
int wait = 1000;
ASSERT_RTNL();
/*
* Some chips are unable to dump tally counters when the receiver
* is disabled.
*/
if ((RTL_R8(ChipCmd) & CmdRxEnb) == 0)
return;
counters = pci_alloc_consistent(tp->pci_dev, sizeof(*counters), &paddr);
if (!counters)
return;
RTL_W32(CounterAddrHigh, (u64)paddr >> 32);
cmd = (u64)paddr & DMA_32BIT_MASK;
cmd = (u64)paddr & DMA_BIT_MASK(32);
RTL_W32(CounterAddrLow, cmd);
RTL_W32(CounterAddrLow, cmd | CounterDump);
while (RTL_R32(CounterAddrLow) & CounterDump) {
if (msleep_interruptible(1))
while (wait--) {
if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) {
/* copy updated counters */
memcpy(&tp->counters, counters, sizeof(*counters));
break;
}
udelay(10);
}
RTL_W32(CounterAddrLow, 0);
RTL_W32(CounterAddrHigh, 0);
data[0] = le64_to_cpu(counters->tx_packets);
data[1] = le64_to_cpu(counters->rx_packets);
data[2] = le64_to_cpu(counters->tx_errors);
data[3] = le32_to_cpu(counters->rx_errors);
data[4] = le16_to_cpu(counters->rx_missed);
data[5] = le16_to_cpu(counters->align_errors);
data[6] = le32_to_cpu(counters->tx_one_collision);
data[7] = le32_to_cpu(counters->tx_multi_collision);
data[8] = le64_to_cpu(counters->rx_unicast);
data[9] = le64_to_cpu(counters->rx_broadcast);
data[10] = le32_to_cpu(counters->rx_multicast);
data[11] = le16_to_cpu(counters->tx_aborted);
data[12] = le16_to_cpu(counters->tx_underun);
pci_free_consistent(tp->pci_dev, sizeof(*counters), counters, paddr);
}
static void rtl8169_get_ethtool_stats(struct net_device *dev,
struct ethtool_stats *stats, u64 *data)
{
struct rtl8169_private *tp = netdev_priv(dev);
ASSERT_RTNL();
rtl8169_update_counters(dev);
data[0] = le64_to_cpu(tp->counters.tx_packets);
data[1] = le64_to_cpu(tp->counters.rx_packets);
data[2] = le64_to_cpu(tp->counters.tx_errors);
data[3] = le32_to_cpu(tp->counters.rx_errors);
data[4] = le16_to_cpu(tp->counters.rx_missed);
data[5] = le16_to_cpu(tp->counters.align_errors);
data[6] = le32_to_cpu(tp->counters.tx_one_collision);
data[7] = le32_to_cpu(tp->counters.tx_multi_collision);
data[8] = le64_to_cpu(tp->counters.rx_unicast);
data[9] = le64_to_cpu(tp->counters.rx_broadcast);
data[10] = le32_to_cpu(tp->counters.rx_multicast);
data[11] = le16_to_cpu(tp->counters.tx_aborted);
data[12] = le16_to_cpu(tp->counters.tx_underun);
}
static void rtl8169_get_strings(struct net_device *dev, u32 stringset, u8 *data)
{
switch(stringset) {
@ -1275,7 +1297,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
{ 0xfc800000, 0x00800000, RTL_GIGA_MAC_VER_02 },
{ 0xfc800000, 0x00000000, RTL_GIGA_MAC_VER_01 },
{ 0x00000000, 0x00000000, RTL_GIGA_MAC_VER_01 } /* Catch-all */
/* Catch-all */
{ 0x00000000, 0x00000000, RTL_GIGA_MAC_NONE }
}, *p = mac_info;
u32 reg;
@ -1283,12 +1306,6 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
while ((reg & p->mask) != p->val)
p++;
tp->mac_version = p->mac_version;
if (p->mask == 0x00000000) {
struct pci_dev *pdev = tp->pci_dev;
dev_info(&pdev->dev, "unknown MAC (%08x)\n", reg);
}
}
static void rtl8169_print_mac_version(struct rtl8169_private *tp)
@ -1829,9 +1846,11 @@ 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;
return netif_running(dev) ? tp->do_ioctl(tp, data, cmd) : -ENODEV;
}
static int rtl_xmii_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
{
switch (cmd) {
case SIOCGMIIPHY:
data->phy_id = 32; /* Internal PHY */
@ -1850,6 +1869,11 @@ static int rtl8169_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return -EOPNOTSUPP;
}
static int rtl_tbi_ioctl(struct rtl8169_private *tp, struct mii_ioctl_data *data, int cmd)
{
return -EOPNOTSUPP;
}
static const struct rtl_cfg_info {
void (*hw_start)(struct net_device *);
unsigned int region;
@ -1857,6 +1881,7 @@ static const struct rtl_cfg_info {
u16 intr_event;
u16 napi_event;
unsigned features;
u8 default_ver;
} rtl_cfg_infos [] = {
[RTL_CFG_0] = {
.hw_start = rtl_hw_start_8169,
@ -1865,7 +1890,8 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
.features = RTL_FEATURE_GMII
.features = RTL_FEATURE_GMII,
.default_ver = RTL_GIGA_MAC_VER_01,
},
[RTL_CFG_1] = {
.hw_start = rtl_hw_start_8168,
@ -1874,7 +1900,8 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow |
TxErr | TxOK | RxOK | RxErr,
.napi_event = TxErr | TxOK | RxOK | RxOverflow,
.features = RTL_FEATURE_GMII | RTL_FEATURE_MSI
.features = RTL_FEATURE_GMII | RTL_FEATURE_MSI,
.default_ver = RTL_GIGA_MAC_VER_11,
},
[RTL_CFG_2] = {
.hw_start = rtl_hw_start_8101,
@ -1883,7 +1910,8 @@ static const struct rtl_cfg_info {
.intr_event = SYSErr | LinkChg | RxOverflow | PCSTimeout |
RxFIFOOver | TxErr | TxOK | RxOK | RxErr,
.napi_event = RxFIFOOver | TxErr | TxOK | RxOK | RxOverflow,
.features = RTL_FEATURE_MSI
.features = RTL_FEATURE_MSI,
.default_ver = RTL_GIGA_MAC_VER_13,
}
};
@ -1915,6 +1943,26 @@ static void rtl_disable_msi(struct pci_dev *pdev, struct rtl8169_private *tp)
}
}
static const struct net_device_ops rtl8169_netdev_ops = {
.ndo_open = rtl8169_open,
.ndo_stop = rtl8169_close,
.ndo_get_stats = rtl8169_get_stats,
.ndo_start_xmit = rtl8169_start_xmit,
.ndo_tx_timeout = rtl8169_tx_timeout,
.ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = rtl8169_change_mtu,
.ndo_set_mac_address = rtl_set_mac_address,
.ndo_do_ioctl = rtl8169_ioctl,
.ndo_set_multicast_list = rtl_set_rx_mode,
#ifdef CONFIG_R8169_VLAN
.ndo_vlan_rx_register = rtl8169_vlan_rx_register,
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = rtl8169_netpoll,
#endif
};
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@ -1941,6 +1989,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
SET_NETDEV_DEV(dev, &pdev->dev);
dev->netdev_ops = &rtl8169_netdev_ops;
tp = netdev_priv(dev);
tp->dev = dev;
tp->pci_dev = pdev;
@ -1997,11 +2046,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->cp_cmd = PCIMulRW | RxChkSum;
if ((sizeof(dma_addr_t) > 4) &&
!pci_set_dma_mask(pdev, DMA_64BIT_MASK) && use_dac) {
!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) {
tp->cp_cmd |= PCIDAC;
dev->features |= NETIF_F_HIGHDMA;
} else {
rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (rc < 0) {
if (netif_msg_probe(tp)) {
dev_err(&pdev->dev,
@ -2011,8 +2060,6 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
pci_set_master(pdev);
/* ioremap MMIO region */
ioaddr = ioremap(pci_resource_start(pdev, region), R8169_REGS_SIZE);
if (!ioaddr) {
@ -2040,9 +2087,20 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
RTL_W16(IntrStatus, 0xffff);
pci_set_master(pdev);
/* Identify chip attached to board */
rtl8169_get_mac_version(tp, ioaddr);
/* Use appropriate default if unknown */
if (tp->mac_version == RTL_GIGA_MAC_NONE) {
if (netif_msg_probe(tp)) {
dev_notice(&pdev->dev,
"unknown MAC, using family default\n");
}
tp->mac_version = cfg->default_ver;
}
rtl8169_print_mac_version(tp);
for (i = 0; i < ARRAY_SIZE(rtl_chip_info); i++) {
@ -2050,13 +2108,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
if (i == ARRAY_SIZE(rtl_chip_info)) {
/* Unknown chip: assume array element #0, original RTL-8169 */
if (netif_msg_probe(tp)) {
dev_printk(KERN_DEBUG, &pdev->dev,
"unknown chip version, assuming %s\n",
rtl_chip_info[0].name);
}
i = 0;
dev_err(&pdev->dev,
"driver bug, MAC version not found in rtl_chip_info\n");
goto err_out_msi_5;
}
tp->chipset = i;
@ -2077,6 +2131,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->phy_reset_enable = rtl8169_tbi_reset_enable;
tp->phy_reset_pending = rtl8169_tbi_reset_pending;
tp->link_ok = rtl8169_tbi_link_ok;
tp->do_ioctl = rtl_tbi_ioctl;
tp->phy_1000_ctrl_reg = ADVERTISE_1000FULL; /* Implied by TBI */
} else {
@ -2085,8 +2140,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
tp->phy_reset_enable = rtl8169_xmii_reset_enable;
tp->phy_reset_pending = rtl8169_xmii_reset_pending;
tp->link_ok = rtl8169_xmii_link_ok;
dev->do_ioctl = rtl8169_ioctl;
tp->do_ioctl = rtl_xmii_ioctl;
}
spin_lock_init(&tp->lock);
@ -2098,28 +2152,15 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->dev_addr[i] = RTL_R8(MAC0 + i);
memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
dev->open = rtl8169_open;
dev->hard_start_xmit = rtl8169_start_xmit;
dev->get_stats = rtl8169_get_stats;
SET_ETHTOOL_OPS(dev, &rtl8169_ethtool_ops);
dev->stop = rtl8169_close;
dev->tx_timeout = rtl8169_tx_timeout;
dev->set_multicast_list = rtl_set_rx_mode;
dev->watchdog_timeo = RTL8169_TX_TIMEOUT;
dev->irq = pdev->irq;
dev->base_addr = (unsigned long) ioaddr;
dev->change_mtu = rtl8169_change_mtu;
dev->set_mac_address = rtl_set_mac_address;
netif_napi_add(dev, &tp->napi, rtl8169_poll, R8169_NAPI_WEIGHT);
#ifdef CONFIG_R8169_VLAN
dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
dev->vlan_rx_register = rtl8169_vlan_rx_register;
#endif
#ifdef CONFIG_NET_POLL_CONTROLLER
dev->poll_controller = rtl8169_netpoll;
#endif
tp->intr_mask = 0xffff;
@ -2307,9 +2348,9 @@ static void rtl_set_rx_tx_desc_registers(struct rtl8169_private *tp,
* Switching from MMIO to I/O access fixes the issue as well.
*/
RTL_W32(TxDescStartAddrHigh, ((u64) tp->TxPhyAddr) >> 32);
RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_32BIT_MASK);
RTL_W32(TxDescStartAddrLow, ((u64) tp->TxPhyAddr) & DMA_BIT_MASK(32));
RTL_W32(RxDescAddrHigh, ((u64) tp->RxPhyAddr) >> 32);
RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_32BIT_MASK);
RTL_W32(RxDescAddrLow, ((u64) tp->RxPhyAddr) & DMA_BIT_MASK(32));
}
static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
@ -2321,10 +2362,10 @@ static u16 rtl_rw_cpluscmd(void __iomem *ioaddr)
return cmd;
}
static void rtl_set_rx_max_size(void __iomem *ioaddr)
static void rtl_set_rx_max_size(void __iomem *ioaddr, unsigned int rx_buf_sz)
{
/* Low hurts. Let's disable the filtering. */
RTL_W16(RxMaxSize, 16383);
RTL_W16(RxMaxSize, rx_buf_sz);
}
static void rtl8169_set_magic_reg(void __iomem *ioaddr, unsigned mac_version)
@ -2371,7 +2412,7 @@ static void rtl_hw_start_8169(struct net_device *dev)
RTL_W8(EarlyTxThres, EarlyTxThld);
rtl_set_rx_max_size(ioaddr);
rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
if ((tp->mac_version == RTL_GIGA_MAC_VER_01) ||
(tp->mac_version == RTL_GIGA_MAC_VER_02) ||
@ -2632,7 +2673,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
RTL_W8(EarlyTxThres, EarlyTxThld);
rtl_set_rx_max_size(ioaddr);
rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
tp->cp_cmd |= RTL_R16(CPlusCmd) | PktCntrDisable | INTT_1;
@ -2810,7 +2851,7 @@ static void rtl_hw_start_8101(struct net_device *dev)
RTL_W8(EarlyTxThres, EarlyTxThld);
rtl_set_rx_max_size(ioaddr);
rtl_set_rx_max_size(ioaddr, tp->rx_buf_sz);
tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
@ -3218,13 +3259,6 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
opts1 |= FirstFrag;
} else {
len = skb->len;
if (unlikely(len < ETH_ZLEN)) {
if (skb_padto(skb, ETH_ZLEN))
goto err_update_stats;
len = ETH_ZLEN;
}
opts1 |= FirstFrag | LastFrag;
tp->tx_skb[entry].skb = skb;
}
@ -3241,8 +3275,6 @@ static int rtl8169_start_xmit(struct sk_buff *skb, struct net_device *dev)
status = opts1 | len | (RingEnd * !((entry + 1) % NUM_TX_DESC));
txd->opts1 = cpu_to_le32(status);
dev->trans_start = jiffies;
tp->cur_tx += frags + 1;
smp_wmb();
@ -3262,7 +3294,6 @@ out:
err_stop:
netif_stop_queue(dev);
ret = NETDEV_TX_BUSY;
err_update_stats:
dev->stats.tx_dropped++;
goto out;
}
@ -3344,7 +3375,7 @@ static void rtl8169_tx_interrupt(struct net_device *dev,
rtl8169_unmap_tx_skb(tp->pci_dev, tx_skb, tp->TxDescArray + entry);
if (status & LastFrag) {
dev_kfree_skb_irq(tx_skb->skb);
dev_kfree_skb(tx_skb->skb);
tx_skb->skb = NULL;
}
dirty_tx++;
@ -3485,7 +3516,6 @@ static int rtl8169_rx_interrupt(struct net_device *dev,
if (rtl8169_rx_vlan_skb(tp, desc, skb) < 0)
netif_receive_skb(skb);
dev->last_rx = jiffies;
dev->stats.rx_bytes += pkt_size;
dev->stats.rx_packets++;
}
@ -3527,54 +3557,64 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
int handled = 0;
int status;
/* loop handling interrupts until we have no new ones or
* we hit a invalid/hotplug case.
*/
status = RTL_R16(IntrStatus);
while (status && status != 0xffff) {
handled = 1;
/* hotplug/major error/no more work/shared irq */
if ((status == 0xffff) || !status)
goto out;
handled = 1;
if (unlikely(!netif_running(dev))) {
rtl8169_asic_down(ioaddr);
goto out;
}
status &= tp->intr_mask;
RTL_W16(IntrStatus,
(status & RxFIFOOver) ? (status | RxOverflow) : status);
if (!(status & tp->intr_event))
goto out;
/* Work around for rx fifo overflow */
if (unlikely(status & RxFIFOOver) &&
(tp->mac_version == RTL_GIGA_MAC_VER_11)) {
netif_stop_queue(dev);
rtl8169_tx_timeout(dev);
goto out;
}
if (unlikely(status & SYSErr)) {
rtl8169_pcierr_interrupt(dev);
goto out;
}
if (status & LinkChg)
rtl8169_check_link_status(dev, tp, ioaddr);
if (status & tp->napi_event) {
RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
tp->intr_mask = ~tp->napi_event;
if (likely(netif_rx_schedule_prep(dev, &tp->napi)))
__netif_rx_schedule(dev, &tp->napi);
else if (netif_msg_intr(tp)) {
printk(KERN_INFO "%s: interrupt %04x in poll\n",
dev->name, status);
/* Handle all of the error cases first. These will reset
* the chip, so just exit the loop.
*/
if (unlikely(!netif_running(dev))) {
rtl8169_asic_down(ioaddr);
break;
}
/* Work around for rx fifo overflow */
if (unlikely(status & RxFIFOOver) &&
(tp->mac_version == RTL_GIGA_MAC_VER_11)) {
netif_stop_queue(dev);
rtl8169_tx_timeout(dev);
break;
}
if (unlikely(status & SYSErr)) {
rtl8169_pcierr_interrupt(dev);
break;
}
if (status & LinkChg)
rtl8169_check_link_status(dev, tp, ioaddr);
/* We need to see the lastest version of tp->intr_mask to
* avoid ignoring an MSI interrupt and having to wait for
* another event which may never come.
*/
smp_rmb();
if (status & tp->intr_mask & tp->napi_event) {
RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
tp->intr_mask = ~tp->napi_event;
if (likely(napi_schedule_prep(&tp->napi)))
__napi_schedule(&tp->napi);
else if (netif_msg_intr(tp)) {
printk(KERN_INFO "%s: interrupt %04x in poll\n",
dev->name, status);
}
}
/* We only get a new MSI interrupt when all active irq
* sources on the chip have been acknowledged. So, ack
* everything we've seen and check if new sources have become
* active to avoid blocking all interrupts from the chip.
*/
RTL_W16(IntrStatus,
(status & RxFIFOOver) ? (status | RxOverflow) : status);
status = RTL_R16(IntrStatus);
}
out:
return IRQ_RETVAL(handled);
}
@ -3589,14 +3629,16 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
rtl8169_tx_interrupt(dev, tp, ioaddr);
if (work_done < budget) {
netif_rx_complete(dev, napi);
tp->intr_mask = 0xffff;
/*
* 20040426: the barrier is not strictly required but the
* behavior of the irq handler could be less predictable
* without it. Btw, the lack of flush for the posted pci
* write is safe - FR
napi_complete(napi);
/* We need for force the visibility of tp->intr_mask
* for other CPUs, as we can loose an MSI interrupt
* and potentially wait for a retransmit timeout if we don't.
* The posted write to IntrMask is safe, as it will
* eventually make it to the chip and we won't loose anything
* until it does.
*/
tp->intr_mask = 0xffff;
smp_wmb();
RTL_W16(IntrMask, tp->intr_event);
}
@ -3668,6 +3710,9 @@ static int rtl8169_close(struct net_device *dev)
struct rtl8169_private *tp = netdev_priv(dev);
struct pci_dev *pdev = tp->pci_dev;
/* update counters before going down */
rtl8169_update_counters(dev);
rtl8169_down(dev);
free_irq(dev->irq, dev);
@ -3761,45 +3806,32 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
return &dev->stats;
}
#ifdef CONFIG_PM
static int rtl8169_suspend(struct pci_dev *pdev, pm_message_t state)
static void rtl8169_net_suspend(struct net_device *dev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
if (!netif_running(dev))
goto out_pci_suspend;
return;
netif_device_detach(dev);
netif_stop_queue(dev);
}
spin_lock_irq(&tp->lock);
#ifdef CONFIG_PM
rtl8169_asic_down(ioaddr);
static int rtl8169_suspend(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
rtl8169_rx_missed(dev, ioaddr);
spin_unlock_irq(&tp->lock);
out_pci_suspend:
pci_save_state(pdev);
pci_enable_wake(pdev, pci_choose_state(pdev, state),
(tp->features & RTL_FEATURE_WOL) ? 1 : 0);
pci_set_power_state(pdev, pci_choose_state(pdev, state));
rtl8169_net_suspend(dev);
return 0;
}
static int rtl8169_resume(struct pci_dev *pdev)
static int rtl8169_resume(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
struct net_device *dev = pci_get_drvdata(pdev);
pci_set_power_state(pdev, PCI_D0);
pci_restore_state(pdev);
pci_enable_wake(pdev, PCI_D0, 0);
if (!netif_running(dev))
goto out;
@ -3810,23 +3842,59 @@ out:
return 0;
}
static struct dev_pm_ops rtl8169_pm_ops = {
.suspend = rtl8169_suspend,
.resume = rtl8169_resume,
.freeze = rtl8169_suspend,
.thaw = rtl8169_resume,
.poweroff = rtl8169_suspend,
.restore = rtl8169_resume,
};
#define RTL8169_PM_OPS (&rtl8169_pm_ops)
#else /* !CONFIG_PM */
#define RTL8169_PM_OPS NULL
#endif /* !CONFIG_PM */
static void rtl_shutdown(struct pci_dev *pdev)
{
rtl8169_suspend(pdev, PMSG_SUSPEND);
}
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
void __iomem *ioaddr = tp->mmio_addr;
#endif /* CONFIG_PM */
rtl8169_net_suspend(dev);
spin_lock_irq(&tp->lock);
rtl8169_asic_down(ioaddr);
spin_unlock_irq(&tp->lock);
if (system_state == SYSTEM_POWER_OFF) {
/* WoL fails with some 8168 when the receiver is disabled. */
if (tp->features & RTL_FEATURE_WOL) {
pci_clear_master(pdev);
RTL_W8(ChipCmd, CmdRxEnb);
/* PCI commit */
RTL_R8(ChipCmd);
}
pci_wake_from_d3(pdev, true);
pci_set_power_state(pdev, PCI_D3hot);
}
}
static struct pci_driver rtl8169_pci_driver = {
.name = MODULENAME,
.id_table = rtl8169_pci_tbl,
.probe = rtl8169_init_one,
.remove = __devexit_p(rtl8169_remove_one),
#ifdef CONFIG_PM
.suspend = rtl8169_suspend,
.resume = rtl8169_resume,
.shutdown = rtl_shutdown,
#endif
.driver.pm = RTL8169_PM_OPS,
};
static int __init rtl8169_init_module(void)