* [PATCH net-next 1/2] r8169: support RTL8106E @ 2012-06-29 10:34 Hayes Wang 2012-06-29 10:34 ` [PATCH net-next 2/2] r8169: support RTL8168G Hayes Wang ` (3 more replies) 0 siblings, 4 replies; 18+ messages in thread From: Hayes Wang @ 2012-06-29 10:34 UTC (permalink / raw) To: romieu; +Cc: netdev, linux-kernel, hayes, Hayes Wang From: hayes <hayes@fc17.localdomain> Support the new chip RTL8106E. Signed-off-by: Hayes Wang <hayeswang@realtek.com> --- drivers/net/ethernet/realtek/r8169.c | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index d7a04e0..7afc593 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -46,6 +46,7 @@ #define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw" #define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw" #define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw" +#define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -141,6 +142,7 @@ enum mac_version { RTL_GIGA_MAC_VER_36, RTL_GIGA_MAC_VER_37, RTL_GIGA_MAC_VER_38, + RTL_GIGA_MAC_VER_39, RTL_GIGA_MAC_NONE = 0xff, }; @@ -259,6 +261,9 @@ static const struct { [RTL_GIGA_MAC_VER_38] = _R("RTL8411", RTL_TD_1, FIRMWARE_8411_1, JUMBO_9K, false), + [RTL_GIGA_MAC_VER_39] = + _R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_1, + JUMBO_1K, true), }; #undef _R @@ -431,7 +436,9 @@ enum rtl8168_registers { RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ MISC = 0xf0, /* 8168e only. */ #define TXPLA_RST (1 << 29) +#define DISABLE_LAN_EN (1 << 23) /* Enable GPIO pin */ #define PWM_EN (1 << 22) +#define EARLY_TALLY_EN (1 << 16) }; enum rtl_register_content { @@ -794,6 +801,7 @@ MODULE_FIRMWARE(FIRMWARE_8168F_1); MODULE_FIRMWARE(FIRMWARE_8168F_2); MODULE_FIRMWARE(FIRMWARE_8402_1); MODULE_FIRMWARE(FIRMWARE_8411_1); +MODULE_FIRMWARE(FIRMWARE_8106E_1); static void rtl_lock_work(struct rtl8169_private *tp) { @@ -1933,6 +1941,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, /* 8101 family. */ + { 0x7cf00000, 0x44900000, RTL_GIGA_MAC_VER_39 }, + { 0x7c800000, 0x44800000, RTL_GIGA_MAC_VER_39 }, { 0x7c800000, 0x44000000, RTL_GIGA_MAC_VER_37 }, { 0x7cf00000, 0x40b00000, RTL_GIGA_MAC_VER_30 }, { 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 }, @@ -3273,6 +3283,30 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0000); } +static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + static const struct phy_reg phy_reg_init[] = { + { 0x1f, 0x0004 }, + { 0x10, 0xc07f }, + { 0x19, 0x7030 }, + { 0x1f, 0x0000 } + }; + + /* Disable ALDPS before ram code */ + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, 0x18, 0x0310); + msleep(100); + + rtl_apply_firmware(tp); + + rtl_eri_write(ioaddr, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + + rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); +} + static void rtl_hw_phy_config(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3369,6 +3403,10 @@ static void rtl_hw_phy_config(struct net_device *dev) rtl8411_hw_phy_config(tp); break; + case RTL_GIGA_MAC_VER_39: + rtl8106e_hw_phy_config(tp); + break; + default: break; } @@ -3608,6 +3646,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_34: case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_38: + case RTL_GIGA_MAC_VER_39: RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); break; @@ -3830,6 +3869,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_29: case RTL_GIGA_MAC_VER_30: case RTL_GIGA_MAC_VER_37: + case RTL_GIGA_MAC_VER_39: ops->down = r810x_pll_power_down; ops->up = r810x_pll_power_up; break; @@ -5123,6 +5163,18 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp) ERIAR_EXGMAC); } +static void rtl_hw_start_8106(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + /* Force LAN exit from ASPM if Rx/Tx are not idle */ + RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800); + + RTL_W32(MISC, (RTL_R32(MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN); + RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); + RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN); +} + static void rtl_hw_start_8101(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -5167,6 +5219,10 @@ static void rtl_hw_start_8101(struct net_device *dev) case RTL_GIGA_MAC_VER_37: rtl_hw_start_8402(tp); break; + + case RTL_GIGA_MAC_VER_39: + rtl_hw_start_8106(tp); + break; } RTL_W8(Cfg9346, Cfg9346_Lock); -- 1.7.10.2 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH net-next 2/2] r8169: support RTL8168G 2012-06-29 10:34 [PATCH net-next 1/2] r8169: support RTL8106E Hayes Wang @ 2012-06-29 10:34 ` Hayes Wang 2012-06-29 13:51 ` Francois Romieu 2012-06-29 13:50 ` [PATCH net-next 1/2] r8169: support RTL8106E Francois Romieu ` (2 subsequent siblings) 3 siblings, 1 reply; 18+ messages in thread From: Hayes Wang @ 2012-06-29 10:34 UTC (permalink / raw) To: romieu; +Cc: netdev, linux-kernel, hayes, Hayes Wang From: hayes <hayes@fc17.localdomain> Support the new chip RTL8168G. Signed-off-by: Hayes Wang <hayeswang@realtek.com> --- drivers/net/ethernet/realtek/r8169.c | 344 +++++++++++++++++++++++++++++++++- 1 file changed, 343 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 7afc593..fda4432 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -47,6 +47,7 @@ #define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw" #define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw" #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" +#define FIRMWARE_8168G_1 "rtl_nic/rtl8168g-1.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -143,6 +144,8 @@ enum mac_version { RTL_GIGA_MAC_VER_37, RTL_GIGA_MAC_VER_38, RTL_GIGA_MAC_VER_39, + RTL_GIGA_MAC_VER_40, + RTL_GIGA_MAC_VER_41, RTL_GIGA_MAC_NONE = 0xff, }; @@ -264,6 +267,11 @@ static const struct { [RTL_GIGA_MAC_VER_39] = _R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_1, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_40] = + _R("RTL8168g/8111g", RTL_TD_1, FIRMWARE_8168G_1, + JUMBO_9K, false), + [RTL_GIGA_MAC_VER_41] = + _R("RTL8168g/8111g", RTL_TD_1, NULL, JUMBO_9K, false), }; #undef _R @@ -394,8 +402,11 @@ enum rtl8168_8101_registers { TWSI = 0xd2, MCU = 0xd3, #define NOW_IS_OOB (1 << 7) +#define TX_EMPTY (1 << 5) +#define RX_EMPTY (1 << 4) #define EN_NDP (1 << 3) #define EN_OOB_RESET (1 << 2) +#define LINK_LIST_RDY (1 << 1) EFUSEAR = 0xdc, #define EFUSEAR_FLAG 0x80000000 #define EFUSEAR_WRITE_CMD 0x80000000 @@ -421,6 +432,7 @@ enum rtl8168_registers { #define ERIAR_MASK_SHIFT 12 #define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT) #define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT) +#define ERIAR_MASK_0101 (0x5 << ERIAR_MASK_SHIFT) #define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT) EPHY_RXER_NUM = 0x7c, OCPDR = 0xb0, /* OCP GPHY access */ @@ -433,11 +445,13 @@ enum rtl8168_registers { #define OCPAR_FLAG 0x80000000 #define OCPAR_GPHY_WRITE_CMD 0x8000f060 #define OCPAR_GPHY_READ_CMD 0x0000f060 + GPHY_OCP = 0xb8, RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ MISC = 0xf0, /* 8168e only. */ #define TXPLA_RST (1 << 29) #define DISABLE_LAN_EN (1 << 23) /* Enable GPIO pin */ #define PWM_EN (1 << 22) +#define RXDV_GATED_EN (1 << 19) #define EARLY_TALLY_EN (1 << 16) }; @@ -781,6 +795,8 @@ struct rtl8169_private { } phy_action; } *rtl_fw; #define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN) + + void (*write_fw)(struct rtl8169_private *, struct rtl_fw *); }; MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); @@ -802,6 +818,7 @@ MODULE_FIRMWARE(FIRMWARE_8168F_2); MODULE_FIRMWARE(FIRMWARE_8402_1); MODULE_FIRMWARE(FIRMWARE_8411_1); MODULE_FIRMWARE(FIRMWARE_8106E_1); +MODULE_FIRMWARE(FIRMWARE_8168G_1); static void rtl_lock_work(struct rtl8169_private *tp) { @@ -919,6 +936,99 @@ static int r8168dp_check_dash(struct rtl8169_private *tp) return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0; } +static void r8168_phy_ocp_write(void __iomem *ioaddr, u32 reg, u32 data) +{ + int i; + + if (reg & 0xffff0001) + BUG(); + + RTL_W32(GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); + + for (i = 0; i < 10; i++) { + udelay(25); + if (!(RTL_R32(GPHY_OCP) & OCPAR_FLAG)) + break; + } +} + +static u16 r8168_phy_ocp_read(void __iomem *ioaddr, u32 reg) +{ + int i; + u32 data; + + if (reg & 0xffff0001) + BUG(); + + RTL_W32(GPHY_OCP, (reg << 15)); + + for (i = 0; i < 10; i++) { + udelay(25); + data = RTL_R32(GPHY_OCP); + if (data & OCPAR_FLAG) + break; + } + + return (u16)(data & 0xffff); +} + +static void rtl_w1w0_phy_ocp(void __iomem *ioaddr, int reg_addr, int p, int m) +{ + int val; + + val = r8168_phy_ocp_read(ioaddr, reg_addr); + r8168_phy_ocp_write(ioaddr, reg_addr, (val | p) & ~m); +} + +static void r8168_mac_ocp_write(void __iomem *ioaddr, u32 reg, u32 data) +{ + int i; + + if (reg & 0xffff0001) + BUG(); + + RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data); + + for (i = 0; i < 10; i++) { + udelay(25); + if (!(RTL_R32(OCPDR) & OCPAR_FLAG)) + break; + } +} + +static u16 r8168_mac_ocp_read(void __iomem *ioaddr, u32 reg) +{ + int i; + u32 data; + + if (reg & 0xffff0001) + BUG(); + + RTL_W32(OCPDR, (reg << 15)); + + for (i = 0; i < 10; i++) { + udelay(25); + data = RTL_R32(OCPDR); + if (data & OCPAR_FLAG) + break; + } + + return (u16)(data & 0xffff); +} + +static void r8168g_mdio_write(void __iomem *ioaddr, int reg_addr, int value) +{ + if (reg_addr == 0x1f) + return; + + r8168_phy_ocp_write(ioaddr, 0xa400 + reg_addr * 2, value); +} + +static int r8168g_mdio_read(void __iomem *ioaddr, int reg_addr) +{ + return r8168_phy_ocp_read(ioaddr, 0xa400 + reg_addr * 2); +} + static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value) { int i; @@ -1902,6 +2012,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, u32 val; int mac_version; } mac_info[] = { + /* 8168G family. */ + { 0x7cf00000, 0x4c100000, RTL_GIGA_MAC_VER_41 }, + { 0x7cf00000, 0x4c000000, RTL_GIGA_MAC_VER_40 }, + /* 8168F family. */ { 0x7c800000, 0x48800000, RTL_GIGA_MAC_VER_38 }, { 0x7cf00000, 0x48100000, RTL_GIGA_MAC_VER_36 }, @@ -2241,6 +2355,92 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) } } +static void rtl_ocp_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) +{ + struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; + void __iomem *ioaddr = tp->mmio_addr; + u32 predata, count; + u32 base_addr; + size_t index; + + predata = count = 0; + base_addr = 0xa400; + + for (index = 0; index < pa->size; ) { + u32 action = le32_to_cpu(pa->code[index]); + u32 data = action & 0x0000ffff; + u32 regno = (action & 0x0fff0000) >> 16; + + if (!action) + break; + + switch(action & 0xf0000000) { + case PHY_READ: + predata = r8168_phy_ocp_read(ioaddr, + base_addr + (regno -16) * 2); + count++; + index++; + break; + case PHY_DATA_OR: + predata |= data; + index++; + break; + case PHY_DATA_AND: + predata &= data; + index++; + break; + case PHY_BJMPN: + index -= regno; + break; + case PHY_CLEAR_READCOUNT: + count = 0; + index++; + break; + case PHY_WRITE: + if (regno == 0x1f) + base_addr = data << 4; + else + r8168_phy_ocp_write(ioaddr, + base_addr + (regno - 0x10) * 2, + data); + index++; + break; + case PHY_READCOUNT_EQ_SKIP: + index += (count == data) ? 2 : 1; + break; + case PHY_COMP_EQ_SKIPN: + if (predata == data) + index += regno; + index++; + break; + case PHY_COMP_NEQ_SKIPN: + if (predata != data) + index += regno; + index++; + break; + case PHY_WRITE_PREVIOUS: + r8168_phy_ocp_write(ioaddr, base_addr + (regno -16) * 2, + predata); + index++; + break; + case PHY_SKIPN: + index += regno + 1; + break; + case PHY_DELAY_MS: + mdelay(data); + index++; + break; + + case PHY_READ_MAC_BYTE: + case PHY_WRITE_MAC_BYTE: + case PHY_WRITE_ERI_WORD: + case PHY_READ_EFUSE: + default: + BUG(); + } + } +} + static void rtl_release_firmware(struct rtl8169_private *tp) { if (!IS_ERR_OR_NULL(tp->rtl_fw)) { @@ -2256,7 +2456,7 @@ static void rtl_apply_firmware(struct rtl8169_private *tp) /* TODO: release firmware once rtl_phy_write_fw signals failures. */ if (!IS_ERR_OR_NULL(rtl_fw)) - rtl_phy_write_fw(tp, rtl_fw); + tp->write_fw(tp, rtl_fw); } static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) @@ -3221,6 +3421,56 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0000); } +static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + u32 mac_ocp_addr, i; + static const u16 mac_ocp_patch[] = { + 0xE008, 0xE01B, 0xE01D, 0xE01F, + 0xE021, 0xE023, 0xE025, 0xE027, + 0x49D2 ,0xF10D, 0x766C, 0x49E2, + 0xF00A, 0x1EC0, 0x8EE1, 0xC60A, + 0x77C0, 0x4870, 0x9FC0, 0x1EA0, + 0xC707, 0x8EE1, 0x9D6C, 0xC603, + 0xBE00, 0xB416, 0x0076, 0xE86C, + 0xC602, 0xBE00, 0x0000, 0xC602, + 0xBE00, 0x0000, 0xC602, 0xBE00, + 0x0000, 0xC602, 0xBE00, 0x0000, + 0xC602, 0xBE00, 0x0000, 0xC602, + 0xBE00, 0x0000, 0xC602, 0xBE00, + 0x0000, 0x0000, 0x0000, 0x0000 + }; + + /* patch code for GPHY reset */ + mac_ocp_addr = 0xf800; + for (i = 0; mac_ocp_addr < 0xf868; i++) { + r8168_mac_ocp_write(ioaddr, mac_ocp_addr, mac_ocp_patch[i]); + mac_ocp_addr += 2; + } + r8168_mac_ocp_write(ioaddr, 0xfc26, 0x8000); + r8168_mac_ocp_write(ioaddr, 0xfc28, 0x0075); + + rtl_apply_firmware(tp); + + if (r8168_phy_ocp_read(ioaddr, 0xa460) & 0x0100) + rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x0000, 0x8000); + else + rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x8000, 0x0000); + + if (r8168_phy_ocp_read(ioaddr, 0xa466) & 0x0100) + rtl_w1w0_phy_ocp(ioaddr, 0xc41a, 0x0002, 0x0000); + else + rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x0000, 0x0002); + + rtl_w1w0_phy_ocp(ioaddr, 0xa442, 0x000c, 0x0000); + rtl_w1w0_phy_ocp(ioaddr, 0xa4b2, 0x0004, 0x0000); + + r8168_phy_ocp_write(ioaddr, 0xa436, 0x8012); + rtl_w1w0_phy_ocp(ioaddr, 0xa438, 0x8000, 0x0000); + + rtl_w1w0_phy_ocp(ioaddr, 0xc422, 0x4000, 0x2000); +} + static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -3407,6 +3657,13 @@ static void rtl_hw_phy_config(struct net_device *dev) rtl8106e_hw_phy_config(tp); break; + case RTL_GIGA_MAC_VER_40: + rtl8168g_1_hw_phy_config(tp); + break; + + case RTL_GIGA_MAC_VER_41: + break; + default: break; } @@ -3621,15 +3878,24 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_27: ops->write = r8168dp_1_mdio_write; ops->read = r8168dp_1_mdio_read; + tp->write_fw = rtl_phy_write_fw; break; case RTL_GIGA_MAC_VER_28: case RTL_GIGA_MAC_VER_31: ops->write = r8168dp_2_mdio_write; ops->read = r8168dp_2_mdio_read; + tp->write_fw = rtl_phy_write_fw; + break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + ops->write = r8168g_mdio_write; + ops->read = r8168g_mdio_read; + tp->write_fw = rtl_ocp_write_fw; break; default: ops->write = r8169_mdio_write; ops->read = r8169_mdio_read; + tp->write_fw = rtl_phy_write_fw; break; } } @@ -3647,6 +3913,8 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_38: case RTL_GIGA_MAC_VER_39: + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); break; @@ -3895,6 +4163,8 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_35: case RTL_GIGA_MAC_VER_36: case RTL_GIGA_MAC_VER_38: + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: ops->down = r8168_pll_power_down; ops->up = r8168_pll_power_up; break; @@ -4183,6 +4453,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) tp->mac_version == RTL_GIGA_MAC_VER_35 || tp->mac_version == RTL_GIGA_MAC_VER_36 || tp->mac_version == RTL_GIGA_MAC_VER_37 || + tp->mac_version == RTL_GIGA_MAC_VER_40 || + tp->mac_version == RTL_GIGA_MAC_VER_41 || tp->mac_version == RTL_GIGA_MAC_VER_38) { RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); while (!(RTL_R32(TxConfig) & TXCFG_EMPTY)) @@ -4921,6 +5193,28 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp) ERIAR_EXGMAC); } +static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; + + rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 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(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); + rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); + RTL_W8(MaxTxPacketSize, EarlySize); + rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); + rtl_w1w0_eri(ioaddr, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC); +} + static void rtl_hw_start_8168(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -5022,6 +5316,11 @@ static void rtl_hw_start_8168(struct net_device *dev) rtl_hw_start_8411(tp); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + rtl_hw_start_8168g_1(tp); + break; + default: printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", dev->name, tp->mac_version); @@ -6491,6 +6790,47 @@ static unsigned rtl_try_msi(struct rtl8169_private *tp, return msi; } +static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + u32 tmp_data; + + RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN); + while (!(RTL_R32(TxConfig) & TXCFG_EMPTY)) + udelay(100); + + while ((RTL_R8(MCU) & (TX_EMPTY | RX_EMPTY)) != (TX_EMPTY | RX_EMPTY)) + udelay(100); + + RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); + msleep(1); + RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); + + tmp_data = r8168_mac_ocp_read(ioaddr, 0xe8de); + tmp_data &= ~(1 << 14); + r8168_mac_ocp_write(ioaddr, 0xe8de, tmp_data); + while (!(RTL_R8(MCU) & LINK_LIST_RDY)) + udelay(100); + + tmp_data = r8168_mac_ocp_read(ioaddr, 0xe8de); + tmp_data |= (1 << 15); + r8168_mac_ocp_write(ioaddr, 0xe8de, tmp_data); + while (!(RTL_R8(MCU) & LINK_LIST_RDY)) + udelay(100); +} + +static void __devinit rtl_hw_initialize(struct rtl8169_private *tp) +{ + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + rtl_hw_init_8168g(tp); + break; + default: + break; + } +} + static int __devinit rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -6600,6 +6940,8 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rtl_irq_disable(tp); + rtl_hw_initialize(tp); + rtl_hw_reset(tp); rtl_ack_events(tp, 0xffff); -- 1.7.10.2 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH net-next 2/2] r8169: support RTL8168G 2012-06-29 10:34 ` [PATCH net-next 2/2] r8169: support RTL8168G Hayes Wang @ 2012-06-29 13:51 ` Francois Romieu 2012-07-02 7:27 ` hayeswang 0 siblings, 1 reply; 18+ messages in thread From: Francois Romieu @ 2012-06-29 13:51 UTC (permalink / raw) To: Hayes Wang; +Cc: netdev, linux-kernel Hayes Wang <hayeswang@realtek.com> : [...] > @@ -264,6 +267,11 @@ static const struct { > [RTL_GIGA_MAC_VER_39] = > _R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_1, > JUMBO_1K, true), > + [RTL_GIGA_MAC_VER_40] = > + _R("RTL8168g/8111g", RTL_TD_1, FIRMWARE_8168G_1, > + JUMBO_9K, false), > + [RTL_GIGA_MAC_VER_41] = > + _R("RTL8168g/8111g", RTL_TD_1, NULL, JUMBO_9K, false), You may explicitely state that jumbo operation requires no special action by completing rtl_init_jumbo_ops. (no checksuming with jumbo, sigh) [...] > static void rtl_lock_work(struct rtl8169_private *tp) > { > @@ -919,6 +936,99 @@ static int r8168dp_check_dash(struct rtl8169_private *tp) > return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0; > } > > +static void r8168_phy_ocp_write(void __iomem *ioaddr, u32 reg, u32 data) > +{ > + int i; > + > + if (reg & 0xffff0001) > + BUG(); The patch adds a lot of BUG(). BUG is terrible from a system or end user viewpoint. Were they only a devel helper or are they still supposed to be of use in the future ? If the latter applies, why ? [...] > +static u16 r8168_phy_ocp_read(void __iomem *ioaddr, u32 reg) > +{ > + int i; > + u32 data; > + > + if (reg & 0xffff0001) > + BUG(); > + > + RTL_W32(GPHY_OCP, (reg << 15)); You can save on parenthesis here. [...] > +static void r8168g_mdio_write(void __iomem *ioaddr, int reg_addr, int value) > +{ > + if (reg_addr == 0x1f) > + return; > + > + r8168_phy_ocp_write(ioaddr, 0xa400 + reg_addr * 2, value); > +} > + > +static int r8168g_mdio_read(void __iomem *ioaddr, int reg_addr) > +{ > + return r8168_phy_ocp_read(ioaddr, 0xa400 + reg_addr * 2); > +} #define XYZ_{BASE/OFFSET} 0xa400 ? [...] > @@ -2241,6 +2355,92 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) > } > } > > +static void rtl_ocp_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) > +{ > + struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; > + void __iomem *ioaddr = tp->mmio_addr; > + u32 predata, count; > + u32 base_addr; > + size_t index; > + > + predata = count = 0; > + base_addr = 0xa400; > + > + for (index = 0; index < pa->size; ) { > + u32 action = le32_to_cpu(pa->code[index]); > + u32 data = action & 0x0000ffff; > + u32 regno = (action & 0x0fff0000) >> 16; > + > + if (!action) > + break; > + > + switch(action & 0xf0000000) { > + case PHY_READ: > + predata = r8168_phy_ocp_read(ioaddr, > + base_addr + (regno -16) * 2); > + count++; > + index++; > + break; [duplicated code removed] > + case PHY_WRITE: > + if (regno == 0x1f) > + base_addr = data << 4; > + else > + r8168_phy_ocp_write(ioaddr, > + base_addr + (regno - 0x10) * 2, > + data); > + index++; > + break; [duplicated code removed] > + case PHY_WRITE_PREVIOUS: > + r8168_phy_ocp_write(ioaddr, base_addr + (regno -16) * 2, > + predata); > + index++; > + break; I can't believe that the hardware people have designed something which needs a different firmware write method, especially as it copies at lot of code. How did you come to the conclusion that it was not possible to hide this stuff behind r8168g_mdio_{read / write} ? I would not mind replacing the PHY_{READ/WRITE/WRITE_PREVIOUS} case with chipset specific {READ/WRITE/WRITE_PREVIOUS} methods as long as the semantic looks the same but going through a different (*write_fw) does not trivially seem to be the best abstraction. [...] > @@ -3221,6 +3421,56 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) > rtl_writephy(tp, 0x1f, 0x0000); > } > > +static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) > +{ > + void __iomem *ioaddr = tp->mmio_addr; > + u32 mac_ocp_addr, i; > + static const u16 mac_ocp_patch[] = { > + 0xE008, 0xE01B, 0xE01D, 0xE01F, > + 0xE021, 0xE023, 0xE025, 0xE027, > + 0x49D2 ,0xF10D, 0x766C, 0x49E2, > + 0xF00A, 0x1EC0, 0x8EE1, 0xC60A, > + 0x77C0, 0x4870, 0x9FC0, 0x1EA0, > + 0xC707, 0x8EE1, 0x9D6C, 0xC603, > + 0xBE00, 0xB416, 0x0076, 0xE86C, > + 0xC602, 0xBE00, 0x0000, 0xC602, > + 0xBE00, 0x0000, 0xC602, 0xBE00, > + 0x0000, 0xC602, 0xBE00, 0x0000, > + 0xC602, 0xBE00, 0x0000, 0xC602, > + 0xBE00, 0x0000, 0xC602, 0xBE00, > + 0x0000, 0x0000, 0x0000, 0x0000 Please s/\(.*\)/\L\1/ > + }; > + > + /* patch code for GPHY reset */ > + mac_ocp_addr = 0xf800; > + for (i = 0; mac_ocp_addr < 0xf868; i++) { > + r8168_mac_ocp_write(ioaddr, mac_ocp_addr, mac_ocp_patch[i]); > + mac_ocp_addr += 2; > + } for (i = 0; i < ARRAY_SIZE(mac_ocp_patch); i++) r8168_mac_ocp_write(ioaddr, 0xf800 + 2*i, mac_ocp_patch[i]); The array must be correctly sized anyway. :o) You may save a bit on the 'mac_ocp_patch' identifier and replace 0xf800 with a #define. > + r8168_mac_ocp_write(ioaddr, 0xfc26, 0x8000); > + r8168_mac_ocp_write(ioaddr, 0xfc28, 0x0075); > + > + rtl_apply_firmware(tp); > + > + if (r8168_phy_ocp_read(ioaddr, 0xa460) & 0x0100) > + rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x0000, 0x8000); > + else > + rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x8000, 0x0000); > + > + if (r8168_phy_ocp_read(ioaddr, 0xa466) & 0x0100) > + rtl_w1w0_phy_ocp(ioaddr, 0xc41a, 0x0002, 0x0000); > + else > + rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x0000, 0x0002); > + > + rtl_w1w0_phy_ocp(ioaddr, 0xa442, 0x000c, 0x0000); > + rtl_w1w0_phy_ocp(ioaddr, 0xa4b2, 0x0004, 0x0000); > + > + r8168_phy_ocp_write(ioaddr, 0xa436, 0x8012); > + rtl_w1w0_phy_ocp(ioaddr, 0xa438, 0x8000, 0x0000); > + > + rtl_w1w0_phy_ocp(ioaddr, 0xc422, 0x4000, 0x2000); > +} Is there any chance for this part to be a bit more literate ? [...] > @@ -4921,6 +5193,28 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp) > ERIAR_EXGMAC); > } > > +static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) > +{ > + void __iomem *ioaddr = tp->mmio_addr; > + struct pci_dev *pdev = tp->pci_dev; > + > + rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC); > + rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC); > + rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC); > + rtl_eri_write(ioaddr, 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(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); > + rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); > + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); > + RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); > + RTL_W8(MaxTxPacketSize, EarlySize); > + rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); > + rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); > + RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); > + rtl_w1w0_eri(ioaddr, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC); > +} (ok, now it can be compared with similar functions) [...] > @@ -6491,6 +6790,47 @@ static unsigned rtl_try_msi(struct rtl8169_private *tp, > return msi; > } > > +static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp) > +{ > + void __iomem *ioaddr = tp->mmio_addr; > + u32 tmp_data; > + > + RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN); > + while (!(RTL_R32(TxConfig) & TXCFG_EMPTY)) > + udelay(100); > + > + while ((RTL_R8(MCU) & (TX_EMPTY | RX_EMPTY)) != (TX_EMPTY | RX_EMPTY)) > + udelay(100); #define RXTX_EMPTY (TX_EMPTY | RX_EMPTY) ? > + > + RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); > + msleep(1); > + RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); > + > + tmp_data = r8168_mac_ocp_read(ioaddr, 0xe8de); > + tmp_data &= ~(1 << 14); > + r8168_mac_ocp_write(ioaddr, 0xe8de, tmp_data); > + while (!(RTL_R8(MCU) & LINK_LIST_RDY)) > + udelay(100); > + > + tmp_data = r8168_mac_ocp_read(ioaddr, 0xe8de); Same 0xe8de offset used twice. #define ? > + tmp_data |= (1 << 15); > + r8168_mac_ocp_write(ioaddr, 0xe8de, tmp_data); > + while (!(RTL_R8(MCU) & LINK_LIST_RDY)) > + udelay(100); > +} > + > +static void __devinit rtl_hw_initialize(struct rtl8169_private *tp) > +{ > + switch (tp->mac_version) { > + case RTL_GIGA_MAC_VER_40: > + case RTL_GIGA_MAC_VER_41: > + rtl_hw_init_8168g(tp); > + break; > + default: > + break; > + } > +} Why doesn't it belong to hw_start ? Is it completely unneeded if the device requires a rtl8169_hw_reset, resumes or such ? Thanks. -- Ueimor ^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH net-next 2/2] r8169: support RTL8168G 2012-06-29 13:51 ` Francois Romieu @ 2012-07-02 7:27 ` hayeswang 0 siblings, 0 replies; 18+ messages in thread From: hayeswang @ 2012-07-02 7:27 UTC (permalink / raw) To: 'Francois Romieu'; +Cc: netdev, linux-kernel [...] > > +static void r8168_phy_ocp_write(void __iomem *ioaddr, u32 > reg, u32 data) > > +{ > > + int i; > > + > > + if (reg & 0xffff0001) > > + BUG(); > > The patch adds a lot of BUG(). BUG is terrible from a system > or end user > viewpoint. > > Were they only a devel helper or are they still supposed to be of use > in the future ? If the latter applies, why ? > I think if the reg is invalid, there must be something wrong. The code should have bug, and I should notice develper or someone using the code. I would replace them with showing messages. [...] > > +static void rtl_ocp_write_fw(struct rtl8169_private *tp, > struct rtl_fw *rtl_fw) > > +{ > > + struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; > > + void __iomem *ioaddr = tp->mmio_addr; > > + u32 predata, count; > > + u32 base_addr; > > + size_t index; > > + > > + predata = count = 0; > > + base_addr = 0xa400; > > + > > + for (index = 0; index < pa->size; ) { > > + u32 action = le32_to_cpu(pa->code[index]); > > + u32 data = action & 0x0000ffff; > > + u32 regno = (action & 0x0fff0000) >> 16; > > + > > + if (!action) > > + break; > > + > > + switch(action & 0xf0000000) { > > + case PHY_READ: > > + predata = r8168_phy_ocp_read(ioaddr, > > + base_addr + (regno -16) * 2); > > + count++; > > + index++; > > + break; > [duplicated code removed] > > + case PHY_WRITE: > > + if (regno == 0x1f) > > + base_addr = data << 4; > > + else > > + r8168_phy_ocp_write(ioaddr, > > + base_addr + > (regno - 0x10) * 2, > > + data); > > + index++; > > + break; > [duplicated code removed] > > + case PHY_WRITE_PREVIOUS: > > + r8168_phy_ocp_write(ioaddr, base_addr + > (regno -16) * 2, > > + predata); > > + index++; > > + break; > > I can't believe that the hardware people have designed something which > needs a different firmware write method, especially as it > copies at lot > of code. > > How did you come to the conclusion that it was not possible > to hide this > stuff behind r8168g_mdio_{read / write} ? > > I would not mind replacing the > PHY_{READ/WRITE/WRITE_PREVIOUS} case with > chipset specific {READ/WRITE/WRITE_PREVIOUS} methods as long as the > semantic looks the same but going through a different > (*write_fw) does not > trivially seem to be the best abstraction. > The difficulty is how to deal with the base_addr. Although it should not happen, the base_addr may be modify if two threads access phy at the same time. I would replace the method by saving the base_addr with a global variable. Then, the r8168g_mdio functions could deal with both of the firmware and phy settings. [...] > > +static void __devinit rtl_hw_initialize(struct rtl8169_private *tp) > > +{ > > + switch (tp->mac_version) { > > + case RTL_GIGA_MAC_VER_40: > > + case RTL_GIGA_MAC_VER_41: > > + rtl_hw_init_8168g(tp); > > + break; > > + default: > > + break; > > + } > > +} > > Why doesn't it belong to hw_start ? > According to the initialization process from our hardware, there are something needed to do before reset. Maybe this considers the rebooting from the other OS or hwardware behavior. I don't sure if it is safe, to let them belong to hw_start. > Is it completely unneeded if the device requires a rtl8169_hw_reset, > resumes or such ? > By the information from our hardware, these are the initial settings and only need be done once. Best Regards, Hayes ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH net-next 1/2] r8169: support RTL8106E 2012-06-29 10:34 [PATCH net-next 1/2] r8169: support RTL8106E Hayes Wang 2012-06-29 10:34 ` [PATCH net-next 2/2] r8169: support RTL8168G Hayes Wang @ 2012-06-29 13:50 ` Francois Romieu 2012-07-02 9:23 ` [PATCH v2 " Hayes Wang 2012-07-09 6:48 ` [PATCH " David Miller 3 siblings, 0 replies; 18+ messages in thread From: Francois Romieu @ 2012-06-29 13:50 UTC (permalink / raw) To: Hayes Wang; +Cc: netdev, linux-kernel Hayes Wang <hayeswang@realtek.com> : [...] > Support the new chip RTL8106E. I'll give it a try this week end. Thanks. -- Ueimor ^ permalink raw reply [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 1/2] r8169: support RTL8106E 2012-06-29 10:34 [PATCH net-next 1/2] r8169: support RTL8106E Hayes Wang 2012-06-29 10:34 ` [PATCH net-next 2/2] r8169: support RTL8168G Hayes Wang 2012-06-29 13:50 ` [PATCH net-next 1/2] r8169: support RTL8106E Francois Romieu @ 2012-07-02 9:23 ` Hayes Wang 2012-07-02 9:23 ` [PATCH v2 net-next 2/2] r8169: support RTL8168G Hayes Wang 2012-07-03 11:01 ` [PATCH v2 net-next 1/2] r8169: support RTL8106E Francois Romieu 2012-07-09 6:48 ` [PATCH " David Miller 3 siblings, 2 replies; 18+ messages in thread From: Hayes Wang @ 2012-07-02 9:23 UTC (permalink / raw) To: romieu; +Cc: netdev, linux-kernel, Hayes Wang Support the new chip RTL8106E. Signed-off-by: Hayes Wang <hayeswang@realtek.com> --- drivers/net/ethernet/realtek/r8169.c | 56 ++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index d7a04e0..7afc593 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -46,6 +46,7 @@ #define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw" #define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw" #define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw" +#define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -141,6 +142,7 @@ enum mac_version { RTL_GIGA_MAC_VER_36, RTL_GIGA_MAC_VER_37, RTL_GIGA_MAC_VER_38, + RTL_GIGA_MAC_VER_39, RTL_GIGA_MAC_NONE = 0xff, }; @@ -259,6 +261,9 @@ static const struct { [RTL_GIGA_MAC_VER_38] = _R("RTL8411", RTL_TD_1, FIRMWARE_8411_1, JUMBO_9K, false), + [RTL_GIGA_MAC_VER_39] = + _R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_1, + JUMBO_1K, true), }; #undef _R @@ -431,7 +436,9 @@ enum rtl8168_registers { RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ MISC = 0xf0, /* 8168e only. */ #define TXPLA_RST (1 << 29) +#define DISABLE_LAN_EN (1 << 23) /* Enable GPIO pin */ #define PWM_EN (1 << 22) +#define EARLY_TALLY_EN (1 << 16) }; enum rtl_register_content { @@ -794,6 +801,7 @@ MODULE_FIRMWARE(FIRMWARE_8168F_1); MODULE_FIRMWARE(FIRMWARE_8168F_2); MODULE_FIRMWARE(FIRMWARE_8402_1); MODULE_FIRMWARE(FIRMWARE_8411_1); +MODULE_FIRMWARE(FIRMWARE_8106E_1); static void rtl_lock_work(struct rtl8169_private *tp) { @@ -1933,6 +1941,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, /* 8101 family. */ + { 0x7cf00000, 0x44900000, RTL_GIGA_MAC_VER_39 }, + { 0x7c800000, 0x44800000, RTL_GIGA_MAC_VER_39 }, { 0x7c800000, 0x44000000, RTL_GIGA_MAC_VER_37 }, { 0x7cf00000, 0x40b00000, RTL_GIGA_MAC_VER_30 }, { 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 }, @@ -3273,6 +3283,30 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0000); } +static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + static const struct phy_reg phy_reg_init[] = { + { 0x1f, 0x0004 }, + { 0x10, 0xc07f }, + { 0x19, 0x7030 }, + { 0x1f, 0x0000 } + }; + + /* Disable ALDPS before ram code */ + rtl_writephy(tp, 0x1f, 0x0000); + rtl_writephy(tp, 0x18, 0x0310); + msleep(100); + + rtl_apply_firmware(tp); + + rtl_eri_write(ioaddr, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + + rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); +} + static void rtl_hw_phy_config(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -3369,6 +3403,10 @@ static void rtl_hw_phy_config(struct net_device *dev) rtl8411_hw_phy_config(tp); break; + case RTL_GIGA_MAC_VER_39: + rtl8106e_hw_phy_config(tp); + break; + default: break; } @@ -3608,6 +3646,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_34: case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_38: + case RTL_GIGA_MAC_VER_39: RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); break; @@ -3830,6 +3869,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_29: case RTL_GIGA_MAC_VER_30: case RTL_GIGA_MAC_VER_37: + case RTL_GIGA_MAC_VER_39: ops->down = r810x_pll_power_down; ops->up = r810x_pll_power_up; break; @@ -5123,6 +5163,18 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp) ERIAR_EXGMAC); } +static void rtl_hw_start_8106(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + + /* Force LAN exit from ASPM if Rx/Tx are not idle */ + RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800); + + RTL_W32(MISC, (RTL_R32(MISC) | DISABLE_LAN_EN) & ~EARLY_TALLY_EN); + RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); + RTL_W8(DLLPR, RTL_R8(DLLPR) & ~PFM_EN); +} + static void rtl_hw_start_8101(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -5167,6 +5219,10 @@ static void rtl_hw_start_8101(struct net_device *dev) case RTL_GIGA_MAC_VER_37: rtl_hw_start_8402(tp); break; + + case RTL_GIGA_MAC_VER_39: + rtl_hw_start_8106(tp); + break; } RTL_W8(Cfg9346, Cfg9346_Lock); -- 1.7.10.2 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* [PATCH v2 net-next 2/2] r8169: support RTL8168G 2012-07-02 9:23 ` [PATCH v2 " Hayes Wang @ 2012-07-02 9:23 ` Hayes Wang 2012-07-04 22:04 ` Francois Romieu 2012-07-03 11:01 ` [PATCH v2 net-next 1/2] r8169: support RTL8106E Francois Romieu 1 sibling, 1 reply; 18+ messages in thread From: Hayes Wang @ 2012-07-02 9:23 UTC (permalink / raw) To: romieu; +Cc: netdev, linux-kernel, Hayes Wang Support the new chip RTL8168G. For RTL8111G, the settings of phy and firmware are replaced with ocp functions. The r8168g_mdio_{write / read} would redirect the relative settings to suitable opc functions. However, a global variable ocp_base is needed to calculate the real address of ocp functions. rtl_writephy(tp, 0x1f, xxxx) means the changing of ocp_base. Signed-off-by: Hayes Wang <hayeswang@realtek.com> --- drivers/net/ethernet/realtek/r8169.c | 308 ++++++++++++++++++++++++++++++++-- 1 file changed, 296 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 7afc593..0cf8626 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -47,6 +47,7 @@ #define FIRMWARE_8402_1 "rtl_nic/rtl8402-1.fw" #define FIRMWARE_8411_1 "rtl_nic/rtl8411-1.fw" #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" +#define FIRMWARE_8168G_1 "rtl_nic/rtl8168g-1.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -143,6 +144,8 @@ enum mac_version { RTL_GIGA_MAC_VER_37, RTL_GIGA_MAC_VER_38, RTL_GIGA_MAC_VER_39, + RTL_GIGA_MAC_VER_40, + RTL_GIGA_MAC_VER_41, RTL_GIGA_MAC_NONE = 0xff, }; @@ -264,6 +267,11 @@ static const struct { [RTL_GIGA_MAC_VER_39] = _R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_1, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_40] = + _R("RTL8168g/8111g", RTL_TD_1, FIRMWARE_8168G_1, + JUMBO_9K, false), + [RTL_GIGA_MAC_VER_41] = + _R("RTL8168g/8111g", RTL_TD_1, NULL, JUMBO_9K, false), }; #undef _R @@ -394,8 +402,12 @@ enum rtl8168_8101_registers { TWSI = 0xd2, MCU = 0xd3, #define NOW_IS_OOB (1 << 7) +#define TX_EMPTY (1 << 5) +#define RX_EMPTY (1 << 4) +#define RXTX_EMPTY (TX_EMPTY | RX_EMPTY) #define EN_NDP (1 << 3) #define EN_OOB_RESET (1 << 2) +#define LINK_LIST_RDY (1 << 1) EFUSEAR = 0xdc, #define EFUSEAR_FLAG 0x80000000 #define EFUSEAR_WRITE_CMD 0x80000000 @@ -421,6 +433,7 @@ enum rtl8168_registers { #define ERIAR_MASK_SHIFT 12 #define ERIAR_MASK_0001 (0x1 << ERIAR_MASK_SHIFT) #define ERIAR_MASK_0011 (0x3 << ERIAR_MASK_SHIFT) +#define ERIAR_MASK_0101 (0x5 << ERIAR_MASK_SHIFT) #define ERIAR_MASK_1111 (0xf << ERIAR_MASK_SHIFT) EPHY_RXER_NUM = 0x7c, OCPDR = 0xb0, /* OCP GPHY access */ @@ -433,11 +446,13 @@ enum rtl8168_registers { #define OCPAR_FLAG 0x80000000 #define OCPAR_GPHY_WRITE_CMD 0x8000f060 #define OCPAR_GPHY_READ_CMD 0x0000f060 + GPHY_OCP = 0xb8, RDSAR1 = 0xd0, /* 8168c only. Undocumented on 8168dp */ MISC = 0xf0, /* 8168e only. */ #define TXPLA_RST (1 << 29) #define DISABLE_LAN_EN (1 << 23) /* Enable GPIO pin */ #define PWM_EN (1 << 22) +#define RXDV_GATED_EN (1 << 19) #define EARLY_TALLY_EN (1 << 16) }; @@ -728,8 +743,8 @@ struct rtl8169_private { u16 event_slow; struct mdio_ops { - void (*write)(void __iomem *, int, int); - int (*read)(void __iomem *, int); + void (*write)(struct rtl8169_private *, int, int); + int (*read)(struct rtl8169_private *, int); } mdio_ops; struct pll_power_ops { @@ -781,6 +796,8 @@ struct rtl8169_private { } phy_action; } *rtl_fw; #define RTL_FIRMWARE_UNKNOWN ERR_PTR(-EAGAIN) + + u32 ocp_base; }; MODULE_AUTHOR("Realtek and the Linux r8169 crew <netdev@vger.kernel.org>"); @@ -802,6 +819,7 @@ MODULE_FIRMWARE(FIRMWARE_8168F_2); MODULE_FIRMWARE(FIRMWARE_8402_1); MODULE_FIRMWARE(FIRMWARE_8411_1); MODULE_FIRMWARE(FIRMWARE_8106E_1); +MODULE_FIRMWARE(FIRMWARE_8168G_1); static void rtl_lock_work(struct rtl8169_private *tp) { @@ -919,9 +937,125 @@ static int r8168dp_check_dash(struct rtl8169_private *tp) return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0; } -static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value) +static void r8168_phy_ocp_write(void __iomem *ioaddr, u32 reg, u32 data) +{ + int i; + + if (reg & 0xffff0001) { + printk(KERN_ERR "Invalid ocp reg %x!\n", reg); + return; + } + + RTL_W32(GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); + + for (i = 0; i < 10; i++) { + udelay(25); + if (!(RTL_R32(GPHY_OCP) & OCPAR_FLAG)) + break; + } +} + +static u16 r8168_phy_ocp_read(void __iomem *ioaddr, u32 reg) +{ + int i; + u32 data; + + if (reg & 0xffff0001) { + printk(KERN_ERR "Invalid ocp reg %x!\n", reg); + return 0; + } + + RTL_W32(GPHY_OCP, reg << 15); + + for (i = 0; i < 10; i++) { + udelay(25); + data = RTL_R32(GPHY_OCP); + if (data & OCPAR_FLAG) + break; + } + + return (u16)(data & 0xffff); +} + +static void rtl_w1w0_phy_ocp(void __iomem *ioaddr, int reg_addr, int p, int m) +{ + int val; + + val = r8168_phy_ocp_read(ioaddr, reg_addr); + r8168_phy_ocp_write(ioaddr, reg_addr, (val | p) & ~m); +} + +static void r8168_mac_ocp_write(void __iomem *ioaddr, u32 reg, u32 data) +{ + int i; + + if (reg & 0xffff0001) + BUG(); + + RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data); + + for (i = 0; i < 10; i++) { + udelay(25); + if (!(RTL_R32(OCPDR) & OCPAR_FLAG)) + break; + } +} + +static u16 r8168_mac_ocp_read(void __iomem *ioaddr, u32 reg) +{ + int i; + u32 data; + + if (reg & 0xffff0001) + BUG(); + + RTL_W32(OCPDR, (reg << 15)); + + for (i = 0; i < 10; i++) { + udelay(25); + data = RTL_R32(OCPDR); + if (data & OCPAR_FLAG) + break; + } + + return (u16)(data & 0xffff); +} + +#define OCP_STD_PHY_BASE 0xa400 + +static +void r8168g_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) +{ + void __iomem *ioaddr = tp->mmio_addr; + + if (reg_addr == 0x1f) { + if (reg_addr == 0) + tp->ocp_base = OCP_STD_PHY_BASE; + else + tp->ocp_base = value << 4; + + return; + } else if (tp->ocp_base != OCP_STD_PHY_BASE) + reg_addr -= 0x10; + + r8168_phy_ocp_write(ioaddr, tp->ocp_base + reg_addr * 2, value); +} + +static int r8168g_mdio_read(struct rtl8169_private *tp, int reg_addr) +{ + void __iomem *ioaddr = tp->mmio_addr; + + if (tp->ocp_base != OCP_STD_PHY_BASE) + reg_addr -= 0x10; + + return r8168_phy_ocp_read(ioaddr, tp->ocp_base + reg_addr * 2); +} + +static +void r8169_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) { int i; + void __iomem *ioaddr = tp->mmio_addr; RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff)); @@ -941,9 +1075,10 @@ static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value) udelay(20); } -static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr) +static int r8169_mdio_read(struct rtl8169_private *tp, int reg_addr) { int i, value = -1; + void __iomem *ioaddr = tp->mmio_addr; RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16); @@ -983,15 +1118,19 @@ static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data) } } -static void r8168dp_1_mdio_write(void __iomem *ioaddr, int reg_addr, int value) +static +void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) { + void __iomem *ioaddr = tp->mmio_addr; + r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_WRITE_CMD | (value & OCPDR_DATA_MASK)); } -static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr) +static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr) { int i; + void __iomem *ioaddr = tp->mmio_addr; r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD); @@ -1020,22 +1159,26 @@ static void r8168dp_2_mdio_stop(void __iomem *ioaddr) RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT); } -static void r8168dp_2_mdio_write(void __iomem *ioaddr, int reg_addr, int value) +static +void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) { + void __iomem *ioaddr = tp->mmio_addr; + r8168dp_2_mdio_start(ioaddr); - r8169_mdio_write(ioaddr, reg_addr, value); + r8169_mdio_write(tp, reg_addr, value); r8168dp_2_mdio_stop(ioaddr); } -static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr) +static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg_addr) { int value; + void __iomem *ioaddr = tp->mmio_addr; r8168dp_2_mdio_start(ioaddr); - value = r8169_mdio_read(ioaddr, reg_addr); + value = r8169_mdio_read(tp, reg_addr); r8168dp_2_mdio_stop(ioaddr); @@ -1044,12 +1187,12 @@ static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr) static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val) { - tp->mdio_ops.write(tp->mmio_addr, location, val); + tp->mdio_ops.write(tp, location, val); } static int rtl_readphy(struct rtl8169_private *tp, int location) { - return tp->mdio_ops.read(tp->mmio_addr, location); + return tp->mdio_ops.read(tp, location); } static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value) @@ -1902,6 +2045,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, u32 val; int mac_version; } mac_info[] = { + /* 8168G family. */ + { 0x7cf00000, 0x4c100000, RTL_GIGA_MAC_VER_41 }, + { 0x7cf00000, 0x4c000000, RTL_GIGA_MAC_VER_40 }, + /* 8168F family. */ { 0x7c800000, 0x48800000, RTL_GIGA_MAC_VER_38 }, { 0x7cf00000, 0x48100000, RTL_GIGA_MAC_VER_36 }, @@ -3221,6 +3368,53 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0000); } +static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + u32 i; + static const u16 mac_ocp_patch[] = { + 0xe008, 0xe01b, 0xe01d, 0xe01f, + 0xe021, 0xe023, 0xe025, 0xe027, + 0x49d2 ,0xf10d, 0x766c, 0x49e2, + 0xf00a, 0x1ec0, 0x8ee1, 0xc60a, + 0x77c0, 0x4870, 0x9fc0, 0x1ea0, + 0xc707, 0x8ee1, 0x9d6c, 0xc603, + 0xbe00, 0xb416, 0x0076, 0xe86c, + 0xc602, 0xbe00, 0x0000, 0xc602, + 0xbe00, 0x0000, 0xc602, 0xbe00, + 0x0000, 0xc602, 0xbe00, 0x0000, + 0xc602, 0xbe00, 0x0000, 0xc602, + 0xbe00, 0x0000, 0xc602, 0xbe00, + 0x0000, 0x0000, 0x0000, 0x0000 + }; + + /* patch code for GPHY reset */ + for (i = 0; ARRAY_SIZE(mac_ocp_patch); i++) + r8168_mac_ocp_write(ioaddr, 0xf800 + 2*i, mac_ocp_patch[i]); + r8168_mac_ocp_write(ioaddr, 0xfc26, 0x8000); + r8168_mac_ocp_write(ioaddr, 0xfc28, 0x0075); + + rtl_apply_firmware(tp); + + if (r8168_phy_ocp_read(ioaddr, 0xa460) & 0x0100) + rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x0000, 0x8000); + else + rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x8000, 0x0000); + + if (r8168_phy_ocp_read(ioaddr, 0xa466) & 0x0100) + rtl_w1w0_phy_ocp(ioaddr, 0xc41a, 0x0002, 0x0000); + else + rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x0000, 0x0002); + + rtl_w1w0_phy_ocp(ioaddr, 0xa442, 0x000c, 0x0000); + rtl_w1w0_phy_ocp(ioaddr, 0xa4b2, 0x0004, 0x0000); + + r8168_phy_ocp_write(ioaddr, 0xa436, 0x8012); + rtl_w1w0_phy_ocp(ioaddr, 0xa438, 0x8000, 0x0000); + + rtl_w1w0_phy_ocp(ioaddr, 0xc422, 0x4000, 0x2000); +} + static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -3407,6 +3601,13 @@ static void rtl_hw_phy_config(struct net_device *dev) rtl8106e_hw_phy_config(tp); break; + case RTL_GIGA_MAC_VER_40: + rtl8168g_1_hw_phy_config(tp); + break; + + case RTL_GIGA_MAC_VER_41: + break; + default: break; } @@ -3627,6 +3828,11 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp) ops->write = r8168dp_2_mdio_write; ops->read = r8168dp_2_mdio_read; break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + ops->write = r8168g_mdio_write; + ops->read = r8168g_mdio_read; + break; default: ops->write = r8169_mdio_write; ops->read = r8169_mdio_read; @@ -3647,6 +3853,8 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_38: case RTL_GIGA_MAC_VER_39: + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); break; @@ -3895,6 +4103,8 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_35: case RTL_GIGA_MAC_VER_36: case RTL_GIGA_MAC_VER_38: + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: ops->down = r8168_pll_power_down; ops->up = r8168_pll_power_up; break; @@ -4091,6 +4301,8 @@ static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp) * No action needed for jumbo frames with 8169. * No jumbo for 810x at all. */ + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: default: ops->disable = NULL; ops->enable = NULL; @@ -4183,6 +4395,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) tp->mac_version == RTL_GIGA_MAC_VER_35 || tp->mac_version == RTL_GIGA_MAC_VER_36 || tp->mac_version == RTL_GIGA_MAC_VER_37 || + tp->mac_version == RTL_GIGA_MAC_VER_40 || + tp->mac_version == RTL_GIGA_MAC_VER_41 || tp->mac_version == RTL_GIGA_MAC_VER_38) { RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); while (!(RTL_R32(TxConfig) & TXCFG_EMPTY)) @@ -4921,6 +5135,28 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp) ERIAR_EXGMAC); } +static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + struct pci_dev *pdev = tp->pci_dev; + + rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 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(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); + rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); + RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); + RTL_W8(MaxTxPacketSize, EarlySize); + rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); + rtl_w1w0_eri(ioaddr, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC); +} + static void rtl_hw_start_8168(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -5022,6 +5258,11 @@ static void rtl_hw_start_8168(struct net_device *dev) rtl_hw_start_8411(tp); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + rtl_hw_start_8168g_1(tp); + break; + default: printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n", dev->name, tp->mac_version); @@ -6491,6 +6732,47 @@ static unsigned rtl_try_msi(struct rtl8169_private *tp, return msi; } +static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp) +{ + void __iomem *ioaddr = tp->mmio_addr; + u32 tmp_data; + + RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN); + while (!(RTL_R32(TxConfig) & TXCFG_EMPTY)) + udelay(100); + + while ((RTL_R8(MCU) & RXTX_EMPTY) != RXTX_EMPTY) + udelay(100); + + RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); + msleep(1); + RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); + + tmp_data = r8168_mac_ocp_read(ioaddr, 0xe8de); + tmp_data &= ~(1 << 14); + r8168_mac_ocp_write(ioaddr, 0xe8de, tmp_data); + while (!(RTL_R8(MCU) & LINK_LIST_RDY)) + udelay(100); + + tmp_data = r8168_mac_ocp_read(ioaddr, 0xe8de); + tmp_data |= (1 << 15); + r8168_mac_ocp_write(ioaddr, 0xe8de, tmp_data); + while (!(RTL_R8(MCU) & LINK_LIST_RDY)) + udelay(100); +} + +static void __devinit rtl_hw_initialize(struct rtl8169_private *tp) +{ + switch (tp->mac_version) { + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + rtl_hw_init_8168g(tp); + break; + default: + break; + } +} + static int __devinit rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -6600,6 +6882,8 @@ rtl_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) rtl_irq_disable(tp); + rtl_hw_initialize(tp); + rtl_hw_reset(tp); rtl_ack_events(tp, 0xffff); -- 1.7.10.2 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net-next 2/2] r8169: support RTL8168G 2012-07-02 9:23 ` [PATCH v2 net-next 2/2] r8169: support RTL8168G Hayes Wang @ 2012-07-04 22:04 ` Francois Romieu 2012-07-05 0:51 ` Joe Perches 2012-07-06 7:57 ` hayeswang 0 siblings, 2 replies; 18+ messages in thread From: Francois Romieu @ 2012-07-04 22:04 UTC (permalink / raw) To: Hayes Wang; +Cc: netdev, linux-kernel Hayes Wang <hayeswang@realtek.com> : > Support the new chip RTL8168G. [...] Any objection against merging it with the patch below ? - more BUG() avoidance - save Joe P. some work - remove useless parenthesis - fix r8168g_mdio_write (if (reg_addr == 0x1f) { if (reg_addr == 0) snafu) -> Please check this one. - long declarations before short ones - avoid unbounded loops - use a descriptive name for the 0xe8de value in rtl_hw_init_8168g. -> Please suggest something better than "PLOP" diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 0cf8626..c37aed9 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -937,14 +937,22 @@ static int r8168dp_check_dash(struct rtl8169_private *tp) return (ocp_read(tp, 0x0f, reg) & 0x00008000) ? 1 : 0; } -static void r8168_phy_ocp_write(void __iomem *ioaddr, u32 reg, u32 data) +static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg) { + if (reg & 0xffff0001) { + netif_err(tp, drv, tp->dev, "Invalid ocp reg %x!\n", reg); + return true; + } + return false; +} + +static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) +{ + void __iomem *ioaddr = tp->mmio_addr; int i; - if (reg & 0xffff0001) { - printk(KERN_ERR "Invalid ocp reg %x!\n", reg); + if (rtl_ocp_reg_failure(tp, reg)) return; - } RTL_W32(GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); @@ -955,15 +963,14 @@ static void r8168_phy_ocp_write(void __iomem *ioaddr, u32 reg, u32 data) } } -static u16 r8168_phy_ocp_read(void __iomem *ioaddr, u32 reg) +static u16 r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) { - int i; + void __iomem *ioaddr = tp->mmio_addr; u32 data; + int i; - if (reg & 0xffff0001) { - printk(KERN_ERR "Invalid ocp reg %x!\n", reg); + if (rtl_ocp_reg_failure(tp, reg)) return 0; - } RTL_W32(GPHY_OCP, reg << 15); @@ -977,20 +984,21 @@ static u16 r8168_phy_ocp_read(void __iomem *ioaddr, u32 reg) return (u16)(data & 0xffff); } -static void rtl_w1w0_phy_ocp(void __iomem *ioaddr, int reg_addr, int p, int m) +static void rtl_w1w0_phy_ocp(struct rtl8169_private *tp, int reg, int p, int m) { int val; - val = r8168_phy_ocp_read(ioaddr, reg_addr); - r8168_phy_ocp_write(ioaddr, reg_addr, (val | p) & ~m); + val = r8168_phy_ocp_read(tp, reg); + r8168_phy_ocp_write(tp, reg, (val | p) & ~m); } -static void r8168_mac_ocp_write(void __iomem *ioaddr, u32 reg, u32 data) +static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) { + void __iomem *ioaddr = tp->mmio_addr; int i; - if (reg & 0xffff0001) - BUG(); + if (rtl_ocp_reg_failure(tp, reg)) + return; RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data); @@ -1001,15 +1009,16 @@ static void r8168_mac_ocp_write(void __iomem *ioaddr, u32 reg, u32 data) } } -static u16 r8168_mac_ocp_read(void __iomem *ioaddr, u32 reg) +static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) { - int i; + void __iomem *ioaddr = tp->mmio_addr; u32 data; + int i; - if (reg & 0xffff0001) - BUG(); + if (rtl_ocp_reg_failure(tp, reg)) + return 0; - RTL_W32(OCPDR, (reg << 15)); + RTL_W32(OCPDR, reg << 15); for (i = 0; i < 10; i++) { udelay(25); @@ -1023,39 +1032,32 @@ static u16 r8168_mac_ocp_read(void __iomem *ioaddr, u32 reg) #define OCP_STD_PHY_BASE 0xa400 -static -void r8168g_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) +static void r8168g_mdio_write(struct rtl8169_private *tp, int reg, int value) { - void __iomem *ioaddr = tp->mmio_addr; - - if (reg_addr == 0x1f) { - if (reg_addr == 0) - tp->ocp_base = OCP_STD_PHY_BASE; - else - tp->ocp_base = value << 4; - + if (reg == 0x1f) { + tp->ocp_base = value ? value << 4 : OCP_STD_PHY_BASE; return; - } else if (tp->ocp_base != OCP_STD_PHY_BASE) - reg_addr -= 0x10; + } + + if (tp->ocp_base != OCP_STD_PHY_BASE) + reg -= 0x10; - r8168_phy_ocp_write(ioaddr, tp->ocp_base + reg_addr * 2, value); + r8168_phy_ocp_write(tp, tp->ocp_base + reg * 2, value); } static int r8168g_mdio_read(struct rtl8169_private *tp, int reg_addr) { - void __iomem *ioaddr = tp->mmio_addr; - if (tp->ocp_base != OCP_STD_PHY_BASE) reg_addr -= 0x10; - return r8168_phy_ocp_read(ioaddr, tp->ocp_base + reg_addr * 2); + return r8168_phy_ocp_read(tp, tp->ocp_base + reg_addr * 2); } static void r8169_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) { - int i; void __iomem *ioaddr = tp->mmio_addr; + int i; RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff)); @@ -1077,8 +1079,8 @@ void r8169_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) static int r8169_mdio_read(struct rtl8169_private *tp, int reg_addr) { - int i, value = -1; void __iomem *ioaddr = tp->mmio_addr; + int i, value = -1; RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16); @@ -1129,8 +1131,8 @@ void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr) { - int i; void __iomem *ioaddr = tp->mmio_addr; + int i; r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD); @@ -1159,26 +1161,25 @@ static void r8168dp_2_mdio_stop(void __iomem *ioaddr) RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT); } -static -void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) +static void r8168dp_2_mdio_write(struct rtl8169_private *tp, int reg, int value) { void __iomem *ioaddr = tp->mmio_addr; r8168dp_2_mdio_start(ioaddr); - r8169_mdio_write(tp, reg_addr, value); + r8169_mdio_write(tp, reg, value); r8168dp_2_mdio_stop(ioaddr); } -static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg_addr) +static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg) { - int value; void __iomem *ioaddr = tp->mmio_addr; + int value; r8168dp_2_mdio_start(ioaddr); - value = r8169_mdio_read(tp, reg_addr); + value = r8169_mdio_read(tp, reg); r8168dp_2_mdio_stop(ioaddr); @@ -3370,49 +3371,51 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) { - void __iomem *ioaddr = tp->mmio_addr; u32 i; static const u16 mac_ocp_patch[] = { 0xe008, 0xe01b, 0xe01d, 0xe01f, 0xe021, 0xe023, 0xe025, 0xe027, 0x49d2 ,0xf10d, 0x766c, 0x49e2, 0xf00a, 0x1ec0, 0x8ee1, 0xc60a, + 0x77c0, 0x4870, 0x9fc0, 0x1ea0, 0xc707, 0x8ee1, 0x9d6c, 0xc603, 0xbe00, 0xb416, 0x0076, 0xe86c, 0xc602, 0xbe00, 0x0000, 0xc602, + 0xbe00, 0x0000, 0xc602, 0xbe00, 0x0000, 0xc602, 0xbe00, 0x0000, 0xc602, 0xbe00, 0x0000, 0xc602, 0xbe00, 0x0000, 0xc602, 0xbe00, + 0x0000, 0x0000, 0x0000, 0x0000 }; /* patch code for GPHY reset */ for (i = 0; ARRAY_SIZE(mac_ocp_patch); i++) - r8168_mac_ocp_write(ioaddr, 0xf800 + 2*i, mac_ocp_patch[i]); - r8168_mac_ocp_write(ioaddr, 0xfc26, 0x8000); - r8168_mac_ocp_write(ioaddr, 0xfc28, 0x0075); + r8168_mac_ocp_write(tp, 0xf800 + 2*i, mac_ocp_patch[i]); + r8168_mac_ocp_write(tp, 0xfc26, 0x8000); + r8168_mac_ocp_write(tp, 0xfc28, 0x0075); rtl_apply_firmware(tp); - if (r8168_phy_ocp_read(ioaddr, 0xa460) & 0x0100) - rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x0000, 0x8000); + if (r8168_phy_ocp_read(tp, 0xa460) & 0x0100) + rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x0000, 0x8000); else - rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x8000, 0x0000); + rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x8000, 0x0000); - if (r8168_phy_ocp_read(ioaddr, 0xa466) & 0x0100) - rtl_w1w0_phy_ocp(ioaddr, 0xc41a, 0x0002, 0x0000); + if (r8168_phy_ocp_read(tp, 0xa466) & 0x0100) + rtl_w1w0_phy_ocp(tp, 0xc41a, 0x0002, 0x0000); else - rtl_w1w0_phy_ocp(ioaddr, 0xbcc4, 0x0000, 0x0002); + rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x0000, 0x0002); - rtl_w1w0_phy_ocp(ioaddr, 0xa442, 0x000c, 0x0000); - rtl_w1w0_phy_ocp(ioaddr, 0xa4b2, 0x0004, 0x0000); + rtl_w1w0_phy_ocp(tp, 0xa442, 0x000c, 0x0000); + rtl_w1w0_phy_ocp(tp, 0xa4b2, 0x0004, 0x0000); - r8168_phy_ocp_write(ioaddr, 0xa436, 0x8012); - rtl_w1w0_phy_ocp(ioaddr, 0xa438, 0x8000, 0x0000); + r8168_phy_ocp_write(tp, 0xa436, 0x8012); + rtl_w1w0_phy_ocp(tp, 0xa438, 0x8000, 0x0000); - rtl_w1w0_phy_ocp(ioaddr, 0xc422, 0x4000, 0x2000); + rtl_w1w0_phy_ocp(tp, 0xc422, 0x4000, 0x2000); } static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) @@ -5144,16 +5147,24 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC); rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC); rtl_eri_write(ioaddr, 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(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); RTL_W8(MaxTxPacketSize, EarlySize); + rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + + /* Adjust EEE LED frequency */ RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); + rtl_w1w0_eri(ioaddr, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC); } @@ -6732,33 +6743,56 @@ static unsigned rtl_try_msi(struct rtl8169_private *tp, return msi; } +#define RTL_LOOP_MAX 10000 + +static void rtl_mcu_wait_list_ready(void __iomem *ioaddr) +{ + int i; + + for (i = 0; i < RTL_LOOP_MAX; i++) { + if (RTL_R8(MCU) & LINK_LIST_RDY) + return; + udelay(100); + } +} + +#define PLOP 0xe8de + static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - u32 tmp_data; + u32 data; + int i; RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN); - while (!(RTL_R32(TxConfig) & TXCFG_EMPTY)) + + for (i = 0; i < RTL_LOOP_MAX; i++) { + if (RTL_R32(TxConfig) & TXCFG_EMPTY) + break; udelay(100); + } - while ((RTL_R8(MCU) & RXTX_EMPTY) != RXTX_EMPTY) + for (i = 0; i < RTL_LOOP_MAX; i++) { + if ((RTL_R8(MCU) & RXTX_EMPTY) == RXTX_EMPTY) + break; udelay(100); + } RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); msleep(1); RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); - tmp_data = r8168_mac_ocp_read(ioaddr, 0xe8de); - tmp_data &= ~(1 << 14); - r8168_mac_ocp_write(ioaddr, 0xe8de, tmp_data); - while (!(RTL_R8(MCU) & LINK_LIST_RDY)) - udelay(100); + data = r8168_mac_ocp_read(ioaddr, PLOP); + data &= ~(1 << 14); + r8168_mac_ocp_write(ioaddr, PLOP, data); - tmp_data = r8168_mac_ocp_read(ioaddr, 0xe8de); - tmp_data |= (1 << 15); - r8168_mac_ocp_write(ioaddr, 0xe8de, tmp_data); - while (!(RTL_R8(MCU) & LINK_LIST_RDY)) - udelay(100); + rtl_mcu_wait_list_ready(ioaddr); + + data = r8168_mac_ocp_read(ioaddr, PLOP); + data |= (1 << 15); + r8168_mac_ocp_write(ioaddr, PLOP, data); + + rtl_mcu_wait_list_ready(ioaddr); } static void __devinit rtl_hw_initialize(struct rtl8169_private *tp) ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net-next 2/2] r8169: support RTL8168G 2012-07-04 22:04 ` Francois Romieu @ 2012-07-05 0:51 ` Joe Perches 2012-07-06 15:20 ` Francois Romieu 2012-07-06 7:57 ` hayeswang 1 sibling, 1 reply; 18+ messages in thread From: Joe Perches @ 2012-07-05 0:51 UTC (permalink / raw) To: Francois Romieu; +Cc: Hayes Wang, netdev, linux-kernel On Thu, 2012-07-05 at 00:04 +0200, Francois Romieu wrote: > Hayes Wang <hayeswang@realtek.com> : > > Support the new chip RTL8168G. > - save Joe P. some work Thanks. Just a trivial thing below: [] > diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c [] > +#define RTL_LOOP_MAX 10000 > + > +static void rtl_mcu_wait_list_ready(void __iomem *ioaddr) > +{ > + int i; > + > + for (i = 0; i < RTL_LOOP_MAX; i++) { > + if (RTL_R8(MCU) & LINK_LIST_RDY) > + return; > + udelay(100); > + } > +} This pattern is used a couple more times. There's no failure handling either. Maybe use a macro with RTL_R8/32, register and test? Maybe the delays could be tuned out a bit better. Maybe a continuous read or a less frequent read might be better. > static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp) > { [] > + for (i = 0; i < RTL_LOOP_MAX; i++) { > + if (RTL_R32(TxConfig) & TXCFG_EMPTY) > + break; > udelay(100); > + } pattern > + for (i = 0; i < RTL_LOOP_MAX; i++) { > + if ((RTL_R8(MCU) & RXTX_EMPTY) == RXTX_EMPTY) > + break; > udelay(100); > + } pattern ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net-next 2/2] r8169: support RTL8168G 2012-07-05 0:51 ` Joe Perches @ 2012-07-06 15:20 ` Francois Romieu 2012-07-06 15:37 ` Joe Perches 0 siblings, 1 reply; 18+ messages in thread From: Francois Romieu @ 2012-07-06 15:20 UTC (permalink / raw) To: Joe Perches; +Cc: Hayes Wang, netdev, linux-kernel [-- Attachment #1: Type: text/plain, Size: 22030 bytes --] Joe Perches <joe@perches.com> : [...] > This pattern is used a couple more times. > There's no failure handling either. I can do something for the initialize path. Other than that it's mostly deeply burried hardware failure so I'd rather concentrate a bit on current problem reports. This series already took me a bit further than expected (see below). > Maybe use a macro with RTL_R8/32, register and test? Here is what I came up with. Completely untested. Attached patches #1 and #2 should be applied on top of the previous patch beforehand. [PATCH 3/3] r8169: abstract out loop conditions. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> --- drivers/net/ethernet/realtek/r8169.c | 460 +++++++++++++++++----------------- 1 file changed, 225 insertions(+), 235 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 0759c76..4f350fc 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -844,47 +844,113 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force) } } +struct rtl_cond { + bool (*check)(struct rtl8169_private *); + const char *msg; +}; + +static void rtl_udelay(unsigned int d) +{ + udelay(d); +} + +static bool rtl_loop_wait(struct rtl8169_private *tp, const struct rtl_cond *c, + void (*delay)(unsigned int), unsigned int d, int n, + bool high) +{ + int i; + + for (i = 0; i < n; i++) { + delay(d); + if (c->check(tp) == high) + return true; + } + netif_err(tp, drv, tp->dev, c->msg); + return false; +} + +static bool rtl_udelay_loop_wait_high(struct rtl8169_private *tp, + const struct rtl_cond *c, + unsigned int d, int n) +{ + return rtl_loop_wait(tp, c, rtl_udelay, d, n, true); +} + +static bool rtl_udelay_loop_wait_low(struct rtl8169_private *tp, + const struct rtl_cond *c, + unsigned int d, int n) +{ + return rtl_loop_wait(tp, c, rtl_udelay, d, n, false); +} + +static bool rtl_msleep_loop_wait_high(struct rtl8169_private *tp, + const struct rtl_cond *c, + unsigned int d, int n) +{ + return rtl_loop_wait(tp, c, msleep, d, n, true); +} + +static bool rtl_msleep_loop_wait_low(struct rtl8169_private *tp, + const struct rtl_cond *c, + unsigned int d, int n) +{ + return rtl_loop_wait(tp, c, msleep, d, n, false); +} + +#define DECLARE_RTL_COND(name) \ +static bool name ## _check(struct rtl8169_private *); \ + \ +static const struct rtl_cond name = { \ + .check = name ## _check, \ + .msg = #name \ +}; \ + \ +static bool name ## _check(struct rtl8169_private *tp) + +DECLARE_RTL_COND(rtl_ocpar_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R32(OCPAR) & OCPAR_FLAG; +} + static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg) { void __iomem *ioaddr = tp->mmio_addr; - int i; RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff)); - for (i = 0; i < 20; i++) { - udelay(100); - if (RTL_R32(OCPAR) & OCPAR_FLAG) - break; - } - return RTL_R32(OCPDR); + + return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 100, 20) ? + RTL_R32(OCPDR) : ~0; } static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data) { void __iomem *ioaddr = tp->mmio_addr; - int i; RTL_W32(OCPDR, data); RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff)); - for (i = 0; i < 20; i++) { - udelay(100); - if ((RTL_R32(OCPAR) & OCPAR_FLAG) == 0) - break; - } + + rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 100, 20); +} + +DECLARE_RTL_COND(rtl_eriar_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R32(ERIAR) & ERIAR_FLAG; } static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd) { void __iomem *ioaddr = tp->mmio_addr; - int i; RTL_W8(ERIDR, cmd); RTL_W32(ERIAR, 0x800010e8); msleep(2); - for (i = 0; i < 5; i++) { - udelay(100); - if (!(RTL_R32(ERIAR) & ERIAR_FLAG)) - break; - } + + if (!rtl_udelay_loop_wait_low(tp, &rtl_eriar_cond, 100, 5)) + return; ocp_write(tp, 0x1, 0x30, 0x00000001); } @@ -898,36 +964,27 @@ static u16 rtl8168_get_ocp_reg(struct rtl8169_private *tp) return (tp->mac_version == RTL_GIGA_MAC_VER_31) ? 0xb8 : 0x10; } -static void rtl8168_driver_start(struct rtl8169_private *tp) +DECLARE_RTL_COND(rtl_ocp_read_cond) { u16 reg; - int i; - - rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START); reg = rtl8168_get_ocp_reg(tp); - for (i = 0; i < 10; i++) { - msleep(10); - if (ocp_read(tp, 0x0f, reg) & 0x00000800) - break; - } + return ocp_read(tp, 0x0f, reg) & 0x00000800; } -static void rtl8168_driver_stop(struct rtl8169_private *tp) +static void rtl8168_driver_start(struct rtl8169_private *tp) { - u16 reg; - int i; + rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START); - rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP); + rtl_msleep_loop_wait_high(tp, &rtl_ocp_read_cond, 10, 10); +} - reg = rtl8168_get_ocp_reg(tp); +static void rtl8168_driver_stop(struct rtl8169_private *tp) +{ + rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP); - for (i = 0; i < 10; i++) { - msleep(10); - if ((ocp_read(tp, 0x0f, reg) & 0x00000800) == 0) - break; - } + rtl_msleep_loop_wait_low(tp, &rtl_ocp_read_cond, 10, 10); } static int r8168dp_check_dash(struct rtl8169_private *tp) @@ -946,42 +1003,36 @@ static bool rtl_ocp_reg_failure(struct rtl8169_private *tp, u32 reg) return false; } +DECLARE_RTL_COND(rtl_ocp_gphy_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R32(GPHY_OCP) & OCPAR_FLAG; +} + static void r8168_phy_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) { void __iomem *ioaddr = tp->mmio_addr; - int i; if (rtl_ocp_reg_failure(tp, reg)) return; RTL_W32(GPHY_OCP, OCPAR_FLAG | (reg << 15) | data); - for (i = 0; i < 10; i++) { - udelay(25); - if (!(RTL_R32(GPHY_OCP) & OCPAR_FLAG)) - break; - } + rtl_udelay_loop_wait_low(tp, &rtl_ocp_gphy_cond, 25, 10); } static u16 r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) { void __iomem *ioaddr = tp->mmio_addr; - u32 data; - int i; if (rtl_ocp_reg_failure(tp, reg)) return 0; RTL_W32(GPHY_OCP, reg << 15); - for (i = 0; i < 10; i++) { - udelay(25); - data = RTL_R32(GPHY_OCP); - if (data & OCPAR_FLAG) - break; - } - - return (u16)(data & 0xffff); + return rtl_udelay_loop_wait_high(tp, &rtl_ocp_gphy_cond, 25, 10) ? + (RTL_R32(GPHY_OCP) & 0xffff) : ~0; } static void rtl_w1w0_phy_ocp(struct rtl8169_private *tp, int reg, int p, int m) @@ -992,42 +1043,36 @@ static void rtl_w1w0_phy_ocp(struct rtl8169_private *tp, int reg, int p, int m) r8168_phy_ocp_write(tp, reg, (val | p) & ~m); } +DECLARE_RTL_COND(rtl_ocpdr_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R32(OCPDR) & OCPAR_FLAG; +} + static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) { void __iomem *ioaddr = tp->mmio_addr; - int i; if (rtl_ocp_reg_failure(tp, reg)) return; RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data); - for (i = 0; i < 10; i++) { - udelay(25); - if (!(RTL_R32(OCPDR) & OCPAR_FLAG)) - break; - } + rtl_udelay_loop_wait_low(tp, &rtl_ocpdr_cond, 25, 10); } static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) { void __iomem *ioaddr = tp->mmio_addr; - u32 data; - int i; if (rtl_ocp_reg_failure(tp, reg)) return 0; RTL_W32(OCPDR, reg << 15); - for (i = 0; i < 10; i++) { - udelay(25); - data = RTL_R32(OCPDR); - if (data & OCPAR_FLAG) - break; - } - - return (u16)(data & 0xffff); + return rtl_udelay_loop_wait_high(tp, &rtl_ocpdr_cond, 25, 10) ? + RTL_R32(OCPDR) : ~0; } #define OCP_STD_PHY_BASE 0xa400 @@ -1053,23 +1098,22 @@ static int r8168g_mdio_read(struct rtl8169_private *tp, int reg_addr) return r8168_phy_ocp_read(tp, tp->ocp_base + reg_addr * 2); } +DECLARE_RTL_COND(rtl_phyar_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R32(PHYAR) & 0x80000000; +} + static void r8169_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) { void __iomem *ioaddr = tp->mmio_addr; - int i; RTL_W32(PHYAR, 0x80000000 | (reg_addr & 0x1f) << 16 | (value & 0xffff)); - for (i = 20; i > 0; i--) { - /* - * Check if the RTL8169 has completed writing to the specified - * MII register. - */ - if (!(RTL_R32(PHYAR) & 0x80000000)) - break; - udelay(25); - } + rtl_udelay_loop_wait_low(tp, &rtl_phyar_cond, 25, 20); + /* * According to hardware specs a 20us delay is required after write * complete indication, but before sending next command. @@ -1080,21 +1124,13 @@ void r8169_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) static int r8169_mdio_read(struct rtl8169_private *tp, int reg_addr) { void __iomem *ioaddr = tp->mmio_addr; - int i, value = -1; + int value; RTL_W32(PHYAR, 0x0 | (reg_addr & 0x1f) << 16); - for (i = 20; i > 0; i--) { - /* - * Check if the RTL8169 has completed retrieving data from - * the specified MII register. - */ - if (RTL_R32(PHYAR) & 0x80000000) { - value = RTL_R32(PHYAR) & 0xffff; - break; - } - udelay(25); - } + value = rtl_udelay_loop_wait_high(tp, &rtl_phyar_cond, 25, 20) ? + RTL_R32(PHYAR) & 0xffff : ~0; + /* * According to hardware specs a 20us delay is required after read * complete indication, but before sending next command. @@ -1107,17 +1143,12 @@ static int r8169_mdio_read(struct rtl8169_private *tp, int reg_addr) static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data) { void __iomem *ioaddr = tp->mmio_addr; - int i; RTL_W32(OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT)); RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD); RTL_W32(EPHY_RXER_NUM, 0); - for (i = 0; i < 100; i++) { - mdelay(1); - if (!(RTL_R32(OCPAR) & OCPAR_FLAG)) - break; - } + rtl_udelay_loop_wait_low(tp, &rtl_ocpar_cond, 1000, 100); } static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value) @@ -1129,7 +1160,6 @@ static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value) static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr) { void __iomem *ioaddr = tp->mmio_addr; - int i; r8168dp_1_mdio_access(tp, reg_addr, OCPDR_READ_CMD); @@ -1137,13 +1167,8 @@ static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr) RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD); RTL_W32(EPHY_RXER_NUM, 0); - for (i = 0; i < 100; i++) { - mdelay(1); - if (RTL_R32(OCPAR) & OCPAR_FLAG) - break; - } - - return RTL_R32(OCPDR) & OCPDR_DATA_MASK; + return rtl_udelay_loop_wait_high(tp, &rtl_ocpar_cond, 1000, 100) ? + RTL_R32(OCPDR) & OCPDR_DATA_MASK : ~0; } #define R8168DP_1_MDIO_ACCESS_BIT 0x00020000 @@ -1221,74 +1246,55 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location) return rtl_readphy(tp, location); } +DECLARE_RTL_COND(rtl_ephyar_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R32(EPHYAR) & EPHYAR_FLAG; +} + static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value) { void __iomem *ioaddr = tp->mmio_addr; - 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); - } + rtl_udelay_loop_wait_low(tp, &rtl_ephyar_cond, 10, 100); + + udelay(10); } static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr) { void __iomem *ioaddr = tp->mmio_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; + return rtl_udelay_loop_wait_high(tp, &rtl_ephyar_cond, 10, 100) ? + RTL_R32(EPHYAR) & EPHYAR_DATA_MASK : ~0; } static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, u32 val, int type) { void __iomem *ioaddr = tp->mmio_addr; - unsigned int i; BUG_ON((addr & 3) || (mask == 0)); RTL_W32(ERIDR, val); RTL_W32(ERIAR, ERIAR_WRITE_CMD | type | mask | addr); - for (i = 0; i < 100; i++) { - if (!(RTL_R32(ERIAR) & ERIAR_FLAG)) - break; - udelay(100); - } + rtl_udelay_loop_wait_low(tp, &rtl_eriar_cond, 100, 100); } static u32 rtl_eri_read(struct rtl8169_private *tp, int addr, int type) { void __iomem *ioaddr = tp->mmio_addr; - u32 value = ~0x00; - unsigned int i; RTL_W32(ERIAR, ERIAR_READ_CMD | type | ERIAR_MASK_1111 | addr); - for (i = 0; i < 100; i++) { - if (RTL_R32(ERIAR) & ERIAR_FLAG) { - value = RTL_R32(ERIDR); - break; - } - udelay(100); - } - - return value; + return rtl_udelay_loop_wait_high(tp, &rtl_eriar_cond, 100, 100) ? + RTL_R32(ERIDR) : ~0; } static void rtl_w1w0_eri(struct rtl8169_private *tp, int addr, u32 mask, u32 p, @@ -1315,23 +1321,21 @@ static void rtl_write_exgmac_batch(struct rtl8169_private *tp, } } +DECLARE_RTL_COND(rtl_efusear_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R32(EFUSEAR) & EFUSEAR_FLAG; +} + static u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr) { void __iomem *ioaddr = tp->mmio_addr; - u8 value = 0xff; - unsigned int i; RTL_W32(EFUSEAR, (reg_addr & EFUSEAR_REG_MASK) << EFUSEAR_REG_SHIFT); - for (i = 0; i < 300; i++) { - if (RTL_R32(EFUSEAR) & EFUSEAR_FLAG) { - value = RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK; - break; - } - udelay(100); - } - - return value; + return rtl_udelay_loop_wait_high(tp, &rtl_efusear_cond, 100, 300) ? + RTL_R32(EFUSEAR) & EFUSEAR_DATA_MASK : ~0; } static u16 rtl_get_events(struct rtl8169_private *tp) @@ -1938,6 +1942,13 @@ static int rtl8169_get_sset_count(struct net_device *dev, int sset) } } +DECLARE_RTL_COND(rtl_counters_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R32(CounterAddrLow) & CounterDump; +} + static void rtl8169_update_counters(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); @@ -1946,7 +1957,6 @@ static void rtl8169_update_counters(struct net_device *dev) struct rtl8169_counters *counters; dma_addr_t paddr; u32 cmd; - int wait = 1000; /* * Some chips are unable to dump tally counters when the receiver @@ -1964,13 +1974,8 @@ static void rtl8169_update_counters(struct net_device *dev) RTL_W32(CounterAddrLow, cmd); RTL_W32(CounterAddrLow, cmd | CounterDump); - while (wait--) { - if ((RTL_R32(CounterAddrLow) & CounterDump) == 0) { - memcpy(&tp->counters, counters, sizeof(*counters)); - break; - } - udelay(10); - } + if (rtl_udelay_loop_wait_low(tp, &rtl_counters_cond, 10, 1000)) + memcpy(&tp->counters, counters, sizeof(*counters)); RTL_W32(CounterAddrLow, 0); RTL_W32(CounterAddrHigh, 0); @@ -3662,18 +3667,16 @@ static void rtl8169_release_board(struct pci_dev *pdev, struct net_device *dev, free_netdev(dev); } +DECLARE_RTL_COND(rtl_phy_reset_cond) +{ + return tp->phy_reset_pending(tp); +} + static void rtl8169_phy_reset(struct net_device *dev, struct rtl8169_private *tp) { - unsigned int i; - tp->phy_reset_enable(tp); - for (i = 0; i < 100; i++) { - if (!tp->phy_reset_pending(tp)) - return; - msleep(1); - } - netif_err(tp, link, dev, "PHY reset failed\n"); + rtl_msleep_loop_wait_low(tp, &rtl_phy_reset_cond, 1, 100); } static bool rtl_tbi_enabled(struct rtl8169_private *tp) @@ -4307,20 +4310,20 @@ static void __devinit rtl_init_jumbo_ops(struct rtl8169_private *tp) } } +DECLARE_RTL_COND(rtl_chipcmd_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R8(ChipCmd) & CmdReset; +} + static void rtl_hw_reset(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; - int i; - /* Soft reset the chip. */ RTL_W8(ChipCmd, CmdReset); - /* Check that the chip has finished the reset. */ - for (i = 0; i < 100; i++) { - if ((RTL_R8(ChipCmd) & CmdReset) == 0) - break; - udelay(100); - } + rtl_udelay_loop_wait_low(tp, &rtl_chipcmd_cond, 100, 100); } static void rtl_request_uncached_firmware(struct rtl8169_private *tp) @@ -4374,6 +4377,20 @@ static void rtl_rx_close(struct rtl8169_private *tp) RTL_W32(RxConfig, RTL_R32(RxConfig) & ~RX_CONFIG_ACCEPT_MASK); } +DECLARE_RTL_COND(rtl_npq_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R8(TxPoll) & NPQ; +} + +DECLARE_RTL_COND(rtl_txcfg_empty_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R32(TxConfig) & TXCFG_EMPTY; +} + static void rtl8169_hw_reset(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -4386,8 +4403,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) if (tp->mac_version == RTL_GIGA_MAC_VER_27 || tp->mac_version == RTL_GIGA_MAC_VER_28 || tp->mac_version == RTL_GIGA_MAC_VER_31) { - while (RTL_R8(TxPoll) & NPQ) - udelay(20); + rtl_udelay_loop_wait_low(tp, &rtl_npq_cond, 20, 42*42); } else if (tp->mac_version == RTL_GIGA_MAC_VER_34 || tp->mac_version == RTL_GIGA_MAC_VER_35 || tp->mac_version == RTL_GIGA_MAC_VER_36 || @@ -4396,8 +4412,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) tp->mac_version == RTL_GIGA_MAC_VER_41 || tp->mac_version == RTL_GIGA_MAC_VER_38) { RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); - while (!(RTL_R32(TxConfig) & TXCFG_EMPTY)) - udelay(100); + rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); } else { RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); udelay(100); @@ -4608,7 +4623,7 @@ static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value) static u32 rtl_csi_read(struct rtl8169_private *tp, int addr) { - return tp->csi_ops.read ? tp->csi_ops.read(tp, addr) :~0; + return tp->csi_ops.read ? tp->csi_ops.read(tp, addr) : ~0; } static void rtl_csi_access_enable(struct rtl8169_private *tp, u32 bits) @@ -4629,77 +4644,56 @@ static void rtl_csi_access_enable_2(struct rtl8169_private *tp) rtl_csi_access_enable(tp, 0x27000000); } +DECLARE_RTL_COND(rtl_csiar_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; + + return RTL_R32(CSIAR) & CSIAR_FLAG; +} + static void r8169_csi_write(struct rtl8169_private *tp, int addr, int value) { void __iomem *ioaddr = tp->mmio_addr; - 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); - } + rtl_udelay_loop_wait_low(tp, &rtl_csiar_cond, 10, 100); } static u32 r8169_csi_read(struct rtl8169_private *tp, int addr) { void __iomem *ioaddr = tp->mmio_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; + return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ? + RTL_R32(CSIDR) : ~0; } static void r8402_csi_write(struct rtl8169_private *tp, int addr, int value) { void __iomem *ioaddr = tp->mmio_addr; - unsigned int i; RTL_W32(CSIDR, value); RTL_W32(CSIAR, CSIAR_WRITE_CMD | (addr & CSIAR_ADDR_MASK) | CSIAR_BYTE_ENABLE << CSIAR_BYTE_ENABLE_SHIFT | CSIAR_FUNC_NIC); - for (i = 0; i < 100; i++) { - if (!(RTL_R32(CSIAR) & CSIAR_FLAG)) - break; - udelay(10); - } + rtl_udelay_loop_wait_low(tp, &rtl_csiar_cond, 10, 100); } static u32 r8402_csi_read(struct rtl8169_private *tp, int addr) { void __iomem *ioaddr = tp->mmio_addr; - u32 value = ~0x00; - unsigned int i; RTL_W32(CSIAR, (addr & CSIAR_ADDR_MASK) | CSIAR_FUNC_NIC | 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; + return rtl_udelay_loop_wait_high(tp, &rtl_csiar_cond, 10, 100) ? + RTL_R32(CSIDR) : ~0; } static void __devinit rtl_init_csi_ops(struct rtl8169_private *tp) @@ -6731,17 +6725,18 @@ static unsigned rtl_try_msi(struct rtl8169_private *tp, return msi; } -#define RTL_LOOP_MAX 10000 +DECLARE_RTL_COND(rtl_link_list_ready_cond) +{ + void __iomem *ioaddr = tp->mmio_addr; -static void rtl_mcu_wait_list_ready(void __iomem *ioaddr) + return RTL_R8(MCU) & LINK_LIST_RDY; +} + +DECLARE_RTL_COND(rtl_rxtx_empty_cond) { - int i; + void __iomem *ioaddr = tp->mmio_addr; - for (i = 0; i < RTL_LOOP_MAX; i++) { - if (RTL_R8(MCU) & LINK_LIST_RDY) - return; - udelay(100); - } + return (RTL_R8(MCU) & RXTX_EMPTY) == RXTX_EMPTY; } #define PLOP 0xe8de @@ -6750,21 +6745,14 @@ static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; u32 data; - int i; RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN); - for (i = 0; i < RTL_LOOP_MAX; i++) { - if (RTL_R32(TxConfig) & TXCFG_EMPTY) - break; - udelay(100); - } + if (!rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 42)) + return; - for (i = 0; i < RTL_LOOP_MAX; i++) { - if ((RTL_R8(MCU) & RXTX_EMPTY) == RXTX_EMPTY) - break; - udelay(100); - } + if (!rtl_udelay_loop_wait_high(tp, &rtl_rxtx_empty_cond, 100, 42)) + return; RTL_W8(ChipCmd, RTL_R8(ChipCmd) & ~(CmdTxEnb | CmdRxEnb)); msleep(1); @@ -6774,13 +6762,15 @@ static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp) data &= ~(1 << 14); r8168_mac_ocp_write(ioaddr, PLOP, data); - rtl_mcu_wait_list_ready(ioaddr); + if (!rtl_udelay_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42)) + return; data = r8168_mac_ocp_read(ioaddr, PLOP); data |= (1 << 15); r8168_mac_ocp_write(ioaddr, PLOP, data); - rtl_mcu_wait_list_ready(ioaddr); + if (!rtl_udelay_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42)) + return; } static void __devinit rtl_hw_initialize(struct rtl8169_private *tp) -- 1.7.10.4 [-- Attachment #2: 0001-r8169-csi_ops-signature-change.patch --] [-- Type: text/plain, Size: 2992 bytes --] >From 29b8c48d9b08fbc0e751460b2a46d3de426db2f5 Mon Sep 17 00:00:00 2001 Message-Id: <29b8c48d9b08fbc0e751460b2a46d3de426db2f5.1341578247.git.romieu@fr.zoreil.com> From: Francois Romieu <romieu@fr.zoreil.com> Date: Fri, 6 Jul 2012 13:37:00 +0200 Subject: [PATCH 1/3] r8169: csi_ops signature change. X-Organisation: Land of Sunshine Inc. Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> --- drivers/net/ethernet/realtek/r8169.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index c37aed9..adab11f 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -758,8 +758,8 @@ struct rtl8169_private { } jumbo_ops; struct csi_ops { - void (*write)(void __iomem *, int, int); - u32 (*read)(void __iomem *, int); + void (*write)(struct rtl8169_private *, int, int); + u32 (*read)(struct rtl8169_private *, int); } csi_ops; int (*set_speed)(struct net_device *, u8 aneg, u16 sp, u8 dpx, u32 adv); @@ -4609,15 +4609,12 @@ static void rtl_hw_start_8169(struct net_device *dev) static void rtl_csi_write(struct rtl8169_private *tp, int addr, int value) { if (tp->csi_ops.write) - tp->csi_ops.write(tp->mmio_addr, addr, value); + tp->csi_ops.write(tp, addr, value); } static u32 rtl_csi_read(struct rtl8169_private *tp, int addr) { - if (tp->csi_ops.read) - return tp->csi_ops.read(tp->mmio_addr, addr); - else - return ~0; + return tp->csi_ops.read ? tp->csi_ops.read(tp, addr) :~0; } static void rtl_csi_access_enable(struct rtl8169_private *tp, u32 bits) @@ -4638,8 +4635,9 @@ static void rtl_csi_access_enable_2(struct rtl8169_private *tp) rtl_csi_access_enable(tp, 0x27000000); } -static void r8169_csi_write(void __iomem *ioaddr, int addr, int value) +static void r8169_csi_write(struct rtl8169_private *tp, int addr, int value) { + void __iomem *ioaddr = tp->mmio_addr; unsigned int i; RTL_W32(CSIDR, value); @@ -4653,8 +4651,9 @@ static void r8169_csi_write(void __iomem *ioaddr, int addr, int value) } } -static u32 r8169_csi_read(void __iomem *ioaddr, int addr) +static u32 r8169_csi_read(struct rtl8169_private *tp, int addr) { + void __iomem *ioaddr = tp->mmio_addr; u32 value = ~0x00; unsigned int i; @@ -4672,8 +4671,9 @@ static u32 r8169_csi_read(void __iomem *ioaddr, int addr) return value; } -static void r8402_csi_write(void __iomem *ioaddr, int addr, int value) +static void r8402_csi_write(struct rtl8169_private *tp, int addr, int value) { + void __iomem *ioaddr = tp->mmio_addr; unsigned int i; RTL_W32(CSIDR, value); @@ -4688,8 +4688,9 @@ static void r8402_csi_write(void __iomem *ioaddr, int addr, int value) } } -static u32 r8402_csi_read(void __iomem *ioaddr, int addr) +static u32 r8402_csi_read(struct rtl8169_private *tp, int addr) { + void __iomem *ioaddr = tp->mmio_addr; u32 value = ~0x00; unsigned int i; -- 1.7.10.4 [-- Attachment #3: 0002-r8169-push-void-__iomem-deeper.patch --] [-- Type: text/plain, Size: 24369 bytes --] >From 4f9e2c24bbcbb2b0ae1c902597e4855ad25e4673 Mon Sep 17 00:00:00 2001 Message-Id: <4f9e2c24bbcbb2b0ae1c902597e4855ad25e4673.1341578247.git.romieu@fr.zoreil.com> In-Reply-To: <29b8c48d9b08fbc0e751460b2a46d3de426db2f5.1341578247.git.romieu@fr.zoreil.com> References: <29b8c48d9b08fbc0e751460b2a46d3de426db2f5.1341578247.git.romieu@fr.zoreil.com> From: Francois Romieu <romieu@fr.zoreil.com> Date: Fri, 6 Jul 2012 13:56:55 +0200 Subject: [PATCH 2/3] r8169: push void __iomem * deeper. X-Organisation: Land of Sunshine Inc. I need more context than they carry and they are too easy to mess up with anyway. Concerned: - r8168dp_1_mdio_access - r8168dp_1_mdio_write - rtl_ephy_write - rtl_ephy_read - rtl_eri_write - rtl_eri_read - rtl_w1w0_eri - rtl_write_exgmac_batch - rtl8168d_efuse_read Signed-off-by: Francois Romieu <romieu@fr.zoreil.com> --- drivers/net/ethernet/realtek/r8169.c | 245 ++++++++++++++++------------------ 1 file changed, 116 insertions(+), 129 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index adab11f..0759c76 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1104,12 +1104,12 @@ static int r8169_mdio_read(struct rtl8169_private *tp, int reg_addr) return value; } -static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data) +static void r8168dp_1_mdio_access(struct rtl8169_private *tp, int reg, u32 data) { + void __iomem *ioaddr = tp->mmio_addr; int i; - RTL_W32(OCPDR, data | - ((reg_addr & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT)); + RTL_W32(OCPDR, data | ((reg & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT)); RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD); RTL_W32(EPHY_RXER_NUM, 0); @@ -1120,13 +1120,10 @@ static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data) } } -static -void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg_addr, int value) +static void r8168dp_1_mdio_write(struct rtl8169_private *tp, int reg, int value) { - void __iomem *ioaddr = tp->mmio_addr; - - r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_WRITE_CMD | - (value & OCPDR_DATA_MASK)); + r8168dp_1_mdio_access(tp, reg, + OCPDR_WRITE_CMD | (value & OCPDR_DATA_MASK)); } static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr) @@ -1134,7 +1131,7 @@ static int r8168dp_1_mdio_read(struct rtl8169_private *tp, int reg_addr) void __iomem *ioaddr = tp->mmio_addr; int i; - r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD); + r8168dp_1_mdio_access(tp, reg_addr, OCPDR_READ_CMD); mdelay(1); RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD); @@ -1224,8 +1221,9 @@ static int rtl_mdio_read(struct net_device *dev, int phy_id, int location) return rtl_readphy(tp, location); } -static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value) +static void rtl_ephy_write(struct rtl8169_private *tp, int reg_addr, int value) { + void __iomem *ioaddr = tp->mmio_addr; unsigned int i; RTL_W32(EPHYAR, EPHYAR_WRITE_CMD | (value & EPHYAR_DATA_MASK) | @@ -1238,8 +1236,9 @@ static void rtl_ephy_write(void __iomem *ioaddr, int reg_addr, int value) } } -static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr) +static u16 rtl_ephy_read(struct rtl8169_private *tp, int reg_addr) { + void __iomem *ioaddr = tp->mmio_addr; u16 value = 0xffff; unsigned int i; @@ -1256,9 +1255,10 @@ static u16 rtl_ephy_read(void __iomem *ioaddr, int reg_addr) return value; } -static -void rtl_eri_write(void __iomem *ioaddr, int addr, u32 mask, u32 val, int type) +static void rtl_eri_write(struct rtl8169_private *tp, int addr, u32 mask, + u32 val, int type) { + void __iomem *ioaddr = tp->mmio_addr; unsigned int i; BUG_ON((addr & 3) || (mask == 0)); @@ -1272,8 +1272,9 @@ void rtl_eri_write(void __iomem *ioaddr, int addr, u32 mask, u32 val, int type) } } -static u32 rtl_eri_read(void __iomem *ioaddr, int addr, int type) +static u32 rtl_eri_read(struct rtl8169_private *tp, int addr, int type) { + void __iomem *ioaddr = tp->mmio_addr; u32 value = ~0x00; unsigned int i; @@ -1290,13 +1291,13 @@ static u32 rtl_eri_read(void __iomem *ioaddr, int addr, int type) return value; } -static void -rtl_w1w0_eri(void __iomem *ioaddr, int addr, u32 mask, u32 p, u32 m, int type) +static void rtl_w1w0_eri(struct rtl8169_private *tp, int addr, u32 mask, u32 p, + u32 m, int type) { u32 val; - val = rtl_eri_read(ioaddr, addr, type); - rtl_eri_write(ioaddr, addr, mask, (val & ~m) | p, type); + val = rtl_eri_read(tp, addr, type); + rtl_eri_write(tp, addr, mask, (val & ~m) | p, type); } struct exgmac_reg { @@ -1305,17 +1306,18 @@ struct exgmac_reg { u32 val; }; -static void rtl_write_exgmac_batch(void __iomem *ioaddr, +static void rtl_write_exgmac_batch(struct rtl8169_private *tp, const struct exgmac_reg *r, int len) { while (len-- > 0) { - rtl_eri_write(ioaddr, r->addr, r->mask, r->val, ERIAR_EXGMAC); + rtl_eri_write(tp, r->addr, r->mask, r->val, ERIAR_EXGMAC); r++; } } -static u8 rtl8168d_efuse_read(void __iomem *ioaddr, int reg_addr) +static u8 rtl8168d_efuse_read(struct rtl8169_private *tp, int reg_addr) { + void __iomem *ioaddr = tp->mmio_addr; u8 value = 0xff; unsigned int i; @@ -1428,48 +1430,48 @@ static void rtl_link_chg_patch(struct rtl8169_private *tp) if (tp->mac_version == RTL_GIGA_MAC_VER_34 || tp->mac_version == RTL_GIGA_MAC_VER_38) { if (RTL_R8(PHYstatus) & _1000bpsF) { - rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, - 0x00000011, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, - 0x00000005, ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011, + ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005, + ERIAR_EXGMAC); } else if (RTL_R8(PHYstatus) & _100bps) { - rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, - 0x0000001f, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, - 0x00000005, ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f, + ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005, + ERIAR_EXGMAC); } else { - rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, - 0x0000001f, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, - 0x0000003f, ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f, + ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f, + ERIAR_EXGMAC); } /* Reset packet filter */ - rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, + rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, + rtl_w1w0_eri(tp, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); } else if (tp->mac_version == RTL_GIGA_MAC_VER_35 || tp->mac_version == RTL_GIGA_MAC_VER_36) { if (RTL_R8(PHYstatus) & _1000bpsF) { - rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, - 0x00000011, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, - 0x00000005, ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x00000011, + ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x00000005, + ERIAR_EXGMAC); } else { - rtl_eri_write(ioaddr, 0x1bc, ERIAR_MASK_1111, - 0x0000001f, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_1111, - 0x0000003f, ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1bc, ERIAR_MASK_1111, 0x0000001f, + ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1dc, ERIAR_MASK_1111, 0x0000003f, + ERIAR_EXGMAC); } } else if (tp->mac_version == RTL_GIGA_MAC_VER_37) { if (RTL_R8(PHYstatus) & _10bps) { - rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011, - 0x4d02, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0x1dc, ERIAR_MASK_0011, - 0x0060, ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x4d02, + ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1dc, ERIAR_MASK_0011, 0x0060, + ERIAR_EXGMAC); } else { - rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011, - 0x0000, ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000, + ERIAR_EXGMAC); } } } @@ -2344,7 +2346,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) index -= regno; break; case PHY_READ_EFUSE: - predata = rtl8168d_efuse_read(tp->mmio_addr, regno); + predata = rtl8168d_efuse_read(tp, regno); index++; break; case PHY_CLEAR_READCOUNT: @@ -2784,7 +2786,6 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) { 0x1f, 0x0000 }, { 0x0d, 0xf880 } }; - void __iomem *ioaddr = tp->mmio_addr; rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); @@ -2796,7 +2797,7 @@ static void rtl8168d_1_hw_phy_config(struct rtl8169_private *tp) rtl_w1w0_phy(tp, 0x0b, 0x0010, 0x00ef); rtl_w1w0_phy(tp, 0x0c, 0xa200, 0x5d00); - if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) { + if (rtl8168d_efuse_read(tp, 0x01) == 0xb1) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0002 }, { 0x05, 0x669a }, @@ -2896,11 +2897,10 @@ static void rtl8168d_2_hw_phy_config(struct rtl8169_private *tp) { 0x1f, 0x0000 }, { 0x0d, 0xf880 } }; - void __iomem *ioaddr = tp->mmio_addr; rtl_writephy_batch(tp, phy_reg_init_0, ARRAY_SIZE(phy_reg_init_0)); - if (rtl8168d_efuse_read(ioaddr, 0x01) == 0xb1) { + if (rtl8168d_efuse_read(tp, 0x01) == 0xb1) { static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0002 }, { 0x05, 0x669a }, @@ -3168,8 +3168,7 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0000); /* EEE setting */ - rtl_w1w0_eri(tp->mmio_addr, 0x1b0, ERIAR_MASK_1111, 0x0000, 0x0003, - ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_1111, 0x0000, 0x0003, ERIAR_EXGMAC); rtl_writephy(tp, 0x1f, 0x0005); rtl_writephy(tp, 0x05, 0x8b85); rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000); @@ -3273,7 +3272,6 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) static void rtl8411_hw_phy_config(struct rtl8169_private *tp) { - void __iomem *ioaddr = tp->mmio_addr; static const struct phy_reg phy_reg_init[] = { /* Channel estimation fine tune */ { 0x1f, 0x0003 }, @@ -3347,7 +3345,7 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0000); /* eee setting */ - rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x00, 0x03, ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0001, 0x00, 0x03, ERIAR_EXGMAC); rtl_writephy(tp, 0x1f, 0x0005); rtl_writephy(tp, 0x05, 0x8b85); rtl_w1w0_phy(tp, 0x06, 0x0000, 0x2000); @@ -3463,8 +3461,6 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp) static void rtl8402_hw_phy_config(struct rtl8169_private *tp) { - void __iomem *ioaddr = tp->mmio_addr; - /* Disable ALDPS before setting firmware */ rtl_writephy(tp, 0x1f, 0x0000); rtl_writephy(tp, 0x18, 0x0310); @@ -3473,7 +3469,7 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp) rtl_apply_firmware(tp); /* EEE setting */ - rtl_eri_write(ioaddr, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_writephy(tp, 0x1f, 0x0004); rtl_writephy(tp, 0x10, 0x401f); rtl_writephy(tp, 0x19, 0x7030); @@ -3482,8 +3478,6 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp) static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) { - void __iomem *ioaddr = tp->mmio_addr; - static const struct phy_reg phy_reg_init[] = { { 0x1f, 0x0004 }, { 0x10, 0xc07f }, @@ -3498,10 +3492,10 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) rtl_apply_firmware(tp); - rtl_eri_write(ioaddr, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1b0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); - rtl_eri_write(ioaddr, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); } static void rtl_hw_phy_config(struct net_device *dev) @@ -3754,7 +3748,7 @@ static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr) low >> 16 }, }; - rtl_write_exgmac_batch(ioaddr, e, ARRAY_SIZE(e)); + rtl_write_exgmac_batch(tp, e, ARRAY_SIZE(e)); } RTL_W8(Cfg9346, Cfg9346_Lock); @@ -4011,7 +4005,7 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) if (tp->mac_version == RTL_GIGA_MAC_VER_32 || tp->mac_version == RTL_GIGA_MAC_VER_33) - rtl_ephy_write(ioaddr, 0x19, 0xff64); + rtl_ephy_write(tp, 0x19, 0xff64); if (rtl_wol_pll_power_down(tp)) return; @@ -4750,13 +4744,14 @@ struct ephy_info { u16 bits; }; -static void rtl_ephy_init(void __iomem *ioaddr, const struct ephy_info *e, int len) +static void rtl_ephy_init(struct rtl8169_private *tp, const 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); + w = (rtl_ephy_read(tp, e->offset) & ~e->mask) | e->bits; + rtl_ephy_write(tp, e->offset, w); e++; } } @@ -4840,7 +4835,6 @@ static void __rtl_hw_start_8168cp(struct rtl8169_private *tp) static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp) { - void __iomem *ioaddr = tp->mmio_addr; static const struct ephy_info e_info_8168cp[] = { { 0x01, 0, 0x0001 }, { 0x02, 0x0800, 0x1000 }, @@ -4851,7 +4845,7 @@ static void rtl_hw_start_8168cp_1(struct rtl8169_private *tp) rtl_csi_access_enable_2(tp); - rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp)); + rtl_ephy_init(tp, e_info_8168cp, ARRAY_SIZE(e_info_8168cp)); __rtl_hw_start_8168cp(tp); } @@ -4902,14 +4896,13 @@ static void rtl_hw_start_8168c_1(struct rtl8169_private *tp) RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2); - rtl_ephy_init(ioaddr, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1)); + rtl_ephy_init(tp, e_info_8168c_1, ARRAY_SIZE(e_info_8168c_1)); __rtl_hw_start_8168cp(tp); } static void rtl_hw_start_8168c_2(struct rtl8169_private *tp) { - void __iomem *ioaddr = tp->mmio_addr; static const struct ephy_info e_info_8168c_2[] = { { 0x01, 0, 0x0001 }, { 0x03, 0x0400, 0x0220 } @@ -4917,7 +4910,7 @@ static void rtl_hw_start_8168c_2(struct rtl8169_private *tp) rtl_csi_access_enable_2(tp); - rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2)); + rtl_ephy_init(tp, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2)); __rtl_hw_start_8168cp(tp); } @@ -4985,8 +4978,8 @@ static void rtl_hw_start_8168d_4(struct rtl8169_private *tp) const struct ephy_info *e = e_info_8168d_4 + i; u16 w; - w = rtl_ephy_read(ioaddr, e->offset); - rtl_ephy_write(ioaddr, 0x03, (w & e->mask) | e->bits); + w = rtl_ephy_read(tp, e->offset); + rtl_ephy_write(tp, 0x03, (w & e->mask) | e->bits); } rtl_enable_clock_request(pdev); @@ -5014,7 +5007,7 @@ static void rtl_hw_start_8168e_1(struct rtl8169_private *tp) rtl_csi_access_enable_2(tp); - rtl_ephy_init(ioaddr, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1)); + rtl_ephy_init(tp, e_info_8168e_1, ARRAY_SIZE(e_info_8168e_1)); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); @@ -5040,18 +5033,18 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) rtl_csi_access_enable_1(tp); - rtl_ephy_init(ioaddr, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2)); + rtl_ephy_init(tp, e_info_8168e_2, ARRAY_SIZE(e_info_8168e_2)); rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); - rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_1111, 0x07ff0060, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, + rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x07ff0060, ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, ERIAR_EXGMAC); RTL_W8(MaxTxPacketSize, EarlySize); @@ -5078,16 +5071,16 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp) rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT); - rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0x1d0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_1111, 0x00000060, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00100002, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC); + 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, 0x1b0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x1d0, ERIAR_MASK_0001, 0x10, 0x00, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xcc, ERIAR_MASK_1111, 0x00000050, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xd0, ERIAR_MASK_1111, 0x00000060, ERIAR_EXGMAC); RTL_W8(MaxTxPacketSize, EarlySize); @@ -5112,10 +5105,9 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) rtl_hw_start_8168f(tp); - rtl_ephy_init(ioaddr, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1)); + rtl_ephy_init(tp, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1)); - rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, - ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0xff00, ERIAR_EXGMAC); /* Adjust EEE LED frequency */ RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); @@ -5123,7 +5115,6 @@ static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) static void rtl_hw_start_8411(struct rtl8169_private *tp) { - void __iomem *ioaddr = tp->mmio_addr; static const struct ephy_info e_info_8168f_1[] = { { 0x06, 0x00c0, 0x0020 }, { 0x0f, 0xffff, 0x5200 }, @@ -5133,10 +5124,9 @@ static void rtl_hw_start_8411(struct rtl8169_private *tp) rtl_hw_start_8168f(tp); - rtl_ephy_init(ioaddr, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1)); + rtl_ephy_init(tp, e_info_8168f_1, ARRAY_SIZE(e_info_8168f_1)); - rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0x0000, - ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0c00, 0x0000, ERIAR_EXGMAC); } static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) @@ -5144,29 +5134,29 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) void __iomem *ioaddr = tp->mmio_addr; struct pci_dev *pdev = tp->pci_dev; - rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_0101, 0x080002, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xcc, ERIAR_MASK_0001, 0x38, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xd0, ERIAR_MASK_0001, 0x48, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00100006, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xc8, ERIAR_MASK_0101, 0x080002, 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(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); + 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_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); RTL_W8(MaxTxPacketSize, EarlySize); - rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + 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_w1w0_eri(ioaddr, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC); } static void rtl_hw_start_8168(struct net_device *dev) @@ -5329,7 +5319,7 @@ static void rtl_hw_start_8102e_1(struct rtl8169_private *tp) if ((cfg1 & LEDS0) && (cfg1 & LEDS1)) RTL_W8(Config1, cfg1 & ~LEDS0); - rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1)); + rtl_ephy_init(tp, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1)); } static void rtl_hw_start_8102e_2(struct rtl8169_private *tp) @@ -5349,7 +5339,7 @@ static void rtl_hw_start_8102e_3(struct rtl8169_private *tp) { rtl_hw_start_8102e_2(tp); - rtl_ephy_write(tp->mmio_addr, 0x03, 0xc2f9); + rtl_ephy_write(tp, 0x03, 0xc2f9); } static void rtl_hw_start_8105e_1(struct rtl8169_private *tp) @@ -5375,15 +5365,13 @@ static void rtl_hw_start_8105e_1(struct rtl8169_private *tp) RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); - rtl_ephy_init(ioaddr, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); + rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); } static void rtl_hw_start_8105e_2(struct rtl8169_private *tp) { - void __iomem *ioaddr = tp->mmio_addr; - rtl_hw_start_8105e_1(tp); - rtl_ephy_write(ioaddr, 0x1e, rtl_ephy_read(ioaddr, 0x1e) | 0x8000); + rtl_ephy_write(tp, 0x1e, rtl_ephy_read(tp, 0x1e) | 0x8000); } static void rtl_hw_start_8402(struct rtl8169_private *tp) @@ -5402,18 +5390,17 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp) RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); - rtl_ephy_init(ioaddr, e_info_8402, ARRAY_SIZE(e_info_8402)); + rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402)); rtl_tx_performance_tweak(tp->pci_dev, 0x5 << MAX_READ_REQUEST_SHIFT); - rtl_eri_write(ioaddr, 0xc8, ERIAR_MASK_1111, 0x00000002, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xe8, ERIAR_MASK_1111, 0x00000006, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x00, 0x01, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0xdc, ERIAR_MASK_0001, 0x01, 0x00, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); - rtl_eri_write(ioaddr, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); - rtl_w1w0_eri(ioaddr, 0x0d4, ERIAR_MASK_0011, 0x0e00, 0xff00, - ERIAR_EXGMAC); + rtl_eri_write(tp, 0xc8, ERIAR_MASK_1111, 0x00000002, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xe8, ERIAR_MASK_1111, 0x00000006, ERIAR_EXGMAC); + 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_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000, ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x0d4, ERIAR_MASK_0011, 0x0e00, 0xff00, ERIAR_EXGMAC); } static void rtl_hw_start_8106(struct rtl8169_private *tp) -- 1.7.10.4 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net-next 2/2] r8169: support RTL8168G 2012-07-06 15:20 ` Francois Romieu @ 2012-07-06 15:37 ` Joe Perches 0 siblings, 0 replies; 18+ messages in thread From: Joe Perches @ 2012-07-06 15:37 UTC (permalink / raw) To: Francois Romieu; +Cc: Hayes Wang, netdev, linux-kernel On Fri, 2012-07-06 at 17:20 +0200, Francois Romieu wrote: > Joe Perches <joe@perches.com> : > [...] > > This pattern is used a couple more times. > > There's no failure handling either. > > I can do something for the initialize path. Other than that it's mostly > deeply burried hardware failure so I'd rather concentrate a bit on > current problem reports. > > This series already took me a bit further than expected (see below). Allez Francois. When you take up a suggestion, you really go with it. ^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH v2 net-next 2/2] r8169: support RTL8168G 2012-07-04 22:04 ` Francois Romieu 2012-07-05 0:51 ` Joe Perches @ 2012-07-06 7:57 ` hayeswang 2012-07-06 15:20 ` Francois Romieu 1 sibling, 1 reply; 18+ messages in thread From: hayeswang @ 2012-07-06 7:57 UTC (permalink / raw) To: 'Francois Romieu'; +Cc: netdev, linux-kernel [-- Attachment #1: Type: text/plain, Size: 642 bytes --] Francois Romieu [romieu@fr.zoreil.com] [...] > > Any objection against merging it with the patch below ? > > - more BUG() avoidance > - save Joe P. some work > - remove useless parenthesis > - fix r8168g_mdio_write (if (reg_addr == 0x1f) { if (reg_addr == 0) snafu) > -> Please check this one. That is fine. > - long declarations before short ones > - avoid unbounded loops > - use a descriptive name for the 0xe8de value in rtl_hw_init_8168g. > -> Please suggest something better than "PLOP" I have no idea about naming 0xe8de. Our hardware engineers don't release any datasheet about it. It seems to be related with oob settings. [-- Attachment #2: fix.patch --] [-- Type: application/octet-stream, Size: 1656 bytes --] Fix some code. Signed-off-by: Hayes Wang <hayeswang@realtek.com> --- drivers/net/ethernet/realtek/r8169.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index c37aed9..1d7d6f0 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3392,7 +3392,7 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) }; /* patch code for GPHY reset */ - for (i = 0; ARRAY_SIZE(mac_ocp_patch); i++) + for (i = 0; i < ARRAY_SIZE(mac_ocp_patch); i++) r8168_mac_ocp_write(tp, 0xf800 + 2*i, mac_ocp_patch[i]); r8168_mac_ocp_write(tp, 0xfc26, 0x8000); r8168_mac_ocp_write(tp, 0xfc28, 0x0075); @@ -6764,6 +6764,7 @@ static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp) u32 data; int i; + tp->ocp_base = OCP_STD_PHY_BASE; RTL_W32(MISC, RTL_R32(MISC) | RXDV_GATED_EN); for (i = 0; i < RTL_LOOP_MAX; i++) { @@ -6782,15 +6783,15 @@ static void __devinit rtl_hw_init_8168g(struct rtl8169_private *tp) msleep(1); RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); - data = r8168_mac_ocp_read(ioaddr, PLOP); + data = r8168_mac_ocp_read(tp, PLOP); data &= ~(1 << 14); - r8168_mac_ocp_write(ioaddr, PLOP, data); + r8168_mac_ocp_write(tp, PLOP, data); rtl_mcu_wait_list_ready(ioaddr); - data = r8168_mac_ocp_read(ioaddr, PLOP); + data = r8168_mac_ocp_read(tp, PLOP); data |= (1 << 15); - r8168_mac_ocp_write(ioaddr, PLOP, data); + r8168_mac_ocp_write(tp, PLOP, data); rtl_mcu_wait_list_ready(ioaddr); } -- 1.7.10.2 ^ permalink raw reply related [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net-next 2/2] r8169: support RTL8168G 2012-07-06 7:57 ` hayeswang @ 2012-07-06 15:20 ` Francois Romieu 0 siblings, 0 replies; 18+ messages in thread From: Francois Romieu @ 2012-07-06 15:20 UTC (permalink / raw) To: hayeswang; +Cc: netdev, linux-kernel hayeswang <hayeswang@realtek.com> : > Francois Romieu [romieu@fr.zoreil.com] [...] > > - fix r8168g_mdio_write (if (reg_addr == 0x1f) { if (reg_addr == 0) snafu) > > -> Please check this one. > > That is fine. Thanks, I'll merge your patch and feed both drivers to davem. -- Ueimor ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH v2 net-next 1/2] r8169: support RTL8106E 2012-07-02 9:23 ` [PATCH v2 " Hayes Wang 2012-07-02 9:23 ` [PATCH v2 net-next 2/2] r8169: support RTL8168G Hayes Wang @ 2012-07-03 11:01 ` Francois Romieu 2012-07-04 9:02 ` hayeswang 1 sibling, 1 reply; 18+ messages in thread From: Francois Romieu @ 2012-07-03 11:01 UTC (permalink / raw) To: Hayes Wang; +Cc: netdev, linux-kernel Hayes Wang <hayeswang@realtek.com> : > Support the new chip RTL8106E. > > Signed-off-by: Hayes Wang <hayeswang@realtek.com> Almost-Acked-by: Francois Romieu <romieu@fr.zoreil.com> Simple bidirectional traffic worked fine (rsync + wget + ping) both with and without tx checksumming offload. Wol g or u worked as well. Link was ok and traffic flowing after a suspend to ram. No problem with module removal / insertion / device up / traffic loop. > +#define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" I did not notice it. Was it submitted ? It was obviously not required for testing :o) > @@ -1933,6 +1941,8 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, > { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, > > /* 8101 family. */ > + { 0x7cf00000, 0x44900000, RTL_GIGA_MAC_VER_39 }, > + { 0x7c800000, 0x44800000, RTL_GIGA_MAC_VER_39 }, > { 0x7c800000, 0x44000000, RTL_GIGA_MAC_VER_37 }, > { 0x7cf00000, 0x40b00000, RTL_GIGA_MAC_VER_30 }, > { 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 }, Realtek's 1.022.00 8101 driver only maps { 0x7c800000; 0x44800000 } to a generic device - if at all - and it maps { 0x7cf00000; 0x44800000 } to a different chipset (namely CFG_METHOD_15 where RTL_GIGA_MAC_VER_39 is CFG_METHOD_16). Why should both drivers diverge ? -- Ueimor ^ permalink raw reply [flat|nested] 18+ messages in thread
* RE: [PATCH v2 net-next 1/2] r8169: support RTL8106E 2012-07-03 11:01 ` [PATCH v2 net-next 1/2] r8169: support RTL8106E Francois Romieu @ 2012-07-04 9:02 ` hayeswang 0 siblings, 0 replies; 18+ messages in thread From: hayeswang @ 2012-07-04 9:02 UTC (permalink / raw) To: 'Francois Romieu'; +Cc: netdev, linux-kernel Francois Romieu [mailto:romieu@fr.zoreil.com] [...] > > +#define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" > > I did not notice it. Was it submitted ? > I don't submit it yet. > It was obviously not required for testing :o) > > > @@ -1933,6 +1941,8 @@ static void > rtl8169_get_mac_version(struct rtl8169_private *tp, > > { 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 }, > > > > /* 8101 family. */ > > + { 0x7cf00000, 0x44900000, RTL_GIGA_MAC_VER_39 }, > > + { 0x7c800000, 0x44800000, RTL_GIGA_MAC_VER_39 }, > > { 0x7c800000, 0x44000000, RTL_GIGA_MAC_VER_37 }, > > { 0x7cf00000, 0x40b00000, RTL_GIGA_MAC_VER_30 }, > > { 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 }, > > Realtek's 1.022.00 8101 driver only maps { 0x7c800000; 0x44800000 } to > a generic device - if at all - and it maps { 0x7cf00000; 0x44800000 } > to a different chipset (namely CFG_METHOD_15 where RTL_GIGA_MAC_VER_39 > is CFG_METHOD_16). > > Why should both drivers diverge ? > Our PMs say only 0x44900000 would have mass production. Besides, you could use the same setting for both of them. Best Regards, Hayes ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH net-next 1/2] r8169: support RTL8106E 2012-06-29 10:34 [PATCH net-next 1/2] r8169: support RTL8106E Hayes Wang ` (2 preceding siblings ...) 2012-07-02 9:23 ` [PATCH v2 " Hayes Wang @ 2012-07-09 6:48 ` David Miller 2012-07-09 10:12 ` Francois Romieu 3 siblings, 1 reply; 18+ messages in thread From: David Miller @ 2012-07-09 6:48 UTC (permalink / raw) To: hayeswang; +Cc: romieu, netdev, linux-kernel, hayes Francois, what would you like me to do with these two patches? I haven't seen full ACKs from you yet. Thanks. ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH net-next 1/2] r8169: support RTL8106E 2012-07-09 6:48 ` [PATCH " David Miller @ 2012-07-09 10:12 ` Francois Romieu 2012-07-09 21:10 ` David Miller 0 siblings, 1 reply; 18+ messages in thread From: Francois Romieu @ 2012-07-09 10:12 UTC (permalink / raw) To: David Miller; +Cc: netdev, linux-kernel, hayeswang David Miller <davem@davemloft.net> : > Francois, what would you like me to do with these two patches? I > haven't seen full ACKs from you yet. You have two options: - You can apply the first (8106) patch. I tested it. I'm ok with Hayes point. Consider it Acked. - You wait for a pull request with both patches + the incremental bits for the second one. Some of the incremental bits are needed in the original patch itself while some make more sense before the patch itself. ETA: this evening or tomorrow morning at worst. If you go for the first option, I'll simply skip the first patch and apply again. It's the same work for me. -- Ueimor ^ permalink raw reply [flat|nested] 18+ messages in thread
* Re: [PATCH net-next 1/2] r8169: support RTL8106E 2012-07-09 10:12 ` Francois Romieu @ 2012-07-09 21:10 ` David Miller 0 siblings, 0 replies; 18+ messages in thread From: David Miller @ 2012-07-09 21:10 UTC (permalink / raw) To: romieu; +Cc: netdev, linux-kernel, hayeswang From: Francois Romieu <romieu@fr.zoreil.com> Date: Mon, 9 Jul 2012 12:12:15 +0200 > David Miller <davem@davemloft.net> : >> Francois, what would you like me to do with these two patches? I >> haven't seen full ACKs from you yet. > > You have two options: > - You can apply the first (8106) patch. I tested it. I'm ok with Hayes point. > Consider it Acked. > - You wait for a pull request with both patches + the incremental bits for > the second one. Some of the incremental bits are needed in the original > patch itself while some make more sense before the patch itself. > ETA: this evening or tomorrow morning at worst. > > If you go for the first option, I'll simply skip the first patch and > apply again. It's the same work for me. I'll simply wait for your pull request, thank you. ^ permalink raw reply [flat|nested] 18+ messages in thread
end of thread, other threads:[~2012-07-09 21:10 UTC | newest] Thread overview: 18+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-06-29 10:34 [PATCH net-next 1/2] r8169: support RTL8106E Hayes Wang 2012-06-29 10:34 ` [PATCH net-next 2/2] r8169: support RTL8168G Hayes Wang 2012-06-29 13:51 ` Francois Romieu 2012-07-02 7:27 ` hayeswang 2012-06-29 13:50 ` [PATCH net-next 1/2] r8169: support RTL8106E Francois Romieu 2012-07-02 9:23 ` [PATCH v2 " Hayes Wang 2012-07-02 9:23 ` [PATCH v2 net-next 2/2] r8169: support RTL8168G Hayes Wang 2012-07-04 22:04 ` Francois Romieu 2012-07-05 0:51 ` Joe Perches 2012-07-06 15:20 ` Francois Romieu 2012-07-06 15:37 ` Joe Perches 2012-07-06 7:57 ` hayeswang 2012-07-06 15:20 ` Francois Romieu 2012-07-03 11:01 ` [PATCH v2 net-next 1/2] r8169: support RTL8106E Francois Romieu 2012-07-04 9:02 ` hayeswang 2012-07-09 6:48 ` [PATCH " David Miller 2012-07-09 10:12 ` Francois Romieu 2012-07-09 21:10 ` David Miller
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).