diff options
author | Hayes Wang <hayeswang@realtek.com> | 2012-07-02 05:23:22 -0400 |
---|---|---|
committer | Francois Romieu <romieu@fr.zoreil.com> | 2012-07-09 17:38:23 -0400 |
commit | c558386b836ee97762e12495101c6e373f20e69d (patch) | |
tree | d3f5a74c1334290932e4c2d63be51558743cc68f /drivers/net/ethernet/realtek | |
parent | ffc46952b313ff037debca1b4e3da9472ff4b441 (diff) |
r8169: support RTL8168G
For RTL8111G, the settings of phy and firmware are replaced with
ocp functions. r8168g_mdio_{write / read} redirects the relative
settings to suitable ocp functions. A per-device variable is needed
to evaluate the real address of ocp functions.
rtl_writephy(tp, 0x1f, xxxx) is dedicated to keeping said variable
up-to-date.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Acked-by: Francois Romieu <romieu@fr.zoreil.com>
Diffstat (limited to 'drivers/net/ethernet/realtek')
-rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index eb6fdeff5adf..7ff3423edb9c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw" | 47 | #define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw" |
48 | #define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw" | 48 | #define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw" |
49 | #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" | 49 | #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" |
50 | #define FIRMWARE_8168G_1 "rtl_nic/rtl8168g-1.fw" | ||
50 | 51 | ||
51 | #ifdef RTL8169_DEBUG | 52 | #ifdef RTL8169_DEBUG |
52 | #define assert(expr) \ | 53 | #define assert(expr) \ |
@@ -143,6 +144,8 @@ enum mac_version { | |||
143 | RTL_GIGA_MAC_VER_37, | 144 | RTL_GIGA_MAC_VER_37, |
144 | RTL_GIGA_MAC_VER_38, | 145 | RTL_GIGA_MAC_VER_38, |
145 | RTL_GIGA_MAC_VER_39, | 146 | RTL_GIGA_MAC_VER_39, |
147 | RTL_GIGA_MAC_VER_40, | ||
148 | RTL_GIGA_MAC_VER_41, | ||
146 | RTL_GIGA_MAC_NONE = 0xff, | 149 | RTL_GIGA_MAC_NONE = 0xff, |
147 | }; | 150 | }; |
148 | 151 | ||
@@ -264,6 +267,11 @@ static const struct { | |||
264 | [RTL_GIGA_MAC_VER_39] = | 267 | [RTL_GIGA_MAC_VER_39] = |
265 | _R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_1, | 268 | _R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_1, |
266 | JUMBO_1K, true), | 269 | JUMBO_1K, true), |
270 | [RTL_GIGA_MAC_VER_40] = | ||
271 | _R("RTL8168g/8111g", RTL_TD_1, FIRMWARE_8168G_1, | ||
272 | JUMBO_9K, false), | ||
273 | [RTL_GIGA_MAC_VER_41] = | ||
274 | _R("RTL8168g/8111g", RTL_TD_1, NULL, JUMBO_9K, false), | ||
267 | }; | 275 | }; |
268 | #undef _R | 276 | #undef _R |
269 | 277 | ||
@@ -394,8 +402,12 @@ enum rtl8168_8101_registers { | |||
394 | TWSI = 0xd2, | 402 | TWSI = 0xd2, |
395 | MCU = 0xd3, | 403 | MCU = 0xd3, |
396 | #define NOW_IS_OOB (1 << 7) | 404 | #define NOW_IS_OOB (1 << 7) |
405 | #define TX_EMPTY (1 << 5) | ||
406 | #define RX_EMPTY (1 << 4) | ||
407 | #define RXTX_EMPTY (TX_EMPTY | RX_EMPTY) | ||
397 | #define EN_NDP (1 << 3) | 408 | #define EN_NDP (1 << 3) |
398 | #define EN_OOB_RESET (1 << 2) | 409 | #define EN_OOB_RESET (1 << 2) |
410 | #define LINK_LIST_RDY (1 << 1) | ||
399 | EFUSEAR = 0xdc, | 411 | EFUSEAR = 0xdc, |
400 | #define EFUSEAR_FLAG 0x80000000 | 412 | #define EFUSEAR_FLAG 0x80000000 |
401 | #define EFUSEAR_WRITE_CMD 0x80000000 | 413 | #define EFUSEAR_WRITE_CMD 0x80000000 |
@@ -421,6 +433,7 @@ enum rtl8168_registers { | |||
421 | #define ERIAR_MASK_SHIFT 12 | 433 | #define ERIAR_MASK_SHIFT 12 |
422 | #define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT) | 434 | #define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT) |
423 | #define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT) | 435 | #define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT) |
436 | #define ERIAR_MASK_0101 (0x5 << ERIAR_MASK_SHIFT) | ||
424 | #define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT) | 437 | #define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT) |
425 | EPHY_RXER_NUM = 0x7c, | 438 | EPHY_RXER_NUM = 0x7c, |
426 | OCPDR = 0xb0, /* OCP GPHY access */ | 439 | OCPDR = 0xb0, /* OCP GPHY access */ |
@@ -433,11 +446,13 @@ enum rtl8168_registers { | |||
433 | #define OCPAR_FLAG 0x80000000 | 446 | #define OCPAR_FLAG 0x80000000 |
434 | #define OCPAR_GPHY_WRITE_CMD 0x8000f060 | 447 | #define OCPAR_GPHY_WRITE_CMD 0x8000f060 |
435 | #define OCPAR_GPHY_READ_CMD 0x0000f060 | 448 | #define OCPAR_GPHY_READ_CMD 0x0000f060 |
449 | GPHY_OCP = 0xb8, | ||
436 | RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ | 450 | RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ |
437 | MISC = 0xf0, /* 8168e only. */ | 451 | MISC = 0xf0, /* 8168e only. */ |
438 | #define TXPLA_RST (1 << 29) | 452 | #define TXPLA_RST (1 << 29) |
439 | #define DISABLE_LAN_EN (1 << 23) /* Enable GPIO pin */ | 453 | #define DISABLE_LAN_EN (1 << 23) /* Enable GPIO pin */ |
440 | #define PWM_EN (1 << 22) | 454 | #define PWM_EN (1 << 22) |
455 | #define RXDV_GATED_EN (1 << 19) | ||
441 | #define EARLY_TALLY_EN (1 << 16) | 456 | #define EARLY_TALLY_EN (1 << 16) |
442 | }; | 457 | }; |
443 | 458 | ||
@@ -781,6 +796,8 @@ struct rtl8169_private { | |||
781 | } phy_action; | 796 | } phy_action; |
782 | } *rtl_fw; | 797 | } *rtl_fw; |
783 | #define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN) | 798 | #define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN) |
799 | |||
800 | u32 ocp_base; | ||
784 | }; | 801 | }; |
785 | 802 | ||
786 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); | 803 | MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); |
@@ -802,6 +819,7 @@ MODULE_FIRMWARE(FIRMWARE_8168F_2); | |||
802 | MODULE_FIRMWARE(FIRMWARE_8402_1); | 819 | MODULE_FIRMWARE(FIRMWARE_8402_1); |
803 | MODULE_FIRMWARE(FIRMWARE_8411_1); | 820 | MODULE_FIRMWARE(FIRMWARE_8411_1); |
804 | MODULE_FIRMWARE(FIRMWARE_8106E_1); | 821 | MODULE_FIRMWARE(FIRMWARE_8106E_1); |
822 | MODULE_FIRMWARE(FIRMWARE_8168G_1); | ||
805 | 823 | ||
806 | static void rtl_lock_work(struct rtl8169_private *tp) | 824 | static void rtl_lock_work(struct rtl8169_private *tp) |
807 | { | 825 | { |
@@ -976,6 +994,110 @@ static int r8168dp_check_dash(struct rtl8169_private *tp) | |||
976 | return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0; | 994 | return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0; |
977 | } | 995 | } |
978 | 996 | ||
997 | static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg) | ||
998 | { | ||
999 | if (reg & 0xffff0001) { | ||
1000 | netif_err(tp, drv, tp->dev, "Invalid ocp reg %x!\n", reg); | ||
1001 | return true; | ||
1002 | } | ||
1003 | return false; | ||
1004 | } | ||
1005 | |||
1006 | DECLARE_RTL_COND(rtl_ocp_gphy_cond) | ||
1007 | { | ||
1008 | void __iomem *ioaddr = tp->mmio_addr; | ||
1009 | |||
1010 | return RTL_R32(GPHY_OCP) & OCPAR_FLAG; | ||
1011 | } | ||
1012 | |||
1013 | static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) | ||
1014 | { | ||
1015 | void __iomem *ioaddr = tp->mmio_addr; | ||
1016 | |||
1017 | if (rtl_ocp_reg_failure(tp, reg)) | ||
1018 | return; | ||
1019 | |||
1020 | RTL_W32(GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); | ||
1021 | |||
1022 | rtl_udelay_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10); | ||
1023 | } | ||
1024 | |||
1025 | static u16 r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) | ||
1026 | { | ||
1027 | void __iomem *ioaddr = tp->mmio_addr; | ||
1028 | |||
1029 | if (rtl_ocp_reg_failure(tp, reg)) | ||
1030 | return 0; | ||
1031 | |||
1032 | RTL_W32(GPHY_OCP, reg << 15); | ||
1033 | |||
1034 | return rtl_udelay_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ? | ||
1035 | (RTL_R32(GPHY_OCP) & 0xffff) : ~0; | ||
1036 | } | ||
1037 | |||
1038 | static void rtl_w1w0_phy_ocp(struct rtl8169_private *tp, int reg, int p, int m) | ||
1039 | { | ||
1040 | int val; | ||
1041 | |||
1042 | val = r8168_phy_ocp_read(tp, reg); | ||
1043 | r8168_phy_ocp_write(tp, reg, (val | p) & ~m); | ||
1044 | } | ||
1045 | |||
1046 | DECLARE_RTL_COND(rtl_ocpdr_cond) | ||
1047 | { | ||
1048 | void __iomem *ioaddr = tp->mmio_addr; | ||
1049 | |||
1050 | return RTL_R32(OCPDR) & OCPAR_FLAG; | ||
1051 | } | ||
1052 | |||
1053 | static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) | ||
1054 | { | ||
1055 | void __iomem *ioaddr = tp->mmio_addr; | ||
1056 | |||
1057 | if (rtl_ocp_reg_failure(tp, reg)) | ||
1058 | return; | ||
1059 | |||
1060 | RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data); | ||
1061 | |||
1062 | rtl_udelay_loop_wait_low(tp, &rtl_ocpdr_cond, 25, 10); | ||
1063 | } | ||
1064 | |||
1065 | static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) | ||
1066 | { | ||
1067 | void __iomem *ioaddr = tp->mmio_addr; | ||
1068 | |||
1069 | if (rtl_ocp_reg_failure(tp, reg)) | ||
1070 | return 0; | ||
1071 | |||
1072 | RTL_W32(OCPDR, reg << 15); | ||
1073 | |||
1074 | return rtl_udelay_loop_wait_high(tp, &rtl_ocpdr_cond, 25, 10) ? | ||
1075 | RTL_R32(OCPDR) : ~0; | ||
1076 | } | ||
1077 | |||
1078 | #define OCP_STD_PHY_BASE 0xa400 | ||
1079 | |||
1080 | static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value) | ||
1081 | { | ||
1082 | if (reg == 0x1f) { | ||
1083 | tp->ocp_base = value ? value << 4 : OCP_STD_PHY_BASE; | ||
1084 | return; | ||
1085 | } | ||
1086 | |||
1087 | if (tp->ocp_base != OCP_STD_PHY_BASE) | ||
1088 | reg -= 0x10; | ||
1089 | |||
1090 | r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value); | ||
1091 | } | ||
1092 | |||
1093 | static int r8168g_mdio_read(struct rtl8169_private *tp, int reg) | ||
1094 | { | ||
1095 | if (tp->ocp_base != OCP_STD_PHY_BASE) | ||
1096 | reg -= 0x10; | ||
1097 | |||
1098 | return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2); | ||
1099 | } | ||
1100 | |||
979 | DECLARE_RTL_COND(rtl_phyar_cond) | 1101 | DECLARE_RTL_COND(rtl_phyar_cond) |
980 | { | 1102 | { |
981 | void __iomem *ioaddr = tp->mmio_addr; | 1103 | void __iomem *ioaddr = tp->mmio_addr; |
@@ -1929,6 +2051,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, | |||
1929 | u32 val; | 2051 | u32 val; |
1930 | int mac_version; | 2052 | int mac_version; |
1931 | } mac_info[] = { | 2053 | } mac_info[] = { |
2054 | /* 8168G family. */ | ||
2055 | { 0x7cf00000, 0x4c100000, RTL_GIGA_MAC_VER_41 }, | ||
2056 | { 0x7cf00000, 0x4c000000, RTL_GIGA_MAC_VER_40 }, | ||
2057 | |||
1932 | /* 8168F family. */ | 2058 | /* 8168F family. */ |
1933 | { 0x7c800000, 0x48800000, RTL_GIGA_MAC_VER_38 }, | 2059 | { 0x7c800000, 0x48800000, RTL_GIGA_MAC_VER_38 }, |
1934 | { 0x7cf00000, 0x48100000, RTL_GIGA_MAC_VER_36 }, | 2060 | { 0x7cf00000, 0x48100000, RTL_GIGA_MAC_VER_36 }, |
@@ -3244,6 +3370,55 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) | |||
3244 | rtl_writephy(tp, 0x1f, 0x0000); | 3370 | rtl_writephy(tp, 0x1f, 0x0000); |
3245 | } | 3371 | } |
3246 | 3372 | ||
3373 | static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) | ||
3374 | { | ||
3375 | static const u16 mac_ocp_patch[] = { | ||
3376 | 0xe008, 0xe01b, 0xe01d, 0xe01f, | ||
3377 | 0xe021, 0xe023, 0xe025, 0xe027, | ||
3378 | 0x49d2, 0xf10d, 0x766c, 0x49e2, | ||
3379 | 0xf00a, 0x1ec0, 0x8ee1, 0xc60a, | ||
3380 | |||
3381 | 0x77c0, 0x4870, 0x9fc0, 0x1ea0, | ||
3382 | 0xc707, 0x8ee1, 0x9d6c, 0xc603, | ||
3383 | 0xbe00, 0xb416, 0x0076, 0xe86c, | ||
3384 | 0xc602, 0xbe00, 0x0000, 0xc602, | ||
3385 | |||
3386 | 0xbe00, 0x0000, 0xc602, 0xbe00, | ||
3387 | 0x0000, 0xc602, 0xbe00, 0x0000, | ||
3388 | 0xc602, 0xbe00, 0x0000, 0xc602, | ||
3389 | 0xbe00, 0x0000, 0xc602, 0xbe00, | ||
3390 | |||
3391 | 0x0000, 0x0000, 0x0000, 0x0000 | ||
3392 | }; | ||
3393 | u32 i; | ||
3394 | |||
3395 | /* Patch code for GPHY reset */ | ||
3396 | for (i = 0; i < ARRAY_SIZE(mac_ocp_patch); i++) | ||
3397 | r8168_mac_ocp_write(tp, 0xf800 + 2*i, mac_ocp_patch[i]); | ||
3398 | r8168_mac_ocp_write(tp, 0xfc26, 0x8000); | ||
3399 | r8168_mac_ocp_write(tp, 0xfc28, 0x0075); | ||
3400 | |||
3401 | rtl_apply_firmware(tp); | ||
3402 | |||
3403 | if (r8168_phy_ocp_read(tp, 0xa460) & 0x0100) | ||
3404 | rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x0000, 0x8000); | ||
3405 | else | ||
3406 | rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x8000, 0x0000); | ||
3407 | |||
3408 | if (r8168_phy_ocp_read(tp, 0xa466) & 0x0100) | ||
3409 | rtl_w1w0_phy_ocp(tp, 0xc41a, 0x0002, 0x0000); | ||
3410 | else | ||
3411 | rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x0000, 0x0002); | ||
3412 | |||
3413 | rtl_w1w0_phy_ocp(tp, 0xa442, 0x000c, 0x0000); | ||
3414 | rtl_w1w0_phy_ocp(tp, 0xa4b2, 0x0004, 0x0000); | ||
3415 | |||
3416 | r8168_phy_ocp_write(tp, 0xa436, 0x8012); | ||
3417 | rtl_w1w0_phy_ocp(tp, 0xa438, 0x8000, 0x0000); | ||
3418 | |||
3419 | rtl_w1w0_phy_ocp(tp, 0xc422, 0x4000, 0x2000); | ||
3420 | } | ||
3421 | |||
3247 | static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) | 3422 | static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) |
3248 | { | 3423 | { |
3249 | static const struct phy_reg phy_reg_init[] = { | 3424 | static const struct phy_reg phy_reg_init[] = { |
@@ -3426,6 +3601,11 @@ static void rtl_hw_phy_config(struct net_device *dev) | |||
3426 | rtl8106e_hw_phy_config(tp); | 3601 | rtl8106e_hw_phy_config(tp); |
3427 | break; | 3602 | break; |
3428 | 3603 | ||
3604 | case RTL_GIGA_MAC_VER_40: | ||
3605 | rtl8168g_1_hw_phy_config(tp); | ||
3606 | break; | ||
3607 | |||
3608 | case RTL_GIGA_MAC_VER_41: | ||
3429 | default: | 3609 | default: |
3430 | break; | 3610 | break; |
3431 | } | 3611 | } |
@@ -3644,6 +3824,11 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) | |||
3644 | ops->write = r8168dp_2_mdio_write; | 3824 | ops->write = r8168dp_2_mdio_write; |
3645 | ops->read = r8168dp_2_mdio_read; | 3825 | ops->read = r8168dp_2_mdio_read; |
3646 | break; | 3826 | break; |
3827 | case RTL_GIGA_MAC_VER_40: | ||
3828 | case RTL_GIGA_MAC_VER_41: | ||
3829 | ops->write = r8168g_mdio_write; | ||
3830 | ops->read = r8168g_mdio_read; | ||
3831 | break; | ||
3647 | default: | 3832 | default: |
3648 | ops->write = r8169_mdio_write; | 3833 | ops->write = r8169_mdio_write; |
3649 | ops->read = r8169_mdio_read; | 3834 | ops->read = r8169_mdio_read; |
@@ -3664,6 +3849,8 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) | |||
3664 | case RTL_GIGA_MAC_VER_37: | 3849 | case RTL_GIGA_MAC_VER_37: |
3665 | case RTL_GIGA_MAC_VER_38: | 3850 | case RTL_GIGA_MAC_VER_38: |
3666 | case RTL_GIGA_MAC_VER_39: | 3851 | case RTL_GIGA_MAC_VER_39: |
3852 | case RTL_GIGA_MAC_VER_40: | ||
3853 | case RTL_GIGA_MAC_VER_41: | ||
3667 | RTL_W32(RxConfig, RTL_R32(RxConfig) | | 3854 | RTL_W32(RxConfig, RTL_R32(RxConfig) | |
3668 | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); | 3855 | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); |
3669 | break; | 3856 | break; |
@@ -3912,6 +4099,8 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) | |||
3912 | case RTL_GIGA_MAC_VER_35: | 4099 | case RTL_GIGA_MAC_VER_35: |
3913 | case RTL_GIGA_MAC_VER_36: | 4100 | case RTL_GIGA_MAC_VER_36: |
3914 | case RTL_GIGA_MAC_VER_38: | 4101 | case RTL_GIGA_MAC_VER_38: |
4102 | case RTL_GIGA_MAC_VER_40: | ||
4103 | case RTL_GIGA_MAC_VER_41: | ||
3915 | ops->down = r8168_pll_power_down; | 4104 | ops->down = r8168_pll_power_down; |
3916 | ops->up = r8168_pll_power_up; | 4105 | ops->up = r8168_pll_power_up; |
3917 | break; | 4106 | break; |
@@ -4108,6 +4297,8 @@ static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp) | |||
4108 | * No action needed for jumbo frames with 8169. | 4297 | * No action needed for jumbo frames with 8169. |
4109 | * No jumbo for 810x at all. | 4298 | * No jumbo for 810x at all. |
4110 | */ | 4299 | */ |
4300 | case RTL_GIGA_MAC_VER_40: | ||
4301 | case RTL_GIGA_MAC_VER_41: | ||
4111 | default: | 4302 | default: |
4112 | ops->disable = NULL; | 4303 | ops->disable = NULL; |
4113 | ops->enable = NULL; | 4304 | ops->enable = NULL; |
@@ -4213,6 +4404,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) | |||
4213 | tp->mac_version == RTL_GIGA_MAC_VER_35 || | 4404 | tp->mac_version == RTL_GIGA_MAC_VER_35 || |
4214 | tp->mac_version == RTL_GIGA_MAC_VER_36 || | 4405 | tp->mac_version == RTL_GIGA_MAC_VER_36 || |
4215 | tp->mac_version == RTL_GIGA_MAC_VER_37 || | 4406 | tp->mac_version == RTL_GIGA_MAC_VER_37 || |
4407 | tp->mac_version == RTL_GIGA_MAC_VER_40 || | ||
4408 | tp->mac_version == RTL_GIGA_MAC_VER_41 || | ||
4216 | tp->mac_version == RTL_GIGA_MAC_VER_38) { | 4409 | tp->mac_version == RTL_GIGA_MAC_VER_38) { |
4217 | RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); | 4410 | RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); |
4218 | rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); | 4411 | rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); |
@@ -4925,6 +5118,36 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp) | |||
4925 | rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0x0000, ERIAR_EXGMAC); | 5118 | rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0x0000, ERIAR_EXGMAC); |
4926 | } | 5119 | } |
4927 | 5120 | ||
5121 | static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) | ||
5122 | { | ||
5123 | void __iomem *ioaddr = tp->mmio_addr; | ||
5124 | struct pci_dev *pdev = tp->pci_dev; | ||
5125 | |||
5126 | rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC); | ||
5127 | rtl_eri_write(tp, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC); | ||
5128 | rtl_eri_write(tp, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC); | ||
5129 | rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC); | ||
5130 | |||
5131 | rtl_csi_access_enable_1(tp); | ||
5132 | |||
5133 | rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); | ||
5134 | |||
5135 | rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); | ||
5136 | rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); | ||
5137 | |||
5138 | RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); | ||
5139 | RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); | ||
5140 | RTL_W8(MaxTxPacketSize, EarlySize); | ||
5141 | |||
5142 | rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); | ||
5143 | rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); | ||
5144 | |||
5145 | /* Adjust EEE LED frequency */ | ||
5146 | RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); | ||
5147 | |||
5148 | rtl_w1w0_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC); | ||
5149 | } | ||
5150 | |||
4928 | static void rtl_hw_start_8168(struct net_device *dev) | 5151 | static void rtl_hw_start_8168(struct net_device *dev) |
4929 | { | 5152 | { |
4930 | struct rtl8169_private *tp = netdev_priv(dev); | 5153 | struct rtl8169_private *tp = netdev_priv(dev); |
@@ -5026,6 +5249,11 @@ static void rtl_hw_start_8168(struct net_device *dev) | |||
5026 | rtl_hw_start_8411(tp); | 5249 | rtl_hw_start_8411(tp); |
5027 | break; | 5250 | break; |
5028 | 5251 | ||
5252 | case RTL_GIGA_MAC_VER_40: | ||
5253 | case RTL_GIGA_MAC_VER_41: | ||
5254 | rtl_hw_start_8168g_1(tp); | ||
5255 | break; | ||
5256 | |||
5029 | default: | 5257 | default: |
5030 | printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", | 5258 | printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", |
5031 | dev->name, tp->mac_version); | 5259 | dev->name, tp->mac_version); |
@@ -6492,6 +6720,67 @@ static unsigned rtl_try_msi(struct rtl8169_private *tp, | |||
6492 | return msi; | 6720 | return msi; |
6493 | } | 6721 | } |
6494 | 6722 | ||
6723 | DECLARE_RTL_COND(rtl_link_list_ready_cond) | ||
6724 | { | ||
6725 | void __iomem *ioaddr = tp->mmio_addr; | ||
6726 | |||
6727 | return RTL_R8(MCU) & LINK_LIST_RDY; | ||
6728 | } | ||
6729 | |||
6730 | DECLARE_RTL_COND(rtl_rxtx_empty_cond) | ||
6731 | { | ||
6732 | void __iomem *ioaddr = tp->mmio_addr; | ||
6733 | |||
6734 | return (RTL_R8(MCU) & RXTX_EMPTY) == RXTX_EMPTY; | ||
6735 | } | ||
6736 | |||
6737 | static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp) | ||
6738 | { | ||
6739 | void __iomem *ioaddr = tp->mmio_addr; | ||
6740 | u32 data; | ||
6741 | |||
6742 | tp->ocp_base = OCP_STD_PHY_BASE; | ||
6743 | |||
6744 | RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN); | ||
6745 | |||
6746 | if (!rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42)) | ||
6747 | return; | ||
6748 | |||
6749 | if (!rtl_udelay_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42)) | ||
6750 | return; | ||
6751 | |||
6752 | RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); | ||
6753 | msleep(1); | ||
6754 | RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); | ||
6755 | |||
6756 | data = r8168_mac_ocp_read(ioaddr, 0xe8de); | ||
6757 | data &= ~(1 << 14); | ||
6758 | r8168_mac_ocp_write(tp, 0xe8de, data); | ||
6759 | |||
6760 | if (!rtl_udelay_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42)) | ||
6761 | return; | ||
6762 | |||
6763 | data = r8168_mac_ocp_read(ioaddr, 0xe8de); | ||
6764 | data |= (1 << 15); | ||
6765 | r8168_mac_ocp_write(tp, 0xe8de, data); | ||
6766 | |||
6767 | if (!rtl_udelay_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42)) | ||
6768 | return; | ||
6769 | } | ||
6770 | |||
6771 | static void __devinit rtl_hw_initialize(struct rtl8169_private *tp) | ||
6772 | { | ||
6773 | switch (tp->mac_version) { | ||
6774 | case RTL_GIGA_MAC_VER_40: | ||
6775 | case RTL_GIGA_MAC_VER_41: | ||
6776 | rtl_hw_init_8168g(tp); | ||
6777 | break; | ||
6778 | |||
6779 | default: | ||
6780 | break; | ||
6781 | } | ||
6782 | } | ||
6783 | |||
6495 | static int __devinit | 6784 | static int __devinit |
6496 | rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | 6785 | rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) |
6497 | { | 6786 | { |
@@ -6601,6 +6890,8 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
6601 | 6890 | ||
6602 | rtl_irq_disable(tp); | 6891 | rtl_irq_disable(tp); |
6603 | 6892 | ||
6893 | rtl_hw_initialize(tp); | ||
6894 | |||
6604 | rtl_hw_reset(tp); | 6895 | rtl_hw_reset(tp); |
6605 | 6896 | ||
6606 | rtl_ack_events(tp, 0xffff); | 6897 | rtl_ack_events(tp, 0xffff); |