mirror of
https://github.com/vincentmli/bpfire.git
synced 2026-04-28 11:43:25 +02:00
Add patches to detect Realtek 8102/8103 to r8101 driver.
This commit is contained in:
@@ -30,7 +30,7 @@ else
|
|||||||
VERSUFIX = ipfire
|
VERSUFIX = ipfire
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VER = ipfire-1
|
VER = ipfire-2
|
||||||
|
|
||||||
THISAPP = r8101
|
THISAPP = r8101
|
||||||
DIR_APP = $(DIR_SRC)/$(THISAPP)
|
DIR_APP = $(DIR_SRC)/$(THISAPP)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* r8101.c: RealTek 8101 ethernet driver.
|
* r8101.c: RealTek 8101 ethernet driver.
|
||||||
*
|
*
|
||||||
* This driver based on r8169 from Kernel 2.6.27.31
|
* This driver based on r8169 from Kernel 2.6.27.39 with SuSE patches
|
||||||
* All pciids except for 8101 are removed becaue we want use
|
* All pciids except for 8101 are removed becaue we want use
|
||||||
* original realtek drivers except for 8101 because the
|
* original realtek drivers except for 8101 because the
|
||||||
* vendors r8101 produce a kernel panic.
|
* vendors r8101 produce a kernel panic.
|
||||||
@@ -67,6 +67,7 @@ static const int multicast_filter_limit = 32;
|
|||||||
/* MAC address length */
|
/* MAC address length */
|
||||||
#define MAC_ADDR_LEN 6
|
#define MAC_ADDR_LEN 6
|
||||||
|
|
||||||
|
#define MAX_READ_REQUEST_SHIFT 12
|
||||||
#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
|
#define RX_FIFO_THRESH 7 /* 7 means NO threshold, Rx buffer level before first PCI xfer. */
|
||||||
#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
|
#define RX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
|
||||||
#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
|
#define TX_DMA_BURST 6 /* Maximum PCI burst, '6' is 1024 */
|
||||||
@@ -100,6 +101,10 @@ enum mac_version {
|
|||||||
RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
|
RTL_GIGA_MAC_VER_04 = 0x04, // 8169SB
|
||||||
RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
|
RTL_GIGA_MAC_VER_05 = 0x05, // 8110SCd
|
||||||
RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
|
RTL_GIGA_MAC_VER_06 = 0x06, // 8110SCe
|
||||||
|
RTL_GIGA_MAC_VER_07 = 0x07, // 8102e
|
||||||
|
RTL_GIGA_MAC_VER_08 = 0x08, // 8102e
|
||||||
|
RTL_GIGA_MAC_VER_09 = 0x09, // 8102e
|
||||||
|
RTL_GIGA_MAC_VER_10 = 0x0a, // 8101e
|
||||||
RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
|
RTL_GIGA_MAC_VER_11 = 0x0b, // 8168Bb
|
||||||
RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
|
RTL_GIGA_MAC_VER_12 = 0x0c, // 8168Be
|
||||||
RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
|
RTL_GIGA_MAC_VER_13 = 0x0d, // 8101Eb
|
||||||
@@ -124,8 +129,12 @@ static const struct {
|
|||||||
_R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S
|
_R("RTL8169s", RTL_GIGA_MAC_VER_02, 0xff7e1880), // 8169S
|
||||||
_R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S
|
_R("RTL8110s", RTL_GIGA_MAC_VER_03, 0xff7e1880), // 8110S
|
||||||
_R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
|
_R("RTL8169sb/8110sb", RTL_GIGA_MAC_VER_04, 0xff7e1880), // 8169SB
|
||||||
_R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8169SCd
|
_R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_05, 0xff7e1880), // 8110SCd
|
||||||
_R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8169SCe
|
_R("RTL8169sc/8110sc", RTL_GIGA_MAC_VER_06, 0xff7e1880), // 8110SCe
|
||||||
|
_R("RTL8102e", RTL_GIGA_MAC_VER_07, 0xff7e1880), // PCI-E
|
||||||
|
_R("RTL8102e", RTL_GIGA_MAC_VER_08, 0xff7e1880), // PCI-E
|
||||||
|
_R("RTL8102e", RTL_GIGA_MAC_VER_09, 0xff7e1880), // PCI-E
|
||||||
|
_R("RTL8101e", RTL_GIGA_MAC_VER_10, 0xff7e1880), // PCI-E
|
||||||
_R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
|
_R("RTL8168b/8111b", RTL_GIGA_MAC_VER_11, 0xff7e1880), // PCI-E
|
||||||
_R("RTL8168b/8111b", RTL_GIGA_MAC_VER_12, 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("RTL8101e", RTL_GIGA_MAC_VER_13, 0xff7e1880), // PCI-E 8139
|
||||||
@@ -201,9 +210,6 @@ enum rtl_registers {
|
|||||||
Config5 = 0x56,
|
Config5 = 0x56,
|
||||||
MultiIntr = 0x5c,
|
MultiIntr = 0x5c,
|
||||||
PHYAR = 0x60,
|
PHYAR = 0x60,
|
||||||
TBICSR = 0x64,
|
|
||||||
TBI_ANAR = 0x68,
|
|
||||||
TBI_LPAR = 0x6a,
|
|
||||||
PHYstatus = 0x6c,
|
PHYstatus = 0x6c,
|
||||||
RxMaxSize = 0xda,
|
RxMaxSize = 0xda,
|
||||||
CPlusCmd = 0xe0,
|
CPlusCmd = 0xe0,
|
||||||
@@ -217,6 +223,32 @@ enum rtl_registers {
|
|||||||
FuncForceEvent = 0xfc,
|
FuncForceEvent = 0xfc,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum rtl8110_registers {
|
||||||
|
TBICSR = 0x64,
|
||||||
|
TBI_ANAR = 0x68,
|
||||||
|
TBI_LPAR = 0x6a,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum rtl8168_8101_registers {
|
||||||
|
CSIDR = 0x64,
|
||||||
|
CSIAR = 0x68,
|
||||||
|
#define CSIAR_FLAG 0x80000000
|
||||||
|
#define CSIAR_WRITE_CMD 0x80000000
|
||||||
|
#define CSIAR_BYTE_ENABLE 0x0f
|
||||||
|
#define CSIAR_BYTE_ENABLE_SHIFT 12
|
||||||
|
#define CSIAR_ADDR_MASK 0x0fff
|
||||||
|
|
||||||
|
EPHYAR = 0x80,
|
||||||
|
#define EPHYAR_FLAG 0x80000000
|
||||||
|
#define EPHYAR_WRITE_CMD 0x80000000
|
||||||
|
#define EPHYAR_REG_MASK 0x1f
|
||||||
|
#define EPHYAR_REG_SHIFT 16
|
||||||
|
#define EPHYAR_DATA_MASK 0xffff
|
||||||
|
DBG_REG = 0xd1,
|
||||||
|
#define FIX_NAK_1 (1 << 4)
|
||||||
|
#define FIX_NAK_2 (1 << 3)
|
||||||
|
};
|
||||||
|
|
||||||
enum rtl_register_content {
|
enum rtl_register_content {
|
||||||
/* InterruptStatusBits */
|
/* InterruptStatusBits */
|
||||||
SYSErr = 0x8000,
|
SYSErr = 0x8000,
|
||||||
@@ -270,7 +302,13 @@ enum rtl_register_content {
|
|||||||
TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
|
TxDMAShift = 8, /* DMA burst value (0-7) is shift this many bits */
|
||||||
|
|
||||||
/* Config1 register p.24 */
|
/* Config1 register p.24 */
|
||||||
|
LEDS1 = (1 << 7),
|
||||||
|
LEDS0 = (1 << 6),
|
||||||
MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */
|
MSIEnable = (1 << 5), /* Enable Message Signaled Interrupt */
|
||||||
|
Speed_down = (1 << 4),
|
||||||
|
MEMMAP = (1 << 3),
|
||||||
|
IOMAP = (1 << 2),
|
||||||
|
VPD = (1 << 1),
|
||||||
PMEnable = (1 << 0), /* Power Management Enable */
|
PMEnable = (1 << 0), /* Power Management Enable */
|
||||||
|
|
||||||
/* Config2 register p. 25 */
|
/* Config2 register p. 25 */
|
||||||
@@ -280,6 +318,7 @@ enum rtl_register_content {
|
|||||||
/* Config3 register p.25 */
|
/* Config3 register p.25 */
|
||||||
MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
|
MagicPacket = (1 << 5), /* Wake up when receives a Magic Packet */
|
||||||
LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
|
LinkUp = (1 << 4), /* Wake up when the cable connection is re-established */
|
||||||
|
Beacon_en = (1 << 0), /* 8168 only. Reserved in the 8168b */
|
||||||
|
|
||||||
/* Config5 register p.27 */
|
/* Config5 register p.27 */
|
||||||
BWF = (1 << 6), /* Accept Broadcast wakeup frame */
|
BWF = (1 << 6), /* Accept Broadcast wakeup frame */
|
||||||
@@ -297,7 +336,16 @@ enum rtl_register_content {
|
|||||||
TBINwComplete = 0x01000000,
|
TBINwComplete = 0x01000000,
|
||||||
|
|
||||||
/* CPlusCmd p.31 */
|
/* CPlusCmd p.31 */
|
||||||
PktCntrDisable = (1 << 7), // 8168
|
EnableBist = (1 << 15), // 8168 8101
|
||||||
|
Mac_dbgo_oe = (1 << 14), // 8168 8101
|
||||||
|
Normal_mode = (1 << 13), // unused
|
||||||
|
Force_half_dup = (1 << 12), // 8168 8101
|
||||||
|
Force_rxflow_en = (1 << 11), // 8168 8101
|
||||||
|
Force_txflow_en = (1 << 10), // 8168 8101
|
||||||
|
Cxpl_dbg_sel = (1 << 9), // 8168 8101
|
||||||
|
ASF = (1 << 8), // 8168 8101
|
||||||
|
PktCntrDisable = (1 << 7), // 8168 8101
|
||||||
|
Mac_dbgo_sel = 0x001c, // 8168
|
||||||
RxVlan = (1 << 6),
|
RxVlan = (1 << 6),
|
||||||
RxChkSum = (1 << 5),
|
RxChkSum = (1 << 5),
|
||||||
PCIDAC = (1 << 4),
|
PCIDAC = (1 << 4),
|
||||||
@@ -433,6 +481,7 @@ struct rtl8101_private {
|
|||||||
void (*hw_start)(struct net_device *);
|
void (*hw_start)(struct net_device *);
|
||||||
unsigned int (*phy_reset_pending)(void __iomem *);
|
unsigned int (*phy_reset_pending)(void __iomem *);
|
||||||
unsigned int (*link_ok)(void __iomem *);
|
unsigned int (*link_ok)(void __iomem *);
|
||||||
|
int pcie_cap;
|
||||||
struct delayed_work task;
|
struct delayed_work task;
|
||||||
unsigned features;
|
unsigned features;
|
||||||
|
|
||||||
@@ -507,6 +556,11 @@ static int mdio_read(void __iomem *ioaddr, int reg_addr)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void mdio_patch(void __iomem *ioaddr, int reg_addr, int value)
|
||||||
|
{
|
||||||
|
mdio_write(ioaddr, reg_addr, mdio_read(ioaddr, reg_addr) | value);
|
||||||
|
}
|
||||||
|
|
||||||
static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
|
static void rtl_mdio_write(struct net_device *dev, int phy_id, int location,
|
||||||
int val)
|
int val)
|
||||||
{
|
{
|
||||||
@@ -524,6 +578,72 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location)
|
|||||||
return mdio_read(ioaddr, location);
|
return mdio_read(ioaddr, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) |
|
||||||
|
(reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
|
||||||
|
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
|
if (!(RTL_R32(EPHYAR) & EPHYAR_FLAG))
|
||||||
|
break;
|
||||||
|
udelay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr)
|
||||||
|
{
|
||||||
|
u16 value = 0xffff;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
RTL_W32(EPHYAR, (reg_addr & EPHYAR_REG_MASK) << EPHYAR_REG_SHIFT);
|
||||||
|
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
|
if (RTL_R32(EPHYAR) & EPHYAR_FLAG) {
|
||||||
|
value = RTL_R32(EPHYAR) & EPHYAR_DATA_MASK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
udelay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl_csi_write(void __iomem *ioaddr, int addr, int value)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
RTL_W32(CSIDR, value);
|
||||||
|
RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) |
|
||||||
|
CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
|
||||||
|
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
|
if (!(RTL_R32(CSIAR) & CSIAR_FLAG))
|
||||||
|
break;
|
||||||
|
udelay(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 rtl_csi_read(void __iomem *ioaddr, int addr)
|
||||||
|
{
|
||||||
|
u32 value = ~0x00;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) |
|
||||||
|
CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT);
|
||||||
|
|
||||||
|
for (i = 0; i < 100; i++) {
|
||||||
|
if (RTL_R32(CSIAR) & CSIAR_FLAG) {
|
||||||
|
value = RTL_R32(CSIDR);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
udelay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
static void rtl8101_irq_mask_and_ack(void __iomem *ioaddr)
|
static void rtl8101_irq_mask_and_ack(void __iomem *ioaddr)
|
||||||
{
|
{
|
||||||
RTL_W16(IntrMask, 0x0000);
|
RTL_W16(IntrMask, 0x0000);
|
||||||
@@ -713,72 +833,83 @@ static int rtl8101_set_speed_xmii(struct net_device *dev,
|
|||||||
{
|
{
|
||||||
struct rtl8101_private *tp = netdev_priv(dev);
|
struct rtl8101_private *tp = netdev_priv(dev);
|
||||||
void __iomem *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
int auto_nego, giga_ctrl;
|
int giga_ctrl, bmcr;
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (autoneg == AUTONEG_ENABLE) {
|
if (autoneg == AUTONEG_ENABLE) {
|
||||||
|
int auto_nego;
|
||||||
|
|
||||||
|
auto_nego = mdio_read(ioaddr, MII_ADVERTISE);
|
||||||
auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
|
auto_nego |= (ADVERTISE_10HALF | ADVERTISE_10FULL |
|
||||||
ADVERTISE_100HALF | ADVERTISE_100FULL);
|
ADVERTISE_100HALF | ADVERTISE_100FULL);
|
||||||
giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
|
auto_nego |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
|
||||||
} else {
|
|
||||||
if (speed == SPEED_10)
|
giga_ctrl = mdio_read(ioaddr, MII_CTRL1000);
|
||||||
auto_nego |= ADVERTISE_10HALF | ADVERTISE_10FULL;
|
giga_ctrl &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
|
||||||
else if (speed == SPEED_100)
|
|
||||||
auto_nego |= ADVERTISE_100HALF | ADVERTISE_100FULL;
|
/* The 8100e/8101e/8102e do Fast Ethernet only. */
|
||||||
else if (speed == SPEED_1000)
|
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;
|
giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
|
||||||
|
} else if (netif_msg_link(tp)) {
|
||||||
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 do Fast Ethernet only. */
|
|
||||||
if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
|
|
||||||
(tp->mac_version == RTL_GIGA_MAC_VER_14) ||
|
|
||||||
(tp->mac_version == RTL_GIGA_MAC_VER_15) ||
|
|
||||||
(tp->mac_version == RTL_GIGA_MAC_VER_16)) {
|
|
||||||
if ((giga_ctrl & (ADVERTISE_1000FULL | ADVERTISE_1000HALF)) &&
|
|
||||||
netif_msg_link(tp)) {
|
|
||||||
printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
|
printk(KERN_INFO "%s: PHY does not support 1000Mbps.\n",
|
||||||
dev->name);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
tp->phy_auto_nego_reg = auto_nego;
|
||||||
|
|
||||||
|
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, 0x1f, 0x0000);
|
||||||
mdio_write(ioaddr, 0x0e, 0x0000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tp->phy_auto_nego_reg = auto_nego;
|
|
||||||
tp->phy_1000_ctrl_reg = giga_ctrl;
|
tp->phy_1000_ctrl_reg = giga_ctrl;
|
||||||
|
|
||||||
mdio_write(ioaddr, MII_ADVERTISE, auto_nego);
|
mdio_write(ioaddr, MII_BMCR, bmcr);
|
||||||
mdio_write(ioaddr, MII_CTRL1000, giga_ctrl);
|
|
||||||
mdio_write(ioaddr, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1129,8 +1260,17 @@ static void rtl8101_get_mac_version(struct rtl8101_private *tp,
|
|||||||
{ 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
|
{ 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
|
||||||
|
|
||||||
/* 8101 family. */
|
/* 8101 family. */
|
||||||
|
{ 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 },
|
||||||
|
{ 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 },
|
||||||
|
{ 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 },
|
||||||
|
{ 0x7cf00000, 0x24900000, RTL_GIGA_MAC_VER_08 },
|
||||||
|
{ 0x7cf00000, 0x34800000, RTL_GIGA_MAC_VER_07 },
|
||||||
|
{ 0x7cf00000, 0x24800000, RTL_GIGA_MAC_VER_07 },
|
||||||
{ 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 },
|
{ 0x7cf00000, 0x34000000, RTL_GIGA_MAC_VER_13 },
|
||||||
|
{ 0x7cf00000, 0x34300000, RTL_GIGA_MAC_VER_10 },
|
||||||
{ 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 },
|
{ 0x7cf00000, 0x34200000, RTL_GIGA_MAC_VER_16 },
|
||||||
|
{ 0x7c800000, 0x34800000, RTL_GIGA_MAC_VER_09 },
|
||||||
|
{ 0x7c800000, 0x24800000, RTL_GIGA_MAC_VER_09 },
|
||||||
{ 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 },
|
{ 0x7c800000, 0x34000000, RTL_GIGA_MAC_VER_16 },
|
||||||
/* FIXME: where did these entries come from ? -- FR */
|
/* FIXME: where did these entries come from ? -- FR */
|
||||||
{ 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 },
|
{ 0xfc800000, 0x38800000, RTL_GIGA_MAC_VER_15 },
|
||||||
@@ -1292,6 +1432,22 @@ static void rtl8168cx_hw_phy_config(void __iomem *ioaddr)
|
|||||||
rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
|
rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl8102e_hw_phy_config(void __iomem *ioaddr)
|
||||||
|
{
|
||||||
|
struct phy_reg phy_reg_init[] = {
|
||||||
|
{ 0x1f, 0x0003 },
|
||||||
|
{ 0x08, 0x441d },
|
||||||
|
{ 0x01, 0x9100 },
|
||||||
|
{ 0x1f, 0x0000 }
|
||||||
|
};
|
||||||
|
|
||||||
|
mdio_write(ioaddr, 0x1f, 0x0000);
|
||||||
|
mdio_patch(ioaddr, 0x11, 1 << 12);
|
||||||
|
mdio_patch(ioaddr, 0x19, 1 << 13);
|
||||||
|
|
||||||
|
rtl_phy_write(ioaddr, phy_reg_init, ARRAY_SIZE(phy_reg_init));
|
||||||
|
}
|
||||||
|
|
||||||
static void rtl_hw_phy_config(struct net_device *dev)
|
static void rtl_hw_phy_config(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8101_private *tp = netdev_priv(dev);
|
struct rtl8101_private *tp = netdev_priv(dev);
|
||||||
@@ -1309,6 +1465,11 @@ static void rtl_hw_phy_config(struct net_device *dev)
|
|||||||
case RTL_GIGA_MAC_VER_04:
|
case RTL_GIGA_MAC_VER_04:
|
||||||
rtl8101sb_hw_phy_config(ioaddr);
|
rtl8101sb_hw_phy_config(ioaddr);
|
||||||
break;
|
break;
|
||||||
|
case RTL_GIGA_MAC_VER_07:
|
||||||
|
case RTL_GIGA_MAC_VER_08:
|
||||||
|
case RTL_GIGA_MAC_VER_09:
|
||||||
|
rtl8102e_hw_phy_config(ioaddr);
|
||||||
|
break;
|
||||||
case RTL_GIGA_MAC_VER_18:
|
case RTL_GIGA_MAC_VER_18:
|
||||||
rtl8168cp_hw_phy_config(ioaddr);
|
rtl8168cp_hw_phy_config(ioaddr);
|
||||||
break;
|
break;
|
||||||
@@ -1692,6 +1853,10 @@ rtl8101_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||||||
goto err_out_free_res_4;
|
goto err_out_free_res_4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tp->pcie_cap = pci_find_capability(pdev, PCI_CAP_ID_EXP);
|
||||||
|
if (!tp->pcie_cap && netif_msg_probe(tp))
|
||||||
|
dev_info(&pdev->dev, "no PCI Express capability\n");
|
||||||
|
|
||||||
RTL_W16(IntrMask, 0x0000);
|
RTL_W16(IntrMask, 0x0000);
|
||||||
|
|
||||||
/* Soft reset the chip. */
|
/* Soft reset the chip. */
|
||||||
@@ -2084,12 +2249,51 @@ static void rtl_hw_start_8169(struct net_device *dev)
|
|||||||
RTL_W16(IntrMask, tp->intr_event);
|
RTL_W16(IntrMask, tp->intr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
|
||||||
|
{
|
||||||
|
struct net_device *dev = pci_get_drvdata(pdev);
|
||||||
|
struct rtl8101_private *tp = netdev_priv(dev);
|
||||||
|
int cap = tp->pcie_cap;
|
||||||
|
|
||||||
|
if (cap) {
|
||||||
|
u16 ctl;
|
||||||
|
|
||||||
|
pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &ctl);
|
||||||
|
ctl = (ctl & ~PCI_EXP_DEVCTL_READRQ) | force;
|
||||||
|
pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, ctl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl_csi_access_enable(void __iomem *ioaddr)
|
||||||
|
{
|
||||||
|
u32 csi;
|
||||||
|
|
||||||
|
csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff;
|
||||||
|
rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ephy_info {
|
||||||
|
unsigned int offset;
|
||||||
|
u16 mask;
|
||||||
|
u16 bits;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void rtl_ephy_init(void __iomem *ioaddr, struct ephy_info *e, int len)
|
||||||
|
{
|
||||||
|
u16 w;
|
||||||
|
|
||||||
|
while (len-- > 0) {
|
||||||
|
w = (rtl_ephy_read(ioaddr, e->offset) & ~e->mask) | e->bits;
|
||||||
|
rtl_ephy_write(ioaddr, e->offset, w);
|
||||||
|
e++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void rtl_hw_start_8168(struct net_device *dev)
|
static void rtl_hw_start_8168(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8101_private *tp = netdev_priv(dev);
|
struct rtl8101_private *tp = netdev_priv(dev);
|
||||||
void __iomem *ioaddr = tp->mmio_addr;
|
void __iomem *ioaddr = tp->mmio_addr;
|
||||||
struct pci_dev *pdev = tp->pci_dev;
|
struct pci_dev *pdev = tp->pci_dev;
|
||||||
u8 ctl;
|
|
||||||
|
|
||||||
RTL_W8(Cfg9346, Cfg9346_Unlock);
|
RTL_W8(Cfg9346, Cfg9346_Unlock);
|
||||||
|
|
||||||
@@ -2103,10 +2307,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
|
|||||||
|
|
||||||
RTL_W16(CPlusCmd, tp->cp_cmd);
|
RTL_W16(CPlusCmd, tp->cp_cmd);
|
||||||
|
|
||||||
/* Tx performance tweak. */
|
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
|
||||||
pci_read_config_byte(pdev, 0x69, &ctl);
|
|
||||||
ctl = (ctl & ~0x70) | 0x50;
|
|
||||||
pci_write_config_byte(pdev, 0x69, ctl);
|
|
||||||
|
|
||||||
RTL_W16(IntrMitigate, 0x5151);
|
RTL_W16(IntrMitigate, 0x5151);
|
||||||
|
|
||||||
@@ -2131,6 +2332,70 @@ static void rtl_hw_start_8168(struct net_device *dev)
|
|||||||
RTL_W16(IntrMask, tp->intr_event);
|
RTL_W16(IntrMask, tp->intr_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define R810X_CPCMD_QUIRK_MASK (\
|
||||||
|
EnableBist | \
|
||||||
|
Mac_dbgo_oe | \
|
||||||
|
Force_half_dup | \
|
||||||
|
Force_half_dup | \
|
||||||
|
Force_txflow_en | \
|
||||||
|
Cxpl_dbg_sel | \
|
||||||
|
ASF | \
|
||||||
|
PktCntrDisable | \
|
||||||
|
PCIDAC | \
|
||||||
|
PCIMulRW)
|
||||||
|
|
||||||
|
static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
static struct ephy_info e_info_8102e_1[] = {
|
||||||
|
{ 0x01, 0, 0x6e65 },
|
||||||
|
{ 0x02, 0, 0x091f },
|
||||||
|
{ 0x03, 0, 0xc2f9 },
|
||||||
|
{ 0x06, 0, 0xafb5 },
|
||||||
|
{ 0x07, 0, 0x0e00 },
|
||||||
|
{ 0x19, 0, 0xec80 },
|
||||||
|
{ 0x01, 0, 0x2e65 },
|
||||||
|
{ 0x01, 0, 0x6e65 }
|
||||||
|
};
|
||||||
|
u8 cfg1;
|
||||||
|
|
||||||
|
rtl_csi_access_enable(ioaddr);
|
||||||
|
|
||||||
|
RTL_W8(DBG_REG, FIX_NAK_1);
|
||||||
|
|
||||||
|
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
|
||||||
|
|
||||||
|
RTL_W8(Config1,
|
||||||
|
LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable);
|
||||||
|
RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
|
||||||
|
|
||||||
|
cfg1 = RTL_R8(Config1);
|
||||||
|
if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
|
||||||
|
RTL_W8(Config1, cfg1 & ~LEDS0);
|
||||||
|
|
||||||
|
RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
|
||||||
|
|
||||||
|
rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
rtl_csi_access_enable(ioaddr);
|
||||||
|
|
||||||
|
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
|
||||||
|
|
||||||
|
RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable);
|
||||||
|
RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
|
||||||
|
|
||||||
|
RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
rtl_hw_start_8102e_2(ioaddr, pdev);
|
||||||
|
|
||||||
|
rtl_ephy_write(ioaddr, 0x03, 0xc2f9);
|
||||||
|
}
|
||||||
|
|
||||||
static void rtl_hw_start_8101(struct net_device *dev)
|
static void rtl_hw_start_8101(struct net_device *dev)
|
||||||
{
|
{
|
||||||
struct rtl8101_private *tp = netdev_priv(dev);
|
struct rtl8101_private *tp = netdev_priv(dev);
|
||||||
@@ -2139,8 +2404,26 @@ static void rtl_hw_start_8101(struct net_device *dev)
|
|||||||
|
|
||||||
if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
|
if ((tp->mac_version == RTL_GIGA_MAC_VER_13) ||
|
||||||
(tp->mac_version == RTL_GIGA_MAC_VER_16)) {
|
(tp->mac_version == RTL_GIGA_MAC_VER_16)) {
|
||||||
pci_write_config_word(pdev, 0x68, 0x00);
|
int cap = tp->pcie_cap;
|
||||||
pci_write_config_word(pdev, 0x69, 0x08);
|
|
||||||
|
if (cap) {
|
||||||
|
pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL,
|
||||||
|
PCI_EXP_DEVCTL_NOSNOOP_EN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (tp->mac_version) {
|
||||||
|
case RTL_GIGA_MAC_VER_07:
|
||||||
|
rtl_hw_start_8102e_1(ioaddr, pdev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTL_GIGA_MAC_VER_08:
|
||||||
|
rtl_hw_start_8102e_3(ioaddr, pdev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RTL_GIGA_MAC_VER_09:
|
||||||
|
rtl_hw_start_8102e_2(ioaddr, pdev);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
RTL_W8(Cfg9346, Cfg9346_Unlock);
|
RTL_W8(Cfg9346, Cfg9346_Unlock);
|
||||||
|
|||||||
Reference in New Issue
Block a user