Commit 6e1d0b89 authored by Chun-Hao Lin's avatar Chun-Hao Lin Committed by David S. Miller

r8169:add support for RTL8168H and RTL8107E

RTL8168H is Realtek PCIe Gigabit Ethernet controller.
RTL8107E is Realtek PCIe Fast Ethernet controller.

This patch add support for these two chips.
Signed-off-by: default avatarChun-Hao Lin <hau@realtek.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d4261e56
...@@ -52,6 +52,10 @@ ...@@ -52,6 +52,10 @@
#define FIRMWARE_8106E_2 "rtl_nic/rtl8106e-2.fw" #define FIRMWARE_8106E_2 "rtl_nic/rtl8106e-2.fw"
#define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw" #define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw"
#define FIRMWARE_8168G_3 "rtl_nic/rtl8168g-3.fw" #define FIRMWARE_8168G_3 "rtl_nic/rtl8168g-3.fw"
#define FIRMWARE_8168H_1 "rtl_nic/rtl8168h-1.fw"
#define FIRMWARE_8168H_2 "rtl_nic/rtl8168h-2.fw"
#define FIRMWARE_8107E_1 "rtl_nic/rtl8107e-1.fw"
#define FIRMWARE_8107E_2 "rtl_nic/rtl8107e-2.fw"
#ifdef RTL8169_DEBUG #ifdef RTL8169_DEBUG
#define assert(expr) \ #define assert(expr) \
...@@ -147,6 +151,10 @@ enum mac_version { ...@@ -147,6 +151,10 @@ enum mac_version {
RTL_GIGA_MAC_VER_42, RTL_GIGA_MAC_VER_42,
RTL_GIGA_MAC_VER_43, RTL_GIGA_MAC_VER_43,
RTL_GIGA_MAC_VER_44, RTL_GIGA_MAC_VER_44,
RTL_GIGA_MAC_VER_45,
RTL_GIGA_MAC_VER_46,
RTL_GIGA_MAC_VER_47,
RTL_GIGA_MAC_VER_48,
RTL_GIGA_MAC_NONE = 0xff, RTL_GIGA_MAC_NONE = 0xff,
}; };
...@@ -282,6 +290,18 @@ static const struct { ...@@ -282,6 +290,18 @@ static const struct {
[RTL_GIGA_MAC_VER_44] = [RTL_GIGA_MAC_VER_44] =
_R("RTL8411", RTL_TD_1, FIRMWARE_8411_2, _R("RTL8411", RTL_TD_1, FIRMWARE_8411_2,
JUMBO_9K, false), JUMBO_9K, false),
[RTL_GIGA_MAC_VER_45] =
_R("RTL8168h/8111h", RTL_TD_1, FIRMWARE_8168H_1,
JUMBO_9K, false),
[RTL_GIGA_MAC_VER_46] =
_R("RTL8168h/8111h", RTL_TD_1, FIRMWARE_8168H_2,
JUMBO_9K, false),
[RTL_GIGA_MAC_VER_47] =
_R("RTL8107e", RTL_TD_1, FIRMWARE_8107E_1,
JUMBO_1K, false),
[RTL_GIGA_MAC_VER_48] =
_R("RTL8107e", RTL_TD_1, FIRMWARE_8107E_2,
JUMBO_1K, false),
}; };
#undef _R #undef _R
...@@ -410,6 +430,7 @@ enum rtl8168_8101_registers { ...@@ -410,6 +430,7 @@ enum rtl8168_8101_registers {
#define EPHYAR_DATA_MASK 0xffff #define EPHYAR_DATA_MASK 0xffff
DLLPR = 0xd0, DLLPR = 0xd0,
#define PFM_EN (1 << 6) #define PFM_EN (1 << 6)
#define TX_10M_PS_EN (1 << 7)
DBG_REG = 0xd1, DBG_REG = 0xd1,
#define FIX_NAK_1 (1 << 4) #define FIX_NAK_1 (1 << 4)
#define FIX_NAK_2 (1 << 3) #define FIX_NAK_2 (1 << 3)
...@@ -429,6 +450,8 @@ enum rtl8168_8101_registers { ...@@ -429,6 +450,8 @@ enum rtl8168_8101_registers {
#define EFUSEAR_REG_MASK 0x03ff #define EFUSEAR_REG_MASK 0x03ff
#define EFUSEAR_REG_SHIFT 8 #define EFUSEAR_REG_SHIFT 8
#define EFUSEAR_DATA_MASK 0xff #define EFUSEAR_DATA_MASK 0xff
MISC_1 = 0xf2,
#define PFM_D3COLD_EN (1 << 6)
}; };
enum rtl8168_registers { enum rtl8168_registers {
...@@ -447,6 +470,7 @@ enum rtl8168_registers { ...@@ -447,6 +470,7 @@ enum rtl8168_registers {
#define ERIAR_MASK_SHIFT 12 #define ERIAR_MASK_SHIFT 12
#define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT) #define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT) #define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_0100 (0x4 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_0101 (0x5 << ERIAR_MASK_SHIFT) #define ERIAR_MASK_0101 (0x5 << ERIAR_MASK_SHIFT)
#define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT) #define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT)
EPHY_RXER_NUM = 0x7c, EPHY_RXER_NUM = 0x7c,
...@@ -598,6 +622,9 @@ enum rtl_register_content { ...@@ -598,6 +622,9 @@ enum rtl_register_content {
/* DumpCounterCommand */ /* DumpCounterCommand */
CounterDump = 0x8, CounterDump = 0x8,
/* magic enable v2 */
MagicPacket_v2 = (1 << 16), /* Wake up when receives a Magic Packet */
}; };
enum rtl_desc_bit { enum rtl_desc_bit {
...@@ -823,6 +850,8 @@ MODULE_FIRMWARE(FIRMWARE_8106E_1); ...@@ -823,6 +850,8 @@ MODULE_FIRMWARE(FIRMWARE_8106E_1);
MODULE_FIRMWARE(FIRMWARE_8106E_2); MODULE_FIRMWARE(FIRMWARE_8106E_2);
MODULE_FIRMWARE(FIRMWARE_8168G_2); MODULE_FIRMWARE(FIRMWARE_8168G_2);
MODULE_FIRMWARE(FIRMWARE_8168G_3); MODULE_FIRMWARE(FIRMWARE_8168G_3);
MODULE_FIRMWARE(FIRMWARE_8168H_1);
MODULE_FIRMWARE(FIRMWARE_8168H_2);
static void rtl_lock_work(struct rtl8169_private *tp) static void rtl_lock_work(struct rtl8169_private *tp)
{ {
...@@ -1514,8 +1543,17 @@ static u32 __rtl8169_get_wol(struct rtl8169_private *tp) ...@@ -1514,8 +1543,17 @@ static u32 __rtl8169_get_wol(struct rtl8169_private *tp)
options = RTL_R8(Config3); options = RTL_R8(Config3);
if (options & LinkUp) if (options & LinkUp)
wolopts |= WAKE_PHY; wolopts |= WAKE_PHY;
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
if (rtl_eri_read(tp, 0xdc, ERIAR_EXGMAC) & MagicPacket_v2)
wolopts |= WAKE_MAGIC;
break;
default:
if (options & MagicPacket) if (options & MagicPacket)
wolopts |= WAKE_MAGIC; wolopts |= WAKE_MAGIC;
break;
}
options = RTL_R8(Config5); options = RTL_R8(Config5);
if (options & UWF) if (options & UWF)
...@@ -1543,24 +1581,48 @@ static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) ...@@ -1543,24 +1581,48 @@ static void rtl8169_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts) static void __rtl8169_set_wol(struct rtl8169_private *tp, u32 wolopts)
{ {
void __iomem *ioaddr = tp->mmio_addr; void __iomem *ioaddr = tp->mmio_addr;
unsigned int i; unsigned int i, tmp;
static const struct { static const struct {
u32 opt; u32 opt;
u16 reg; u16 reg;
u8 mask; u8 mask;
} cfg[] = { } cfg[] = {
{ WAKE_PHY, Config3, LinkUp }, { WAKE_PHY, Config3, LinkUp },
{ WAKE_MAGIC, Config3, MagicPacket },
{ WAKE_UCAST, Config5, UWF }, { WAKE_UCAST, Config5, UWF },
{ WAKE_BCAST, Config5, BWF }, { WAKE_BCAST, Config5, BWF },
{ WAKE_MCAST, Config5, MWF }, { WAKE_MCAST, Config5, MWF },
{ WAKE_ANY, Config5, LanWake } { WAKE_ANY, Config5, LanWake },
{ WAKE_MAGIC, Config3, MagicPacket }
}; };
u8 options; u8 options;
RTL_W8(Cfg9346, Cfg9346_Unlock); RTL_W8(Cfg9346, Cfg9346_Unlock);
for (i = 0; i < ARRAY_SIZE(cfg); i++) { switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
tmp = ARRAY_SIZE(cfg) - 1;
if (wolopts & WAKE_MAGIC)
rtl_w1w0_eri(tp,
0x0dc,
ERIAR_MASK_0100,
MagicPacket_v2,
0x0000,
ERIAR_EXGMAC);
else
rtl_w1w0_eri(tp,
0x0dc,
ERIAR_MASK_0100,
0x0000,
MagicPacket_v2,
ERIAR_EXGMAC);
break;
default:
tmp = ARRAY_SIZE(cfg);
break;
}
for (i = 0; i < tmp; i++) {
options = RTL_R8(cfg[i].reg) & ~cfg[i].mask; options = RTL_R8(cfg[i].reg) & ~cfg[i].mask;
if (wolopts & cfg[i].opt) if (wolopts & cfg[i].opt)
options |= cfg[i].mask; options |= cfg[i].mask;
...@@ -2044,6 +2106,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, ...@@ -2044,6 +2106,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
u32 val; u32 val;
int mac_version; int mac_version;
} mac_info[] = { } mac_info[] = {
/* 8168H family. */
{ 0x7cf00000, 0x54100000, RTL_GIGA_MAC_VER_46 },
{ 0x7cf00000, 0x54000000, RTL_GIGA_MAC_VER_45 },
/* 8168G family. */ /* 8168G family. */
{ 0x7cf00000, 0x5c800000, RTL_GIGA_MAC_VER_44 }, { 0x7cf00000, 0x5c800000, RTL_GIGA_MAC_VER_44 },
{ 0x7cf00000, 0x50900000, RTL_GIGA_MAC_VER_42 }, { 0x7cf00000, 0x50900000, RTL_GIGA_MAC_VER_42 },
...@@ -2139,6 +2205,14 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, ...@@ -2139,6 +2205,14 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
tp->mac_version = tp->mii.supports_gmii ? tp->mac_version = tp->mii.supports_gmii ?
RTL_GIGA_MAC_VER_42 : RTL_GIGA_MAC_VER_42 :
RTL_GIGA_MAC_VER_43; RTL_GIGA_MAC_VER_43;
} else if (tp->mac_version == RTL_GIGA_MAC_VER_45) {
tp->mac_version = tp->mii.supports_gmii ?
RTL_GIGA_MAC_VER_45 :
RTL_GIGA_MAC_VER_47;
} else if (tp->mac_version == RTL_GIGA_MAC_VER_46) {
tp->mac_version = tp->mii.supports_gmii ?
RTL_GIGA_MAC_VER_46 :
RTL_GIGA_MAC_VER_48;
} }
} }
...@@ -3464,6 +3538,189 @@ static void rtl8168g_2_hw_phy_config(struct rtl8169_private *tp) ...@@ -3464,6 +3538,189 @@ static void rtl8168g_2_hw_phy_config(struct rtl8169_private *tp)
rtl_apply_firmware(tp); rtl_apply_firmware(tp);
} }
static void rtl8168h_1_hw_phy_config(struct rtl8169_private *tp)
{
u16 dout_tapbin;
u32 data;
rtl_apply_firmware(tp);
/* CHN EST parameters adjust - giga master */
rtl_writephy(tp, 0x1f, 0x0a43);
rtl_writephy(tp, 0x13, 0x809b);
rtl_w1w0_phy(tp, 0x14, 0x8000, 0xf800);
rtl_writephy(tp, 0x13, 0x80a2);
rtl_w1w0_phy(tp, 0x14, 0x8000, 0xff00);
rtl_writephy(tp, 0x13, 0x80a4);
rtl_w1w0_phy(tp, 0x14, 0x8500, 0xff00);
rtl_writephy(tp, 0x13, 0x809c);
rtl_w1w0_phy(tp, 0x14, 0xbd00, 0xff00);
rtl_writephy(tp, 0x1f, 0x0000);
/* CHN EST parameters adjust - giga slave */
rtl_writephy(tp, 0x1f, 0x0a43);
rtl_writephy(tp, 0x13, 0x80ad);
rtl_w1w0_phy(tp, 0x14, 0x7000, 0xf800);
rtl_writephy(tp, 0x13, 0x80b4);
rtl_w1w0_phy(tp, 0x14, 0x5000, 0xff00);
rtl_writephy(tp, 0x13, 0x80ac);
rtl_w1w0_phy(tp, 0x14, 0x4000, 0xff00);
rtl_writephy(tp, 0x1f, 0x0000);
/* CHN EST parameters adjust - fnet */
rtl_writephy(tp, 0x1f, 0x0a43);
rtl_writephy(tp, 0x13, 0x808e);
rtl_w1w0_phy(tp, 0x14, 0x1200, 0xff00);
rtl_writephy(tp, 0x13, 0x8090);
rtl_w1w0_phy(tp, 0x14, 0xe500, 0xff00);
rtl_writephy(tp, 0x13, 0x8092);
rtl_w1w0_phy(tp, 0x14, 0x9f00, 0xff00);
rtl_writephy(tp, 0x1f, 0x0000);
/* enable R-tune & PGA-retune function */
dout_tapbin = 0;
rtl_writephy(tp, 0x1f, 0x0a46);
data = rtl_readphy(tp, 0x13);
data &= 3;
data <<= 2;
dout_tapbin |= data;
data = rtl_readphy(tp, 0x12);
data &= 0xc000;
data >>= 14;
dout_tapbin |= data;
dout_tapbin = ~(dout_tapbin^0x08);
dout_tapbin <<= 12;
dout_tapbin &= 0xf000;
rtl_writephy(tp, 0x1f, 0x0a43);
rtl_writephy(tp, 0x13, 0x827a);
rtl_w1w0_phy(tp, 0x14, dout_tapbin, 0xf000);
rtl_writephy(tp, 0x13, 0x827b);
rtl_w1w0_phy(tp, 0x14, dout_tapbin, 0xf000);
rtl_writephy(tp, 0x13, 0x827c);
rtl_w1w0_phy(tp, 0x14, dout_tapbin, 0xf000);
rtl_writephy(tp, 0x13, 0x827d);
rtl_w1w0_phy(tp, 0x14, dout_tapbin, 0xf000);
rtl_writephy(tp, 0x1f, 0x0a43);
rtl_writephy(tp, 0x13, 0x0811);
rtl_w1w0_phy(tp, 0x14, 0x0800, 0x0000);
rtl_writephy(tp, 0x1f, 0x0a42);
rtl_w1w0_phy(tp, 0x16, 0x0002, 0x0000);
rtl_writephy(tp, 0x1f, 0x0000);
/* enable GPHY 10M */
rtl_writephy(tp, 0x1f, 0x0a44);
rtl_w1w0_phy(tp, 0x11, 0x0800, 0x0000);
rtl_writephy(tp, 0x1f, 0x0000);
/* SAR ADC performance */
rtl_writephy(tp, 0x1f, 0x0bca);
rtl_w1w0_phy(tp, 0x17, 0x4000, 0x3000);
rtl_writephy(tp, 0x1f, 0x0000);
rtl_writephy(tp, 0x1f, 0x0a43);
rtl_writephy(tp, 0x13, 0x803f);
rtl_w1w0_phy(tp, 0x14, 0x0000, 0x3000);
rtl_writephy(tp, 0x13, 0x8047);
rtl_w1w0_phy(tp, 0x14, 0x0000, 0x3000);
rtl_writephy(tp, 0x13, 0x804f);
rtl_w1w0_phy(tp, 0x14, 0x0000, 0x3000);
rtl_writephy(tp, 0x13, 0x8057);
rtl_w1w0_phy(tp, 0x14, 0x0000, 0x3000);
rtl_writephy(tp, 0x13, 0x805f);
rtl_w1w0_phy(tp, 0x14, 0x0000, 0x3000);
rtl_writephy(tp, 0x13, 0x8067);
rtl_w1w0_phy(tp, 0x14, 0x0000, 0x3000);
rtl_writephy(tp, 0x13, 0x806f);
rtl_w1w0_phy(tp, 0x14, 0x0000, 0x3000);
rtl_writephy(tp, 0x1f, 0x0000);
/* disable phy pfm mode */
rtl_writephy(tp, 0x1f, 0x0a44);
rtl_w1w0_phy(tp, 0x14, 0x0000, 0x0080);
rtl_writephy(tp, 0x1f, 0x0000);
/* Check ALDPS bit, disable it if enabled */
rtl_writephy(tp, 0x1f, 0x0a43);
if (rtl_readphy(tp, 0x10) & 0x0004)
rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0004);
rtl_writephy(tp, 0x1f, 0x0000);
}
static void rtl8168h_2_hw_phy_config(struct rtl8169_private *tp)
{
u16 ioffset_p3, ioffset_p2, ioffset_p1, ioffset_p0;
u16 rlen;
u32 data;
rtl_apply_firmware(tp);
/* CHIN EST parameter update */
rtl_writephy(tp, 0x1f, 0x0a43);
rtl_writephy(tp, 0x13, 0x808a);
rtl_w1w0_phy(tp, 0x14, 0x000a, 0x003f);
rtl_writephy(tp, 0x1f, 0x0000);
/* enable R-tune & PGA-retune function */
rtl_writephy(tp, 0x1f, 0x0a43);
rtl_writephy(tp, 0x13, 0x0811);
rtl_w1w0_phy(tp, 0x14, 0x0800, 0x0000);
rtl_writephy(tp, 0x1f, 0x0a42);
rtl_w1w0_phy(tp, 0x16, 0x0002, 0x0000);
rtl_writephy(tp, 0x1f, 0x0000);
/* enable GPHY 10M */
rtl_writephy(tp, 0x1f, 0x0a44);
rtl_w1w0_phy(tp, 0x11, 0x0800, 0x0000);
rtl_writephy(tp, 0x1f, 0x0000);
r8168_mac_ocp_write(tp, 0xdd02, 0x807d);
data = r8168_mac_ocp_read(tp, 0xdd02);
ioffset_p3 = ((data & 0x80)>>7);
ioffset_p3 <<= 3;
data = r8168_mac_ocp_read(tp, 0xdd00);
ioffset_p3 |= ((data & (0xe000))>>13);
ioffset_p2 = ((data & (0x1e00))>>9);
ioffset_p1 = ((data & (0x01e0))>>5);
ioffset_p0 = ((data & 0x0010)>>4);
ioffset_p0 <<= 3;
ioffset_p0 |= (data & (0x07));
data = (ioffset_p3<<12)|(ioffset_p2<<8)|(ioffset_p1<<4)|(ioffset_p0);
if ((ioffset_p3 != 0x0F) || (ioffset_p2 != 0x0F) ||
(ioffset_p1 != 0x0F) || (ioffset_p0 == 0x0F)) {
rtl_writephy(tp, 0x1f, 0x0bcf);
rtl_writephy(tp, 0x16, data);
rtl_writephy(tp, 0x1f, 0x0000);
}
/* Modify rlen (TX LPF corner frequency) level */
rtl_writephy(tp, 0x1f, 0x0bcd);
data = rtl_readphy(tp, 0x16);
data &= 0x000f;
rlen = 0;
if (data > 3)
rlen = data - 3;
data = rlen | (rlen<<4) | (rlen<<8) | (rlen<<12);
rtl_writephy(tp, 0x17, data);
rtl_writephy(tp, 0x1f, 0x0bcd);
rtl_writephy(tp, 0x1f, 0x0000);
/* disable phy pfm mode */
rtl_writephy(tp, 0x1f, 0x0a44);
rtl_w1w0_phy(tp, 0x14, 0x0000, 0x0080);
rtl_writephy(tp, 0x1f, 0x0000);
/* Check ALDPS bit, disable it if enabled */
rtl_writephy(tp, 0x1f, 0x0a43);
if (rtl_readphy(tp, 0x10) & 0x0004)
rtl_w1w0_phy(tp, 0x10, 0x0000, 0x0004);
rtl_writephy(tp, 0x1f, 0x0000);
}
static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
{ {
static const struct phy_reg phy_reg_init[] = { static const struct phy_reg phy_reg_init[] = {
...@@ -3654,6 +3911,14 @@ static void rtl_hw_phy_config(struct net_device *dev) ...@@ -3654,6 +3911,14 @@ static void rtl_hw_phy_config(struct net_device *dev)
case RTL_GIGA_MAC_VER_44: case RTL_GIGA_MAC_VER_44:
rtl8168g_2_hw_phy_config(tp); rtl8168g_2_hw_phy_config(tp);
break; break;
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_47:
rtl8168h_1_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_48:
rtl8168h_2_hw_phy_config(tp);
break;
case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_41:
default: default:
...@@ -3865,6 +4130,10 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp) ...@@ -3865,6 +4130,10 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_42:
case RTL_GIGA_MAC_VER_43: case RTL_GIGA_MAC_VER_43:
case RTL_GIGA_MAC_VER_44: case RTL_GIGA_MAC_VER_44:
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
ops->write = r8168g_mdio_write; ops->write = r8168g_mdio_write;
ops->read = r8168g_mdio_read; ops->read = r8168g_mdio_read;
break; break;
...@@ -3919,6 +4188,10 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) ...@@ -3919,6 +4188,10 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_42:
case RTL_GIGA_MAC_VER_43: case RTL_GIGA_MAC_VER_43:
case RTL_GIGA_MAC_VER_44: case RTL_GIGA_MAC_VER_44:
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
RTL_W32(RxConfig, RTL_R32(RxConfig) | RTL_W32(RxConfig, RTL_R32(RxConfig) |
AcceptBroadcast | AcceptMulticast | AcceptMyPhys); AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
break; break;
...@@ -3987,6 +4260,10 @@ static void r810x_pll_power_up(struct rtl8169_private *tp) ...@@ -3987,6 +4260,10 @@ static void r810x_pll_power_up(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_13: case RTL_GIGA_MAC_VER_13:
case RTL_GIGA_MAC_VER_16: case RTL_GIGA_MAC_VER_16:
break; break;
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
RTL_W8(PMCH, RTL_R8(PMCH) | 0xC0);
break;
default: default:
RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); RTL_W8(PMCH, RTL_R8(PMCH) | 0x80);
break; break;
...@@ -4087,6 +4364,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) ...@@ -4087,6 +4364,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_31: case RTL_GIGA_MAC_VER_31:
case RTL_GIGA_MAC_VER_32: case RTL_GIGA_MAC_VER_32:
case RTL_GIGA_MAC_VER_33: case RTL_GIGA_MAC_VER_33:
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80);
break; break;
case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_40:
...@@ -4111,6 +4390,10 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) ...@@ -4111,6 +4390,10 @@ static void r8168_pll_power_up(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_33: case RTL_GIGA_MAC_VER_33:
RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); RTL_W8(PMCH, RTL_R8(PMCH) | 0x80);
break; break;
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
RTL_W8(PMCH, RTL_R8(PMCH) | 0xC0);
break;
case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_40:
case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_41:
rtl_w1w0_eri(tp, 0x1a8, ERIAR_MASK_1111, 0xfc000000, rtl_w1w0_eri(tp, 0x1a8, ERIAR_MASK_1111, 0xfc000000,
...@@ -4153,6 +4436,8 @@ static void rtl_init_pll_power_ops(struct rtl8169_private *tp) ...@@ -4153,6 +4436,8 @@ static void rtl_init_pll_power_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_37:
case RTL_GIGA_MAC_VER_39: case RTL_GIGA_MAC_VER_39:
case RTL_GIGA_MAC_VER_43: case RTL_GIGA_MAC_VER_43:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
ops->down = r810x_pll_power_down; ops->down = r810x_pll_power_down;
ops->up = r810x_pll_power_up; ops->up = r810x_pll_power_up;
break; break;
...@@ -4182,6 +4467,8 @@ static void rtl_init_pll_power_ops(struct rtl8169_private *tp) ...@@ -4182,6 +4467,8 @@ static void rtl_init_pll_power_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_41:
case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_42:
case RTL_GIGA_MAC_VER_44: case RTL_GIGA_MAC_VER_44:
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
ops->down = r8168_pll_power_down; ops->down = r8168_pll_power_down;
ops->up = r8168_pll_power_up; ops->up = r8168_pll_power_up;
break; break;
...@@ -4232,6 +4519,10 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) ...@@ -4232,6 +4519,10 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_42:
case RTL_GIGA_MAC_VER_43: case RTL_GIGA_MAC_VER_43:
case RTL_GIGA_MAC_VER_44: case RTL_GIGA_MAC_VER_44:
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF); RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF);
break; break;
default: default:
...@@ -4393,6 +4684,10 @@ static void rtl_init_jumbo_ops(struct rtl8169_private *tp) ...@@ -4393,6 +4684,10 @@ static void rtl_init_jumbo_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_42:
case RTL_GIGA_MAC_VER_43: case RTL_GIGA_MAC_VER_43:
case RTL_GIGA_MAC_VER_44: case RTL_GIGA_MAC_VER_44:
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
default: default:
ops->disable = NULL; ops->disable = NULL;
ops->enable = NULL; ops->enable = NULL;
...@@ -4498,12 +4793,16 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) ...@@ -4498,12 +4793,16 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
tp->mac_version == RTL_GIGA_MAC_VER_35 || tp->mac_version == RTL_GIGA_MAC_VER_35 ||
tp->mac_version == RTL_GIGA_MAC_VER_36 || tp->mac_version == RTL_GIGA_MAC_VER_36 ||
tp->mac_version == RTL_GIGA_MAC_VER_37 || tp->mac_version == RTL_GIGA_MAC_VER_37 ||
tp->mac_version == RTL_GIGA_MAC_VER_38 ||
tp->mac_version == RTL_GIGA_MAC_VER_40 || tp->mac_version == RTL_GIGA_MAC_VER_40 ||
tp->mac_version == RTL_GIGA_MAC_VER_41 || tp->mac_version == RTL_GIGA_MAC_VER_41 ||
tp->mac_version == RTL_GIGA_MAC_VER_42 || tp->mac_version == RTL_GIGA_MAC_VER_42 ||
tp->mac_version == RTL_GIGA_MAC_VER_43 || tp->mac_version == RTL_GIGA_MAC_VER_43 ||
tp->mac_version == RTL_GIGA_MAC_VER_44 || tp->mac_version == RTL_GIGA_MAC_VER_44 ||
tp->mac_version == RTL_GIGA_MAC_VER_38) { tp->mac_version == RTL_GIGA_MAC_VER_45 ||
tp->mac_version == RTL_GIGA_MAC_VER_46 ||
tp->mac_version == RTL_GIGA_MAC_VER_47 ||
tp->mac_version == RTL_GIGA_MAC_VER_48) {
RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq);
rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666);
} else { } else {
...@@ -5330,6 +5629,105 @@ static void rtl_hw_start_8411_2(struct rtl8169_private *tp) ...@@ -5330,6 +5629,105 @@ static void rtl_hw_start_8411_2(struct rtl8169_private *tp)
rtl_ephy_init(tp, e_info_8411_2, ARRAY_SIZE(e_info_8411_2)); rtl_ephy_init(tp, e_info_8411_2, ARRAY_SIZE(e_info_8411_2));
} }
static void rtl_hw_start_8168h_1(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
struct pci_dev *pdev = tp->pci_dev;
u16 rg_saw_cnt;
u32 data;
static const struct ephy_info e_info_8168h_1[] = {
{ 0x1e, 0x0800, 0x0001 },
{ 0x1d, 0x0000, 0x0800 },
{ 0x05, 0xffff, 0x2089 },
{ 0x06, 0xffff, 0x5881 },
{ 0x04, 0xffff, 0x154a },
{ 0x01, 0xffff, 0x068b }
};
/* disable aspm and clock request before access ephy */
RTL_W8(Config2, RTL_R8(Config2) & ~ClkReqEn);
RTL_W8(Config5, RTL_R8(Config5) & ~ASPM_en);
rtl_ephy_init(tp, e_info_8168h_1, ARRAY_SIZE(e_info_8168h_1));
RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO);
rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x00080002, ERIAR_EXGMAC);
rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC);
rtl_eri_write(tp, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC);
rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC);
rtl_csi_access_enable_1(tp);
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC);
rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC);
rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_1111, 0x0010, 0x00, ERIAR_EXGMAC);
rtl_w1w0_eri(tp, 0xd4, ERIAR_MASK_1111, 0x1f00, 0x00, ERIAR_EXGMAC);
rtl_eri_write(tp, 0x5f0, ERIAR_MASK_0011, 0x4f87, ERIAR_EXGMAC);
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN);
RTL_W8(MaxTxPacketSize, EarlySize);
rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC);
/* Adjust EEE LED frequency */
RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07);
RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN);
RTL_W8(DLLPR, RTL_R8(MISC_1) & ~PFM_D3COLD_EN);
RTL_W8(DLLPR, RTL_R8(DLLPR) & ~TX_10M_PS_EN);
rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, 0x1000, ERIAR_EXGMAC);
rtl_pcie_state_l2l3_enable(tp, false);
rtl_writephy(tp, 0x1f, 0x0c42);
rg_saw_cnt = rtl_readphy(tp, 0x13);
rtl_writephy(tp, 0x1f, 0x0000);
if (rg_saw_cnt > 0) {
u16 sw_cnt_1ms_ini;
sw_cnt_1ms_ini = 16000000/rg_saw_cnt;
sw_cnt_1ms_ini &= 0x0fff;
data = r8168_mac_ocp_read(tp, 0xd412);
data &= 0x0fff;
data |= sw_cnt_1ms_ini;
r8168_mac_ocp_write(tp, 0xd412, data);
}
data = r8168_mac_ocp_read(tp, 0xe056);
data &= 0xf0;
data |= 0x07;
r8168_mac_ocp_write(tp, 0xe056, data);
data = r8168_mac_ocp_read(tp, 0xe052);
data &= 0x8008;
data |= 0x6000;
r8168_mac_ocp_write(tp, 0xe052, data);
data = r8168_mac_ocp_read(tp, 0xe0d6);
data &= 0x01ff;
data |= 0x017f;
r8168_mac_ocp_write(tp, 0xe0d6, data);
data = r8168_mac_ocp_read(tp, 0xd420);
data &= 0x0fff;
data |= 0x047f;
r8168_mac_ocp_write(tp, 0xd420, data);
r8168_mac_ocp_write(tp, 0xe63e, 0x0001);
r8168_mac_ocp_write(tp, 0xe63e, 0x0000);
r8168_mac_ocp_write(tp, 0xc094, 0x0000);
r8168_mac_ocp_write(tp, 0xc09e, 0x0000);
}
static void rtl_hw_start_8168(struct net_device *dev) static void rtl_hw_start_8168(struct net_device *dev)
{ {
struct rtl8169_private *tp = netdev_priv(dev); struct rtl8169_private *tp = netdev_priv(dev);
...@@ -5440,6 +5838,11 @@ static void rtl_hw_start_8168(struct net_device *dev) ...@@ -5440,6 +5838,11 @@ static void rtl_hw_start_8168(struct net_device *dev)
rtl_hw_start_8411_2(tp); rtl_hw_start_8411_2(tp);
break; break;
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
rtl_hw_start_8168h_1(tp);
break;
default: default:
printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n",
dev->name, tp->mac_version); dev->name, tp->mac_version);
...@@ -5655,6 +6058,10 @@ static void rtl_hw_start_8101(struct net_device *dev) ...@@ -5655,6 +6058,10 @@ static void rtl_hw_start_8101(struct net_device *dev)
case RTL_GIGA_MAC_VER_43: case RTL_GIGA_MAC_VER_43:
rtl_hw_start_8168g_2(tp); rtl_hw_start_8168g_2(tp);
break; break;
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
rtl_hw_start_8168h_1(tp);
break;
} }
RTL_W8(Cfg9346, Cfg9346_Lock); RTL_W8(Cfg9346, Cfg9346_Lock);
...@@ -5895,7 +6302,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb, ...@@ -5895,7 +6302,7 @@ static int rtl8169_xmit_frags(struct rtl8169_private *tp, struct sk_buff *skb,
{ {
struct skb_shared_info *info = skb_shinfo(skb); struct skb_shared_info *info = skb_shinfo(skb);
unsigned int cur_frag, entry; unsigned int cur_frag, entry;
struct TxDesc * uninitialized_var(txd); struct TxDesc *uninitialized_var(txd);
struct device *d = &tp->pci_dev->dev; struct device *d = &tp->pci_dev->dev;
entry = tp->cur_tx; entry = tp->cur_tx;
...@@ -7110,6 +7517,10 @@ static void rtl_hw_initialize(struct rtl8169_private *tp) ...@@ -7110,6 +7517,10 @@ static void rtl_hw_initialize(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_42:
case RTL_GIGA_MAC_VER_43: case RTL_GIGA_MAC_VER_43:
case RTL_GIGA_MAC_VER_44: case RTL_GIGA_MAC_VER_44:
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
case RTL_GIGA_MAC_VER_47:
case RTL_GIGA_MAC_VER_48:
rtl_hw_init_8168g(tp); rtl_hw_init_8168g(tp);
break; break;
...@@ -7255,8 +7666,19 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -7255,8 +7666,19 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
RTL_W8(Cfg9346, Cfg9346_Unlock); RTL_W8(Cfg9346, Cfg9346_Unlock);
RTL_W8(Config1, RTL_R8(Config1) | PMEnable); RTL_W8(Config1, RTL_R8(Config1) | PMEnable);
RTL_W8(Config5, RTL_R8(Config5) & (BWF | MWF | UWF | LanWake | PMEStatus)); RTL_W8(Config5, RTL_R8(Config5) & (BWF | MWF | UWF | LanWake | PMEStatus));
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_45:
case RTL_GIGA_MAC_VER_46:
if (rtl_eri_read(tp, 0xdc, ERIAR_EXGMAC) & MagicPacket_v2)
tp->features |= RTL_FEATURE_WOL;
if ((RTL_R8(Config3) & LinkUp) != 0)
tp->features |= RTL_FEATURE_WOL;
break;
default:
if ((RTL_R8(Config3) & (LinkUp | MagicPacket)) != 0) if ((RTL_R8(Config3) & (LinkUp | MagicPacket)) != 0)
tp->features |= RTL_FEATURE_WOL; tp->features |= RTL_FEATURE_WOL;
break;
}
if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0) if ((RTL_R8(Config5) & (UWF | BWF | MWF)) != 0)
tp->features |= RTL_FEATURE_WOL; tp->features |= RTL_FEATURE_WOL;
tp->features |= rtl_try_msi(tp, cfg); tp->features |= rtl_try_msi(tp, cfg);
...@@ -7283,6 +7705,18 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -7283,6 +7705,18 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
u64_stats_init(&tp->tx_stats.syncp); u64_stats_init(&tp->tx_stats.syncp);
/* Get MAC address */ /* Get MAC address */
if (tp->mac_version == RTL_GIGA_MAC_VER_45 ||
tp->mac_version == RTL_GIGA_MAC_VER_46 ||
tp->mac_version == RTL_GIGA_MAC_VER_47 ||
tp->mac_version == RTL_GIGA_MAC_VER_48) {
u16 mac_addr[3];
*(u32 *)&mac_addr[0] = rtl_eri_read(tp, 0xE0, ERIAR_EXGMAC);
*(u16 *)&mac_addr[2] = rtl_eri_read(tp, 0xE4, ERIAR_EXGMAC);
if (is_valid_ether_addr((u8 *)mac_addr))
rtl_rar_set(tp, (u8 *)mac_addr);
}
for (i = 0; i < ETH_ALEN; i++) for (i = 0; i < ETH_ALEN; i++)
dev->dev_addr[i] = RTL_R8(MAC0 + i); dev->dev_addr[i] = RTL_R8(MAC0 + i);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment