[PATCH 3/5] r8169: Modify the method for setting firmware
Remove useless action PHY_READ_EFUSE, and define the new action PHY_MDIO_CHG. PHY_MDIO_CHG is used to modify the mdio operation. By the way, the firmware could support setting mac ocp. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 36 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index d1bee4c..55a7fb5 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1074,6 +1074,21 @@ static int r8168g_mdio_read(struct rtl8169_private *tp, int reg) return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2); } +static void mac_mcu_write(struct rtl8169_private *tp, int reg, int value) +{ + if (reg == 0x1f) { + tp->ocp_base = value << 4; + return; + } + + r8168_mac_ocp_write(tp, tp->ocp_base + reg, value); +} + +static int mac_mcu_read(struct rtl8169_private *tp, int reg) +{ + return r8168_mac_ocp_read(tp, tp->ocp_base + reg); +} + DECLARE_RTL_COND(rtl_phyar_cond) { void __iomem *ioaddr = tp->mmio_addr; @@ -2139,7 +2154,7 @@ static void rtl_writephy_batch(struct rtl8169_private *tp, #define PHY_DATA_OR0x1000 #define PHY_DATA_AND 0x2000 #define PHY_BJMPN 0x3000 -#define PHY_READ_EFUSE 0x4000 +#define PHY_MDIO_CHG 0x4000 #define PHY_READ_MAC_BYTE 0x5000 #define PHY_WRITE_MAC_BYTE 0x6000 #define PHY_CLEAR_READCOUNT0x7000 @@ -2227,7 +2242,7 @@ static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev, case PHY_READ: case PHY_DATA_OR: case PHY_DATA_AND: - case PHY_READ_EFUSE: + case PHY_MDIO_CHG: case PHY_CLEAR_READCOUNT: case PHY_WRITE: case PHY_WRITE_PREVIOUS: @@ -2291,10 +2306,13 @@ out: static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) { struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; + struct mdio_ops org, *ops = &tp->mdio_ops; u32 predata, count; size_t index; predata = count = 0; + org.write = ops->write; + org.read = ops->read; for (index = 0; index < pa->size; ) { u32 action = le32_to_cpu(pa->code[index]); @@ -2321,8 +2339,15 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) case PHY_BJMPN: index -= regno; break; - case PHY_READ_EFUSE: - predata = rtl8168d_efuse_read(tp, regno); + case PHY_MDIO_CHG: + if (data == 0) { + ops->write = org.write; + ops->read = org.read; + } else if (data == 1) { + ops->write = mac_mcu_write; + ops->read = mac_mcu_read; + } + index++; break; case PHY_CLEAR_READCOUNT: @@ -2365,6 +2390,9 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) BUG(); } } + + ops->write = org.write; + ops->read = org.read; } static void rtl_release_firmware(struct rtl8169_private *tp) -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 4/5] r8169: Update the RTL8111G parameters
- replace rtl8168g-1.fw with rtl8168g-2.fw which support new method. - fix PHY power down is useless. - disable rx early which causes the rx abnormal. - fix the conflict between jumbo frame and flow control. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 18 -- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 55a7fb5..c25a329 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -47,7 +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" +#define FIRMWARE_8168G_1 "rtl_nic/rtl8168g-2.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -329,6 +329,7 @@ enum rtl_registers { #defineRXCFG_FIFO_SHIFT13 /* No threshold before first PCI xfer */ #defineRX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) +#defineRX_EARLY_OFF(1 << 11) #defineRXCFG_DMA_SHIFT 8 /* Unlimited maximum PCI burst. */ #defineRX_DMA_BURST(7 << RXCFG_DMA_SHIFT) @@ -4077,6 +4078,10 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_33: RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + RTL_W8(PMCH, RTL_R8(PMCH) & ~0x40); + break; } } @@ -4094,6 +4099,10 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_33: RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + RTL_W8(PMCH, RTL_R8(PMCH) | 0x40); + break; } r8168_phy_power_up(tp); @@ -4199,6 +4208,10 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_34: RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF); + break; default: RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST); break; @@ -5190,7 +5203,8 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) /* Adjust EEE LED frequency */ RTL_W8(EEE_LED, RTL_R8(EEE_LED) & ~0x07); - rtl_w1w0_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x02, ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x2fc, ERIAR_MASK_0001, 0x01, 0x06, ERIAR_EXGMAC); + rtl_w1w0_eri(tp, 0x1b0, ERIAR_MASK_0011, 0x, 0x1000, ERIAR_EXGMAC); } static void rtl_hw_start_8168(struct net_device *dev) -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 5/5] r8169: fix could not dump registers
For new version of Fedora and Ubuntu, we see all 0xff when dumping the hw regs through ethtool. Using a loop to read registers could fix it. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index c25a329..4ae3c55 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1880,12 +1880,16 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + u32 *d = (u32 *)p; + int i; if (regs->len > R8169_REGS_SIZE) regs->len = R8169_REGS_SIZE; rtl_lock_work(tp); - memcpy_fromio(p, tp->mmio_addr, regs->len); + for (i = 0; i < regs->len; i += 4) + *d++ = RTL_R32(i); rtl_unlock_work(tp); } -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 2/5] r8169: Update PHY settings of RTL8111G
- Replace the current settings with rtl_writephy and rtl_readphy. For the hardware, the settings are same with previous ones. This make the setting method like the previous chips. - Add new PHY settings. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 72 +--- 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index e811ab5..d1bee4c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1029,14 +1029,6 @@ static u16 r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) (RTL_R32(GPHY_OCP) & 0x) : ~0; } -static void rtl_w1w0_phy_ocp(struct rtl8169_private *tp, int reg, int p, int m) -{ - int val; - - val = r8168_phy_ocp_read(tp, reg); - r8168_phy_ocp_write(tp, reg, (val | p) & ~m); -} - static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) { void __iomem *ioaddr = tp->mmio_addr; @@ -3410,23 +3402,61 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) { rtl_apply_firmware(tp); - if (r8168_phy_ocp_read(tp, 0xa460) & 0x0100) - rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x, 0x8000); - else - rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x8000, 0x); + rtl_writephy(tp, 0x1f, 0x0a46); + if (rtl_readphy(tp, 0x10) & 0x0100) { + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x12, 0x, 0x8000); + } else { + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x12, 0x8000, 0x); + } - if (r8168_phy_ocp_read(tp, 0xa466) & 0x0100) - rtl_w1w0_phy_ocp(tp, 0xc41a, 0x0002, 0x); - else - rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x, 0x0002); + rtl_writephy(tp, 0x1f, 0x0a46); + if (rtl_readphy(tp, 0x13) & 0x0100) { + rtl_writephy(tp, 0x1f, 0x0c41); + rtl_w1w0_phy(tp, 0x15, 0x0002, 0x); + } else { + rtl_writephy(tp, 0x1f, 0x0c41); + rtl_w1w0_phy(tp, 0x15, 0x, 0x0002); + } - rtl_w1w0_phy_ocp(tp, 0xa442, 0x000c, 0x); - rtl_w1w0_phy_ocp(tp, 0xa4b2, 0x0004, 0x); + /* Enable PHY auto speed down */ + rtl_writephy(tp, 0x1f, 0x0a44); + rtl_w1w0_phy(tp, 0x11, 0x000c, 0x); + + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x14, 0x0100, 0x); + rtl_writephy(tp, 0x1f, 0x0a44); + rtl_w1w0_phy(tp, 0x11, 0x00c0, 0x); + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_writephy(tp, 0x13, 0x8084); + rtl_w1w0_phy(tp, 0x14, 0x, 0x6000); + rtl_w1w0_phy(tp, 0x10, 0x1003, 0x); + + /* EEE auto-fallback function */ + rtl_writephy(tp, 0x1f, 0x0a4b); + rtl_w1w0_phy(tp, 0x11, 0x0004, 0x); + + /* Enable UC LPF tune function */ + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_writephy(tp, 0x13, 0x8012); + rtl_w1w0_phy(tp, 0x14, 0x8000, 0x); + + rtl_writephy(tp, 0x1f, 0x0c42); + rtl_w1w0_phy(tp, 0x11, 0x4000, 0x2000); - r8168_phy_ocp_write(tp, 0xa436, 0x8012); - rtl_w1w0_phy_ocp(tp, 0xa438, 0x8000, 0x); + /* Improve SWR Efficiency */ + rtl_writephy(tp, 0x1f, 0x0bcd); + rtl_writephy(tp, 0x14, 0x5065); + rtl_writephy(tp, 0x14, 0xd065); + rtl_writephy(tp, 0x1f, 0x0bc8); + rtl_writephy(tp, 0x11, 0x5655); + rtl_writephy(tp, 0x1f, 0x0bcd); + rtl_writephy(tp, 0x14, 0x1065); + rtl_writephy(tp, 0x14, 0x9065); + rtl_writephy(tp, 0x14, 0x1065); - rtl_w1w0_phy_ocp(tp, 0xc422, 0x4000, 0x2000); + rtl_writephy(tp, 0x1f, 0x); } static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH 1/5] r8169: Remove firmware code
Some codes are belong to binary codes and should be removed. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 26 -- 1 file changed, 26 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 1170232..e811ab5 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3408,32 +3408,6 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) { - 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, 0x, 0xc602, - - 0xbe00, 0x, 0xc602, 0xbe00, - 0x, 0xc602, 0xbe00, 0x, - 0xc602, 0xbe00, 0x, 0xc602, - 0xbe00, 0x, 0xc602, 0xbe00, - - 0x, 0x, 0x, 0x - }; - u32 i; - - /* Patch code for GPHY reset */ - 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); - rtl_apply_firmware(tp); if (r8168_phy_ocp_read(tp, 0xa460) & 0x0100) -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH firmware] rtl_nic: update firmware for RTL8168G
File: rtl_nic/rtl8168g-2.fw Version: 0.0.1 This firmware supports new fw setting mothod for linux kernel. Add MAC OCP settings for: -phy reset -PXE in ALDPS -pwron sequence -OBFF Signed-off-by: Hayes Wang --- WHENCE| 3 +++ rtl_nic/rtl8168g-2.fw | Bin 0 -> 4896 bytes 2 files changed, 3 insertions(+) create mode 100644 rtl_nic/rtl8168g-2.fw diff --git a/WHENCE b/WHENCE index 96142c2..34a0bba 100644 --- a/WHENCE +++ b/WHENCE @@ -1841,6 +1841,9 @@ Version: 0.0.1 File: rtl_nic/rtl8168g-1.fw Version: 0.0.3 +File: rtl_nic/rtl8168g-2.fw +Version: 0.0.1 + Licence: * Copyright © 2011, Realtek Semiconductor Corporation * diff --git a/rtl_nic/rtl8168g-2.fw b/rtl_nic/rtl8168g-2.fw new file mode 100644 index ..944d44e6a66a266ee2f92f4eb8215acbf58bf3c0 GIT binary patch literal 4896 zcma)=3viXi7035}xd|bLaFeXzk&xV^5TjK{f&&yShM2?~hql&nv{0rAPo+goF;d53 zJw!05pj0U$qNWOp7DIj1VQ5M&BnGug4Yt0=`M`kIDuFr%L^S=K`+XNK8J#JxoZa(2 z|2@0=CB_)DsBz(>vI&!}KCis4bZqI^vT$knxY7yZ%ElwpKf-uCXiS^AeA&7;JR?x#K~pllh2=E zR&5-uUROP+{|Ahz*fq33j7eprG13_sj1VJ>VHr7+WQ;55rMgCPT}MW_K`C%kq{vN` zF>acax#{vFH$(Q;hGfW*ELphN%Kq9MNjp4TqWL3b-`#nV)|D^O--M+hQY6twMoUY6 zu?*T>g6tew_|UnM)HPPjj#9~azFZcY^JU@36U6D71aGpKmJ69rVO~K#m9jXuN}OFa zVzx(QL-M7pry>6_^2=mK%H?vf@d~*q_ey!c=4WEEXGrqlnR2Z07t#@_m(Iv+Iks}H zd^C5yI33rB`RgyGC1s)XG+rk!);37Wkwwx~+bDyMES8rdH_6M9nC$Nu2rkWjJj7kR;`iDQEMf-YMnUldZ~?UkOONTCdU?X zd{hnxHp=-ukIOr?nfO8v?=CFs5_XXd>t z$sO;r{($%{@%PKJq#oiQlv4L&$vgOor2P9+iS>b`$c^;EgUJ~(J;m#R*8*0Ol5)V^ zR5YETy%OSY>|a!3YtujIPHFL+GH!u(Q^Pdm%{H`8vrF^E9OR!U(`nqqHCwqvz?!rcEtgOfO z`BOSKux>+MgWYGvR^(YLQ#XU(8e%tl_McW-xfZ=ad#zlCUJ|sQco$r0<;HR=S1qwp zft`cj3-GZPU0tX6>$l3R)cZOaJ}(4yR(N_DYdkx}UNLu`w311#)fME!Jc<2yW;(i? z$o+BhLUu8-kgwN5yz#Fv{!Z@jeoK!1tovCPvUdFa3MK5<{9*9fqh_f3+kg+nXXC9_ zUc-Jrc?5mC@Bq6Yc2(%BUYMNX`D|xB)FsDcdI9^uHqU2$g_Ta*D)x$LaGkgQ zwz^d>Ugx?2m}tE!*S^tyIj;N1xmG_r(5-jbtHEA>HL*_`Zw`8q5uC*mkN>x`$#FCG zkAdwn`e!NUs0n-@Wkfw+E!dnn#ER1NA9{YKv9~XrgB>v($J1L)OpUR{m!;!FbNT%M zeg^(s;>G*up#kzRbtPSGm$NN-ej&GxJ6_XJ1LSiQJ!%I1@jMeB1vdN4JbW6!E zb zctT!5Kh{8ul988?PolhSDYX(?a}FbGL#M*GkLRj%AdcE6nrBrd`GA-D)ZWuPA0|)D zP3k<}V0bO?Hu|~W2UYvTJQ90*ef{aZ6YuSj{`-{zeG?3W&@Tqz3;JpbSU}%9N*xJr zU(0RTavN{d)-6`H-DbV{YgXQ19(1r>Z{t>Ufr*AM#Z4N9M|vI)8u>KH5YGpsCE`zV-^ zw+pYj35@!zH1$~Nt+w*bT4Z0NAGC7wG7n?tIV*o6k92IEPV|@$(RnKG*AR~%q*sm~ z^RR2$#~m`x%1G{}CYSkWbPI{o>gC^e72g@GM-w|hO;w63xG1h6bh7Z>H_gfc?8l*_ zKKk$xw^_^nocMc4rf?WOdk@Erk zoE8&bnrH9??<>8LDOSqpslCbg20z6#2wqFwdQ6q+`kd-81jiA!DF7fuo1z}Tz&C^f45Eab6$&-Sn= zq<>@U9B-Y;c`D5Jc_Tbtmd|TCXys9GO*4Lv;#1Fs`mBt{sq*4f!K-n=2mTm;FM8RF zc5=w`*XgYD*+b+zn!zwS@WmYffwS4pgm!{=)-R@_hC0o318 zVr8wf9N(|XV{ajESL`jM4-9ddsH2a(dWyYVdpUpcJ=Xhi59e3$_=+>E_HR8$ zUsCgkw;As+-etUp&LA-TgXjAq=0S8meFVPm@0%{~jWX<0H5i#&pzN=i$r;l1Pw=m6 zd^Hb-e&Ex6P<(CV&ff;@3?s|on~}L8zjY0KS8uYi`33Nq!uRNAzOBadZV|7m4Lk1B z{z|^vIp{Sdiyhttp://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 net-next 1/8] r8169: Remove firmware code
Some codes are belong to binary codes and should be removed. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 26 -- 1 file changed, 26 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 28fb50a..d36aa76 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3368,32 +3368,6 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) { - 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, 0x, 0xc602, - - 0xbe00, 0x, 0xc602, 0xbe00, - 0x, 0xc602, 0xbe00, 0x, - 0xc602, 0xbe00, 0x, 0xc602, - 0xbe00, 0x, 0xc602, 0xbe00, - - 0x, 0x, 0x, 0x - }; - u32 i; - - /* Patch code for GPHY reset */ - 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); - rtl_apply_firmware(tp); if (r8168_phy_ocp_read(tp, 0xa460) & 0x0100) -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 net-next 6/8] r8169: add a new chip for RTL8111G
Add a new chip for RTL8111G series. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 45 1 file changed, 45 insertions(+) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 0211836..573b693 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -48,6 +48,7 @@ #define FIRMWARE_8411_1"rtl_nic/rtl8411-1.fw" #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" #define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw" +#define FIRMWARE_8168G_3 "rtl_nic/rtl8168g-3.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -140,6 +141,7 @@ enum mac_version { RTL_GIGA_MAC_VER_39, RTL_GIGA_MAC_VER_40, RTL_GIGA_MAC_VER_41, + RTL_GIGA_MAC_VER_42, RTL_GIGA_MAC_NONE = 0xff, }; @@ -266,6 +268,9 @@ static const struct { JUMBO_9K, false), [RTL_GIGA_MAC_VER_41] = _R("RTL8168g/8111g",RTL_TD_1, NULL, JUMBO_9K, false), + [RTL_GIGA_MAC_VER_42] = + _R("RTL8168g/8111g",RTL_TD_1, FIRMWARE_8168G_3, + JUMBO_9K, false), }; #undef _R @@ -514,6 +519,7 @@ enum rtl_register_content { PMEnable= (1 << 0), /* Power Management Enable */ /* Config2 register p. 25 */ + ClkReqEn= (1 << 7), /* Clock Request Enable */ MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ PCI_Clock_66MHz = 0x01, PCI_Clock_33MHz = 0x00, @@ -534,6 +540,7 @@ enum rtl_register_content { Spi_en = (1 << 3), LanWake = (1 << 1), /* LanWake enable/disable */ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ + ASPM_en = (1 << 0), /* ASPM enable */ /* TBICSR p.28 */ TBIReset= 0x8000, @@ -816,6 +823,7 @@ MODULE_FIRMWARE(FIRMWARE_8402_1); MODULE_FIRMWARE(FIRMWARE_8411_1); MODULE_FIRMWARE(FIRMWARE_8106E_1); MODULE_FIRMWARE(FIRMWARE_8168G_2); +MODULE_FIRMWARE(FIRMWARE_8168G_3); static void rtl_lock_work(struct rtl8169_private *tp) { @@ -2036,6 +2044,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, int mac_version; } mac_info[] = { /* 8168G family. */ + { 0x7cf0, 0x5090, RTL_GIGA_MAC_VER_42 }, { 0x7cf0, 0x4c10, RTL_GIGA_MAC_VER_41 }, { 0x7cf0, 0x4c00, RTL_GIGA_MAC_VER_40 }, @@ -3439,6 +3448,11 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x); } +static void rtl8168g_2_hw_phy_config(struct rtl8169_private *tp) +{ + rtl_apply_firmware(tp); +} + static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -3624,6 +3638,9 @@ static void rtl_hw_phy_config(struct net_device *dev) case RTL_GIGA_MAC_VER_40: rtl8168g_1_hw_phy_config(tp); break; + case RTL_GIGA_MAC_VER_42: + rtl8168g_2_hw_phy_config(tp); + break; case RTL_GIGA_MAC_VER_41: default: @@ -3832,6 +3849,7 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp) break; case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: + case RTL_GIGA_MAC_VER_42: ops->write = r8168g_mdio_write; ops->read = r8168g_mdio_read; break; @@ -3859,6 +3877,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_39: case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: + case RTL_GIGA_MAC_VER_42: RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); break; @@ -4121,6 +4140,7 @@ static void rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_38: case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: + case RTL_GIGA_MAC_VER_42: ops->down = r8168_pll_power_down; ops->up = r8168_pll_power_up; break; @@ -4165,6 +4185,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) break; case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: + case RTL_GIGA_MAC_VER_42: RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF); break; default: @@ -4323,6 +4344,7 @@ static void rtl_init_jumbo_ops(struct rtl8169_private *tp) */ case RTL_GIGA_MAC_VER_40:
[PATCH v2 net-next 5/8] r8169: Update the RTL8111G parameters
- replace rtl8168g-1.fw with rtl8168g-2.fw which support new method. - fix PHY power down is useless. - disable rx early which causes the rx abnormal. - enable auto fifo. - set 10M IFG to default value. - fix the conflict between jumbo frame and flow control. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 29 + 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index e7e7d37..0211836 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -47,7 +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" +#define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -262,7 +262,7 @@ static const struct { _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, + _R("RTL8168g/8111g",RTL_TD_1, FIRMWARE_8168G_2, JUMBO_9K, false), [RTL_GIGA_MAC_VER_41] = _R("RTL8168g/8111g",RTL_TD_1, NULL, JUMBO_9K, false), @@ -329,6 +329,7 @@ enum rtl_registers { #defineRXCFG_FIFO_SHIFT13 /* No threshold before first PCI xfer */ #defineRX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) +#defineRX_EARLY_OFF(1 << 11) #defineRXCFG_DMA_SHIFT 8 /* Unlimited maximum PCI burst. */ #defineRX_DMA_BURST(7 << RXCFG_DMA_SHIFT) @@ -814,7 +815,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); +MODULE_FIRMWARE(FIRMWARE_8168G_2); static void rtl_lock_work(struct rtl8169_private *tp) { @@ -3967,6 +3968,8 @@ static void r8168_phy_power_down(struct rtl8169_private *tp) switch (tp->mac_version) { case RTL_GIGA_MAC_VER_32: case RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN); break; @@ -4028,6 +4031,11 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_33: RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + rtl_w1w0_eri(tp, 0x1a8, ERIAR_MASK_, 0x, +0xfc00, ERIAR_EXGMAC); + break; } } @@ -4045,6 +4053,11 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_33: RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + rtl_w1w0_eri(tp, 0x1a8, ERIAR_MASK_, 0xfc00, +0x, ERIAR_EXGMAC); + break; } r8168_phy_power_up(tp); @@ -4150,6 +4163,10 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_34: RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF); + break; default: RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST); break; @@ -5128,6 +5145,8 @@ 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_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); + 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); @@ -5139,6 +5158,7 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) 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, 0x2f8, ERIAR_MASK_0011, 0x1d8f, ERIAR_EXGMAC); RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W32(MISC, RTL_R32(MISC) & ~
[PATCH v2 net-next 8/8] r8169: add a new chip for RTL8106E
Add a new chip for RTL8106E series. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 21 + 1 file changed, 21 insertions(+) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 85536bf..e392dd0 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_8106E_2 "rtl_nic/rtl8106e-2.fw" #define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw" #define FIRMWARE_8168G_3 "rtl_nic/rtl8168g-3.fw" @@ -142,6 +143,7 @@ enum mac_version { RTL_GIGA_MAC_VER_40, RTL_GIGA_MAC_VER_41, RTL_GIGA_MAC_VER_42, + RTL_GIGA_MAC_VER_43, RTL_GIGA_MAC_NONE = 0xff, }; @@ -271,6 +273,9 @@ static const struct { [RTL_GIGA_MAC_VER_42] = _R("RTL8168g/8111g",RTL_TD_1, FIRMWARE_8168G_3, JUMBO_9K, false), + [RTL_GIGA_MAC_VER_43] = + _R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_2, + JUMBO_1K, true), }; #undef _R @@ -822,6 +827,7 @@ MODULE_FIRMWARE(FIRMWARE_8168F_2); MODULE_FIRMWARE(FIRMWARE_8402_1); MODULE_FIRMWARE(FIRMWARE_8411_1); MODULE_FIRMWARE(FIRMWARE_8106E_1); +MODULE_FIRMWARE(FIRMWARE_8106E_2); MODULE_FIRMWARE(FIRMWARE_8168G_2); MODULE_FIRMWARE(FIRMWARE_8168G_3); @@ -2133,6 +2139,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, netif_notice(tp, probe, dev, "unknown MAC, using family default\n"); tp->mac_version = default_version; + } else if (tp->mac_version == RTL_GIGA_MAC_VER_42) { + tp->mac_version = tp->mii.supports_gmii ? + RTL_GIGA_MAC_VER_42 : + RTL_GIGA_MAC_VER_43; } } @@ -3639,6 +3649,7 @@ static void rtl_hw_phy_config(struct net_device *dev) rtl8168g_1_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_43: rtl8168g_2_hw_phy_config(tp); break; @@ -3850,6 +3861,7 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_43: ops->write = r8168g_mdio_write; ops->read = r8168g_mdio_read; break; @@ -3878,6 +3890,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_43: RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); break; @@ -4113,6 +4126,7 @@ static void rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_30: case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_39: + case RTL_GIGA_MAC_VER_43: ops->down = r810x_pll_power_down; ops->up = r810x_pll_power_up; break; @@ -4186,6 +4200,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_43: RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF); break; default: @@ -4345,6 +4360,7 @@ static void rtl_init_jumbo_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_43: default: ops->disable= NULL; ops->enable = NULL; @@ -4453,6 +4469,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) tp->mac_version == RTL_GIGA_MAC_VER_40 || tp->mac_version == RTL_GIGA_MAC_VER_41 || tp->mac_version == RTL_GIGA_MAC_VER_42 || + tp->mac_version == RTL_GIGA_MAC_VER_43 || tp->mac_version == RTL_GIGA_MAC_VER_38) { RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); @@ -5527,6 +5544,9 @@ static void rtl_hw_start_8101(struct net_device *dev) case RTL_GIGA_MAC_VER_39: rtl_hw_start_8106(tp); break; + case RTL_GIGA_MAC_VER_43: +
[PATCH v2 net-next 7/8] r8169: adjust the flow of hw_start
The suggestion as following: - initial settings or default settings - rtl_hw_start_xxx. rtl_hw_start_xxx may change some default settings. - enable tx/rx. This has to be after the above two steps. - rtl_set_rx_mode. AcceptXXXs have to be enabled after enabling tx/rx. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 573b693..85536bf 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -5240,10 +5240,7 @@ static void rtl_hw_start_8168(struct net_device *dev) rtl_set_rx_tx_desc_registers(tp, ioaddr); - rtl_set_rx_mode(dev); - - RTL_W32(TxConfig, (TX_DMA_BURST << TxDMAShift) | - (InterFrameGap << TxInterFrameGapShift)); + rtl_set_rx_tx_config_registers(tp); RTL_R8(IntrMask); @@ -5330,9 +5327,11 @@ static void rtl_hw_start_8168(struct net_device *dev) break; } + RTL_W8(Cfg9346, Cfg9346_Lock); + RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - RTL_W8(Cfg9346, Cfg9346_Lock); + rtl_set_rx_mode(dev); RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); } @@ -5490,6 +5489,17 @@ static void rtl_hw_start_8101(struct net_device *dev) RTL_W8(Cfg9346, Cfg9346_Unlock); + RTL_W8(MaxTxPacketSize, TxPacketMax); + + rtl_set_rx_max_size(ioaddr, rx_buf_sz); + + tp->cp_cmd &= ~R810X_CPCMD_QUIRK_MASK; + RTL_W16(CPlusCmd, tp->cp_cmd); + + rtl_set_rx_tx_desc_registers(tp, ioaddr); + + rtl_set_rx_tx_config_registers(tp); + switch (tp->mac_version) { case RTL_GIGA_MAC_VER_07: rtl_hw_start_8102e_1(tp); @@ -5521,24 +5531,14 @@ static void rtl_hw_start_8101(struct net_device *dev) RTL_W8(Cfg9346, Cfg9346_Lock); - RTL_W8(MaxTxPacketSize, TxPacketMax); - - rtl_set_rx_max_size(ioaddr, rx_buf_sz); - - tp->cp_cmd &= ~R810X_CPCMD_QUIRK_MASK; - RTL_W16(CPlusCmd, tp->cp_cmd); - RTL_W16(IntrMitigate, 0x); - rtl_set_rx_tx_desc_registers(tp, ioaddr); - RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); - rtl_set_rx_tx_config_registers(tp); - - RTL_R8(IntrMask); rtl_set_rx_mode(dev); + RTL_R8(IntrMask); + RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000); } -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 net-next 3/8] r8169: Update PHY settings of RTL8111G
Add the new settings and correct the wrong settings. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 24 ++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 2c40309..b8b59a9 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3376,14 +3376,23 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0c41); rtl_w1w0_phy(tp, 0x15, 0x0002, 0x); } else { - rtl_writephy(tp, 0x1f, 0x0bcc); - rtl_w1w0_phy(tp, 0x12, 0x, 0x0002); + rtl_writephy(tp, 0x1f, 0x0c41); + rtl_w1w0_phy(tp, 0x15, 0x, 0x0002); } /* Enable PHY auto speed down */ rtl_writephy(tp, 0x1f, 0x0a44); rtl_w1w0_phy(tp, 0x11, 0x000c, 0x); + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x14, 0x0100, 0x); + rtl_writephy(tp, 0x1f, 0x0a44); + rtl_w1w0_phy(tp, 0x11, 0x00c0, 0x); + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_writephy(tp, 0x13, 0x8084); + rtl_w1w0_phy(tp, 0x14, 0x, 0x6000); + rtl_w1w0_phy(tp, 0x10, 0x1003, 0x); + /* EEE auto-fallback function */ rtl_writephy(tp, 0x1f, 0x0a4b); rtl_w1w0_phy(tp, 0x11, 0x0004, 0x); @@ -3396,6 +3405,17 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x0c42); rtl_w1w0_phy(tp, 0x11, 0x4000, 0x2000); + /* Improve SWR Efficiency */ + rtl_writephy(tp, 0x1f, 0x0bcd); + rtl_writephy(tp, 0x14, 0x5065); + rtl_writephy(tp, 0x14, 0xd065); + rtl_writephy(tp, 0x1f, 0x0bc8); + rtl_writephy(tp, 0x11, 0x5655); + rtl_writephy(tp, 0x1f, 0x0bcd); + rtl_writephy(tp, 0x14, 0x1065); + rtl_writephy(tp, 0x14, 0x9065); + rtl_writephy(tp, 0x14, 0x1065); + rtl_writephy(tp, 0x1f, 0x); } -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 net-next 4/8] r8169: Modify the method for setting firmware
Remove useless action PHY_READ_EFUSE, PHY_READ_MAC_BYTE, PHY_WRITE_MAC_BYTE, PHY_WRITE_ERI_WORD. And define the new action PHY_MDIO_CHG. PHY_MDIO_CHG is used to modify the mdio operation. By the way, the firmware could support setting mac ocp. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 45 +--- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index b8b59a9..e7e7d37 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1069,6 +1069,21 @@ static int r8168g_mdio_read(struct rtl8169_private *tp, int reg) return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2); } +static void mac_mcu_write(struct rtl8169_private *tp, int reg, int value) +{ + if (reg == 0x1f) { + tp->ocp_base = value << 4; + return; + } + + r8168_mac_ocp_write(tp, tp->ocp_base + reg, value); +} + +static int mac_mcu_read(struct rtl8169_private *tp, int reg) +{ + return r8168_mac_ocp_read(tp, tp->ocp_base + reg); +} + DECLARE_RTL_COND(rtl_phyar_cond) { void __iomem *ioaddr = tp->mmio_addr; @@ -2134,9 +2149,7 @@ static void rtl_writephy_batch(struct rtl8169_private *tp, #define PHY_DATA_OR0x1000 #define PHY_DATA_AND 0x2000 #define PHY_BJMPN 0x3000 -#define PHY_READ_EFUSE 0x4000 -#define PHY_READ_MAC_BYTE 0x5000 -#define PHY_WRITE_MAC_BYTE 0x6000 +#define PHY_MDIO_CHG 0x4000 #define PHY_CLEAR_READCOUNT0x7000 #define PHY_WRITE 0x8000 #define PHY_READCOUNT_EQ_SKIP 0x9000 @@ -2145,7 +2158,6 @@ static void rtl_writephy_batch(struct rtl8169_private *tp, #define PHY_WRITE_PREVIOUS 0xc000 #define PHY_SKIPN 0xd000 #define PHY_DELAY_MS 0xe000 -#define PHY_WRITE_ERI_WORD 0xf000 struct fw_info { u32 magic; @@ -,7 +2234,7 @@ static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev, case PHY_READ: case PHY_DATA_OR: case PHY_DATA_AND: - case PHY_READ_EFUSE: + case PHY_MDIO_CHG: case PHY_CLEAR_READCOUNT: case PHY_WRITE: case PHY_WRITE_PREVIOUS: @@ -2253,9 +2265,6 @@ static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev, } break; - case PHY_READ_MAC_BYTE: - case PHY_WRITE_MAC_BYTE: - case PHY_WRITE_ERI_WORD: default: netif_err(tp, ifup, tp->dev, "Invalid action 0x%08x\n", action); @@ -2286,10 +2295,13 @@ out: static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) { struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; + struct mdio_ops org, *ops = &tp->mdio_ops; u32 predata, count; size_t index; predata = count = 0; + org.write = ops->write; + org.read = ops->read; for (index = 0; index < pa->size; ) { u32 action = le32_to_cpu(pa->code[index]); @@ -2316,8 +2328,15 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) case PHY_BJMPN: index -= regno; break; - case PHY_READ_EFUSE: - predata = rtl8168d_efuse_read(tp, regno); + case PHY_MDIO_CHG: + if (data == 0) { + ops->write = org.write; + ops->read = org.read; + } else if (data == 1) { + ops->write = mac_mcu_write; + ops->read = mac_mcu_read; + } + index++; break; case PHY_CLEAR_READCOUNT: @@ -2353,13 +2372,13 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) index++; break; - case PHY_READ_MAC_BYTE: - case PHY_WRITE_MAC_BYTE: - case PHY_WRITE_ERI_WORD: default: BUG(); } } + + ops->write = org.write; + ops->read = org.read; } static void rtl_release_firmware(struct rtl8169_private *tp) -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 net-next 2/8] r8169: Modify the mothod for PHY settings of RTL8111G
Replace the current settings with rtl_writephy and rtl_readphy. For the hardware, the settings are same with previous ones. This make the setting method like the previous chips. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 52 +--- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index d36aa76..2c40309 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1024,14 +1024,6 @@ static u16 r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) (RTL_R32(GPHY_OCP) & 0x) : ~0; } -static void rtl_w1w0_phy_ocp(struct rtl8169_private *tp, int reg, int p, int m) -{ - int val; - - val = r8168_phy_ocp_read(tp, reg); - r8168_phy_ocp_write(tp, reg, (val | p) & ~m); -} - static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) { void __iomem *ioaddr = tp->mmio_addr; @@ -3370,23 +3362,41 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) { rtl_apply_firmware(tp); - if (r8168_phy_ocp_read(tp, 0xa460) & 0x0100) - rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x, 0x8000); - else - rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x8000, 0x); + rtl_writephy(tp, 0x1f, 0x0a46); + if (rtl_readphy(tp, 0x10) & 0x0100) { + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x12, 0x, 0x8000); + } else { + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x12, 0x8000, 0x); + } - if (r8168_phy_ocp_read(tp, 0xa466) & 0x0100) - rtl_w1w0_phy_ocp(tp, 0xc41a, 0x0002, 0x); - else - rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x, 0x0002); + rtl_writephy(tp, 0x1f, 0x0a46); + if (rtl_readphy(tp, 0x13) & 0x0100) { + rtl_writephy(tp, 0x1f, 0x0c41); + rtl_w1w0_phy(tp, 0x15, 0x0002, 0x); + } else { + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x12, 0x, 0x0002); + } - rtl_w1w0_phy_ocp(tp, 0xa442, 0x000c, 0x); - rtl_w1w0_phy_ocp(tp, 0xa4b2, 0x0004, 0x); + /* Enable PHY auto speed down */ + rtl_writephy(tp, 0x1f, 0x0a44); + rtl_w1w0_phy(tp, 0x11, 0x000c, 0x); - r8168_phy_ocp_write(tp, 0xa436, 0x8012); - rtl_w1w0_phy_ocp(tp, 0xa438, 0x8000, 0x); + /* EEE auto-fallback function */ + rtl_writephy(tp, 0x1f, 0x0a4b); + rtl_w1w0_phy(tp, 0x11, 0x0004, 0x); - rtl_w1w0_phy_ocp(tp, 0xc422, 0x4000, 0x2000); + /* Enable UC LPF tune function */ + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_writephy(tp, 0x13, 0x8012); + rtl_w1w0_phy(tp, 0x14, 0x8000, 0x); + + rtl_writephy(tp, 0x1f, 0x0c42); + rtl_w1w0_phy(tp, 0x11, 0x4000, 0x2000); + + rtl_writephy(tp, 0x1f, 0x); } static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 net-next 2/2] r8169: update the settings for RTL8111G
Update the parameters of RTL8111G Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 118 ++- 1 file changed, 101 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index cdd46de..3a393f7 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -335,6 +335,7 @@ enum rtl_registers { #defineRXCFG_FIFO_SHIFT13 /* No threshold before first PCI xfer */ #defineRX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) +#defineRX_EARLY_OFF(1 << 11) #defineRXCFG_DMA_SHIFT 8 /* Unlimited maximum PCI burst. */ #defineRX_DMA_BURST(7 << RXCFG_DMA_SHIFT) @@ -2434,6 +2435,15 @@ static void r8168_aldps_enable_1(struct rtl8169_private *tp) rtl_w1w0_phy(tp, 0x15, 0x1000, 0x); } +static void r8168_aldps_enable_2(struct rtl8169_private *tp) +{ + if (!(tp->features & RTL_FEATURE_EXTENDED)) + return; + + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_w1w0_phy(tp, 0x10, 0x0004, 0x); +} + static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -3400,29 +3410,57 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) { static const u16 mac_ocp_patch[] = { 0xe008, 0xe01b, 0xe01d, 0xe01f, - 0xe021, 0xe023, 0xe025, 0xe027, + 0xe022, 0xe025, 0xe031, 0xe04d, 0x49d2, 0xf10d, 0x766c, 0x49e2, 0xf00a, 0x1ec0, 0x8ee1, 0xc60a, - 0x77c0, 0x4870, 0x9fc0, 0x1ea0, 0xc707, 0x8ee1, 0x9d6c, 0xc603, 0xbe00, 0xb416, 0x0076, 0xe86c, - 0xc602, 0xbe00, 0x, 0xc602, - - 0xbe00, 0x, 0xc602, 0xbe00, - 0x, 0xc602, 0xbe00, 0x, - 0xc602, 0xbe00, 0x, 0xc602, - 0xbe00, 0x, 0xc602, 0xbe00, - - 0x, 0x, 0x, 0x + 0xc602, 0xbe00, 0xa000, 0xc602, + 0xbe00, 0x, 0x1b76, 0xc202, + 0xba00, 0x059c, 0x1b76, 0xc602, + 0xbe00, 0x065a, 0x74e6, 0x1b78, + 0x46dc, 0x1300, 0xf005, 0x74f8, + 0x48c3, 0x48c4, 0x8cf8, 0x64e7, + 0xc302, 0xbb00, 0x06a0, 0x74e4, + 0x49c5, 0xf106, 0x49c6, 0xf107, + 0x48c8, 0x48c9, 0xe011, 0x48c9, + 0x4848, 0xe00e, 0x4848, 0x49c7, + 0xf00a, 0x48c9, 0xc60d, 0x1d1f, + 0x8dc2, 0x1d00, 0x8dc3, 0x1d11, + 0x8dc0, 0xe002, 0x4849, 0x94e5, + 0xc602, 0xbe00, 0x01f0, 0xe434, + 0x49d9, 0xf01b, 0xc31e, 0x7464, + 0x49c4, 0xf114, 0xc31b, 0x6460, + 0x14fa, 0xfa02, 0xe00f, 0xc317, + 0x7460, 0x49c0, 0xf10b, 0xc311, + 0x7462, 0x48c1, 0x9c62, 0x4841, + 0x9c62, 0xc30a, 0x1c04, 0x8c60, + 0xe004, 0x1c15, 0xc305, 0x8c60, + 0xc602, 0xbe00, 0x0384, 0xe434, + 0xe030, 0xe61c, 0xe906 }; u32 i; /* Patch code for GPHY reset */ + r8168_mac_ocp_write(tp, 0xfc26, 0x); + r8168_mac_ocp_write(tp, 0xfc28, 0x); + r8168_mac_ocp_write(tp, 0xfc2a, 0x); + r8168_mac_ocp_write(tp, 0xfc2c, 0x); + r8168_mac_ocp_write(tp, 0xfc2e, 0x); + r8168_mac_ocp_write(tp, 0xfc30, 0x); + r8168_mac_ocp_write(tp, 0xfc32, 0x); + r8168_mac_ocp_write(tp, 0xfc34, 0x); + r8168_mac_ocp_write(tp, 0xfc36, 0x); 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, 0xf800 + 2 * i, mac_ocp_patch[i]); r8168_mac_ocp_write(tp, 0xfc26, 0x8000); r8168_mac_ocp_write(tp, 0xfc28, 0x0075); + r8168_mac_ocp_write(tp, 0xfc2e, 0x059b); + r8168_mac_ocp_write(tp, 0xfc30, 0x0659); + r8168_mac_ocp_write(tp, 0xfc32, 0x069f); + r8168_mac_ocp_write(tp, 0xfc34, 0x01cd); + r8168_mac_ocp_write(tp, 0xfc36, 0x0303); rtl_apply_firmware(tp); @@ -3436,13 +3474,46 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) else rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x, 0x0002); - rtl_w1w0_phy_ocp(tp, 0xa442, 0x000c, 0x); - rtl_w1w0_phy_ocp(tp, 0xa4b2, 0x0004, 0x); + /* Enable PHY auto speed down */ + rtl_writephy(tp, 0x1f, 0x0a44); + rtl_w1w0_phy(tp, 0x11, 0x000c, 0x); + + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x14, 0x0100, 0x); + rtl_writephy(tp, 0x1f, 0x0a44); + rtl_w1w0_
[PATCH v2 net-next 1/2] r8169: enable ALDPS for power saving
Enable ALDPS function to save power when link down. Note that the feature should be set after the other PHY settings. And the firmware is necessary. Don't enable it without loading the firmware. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 62 ++-- 1 file changed, 52 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index e7ff886..cdd46de 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -687,6 +687,7 @@ enum features { RTL_FEATURE_WOL = (1 << 0), RTL_FEATURE_MSI = (1 << 1), RTL_FEATURE_GMII= (1 << 2), + RTL_FEATURE_EXTENDED= (1 << 3), }; struct rtl8169_counters { @@ -2394,8 +2395,10 @@ static void rtl_apply_firmware(struct rtl8169_private *tp) struct rtl_fw *rtl_fw = tp->rtl_fw; /* TODO: release firmware once rtl_phy_write_fw signals failures. */ - if (!IS_ERR_OR_NULL(rtl_fw)) + if (!IS_ERR_OR_NULL(rtl_fw)) { rtl_phy_write_fw(tp, rtl_fw); + tp->features |= RTL_FEATURE_EXTENDED; + } } static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) @@ -2406,6 +2409,31 @@ static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) rtl_apply_firmware(tp); } +static void r810x_aldps_disable(struct rtl8169_private *tp) +{ + rtl_writephy(tp, 0x1f, 0x); + rtl_writephy(tp, 0x18, 0x0310); + msleep(100); +} + +static void r810x_aldps_enable(struct rtl8169_private *tp) +{ + if (!(tp->features & RTL_FEATURE_EXTENDED)) + return; + + rtl_writephy(tp, 0x1f, 0x); + rtl_writephy(tp, 0x18, 0x8310); +} + +static void r8168_aldps_enable_1(struct rtl8169_private *tp) +{ + if (!(tp->features & RTL_FEATURE_EXTENDED)) + return; + + rtl_writephy(tp, 0x1f, 0x); + rtl_w1w0_phy(tp, 0x15, 0x1000, 0x); +} + static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -3178,6 +3206,9 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp) rtl_w1w0_phy(tp, 0x19, 0x, 0x0001); rtl_w1w0_phy(tp, 0x10, 0x, 0x0400); rtl_writephy(tp, 0x1f, 0x); + + /* ALDPS enable */ + r8168_aldps_enable_1(tp); } static void rtl8168f_hw_phy_config(struct rtl8169_private *tp) @@ -3250,6 +3281,9 @@ static void rtl8168f_1_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x05, 0x8b85); rtl_w1w0_phy(tp, 0x06, 0x4000, 0x); rtl_writephy(tp, 0x1f, 0x); + + /* ALDPS enable */ + r8168_aldps_enable_1(tp); } static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) @@ -3257,6 +3291,9 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) rtl_apply_firmware(tp); rtl8168f_hw_phy_config(tp); + + /* ALDPS enable */ + r8168_aldps_enable_1(tp); } static void rtl8411_hw_phy_config(struct rtl8169_private *tp) @@ -3354,6 +3391,9 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) rtl_w1w0_phy(tp, 0x19, 0x, 0x0001); rtl_w1w0_phy(tp, 0x10, 0x, 0x0400); rtl_writephy(tp, 0x1f, 0x); + + /* ALDPS enable */ + r8168_aldps_enable_1(tp); } static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) @@ -3439,21 +3479,19 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp) }; /* Disable ALDPS before ram code */ - rtl_writephy(tp, 0x1f, 0x); - rtl_writephy(tp, 0x18, 0x0310); - msleep(100); + r810x_aldps_disable(tp); rtl_apply_firmware(tp); rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + + r810x_aldps_enable(tp); } static void rtl8402_hw_phy_config(struct rtl8169_private *tp) { /* Disable ALDPS before setting firmware */ - rtl_writephy(tp, 0x1f, 0x); - rtl_writephy(tp, 0x18, 0x0310); - msleep(20); + r810x_aldps_disable(tp); rtl_apply_firmware(tp); @@ -3463,6 +3501,8 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x10, 0x401f); rtl_writephy(tp, 0x19, 0x7030); rtl_writephy(tp, 0x1f, 0x); + + r810x_aldps_enable(tp); } static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) @@ -3475,9 +3515,7 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) }; /* Disable ALDPS before ram code */ - rtl_writephy(tp, 0x1f, 0x); - rtl_writephy(tp, 0x18, 0x0310); - msleep(100); + r810x_aldps_disable(tp); rtl_apply_firmware(tp); @@ -3485,6 +3523,8 @@ static void rtl8106e_hw_phy_config(struct rt
[PATCH firmware] rtl_nic: update firmware for RTL8168G
File: rtl_nic/rtl8168g-1.fw Version: 0.0.3 Signed-off-by: Hayes Wang --- WHENCE| 2 +- rtl_nic/rtl8168g-1.fw | Bin 4272 -> 4304 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/WHENCE b/WHENCE index 6bc7417..2565fa2 100644 --- a/WHENCE +++ b/WHENCE @@ -1835,7 +1835,7 @@ File: rtl_nic/rtl8106e-1.fw Version: 0.0.1 File: rtl_nic/rtl8168g-1.fw -Version: 0.0.2 +Version: 0.0.3 Licence: * Copyright © 2011, Realtek Semiconductor Corporation diff --git a/rtl_nic/rtl8168g-1.fw b/rtl_nic/rtl8168g-1.fw index bc03a5d28fd07d99a6cc89aa115d8ef8942629a6..2c628b03a7fa6cf58775a8ce22717f9d326d5336 100644 GIT binary patch delta 470 zcmXw#O-NK>6o&5|uQ}IY{_tgj8f2!RMKnM6jt;{JE+!0j>ZX{L{Sf`2(BC4$#fyj| zL5nybuEa&b6cojU2%6BvAh@d5krW7mF_R#O!I&O#I`Hv+oO9mi`_6fn{F+P|8V?># z6r6nFR>~RArnBi>!pUabT*h&aiW*n-oU#mK;d$zGwBWkqlXo88NH~4PzI?IYd0&3q z6~6|yd|=`Y=<5KdX2E3pz9x;XlfI6MobV4scEEB8tZ47@9QZ}X{GQufQFjIWX@Eo1 z;F(=;dIS731pb@X+P+dP@W~7~qfVbEz4j+-54_(E{IJx&ueT2c(>EDwy!{qV@Si;6Ht6r<}fzN^}*>uvp|s>8n6 zl4dxTU$_T8eF;`SfTM%pU=^(8bPucGYE9c-g9jzhUkB@ItH!{Unv^2vL$P`fjZQHA Mv4^b#xf{832*S#rjsO4v delta 480 zcmXv~T_~hs82!F67-Q$>(?Km4-{6X!@qI?Kel{1la>J@^8#j~-)UJdJxp6KqB{zC& z+nX(gOj|1&O$v=7w|+_~HQSa_qP^r|vCp^cQ%~pZdCocSdEevEdMK<(jgEh6uwxAa zVY}CgSdlu@dRuGTwRWAel-PlwgYpS<4;uHDhAHY8@ z(EI_qa=?*UF!XZXRk!)2uDe;4=V=aJgYi}{A>7OaxUb%OQm=n+f{$Os;X%}HaCjP= z7KUq8#R|5oZbUN!>L*}(My6-a9{#l#Ru=rGioJ_^he~_1#zg{b6}2xecNkz+trS-J z{!cS9&8oA)X8mW%cr~c&bE!$6SJ$u9jNde>!Nnk$t3O9vd#BR=kEj7J#ncJl7&{i1 zDinB=d*viiJ%OluN#3p&0-aL{4b+anHnGq;#YTQZI~6Ptl;r>LTu^w+zrZcQ15JK#http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 net-next] r8169: enable ALDPS for power saving
Enable ALDPS function to save power when link down. Note that the feature should be set after the other PHY settings. And the firmware is necessary. Don't enable it without loading the firmware. None of the firmware-free chipsets support ALDPS. Neither do the RTL8168d/8111d. For 8136 series, make sure the ALDPS is disabled before loading the firmware. For 8168 series, the ALDPS would be disabled automatically when loading firmware. You must not disable it directly. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 56 +--- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index e7ff886..2317b8c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -687,6 +687,7 @@ enum features { RTL_FEATURE_WOL = (1 << 0), RTL_FEATURE_MSI = (1 << 1), RTL_FEATURE_GMII= (1 << 2), + RTL_FEATURE_FW_LOADED = (1 << 3), }; struct rtl8169_counters { @@ -2394,8 +2395,10 @@ static void rtl_apply_firmware(struct rtl8169_private *tp) struct rtl_fw *rtl_fw = tp->rtl_fw; /* TODO: release firmware once rtl_phy_write_fw signals failures. */ - if (!IS_ERR_OR_NULL(rtl_fw)) + if (!IS_ERR_OR_NULL(rtl_fw)) { rtl_phy_write_fw(tp, rtl_fw); + tp->features |= RTL_FEATURE_FW_LOADED; + } } static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) @@ -2406,6 +2409,31 @@ static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) rtl_apply_firmware(tp); } +static void r810x_aldps_disable(struct rtl8169_private *tp) +{ + rtl_writephy(tp, 0x1f, 0x); + rtl_writephy(tp, 0x18, 0x0310); + msleep(100); +} + +static void r810x_aldps_enable(struct rtl8169_private *tp) +{ + if (!(tp->features & RTL_FEATURE_FW_LOADED)) + return; + + rtl_writephy(tp, 0x1f, 0x); + rtl_writephy(tp, 0x18, 0x8310); +} + +static void r8168_aldps_enable_1(struct rtl8169_private *tp) +{ + if (!(tp->features & RTL_FEATURE_FW_LOADED)) + return; + + rtl_writephy(tp, 0x1f, 0x); + rtl_w1w0_phy(tp, 0x15, 0x1000, 0x); +} + static void rtl8169s_hw_phy_config(struct rtl8169_private *tp) { static const struct phy_reg phy_reg_init[] = { @@ -3178,6 +3206,8 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp) rtl_w1w0_phy(tp, 0x19, 0x, 0x0001); rtl_w1w0_phy(tp, 0x10, 0x, 0x0400); rtl_writephy(tp, 0x1f, 0x); + + r8168_aldps_enable_1(tp); } static void rtl8168f_hw_phy_config(struct rtl8169_private *tp) @@ -3250,6 +3280,8 @@ static void rtl8168f_1_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x05, 0x8b85); rtl_w1w0_phy(tp, 0x06, 0x4000, 0x); rtl_writephy(tp, 0x1f, 0x); + + r8168_aldps_enable_1(tp); } static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) @@ -3257,6 +3289,8 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) rtl_apply_firmware(tp); rtl8168f_hw_phy_config(tp); + + r8168_aldps_enable_1(tp); } static void rtl8411_hw_phy_config(struct rtl8169_private *tp) @@ -3354,6 +3388,8 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) rtl_w1w0_phy(tp, 0x19, 0x, 0x0001); rtl_w1w0_phy(tp, 0x10, 0x, 0x0400); rtl_writephy(tp, 0x1f, 0x); + + r8168_aldps_enable_1(tp); } static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) @@ -3439,21 +3475,19 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp) }; /* Disable ALDPS before ram code */ - rtl_writephy(tp, 0x1f, 0x); - rtl_writephy(tp, 0x18, 0x0310); - msleep(100); + r810x_aldps_disable(tp); rtl_apply_firmware(tp); rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + + r810x_aldps_enable(tp); } static void rtl8402_hw_phy_config(struct rtl8169_private *tp) { /* Disable ALDPS before setting firmware */ - rtl_writephy(tp, 0x1f, 0x); - rtl_writephy(tp, 0x18, 0x0310); - msleep(20); + r810x_aldps_disable(tp); rtl_apply_firmware(tp); @@ -3463,6 +3497,8 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x10, 0x401f); rtl_writephy(tp, 0x19, 0x7030); rtl_writephy(tp, 0x1f, 0x); + + r810x_aldps_enable(tp); } static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) @@ -3475,9 +3511,7 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) }; /* Disable ALDPS before ram code */ - rtl_writephy(tp, 0x1f, 0x); - r
[PATCH net-next] r8169: enable internal ASPM and clock request settings
The following chips need to enable internal settings to let ASPM and clock request work. RTL8111E-VL, RTL8111F, RTL8411, RTL8111G RTL8105, RTL8402, RTL8106 Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 29 + 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 123c6a5..87d03f6 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -456,6 +456,7 @@ enum rtl8168_registers { #define PWM_EN (1 << 22) #define RXDV_GATED_EN (1 << 19) #define EARLY_TALLY_EN (1 << 16) +#define FORCE_CLK (1 << 15) /* force clock request */ }; enum rtl_register_content { @@ -519,6 +520,7 @@ enum rtl_register_content { PMEnable= (1 << 0), /* Power Management Enable */ /* Config2 register p. 25 */ + ClkReqEn= (1 << 7), /* Clock Request Enable */ MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ PCI_Clock_66MHz = 0x01, PCI_Clock_33MHz = 0x00, @@ -539,6 +541,7 @@ enum rtl_register_content { Spi_en = (1 << 3), LanWake = (1 << 1), /* LanWake enable/disable */ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ + ASPM_en = (1 << 0), /* ASPM enable */ /* TBICSR p.28 */ TBIReset= 0x8000, @@ -5046,8 +5049,6 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) RTL_W8(MaxTxPacketSize, EarlySize); - rtl_disable_clock_request(pdev); - RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); @@ -5056,7 +5057,8 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); - RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); + RTL_W8(Config5, (RTL_R8(Config5) & ~Spi_en) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); } static void rtl_hw_start_8168f(struct rtl8169_private *tp) @@ -5081,13 +5083,12 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp) RTL_W8(MaxTxPacketSize, EarlySize); - rtl_disable_clock_request(pdev); - RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); - RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); - RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); + RTL_W32(MISC, RTL_R32(MISC) | PWM_EN | FORCE_CLK); + RTL_W8(Config5, (RTL_R8(Config5) & ~Spi_en) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); } static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) @@ -5145,7 +5146,10 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W32(MISC, RTL_R32(MISC) & ~RXDV_GATED_EN); + RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK); RTL_W8(MaxTxPacketSize, EarlySize); + RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x, ERIAR_EXGMAC); rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x, ERIAR_EXGMAC); @@ -5361,6 +5365,9 @@ 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_W8(Config5, RTL_R8(Config5) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); + RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK); rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); } @@ -5386,6 +5393,9 @@ 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_W8(Config5, RTL_R8(Config5) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); + RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK); rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402)); @@ -5407,7 +5417,10 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp) /* 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_W32(MISC, RTL_R32(MISC) & ~EARLY_TALLY_EN); + RTL_W32(MISC, RTL_R32(MISC) | DISABLE_LAN_EN | FORCE_CLK); + RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET); RTL_W8(DLLP
[PATCH v2 net-next] r8169: enable internal ASPM and clock request settings
The following chips need to enable internal settings to let ASPM and clock request work. RTL8111E-VL, RTL8111F, RTL8411, RTL8111G RTL8105, RTL8402, RTL8106 Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 30 +- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 123c6a5..91c8387 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -456,6 +456,7 @@ enum rtl8168_registers { #define PWM_EN (1 << 22) #define RXDV_GATED_EN (1 << 19) #define EARLY_TALLY_EN (1 << 16) +#define FORCE_CLK (1 << 15) /* force clock request */ }; enum rtl_register_content { @@ -519,6 +520,7 @@ enum rtl_register_content { PMEnable= (1 << 0), /* Power Management Enable */ /* Config2 register p. 25 */ + ClkReqEn= (1 << 7), /* Clock Request Enable */ MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ PCI_Clock_66MHz = 0x01, PCI_Clock_33MHz = 0x00, @@ -539,6 +541,7 @@ enum rtl_register_content { Spi_en = (1 << 3), LanWake = (1 << 1), /* LanWake enable/disable */ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ + ASPM_en = (1 << 0), /* ASPM enable */ /* TBICSR p.28 */ TBIReset= 0x8000, @@ -5046,8 +5049,6 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) RTL_W8(MaxTxPacketSize, EarlySize); - rtl_disable_clock_request(pdev); - RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); @@ -5056,7 +5057,8 @@ static void rtl_hw_start_8168e_2(struct rtl8169_private *tp) RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); - RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); + RTL_W8(Config5, (RTL_R8(Config5) & ~Spi_en) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); } static void rtl_hw_start_8168f(struct rtl8169_private *tp) @@ -5081,13 +5083,12 @@ static void rtl_hw_start_8168f(struct rtl8169_private *tp) RTL_W8(MaxTxPacketSize, EarlySize); - rtl_disable_clock_request(pdev); - RTL_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); RTL_W8(MCU, RTL_R8(MCU) & ~NOW_IS_OOB); RTL_W8(DLLPR, RTL_R8(DLLPR) | PFM_EN); - RTL_W32(MISC, RTL_R32(MISC) | PWM_EN); - RTL_W8(Config5, RTL_R8(Config5) & ~Spi_en); + RTL_W32(MISC, RTL_R32(MISC) | PWM_EN | FORCE_CLK); + RTL_W8(Config5, (RTL_R8(Config5) & ~Spi_en) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); } static void rtl_hw_start_8168f_1(struct rtl8169_private *tp) @@ -5144,8 +5145,10 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) 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_W32(MISC, (RTL_R32(MISC) | FORCE_CLK) & ~RXDV_GATED_EN); RTL_W8(MaxTxPacketSize, EarlySize); + RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x, ERIAR_EXGMAC); rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x, ERIAR_EXGMAC); @@ -5361,6 +5364,9 @@ 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_W8(Config5, RTL_R8(Config5) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); + RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK); rtl_ephy_init(tp, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1)); } @@ -5386,6 +5392,9 @@ 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_W8(Config5, RTL_R8(Config5) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkReqEn); + RTL_W32(MISC, RTL_R32(MISC) | FORCE_CLK); rtl_ephy_init(tp, e_info_8402, ARRAY_SIZE(e_info_8402)); @@ -5407,7 +5416,10 @@ static void rtl_hw_start_8106(struct rtl8169_private *tp) /* 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_W32(MISC, + (RTL_R32(MISC) | DISABLE_LAN_EN | FORCE_CLK) & ~EARLY_TALLY_EN); + RTL_W8(Config5, RTL_R8(Config5) | ASPM_en); + RTL_W8(Config2, RTL_R8(Config2) | ClkR
[PATCH net-next] r8169: add a new chip for RTL8411
Add a new chip for RTL8411 series. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 67 1 file changed, 67 insertions(+) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 393f961..4106a74 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_8411_2"rtl_nic/rtl8411-2.fw" #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" #define FIRMWARE_8106E_2 "rtl_nic/rtl8106e-2.fw" #define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw" @@ -144,6 +145,7 @@ enum mac_version { RTL_GIGA_MAC_VER_41, RTL_GIGA_MAC_VER_42, RTL_GIGA_MAC_VER_43, + RTL_GIGA_MAC_VER_44, RTL_GIGA_MAC_NONE = 0xff, }; @@ -276,6 +278,9 @@ static const struct { [RTL_GIGA_MAC_VER_43] = _R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_2, JUMBO_1K, true), + [RTL_GIGA_MAC_VER_44] = + _R("RTL8411", RTL_TD_1, FIRMWARE_8411_2, + JUMBO_9K, false), }; #undef _R @@ -394,6 +399,7 @@ enum rtl8168_8101_registers { #define CSIAR_FUNC_CARD0x #define CSIAR_FUNC_SDIO0x0001 #define CSIAR_FUNC_NIC 0x0002 +#define CSIAR_FUNC_NIC20x0001 PMCH= 0x6f, EPHYAR = 0x80, #defineEPHYAR_FLAG 0x8000 @@ -826,6 +832,7 @@ MODULE_FIRMWARE(FIRMWARE_8168F_1); MODULE_FIRMWARE(FIRMWARE_8168F_2); MODULE_FIRMWARE(FIRMWARE_8402_1); MODULE_FIRMWARE(FIRMWARE_8411_1); +MODULE_FIRMWARE(FIRMWARE_8411_2); MODULE_FIRMWARE(FIRMWARE_8106E_1); MODULE_FIRMWARE(FIRMWARE_8106E_2); MODULE_FIRMWARE(FIRMWARE_8168G_2); @@ -2051,6 +2058,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, int mac_version; } mac_info[] = { /* 8168G family. */ + { 0x7cf0, 0x5c80, RTL_GIGA_MAC_VER_44 }, { 0x7cf0, 0x5090, RTL_GIGA_MAC_VER_42 }, { 0x7cf0, 0x4c10, RTL_GIGA_MAC_VER_41 }, { 0x7cf0, 0x4c00, RTL_GIGA_MAC_VER_40 }, @@ -3651,6 +3659,7 @@ static void rtl_hw_phy_config(struct net_device *dev) break; case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_43: + case RTL_GIGA_MAC_VER_44: rtl8168g_2_hw_phy_config(tp); break; @@ -3863,6 +3872,7 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_43: + case RTL_GIGA_MAC_VER_44: ops->write = r8168g_mdio_write; ops->read = r8168g_mdio_read; break; @@ -3916,6 +3926,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_43: + case RTL_GIGA_MAC_VER_44: RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); break; @@ -4178,6 +4189,7 @@ static void rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_44: ops->down = r8168_pll_power_down; ops->up = r8168_pll_power_up; break; @@ -4224,6 +4236,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_43: + case RTL_GIGA_MAC_VER_44: RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF); break; default: @@ -4384,6 +4397,7 @@ static void rtl_init_jumbo_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: case RTL_GIGA_MAC_VER_43: + case RTL_GIGA_MAC_VER_44: default: ops->disable= NULL; ops->enable = NULL; @@ -4493,6 +4507,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_42 || tp->mac_version == RTL_GIGA_MAC_VER_43 || +
[PATCH firmware] rtl_nic: add firmware rtl8411-2
File: rtl_nic/rtl8411-2.fw Version: 0.0.1 Signed-off-by: Hayes Wang --- WHENCE | 3 +++ rtl_nic/rtl8411-2.fw | Bin 0 -> 1040 bytes 2 files changed, 3 insertions(+) create mode 100644 rtl_nic/rtl8411-2.fw diff --git a/WHENCE b/WHENCE index d7fba9d..39f11af 100644 --- a/WHENCE +++ b/WHENCE @@ -1879,6 +1879,9 @@ Version: 0.0.4 File: rtl_nic/rtl8411-1.fw Version: 0.0.3 +File: rtl_nic/rtl8411-2.fw +Version: 0.0.1 + File: rtl_nic/rtl8402-1.fw Version: 0.0.1 diff --git a/rtl_nic/rtl8411-2.fw b/rtl_nic/rtl8411-2.fw new file mode 100644 index ..e3789fe576c41c2a12d606ece1e41552693ad9ac GIT binary patch literal 1040 zcmYk(L2DC16bJB^?IsOr*ldz9m16B8MMP@4yJ=$#B7sW1^yIOZG}uE9Qi}8#+=wh#nY!lqyL z%Yo-#o%d_=K?PI#vxfigh{tq$rCRZW=4NZ_PP-ZUK^TN#wY;=^%L^9ki`VLYg`Pa0 zjTeoEUV^CcCO5-GX+#E*MK}l-Q9vj}iN}Z{q7*Y~(-CndvN#*r>_jPcqcj(y467*1 zrO09HJ=VUKwbr{5)2p+*GCsxD+jC4W&vPd2q2>Z=X3_g1@=M4sBcDTFM(!gIkuM;x zBCjE@BfpOP2J8KD3OO|%PQ-h6@zuXR>ucJ?xuTdFL|%ie{dJ-qQPN+^%<%GqB2z+f z`9+Zvq&PMYdCyW@*vA}9VYKHIkDm(rnc@WEzNdIHQG3;2ZXsiWmiJdXF3)>ZQ zjM*?-ENkr4z9)>WqHa~{;yr#gdmqX({%EfEP`4*_UyM00N9?PyL)f9%H)CB`SFEAm GJJCOC1@r*` literal 0 HcmV?d1 -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net 1/2] usb/net/r8152: fix integer overflow in expression
config: make ARCH=avr32 allyesconfig drivers/net/usb/r8152.c: In function 'rtl8152_start_xmit': drivers/net/usb/r8152.c:956: warning: integer overflow in expression 955 memset(tx_desc, 0, sizeof(*tx_desc)); > 956 tx_desc->opts1 = cpu_to_le32((len & TX_LEN_MASK) | TX_FS | TX_LS); 957 tp->tx_skb = skb; Signed-off-by: Hayes Wang Spotted-by: kbuild test robot --- drivers/net/usb/r8152.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index d02bac8..ee13f9e 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -934,7 +934,8 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, struct r8152 *tp = netdev_priv(netdev); struct net_device_stats *stats = rtl8152_get_stats(netdev); struct tx_desc *tx_desc; - int len, res; + unsigned int len; + int res; netif_stop_queue(netdev); len = skb->len; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net 2/2] usb/net/r815x: fix cast to restricted __le32
>> drivers/net/usb/r815x.c:38:16: sparse: cast to restricted __le32 >> drivers/net/usb/r815x.c:67:15: sparse: cast to restricted __le32 >> drivers/net/usb/r815x.c:69:13: sparse: incorrect type in assignment >> (different base types) drivers/net/usb/r815x.c:69:13:expected unsigned int [unsigned] [addressable] [assigned] [usertype] tmp drivers/net/usb/r815x.c:69:13:got restricted __le32 [usertype] Signed-off-by: Hayes Wang Spotted-by: kbuild test robot --- drivers/net/usb/r815x.c | 21 - 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c index 6516737..8523922 100644 --- a/drivers/net/usb/r815x.c +++ b/drivers/net/usb/r815x.c @@ -26,16 +26,18 @@ static int pla_read_word(struct usb_device *udev, u16 index) { int data, ret; u8 shift = index & 2; + __le32 ocp_data; index &= ~3; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, &data, sizeof(data), 500); + index, MCU_TYPE_PLA, &ocp_data, sizeof(ocp_data), + 500); if (ret < 0) return ret; - data = __le32_to_cpu(data); + data = __le32_to_cpu(ocp_data); data >>= (shift * 8); data &= 0x; @@ -44,7 +46,8 @@ static int pla_read_word(struct usb_device *udev, u16 index) static int pla_write_word(struct usb_device *udev, u16 index, u32 data) { - u32 tmp, mask = 0x; + __le32 ocp_data; + u32 mask = 0x; u16 byen = BYTE_EN_WORD; u8 shift = index & 2; int ret; @@ -60,18 +63,18 @@ static int pla_write_word(struct usb_device *udev, u16 index, u32 data) ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, &tmp, sizeof(tmp), 500); + index, MCU_TYPE_PLA, &ocp_data, sizeof(ocp_data), + 500); if (ret < 0) return ret; - tmp = __le32_to_cpu(tmp) & ~mask; - tmp |= data; - tmp = __cpu_to_le32(tmp); + data |= __le32_to_cpu(ocp_data) & ~mask; + ocp_data = __cpu_to_le32(data); ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE, - index, MCU_TYPE_PLA | byen, &tmp, - sizeof(tmp), 500); + index, MCU_TYPE_PLA | byen, &ocp_data, + sizeof(ocp_data), 500); return ret; } -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 1/2] r8169: enable ALDPS for power saving
Enable ALDPS function to save power when link down. Note that the feature should be set after the other PHY settings. And the firmware is necessary. Don't enable it without loading the firmware. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 46 +++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index e7ff886..ba29e4d 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -687,6 +687,7 @@ enum features { RTL_FEATURE_WOL = (1 << 0), RTL_FEATURE_MSI = (1 << 1), RTL_FEATURE_GMII= (1 << 2), + RTL_FEATURE_EXTENDED= (1 << 3), }; struct rtl8169_counters { @@ -2394,8 +2395,10 @@ static void rtl_apply_firmware(struct rtl8169_private *tp) struct rtl_fw *rtl_fw = tp->rtl_fw; /* TODO: release firmware once rtl_phy_write_fw signals failures. */ - if (!IS_ERR_OR_NULL(rtl_fw)) + if (!IS_ERR_OR_NULL(rtl_fw)) { rtl_phy_write_fw(tp, rtl_fw); + tp->features |= RTL_FEATURE_EXTENDED; + } } static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) @@ -3178,6 +3181,12 @@ static void rtl8168e_2_hw_phy_config(struct rtl8169_private *tp) rtl_w1w0_phy(tp, 0x19, 0x, 0x0001); rtl_w1w0_phy(tp, 0x10, 0x, 0x0400); rtl_writephy(tp, 0x1f, 0x); + + /* ALDPS enable */ + if (tp->features & RTL_FEATURE_EXTENDED) { + rtl_writephy(tp, 0x1f, 0x); + rtl_w1w0_phy(tp, 0x15, 0x1000, 0x); + } } static void rtl8168f_hw_phy_config(struct rtl8169_private *tp) @@ -3250,6 +3259,12 @@ static void rtl8168f_1_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x05, 0x8b85); rtl_w1w0_phy(tp, 0x06, 0x4000, 0x); rtl_writephy(tp, 0x1f, 0x); + + /* ALDPS enable */ + if (tp->features & RTL_FEATURE_EXTENDED) { + rtl_writephy(tp, 0x1f, 0x); + rtl_w1w0_phy(tp, 0x15, 0x1000, 0x); + } } static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) @@ -3257,6 +3272,12 @@ static void rtl8168f_2_hw_phy_config(struct rtl8169_private *tp) rtl_apply_firmware(tp); rtl8168f_hw_phy_config(tp); + + /* ALDPS enable */ + if (tp->features & RTL_FEATURE_EXTENDED) { + rtl_writephy(tp, 0x1f, 0x); + rtl_w1w0_phy(tp, 0x15, 0x1000, 0x); + } } static void rtl8411_hw_phy_config(struct rtl8169_private *tp) @@ -3354,6 +3375,12 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) rtl_w1w0_phy(tp, 0x19, 0x, 0x0001); rtl_w1w0_phy(tp, 0x10, 0x, 0x0400); rtl_writephy(tp, 0x1f, 0x); + + /* ALDPS enable */ + if (tp->features & RTL_FEATURE_EXTENDED) { + rtl_writephy(tp, 0x1f, 0x); + rtl_w1w0_phy(tp, 0x15, 0x1000, 0x); + } } static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) @@ -3446,6 +3473,11 @@ static void rtl8105e_hw_phy_config(struct rtl8169_private *tp) rtl_apply_firmware(tp); rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); + + if (tp->features & RTL_FEATURE_EXTENDED) { + rtl_writephy(tp, 0x1f, 0x); + rtl_writephy(tp, 0x18, 0x8310); + } } static void rtl8402_hw_phy_config(struct rtl8169_private *tp) @@ -3463,6 +3495,11 @@ static void rtl8402_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x10, 0x401f); rtl_writephy(tp, 0x19, 0x7030); rtl_writephy(tp, 0x1f, 0x); + + if (tp->features & RTL_FEATURE_EXTENDED) { + rtl_writephy(tp, 0x1f, 0x); + rtl_writephy(tp, 0x18, 0x8310); + } } static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) @@ -3485,6 +3522,11 @@ static void rtl8106e_hw_phy_config(struct rtl8169_private *tp) rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init)); rtl_eri_write(tp, 0x1d0, ERIAR_MASK_0011, 0x, ERIAR_EXGMAC); + + if (tp->features & RTL_FEATURE_EXTENDED) { + rtl_writephy(tp, 0x1f, 0x); + rtl_writephy(tp, 0x18, 0x8310); + } } static void rtl_hw_phy_config(struct net_device *dev) @@ -6391,6 +6433,8 @@ static void rtl8169_net_suspend(struct net_device *dev) { struct rtl8169_private *tp = netdev_priv(dev); + tp->features &= ~RTL_FEATURE_EXTENDED; + if (!netif_running(dev)) return; -- 1.7.11.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH firmware 2/2] rtl_nic: add firmware rtl8106e-2
File: rtl_nic/rtl8106e-2.fw Version: 0.0.1 Signed-off-by: Hayes Wang --- WHENCE| 3 +++ rtl_nic/rtl8106e-2.fw | Bin 0 -> 832 bytes 2 files changed, 3 insertions(+) create mode 100644 rtl_nic/rtl8106e-2.fw diff --git a/WHENCE b/WHENCE index 54f6388..fedf031 100644 --- a/WHENCE +++ b/WHENCE @@ -1869,6 +1869,9 @@ Version: 0.0.1 File: rtl_nic/rtl8106e-1.fw Version: 0.0.1 +File: rtl_nic/rtl8106e-2.fw +Version: 0.0.1 + File: rtl_nic/rtl8168g-1.fw Version: 0.0.3 diff --git a/rtl_nic/rtl8106e-2.fw b/rtl_nic/rtl8106e-2.fw new file mode 100644 index ..ac042757e1392c184b5b75313d6b597c1561cc41 GIT binary patch literal 832 zcmYk(!AcuZ6b9fwaZ;g{I7x011aTgqjT0wG%_?9i2wg~*ZqlGa7HUOYrsY~96r>neUuAbM74g*xlQFR*M%lp3b-8YFw>F zaeZz+nX4ttxz7sM7p}K>^>QJJlh#gqZ>`hXZEv;K-mGs#wZ%pfH|lkKT*mu}Sqp^x z`d@1OHFk2qcSlViY9ilX2abS3y!3F^zSyr=j2T-!t=Jrlbr$jeQQp{cpE;Ug44xP} zes2Yzjm>eri;SHf)jeR$CXEe7F+Yl6?1sko4cXT{1CZV_^AzqfM8H(~e`=QpMb;N$Eb!lC(-)ckJP;97nKsyj~XA`>j1p^G| z1Mx|<8QP3kN$r+)D^^i!)7oN>)sAV$Vnwxp7KlAkyEpfQ+A8Z-rOwTGsk3Kt#^-u{ e!nzZw`=(Z;6~(U9&S+<1*J?dlPps+RJMa%_vcCZU literal 0 HcmV?d1 -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH firmware 1/2] rtl_nic: Add firmware rtl8168g-3
File: rtl_nic/rtl8168g-3.fw Version: 0.0.1 Signed-off-by: Hayes Wang --- WHENCE| 5 - rtl_nic/rtl8168g-3.fw | Bin 0 -> 832 bytes 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 rtl_nic/rtl8168g-3.fw diff --git a/WHENCE b/WHENCE index 013f810..54f6388 100644 --- a/WHENCE +++ b/WHENCE @@ -1875,8 +1875,11 @@ Version: 0.0.3 File: rtl_nic/rtl8168g-2.fw Version: 0.0.1 +File: rtl_nic/rtl8168g-3.fw +Version: 0.0.1 + Licence: - * Copyright © 2011, Realtek Semiconductor Corporation + * Copyright © 2011-2013, Realtek Semiconductor Corporation * * Permission is hereby granted for the distribution of this firmware * data in hexadecimal or equivalent format, provided this copyright diff --git a/rtl_nic/rtl8168g-3.fw b/rtl_nic/rtl8168g-3.fw new file mode 100644 index ..0c97d7ea1437ba515c1dbdabe8aa285e79585786 GIT binary patch literal 832 zcmYk(!AcuZ6b9fwaZ*7`oFrF-f;bOQUrb9|Vbvp~qN z|E1PnV=D*za?}K(Ch{liz#&kGmnY`zv)zitn6cHfip{}TXA%D&=8Y|%Fh?_t!DC~` z@2%jIu{o}t$k<1tx(AHel(E4m=0_2Xz0ml+A^W;#0Mc7#p22N~2$)IlX5w>oKbJli zrl0+O46<8SYtj|pr-an+x8(2bTi+MiN2zhCF*y>SFOTxDOt8mS_I$lp_A~v}+&;o= zU+%wBYtR~EmudxCLF}K}25m#^w_1nR5&NUoqxHnD)rPd8*idai8;H5H3ElgG0Z!?s z;!|p~v{|u|+70bStfJPYwZ*2@j%Y_>MYVtyh&@!hH}|C4D(hCI&dvBuXV2t}zv%Tb e>yD-FyIPS}6#JoeLAwz9sn)0U#hU)T1OEYQX1@Ud literal 0 HcmV?d1 -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next] net/usb: add relative mii functions for r815x
Base on cdc_ether, add the mii functions for RTL8152 and RTL8153. The RTL8152 and RTL8153 support ECM mode which use the driver of cdc_ether. Add the mii functions. Then, the basic PHY access is possible. Signed-off-by: Hayes Wang --- drivers/net/usb/Makefile| 2 +- drivers/net/usb/cdc_ether.c | 9 +- drivers/net/usb/r815x.c | 231 3 files changed, 239 insertions(+), 3 deletions(-) create mode 100644 drivers/net/usb/r815x.c diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 9ab5c9d..e817178 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -11,7 +11,7 @@ obj-$(CONFIG_USB_HSO) += hso.o obj-$(CONFIG_USB_NET_AX8817X) += asix.o asix-y := asix_devices.o asix_common.o ax88172a.o obj-$(CONFIG_USB_NET_AX88179_178A) += ax88179_178a.o -obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o +obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o r815x.o obj-$(CONFIG_USB_NET_CDC_EEM) += cdc_eem.o obj-$(CONFIG_USB_NET_DM9601) += dm9601.o obj-$(CONFIG_USB_NET_SMSC75XX) += smsc75xx.o diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 4393f14..03ad4dc 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -646,13 +646,18 @@ static const struct usb_device_id products [] = { }, /* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */ -#if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE) { USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), .driver_info = 0, }, -#endif + +/* Realtek RTL8153 Based USB 3.0 Ethernet Adapters */ +{ + USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8153, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, /* * WHITELIST!!! diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c new file mode 100644 index 000..6516737 --- /dev/null +++ b/drivers/net/usb/r815x.c @@ -0,0 +1,231 @@ +#include +#include +#include +#include +#include +#include + +#define RTL815x_REQT_READ 0xc0 +#define RTL815x_REQT_WRITE 0x40 +#define RTL815x_REQ_GET_REGS 0x05 +#define RTL815x_REQ_SET_REGS 0x05 + +#define MCU_TYPE_PLA 0x0100 +#define OCP_BASE 0xe86c +#define BASE_MII 0xa400 + +#define BYTE_EN_DWORD 0xff +#define BYTE_EN_WORD 0x33 +#define BYTE_EN_BYTE 0x11 + +#define R815x_PHY_ID 32 +#define REALTEK_VENDOR_ID 0x0bda + + +static int pla_read_word(struct usb_device *udev, u16 index) +{ + int data, ret; + u8 shift = index & 2; + + index &= ~3; + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, + index, MCU_TYPE_PLA, &data, sizeof(data), 500); + if (ret < 0) + return ret; + + data = __le32_to_cpu(data); + data >>= (shift * 8); + data &= 0x; + + return data; +} + +static int pla_write_word(struct usb_device *udev, u16 index, u32 data) +{ + u32 tmp, mask = 0x; + u16 byen = BYTE_EN_WORD; + u8 shift = index & 2; + int ret; + + data &= mask; + + if (shift) { + byen <<= shift; + mask <<= (shift * 8); + data <<= (shift * 8); + index &= ~3; + } + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, + index, MCU_TYPE_PLA, &tmp, sizeof(tmp), 500); + if (ret < 0) + return ret; + + tmp = __le32_to_cpu(tmp) & ~mask; + tmp |= data; + tmp = __cpu_to_le32(tmp); + + ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), + RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE, + index, MCU_TYPE_PLA | byen, &tmp, + sizeof(tmp), 500); + + return ret; +} + +static int ocp_reg_read(struct usbnet *dev, u16 addr) +{ + u16 ocp_base, ocp_index; + int ret; + + ocp_base = addr & 0xf000; + ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); + if (ret < 0) + goto out; + + ocp_index = (addr & 0x0fff) | 0xb000; + ret = pla_read_word(dev->udev, ocp_index); + +out: + return ret; +} + +static int ocp_reg_write(struct usbnet *dev, u16 addr, u16 data) +{ + u16 ocp_base, ocp_index; + int ret; + + ocp_base = addr & 0xf000; + ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); + if (ret < 0) + goto out1; + + ocp_index = (addr & 0x0fff) | 0xb000; + ret = pla_write_word(dev->
[PATCH net-next v2 3/3] net/usb/r8152: enable interrupt transfer
Use the interrupt transfer to replace polling link status. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 140 ++-- 1 file changed, 113 insertions(+), 27 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 4d938a7..ef2498c 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -272,6 +272,9 @@ enum rtl_register_content { #define RTL8152_MAX_TX 10 #define RTL8152_MAX_RX 10 +#define INTBUFSIZE 2 + +#define INTR_LINK 0x0004 #define RTL8152_REQT_READ 0xc0 #define RTL8152_REQT_WRITE 0x40 @@ -292,7 +295,8 @@ enum rtl_register_content { enum rtl8152_flags { RTL8152_UNPLUG = 0, RTL8152_SET_RX_MODE, - WORK_ENABLE + WORK_ENABLE, + RTL8152_LINK_CHG, }; /* Define these values to match your device */ @@ -347,7 +351,9 @@ struct r8152 { unsigned long flags; struct usb_device *udev; struct tasklet_struct tl; + struct usb_interface *intf; struct net_device *netdev; + struct urb *intr_urb; struct tx_agg tx_info[RTL8152_MAX_TX]; struct rx_agg rx_info[RTL8152_MAX_RX]; struct list_head rx_done, tx_free; @@ -355,8 +361,10 @@ struct r8152 { spinlock_t rx_lock, tx_lock; struct delayed_work schedule; struct mii_if_info mii; + int intr_interval; u32 msg_enable; u16 ocp_base; + u8 *intr_buff; u8 version; u8 speed; }; @@ -860,6 +868,62 @@ static void write_bulk_callback(struct urb *urb) tasklet_schedule(&tp->tl); } +static void intr_callback(struct urb *urb) +{ + struct r8152 *tp; + __u16 *d; + int status = urb->status; + int res; + + tp = urb->context; + if (!tp) + return; + + if (!test_bit(WORK_ENABLE, &tp->flags)) + return; + + if (test_bit(RTL8152_UNPLUG, &tp->flags)) + return; + + switch (status) { + case 0: /* success */ + break; + case -ECONNRESET: /* unlink */ + case -ESHUTDOWN: + netif_device_detach(tp->netdev); + case -ENOENT: + return; + case -EOVERFLOW: + netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n"); + goto resubmit; + /* -EPIPE: should clear the halt */ + default: + netif_info(tp, intr, tp->netdev, "intr status %d\n", status); + goto resubmit; + } + + d = urb->transfer_buffer; + if (INTR_LINK & __le16_to_cpu(d[0])) { + if (!(tp->speed & LINK_STATUS)) { + set_bit(RTL8152_LINK_CHG, &tp->flags); + schedule_delayed_work(&tp->schedule, 0); + } + } else { + if (tp->speed & LINK_STATUS) { + set_bit(RTL8152_LINK_CHG, &tp->flags); + schedule_delayed_work(&tp->schedule, 0); + } + } + +resubmit: + res = usb_submit_urb(urb, GFP_ATOMIC); + if (res == -ENODEV) + netif_device_detach(tp->netdev); + else if (res) + netif_err(tp, intr, tp->netdev, + "can't resubmit intr, status %d\n", res); +} + static inline void *rx_agg_align(void *data) { return (void *)ALIGN((uintptr_t)data, 8); @@ -899,11 +963,24 @@ static void free_all_mem(struct r8152 *tp) tp->tx_info[i].head = NULL; } } + + if (tp->intr_urb) { + usb_free_urb(tp->intr_urb); + tp->intr_urb = NULL; + } + + if (tp->intr_buff) { + kfree(tp->intr_buff); + tp->intr_buff = NULL; + } } static int alloc_all_mem(struct r8152 *tp) { struct net_device *netdev = tp->netdev; + struct usb_interface *intf = tp->intf; + struct usb_host_interface *alt = intf->cur_altsetting; + struct usb_host_endpoint *ep_intr = alt->endpoint + 2; struct urb *urb; int node, i; u8 *buf; @@ -968,6 +1045,19 @@ static int alloc_all_mem(struct r8152 *tp) list_add_tail(&tp->tx_info[i].list, &tp->tx_free); } + tp->intr_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!tp->intr_urb) + goto err1; + + tp->intr_buff = kmalloc(INTBUFSIZE, GFP_KERNEL); + if (!tp->intr_buff) + goto err1; + + tp->intr_interval = (int)ep_intr->desc.bInterval; + usb_fill_int_urb(tp->intr_urb, tp->udev, usb_rcvintpipe(tp->udev, 3), +tp->intr_buff, INTBUFSIZE, intr_callback, +tp, tp-
[PATCH net-next v2 2/3] net/usb/r8152: enable tx checksum
Enable tx checksum. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 64 + 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index abb0b9f..4d938a7 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include /* Version Information */ #define DRIVER_VERSION "v1.01.0 (2013/08/12)" @@ -314,8 +316,13 @@ struct tx_desc { u32 opts1; #define TX_FS (1 << 31) /* First segment of a packet */ #define TX_LS (1 << 30) /* Final segment of a packet */ -#define TX_LEN_MASK0x +#define TX_LEN_MASK0x3 + u32 opts2; +#define UDP_CS (1 << 31) /* Calculate UDP/IP checksum */ +#define TCP_CS (1 << 30) /* Calculate TCP/IP checksum */ +#define IPV4_CS(1 << 29) /* Calculate IPv4 checksum */ +#define IPV6_CS(1 << 28) /* Calculate IPv6 checksum */ }; struct rx_agg { @@ -968,6 +975,52 @@ err1: return -ENOMEM; } +static void +r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb) +{ + memset(desc, 0, sizeof(*desc)); + + desc->opts1 = cpu_to_le32((skb->len & TX_LEN_MASK) | TX_FS | TX_LS); + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + __be16 protocol; + u8 ip_protocol; + u32 opts2 = 0; + + if (skb->protocol == htons(ETH_P_8021Q)) + protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; + else + protocol = skb->protocol; + + switch (protocol) { + case htons(ETH_P_IP): + opts2 |= IPV4_CS; + ip_protocol = ip_hdr(skb)->protocol; + break; + + case htons(ETH_P_IPV6): + opts2 |= IPV6_CS; + ip_protocol = ipv6_hdr(skb)->nexthdr; + break; + + default: + ip_protocol = IPPROTO_RAW; + break; + } + + if (ip_protocol == IPPROTO_TCP) { + opts2 |= TCP_CS; + opts2 |= (skb_transport_offset(skb) & 0x7fff) << 17; + } else if (ip_protocol == IPPROTO_UDP) { + opts2 |= UDP_CS; + } else { + WARN_ON_ONCE(1); + } + + desc->opts2 = cpu_to_le32(opts2); + } +} + static void rx_bottom(struct r8152 *tp) { struct net_device_stats *stats; @@ -1097,8 +1150,7 @@ next_agg: tx_desc = (struct tx_desc *)tx_data; tx_data += sizeof(*tx_desc); - tx_desc->opts1 = cpu_to_le32((skb->len & TX_LEN_MASK) | TX_FS | -TX_LS); + r8152_tx_csum(tp, tx_desc, skb); memcpy(tx_data, skb->data, len); agg->skb_num++; agg->skb_len += len; @@ -1256,7 +1308,7 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, agg->skb_num = agg->skb_len = 0; len = skb->len; - tx_desc->opts1 = cpu_to_le32((skb->len & TX_LEN_MASK) | TX_FS | TX_LS); + r8152_tx_csum(tp, tx_desc, skb); memcpy(tx_data, skb->data, len); dev_kfree_skb_any(skb); agg->skb_num++; @@ -1977,7 +2029,9 @@ static int rtl8152_probe(struct usb_interface *intf, tp->netdev = netdev; netdev->netdev_ops = &rtl8152_netdev_ops; netdev->watchdog_timeo = RTL8152_TX_TIMEOUT; - netdev->features &= ~NETIF_F_IP_CSUM; + + netdev->features |= NETIF_F_IP_CSUM; + netdev->hw_features = NETIF_F_IP_CSUM; SET_ETHTOOL_OPS(netdev, &ops); tp->speed = 0; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next v2 1/3] net/usb/r8152: support aggregation
Enable the tx/rx aggregation which could contain one or more packets for each bulk in/out. This could reduce the loading of the host controller by sending less bulk transfer. The rx packets in the bulk in buffer should be 8-byte aligned, and the tx packets in the bulk out buffer should be 4-byte aligned. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 647 1 file changed, 486 insertions(+), 161 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 11c51f2..abb0b9f 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -19,9 +19,10 @@ #include #include #include +#include /* Version Information */ -#define DRIVER_VERSION "v1.0.0 (2013/05/03)" +#define DRIVER_VERSION "v1.01.0 (2013/08/12)" #define DRIVER_AUTHOR "Realtek linux nic maintainers " #define DRIVER_DESC "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" #define MODULENAME "r8152" @@ -267,6 +268,9 @@ enum rtl_register_content { FULL_DUP= 0x01, }; +#define RTL8152_MAX_TX 10 +#define RTL8152_MAX_RX 10 + #define RTL8152_REQT_READ 0xc0 #define RTL8152_REQT_WRITE 0x40 #define RTL8152_REQ_GET_REGS 0x05 @@ -285,7 +289,6 @@ enum rtl_register_content { /* rtl8152 flags */ enum rtl8152_flags { RTL8152_UNPLUG = 0, - RX_URB_FAIL, RTL8152_SET_RX_MODE, WORK_ENABLE }; @@ -315,13 +318,34 @@ struct tx_desc { u32 opts2; }; +struct rx_agg { + struct list_head list; + struct urb *urb; + void *context; + void *buffer; + void *head; +}; + +struct tx_agg { + struct list_head list; + struct urb *urb; + void *context; + void *buffer; + void *head; + u32 skb_num; + u32 skb_len; +}; + struct r8152 { unsigned long flags; struct usb_device *udev; struct tasklet_struct tl; struct net_device *netdev; - struct urb *rx_urb, *tx_urb; - struct sk_buff *tx_skb, *rx_skb; + struct tx_agg tx_info[RTL8152_MAX_TX]; + struct rx_agg rx_info[RTL8152_MAX_RX]; + struct list_head rx_done, tx_free; + struct sk_buff_head tx_queue; + spinlock_t rx_lock, tx_lock; struct delayed_work schedule; struct mii_if_info mii; u32 msg_enable; @@ -340,6 +364,7 @@ enum rtl_version { * The RTL chips use a 64 element hash table based on the Ethernet CRC. */ static const int multicast_filter_limit = 32; +static unsigned int rx_buf_sz = 16384; static int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) @@ -686,6 +711,9 @@ static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) ocp_write_word(tp, MCU_TYPE_PLA, ocp_index, data); } +static +int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags); + static inline void set_ethernet_addr(struct r8152 *tp) { struct net_device *dev = tp->netdev; @@ -716,26 +744,6 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p) return 0; } -static int alloc_all_urbs(struct r8152 *tp) -{ - tp->rx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!tp->rx_urb) - return 0; - tp->tx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!tp->tx_urb) { - usb_free_urb(tp->rx_urb); - return 0; - } - - return 1; -} - -static void free_all_urbs(struct r8152 *tp) -{ - usb_free_urb(tp->rx_urb); - usb_free_urb(tp->tx_urb); -} - static struct net_device_stats *rtl8152_get_stats(struct net_device *dev) { return &dev->stats; @@ -743,129 +751,425 @@ static struct net_device_stats *rtl8152_get_stats(struct net_device *dev) static void read_bulk_callback(struct urb *urb) { - struct r8152 *tp; - unsigned pkt_len; - struct sk_buff *skb; struct net_device *netdev; - struct net_device_stats *stats; + unsigned long lockflags; int status = urb->status; + struct rx_agg *agg; + struct r8152 *tp; int result; - struct rx_desc *rx_desc; - tp = urb->context; + agg = urb->context; + if (!agg) + return; + + tp = agg->context; if (!tp) return; + if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; + + if (!test_bit(WORK_ENABLE, &tp->flags)) + return; + netdev = tp->netdev; - if (!netif_device_present(netdev)) + if (!netif_carrier_ok(netdev)) return; - stats = rtl8152_get_stats(netdev); switch (status) { case 0: - break; + if (urb->actual_length < ETH_ZLEN) + break; + + spin_lock_irqsave(&tp->rx_lock, lockflag
[PATCH net-next 2/7] r8152: replace void * with struct r8152 *
Change the type of contex of tx_agg and rx_agg from void * to staruc r8152 *. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index c13662b..a18f02d 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -329,10 +329,12 @@ struct tx_desc { #define IPV6_CS(1 << 28) /* Calculate IPv6 checksum */ }; +struct r8152; + struct rx_agg { struct list_head list; struct urb *urb; - void *context; + struct r8152 *context; void *buffer; void *head; }; @@ -340,7 +342,7 @@ struct rx_agg { struct tx_agg { struct list_head list; struct urb *urb; - void *context; + struct r8152 *context; void *buffer; void *head; u32 skb_num; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 1/7] r8152: remove clearing the memory to zero for netdev priv
Remove memset(tp, 0, sizeof(*tp)); Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ef2498c..c13662b 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -2105,7 +2105,6 @@ static int rtl8152_probe(struct usb_interface *intf, SET_NETDEV_DEV(netdev, &intf->dev); tp = netdev_priv(netdev); - memset(tp, 0, sizeof(*tp)); tp->msg_enable = 0x7FFF; tasklet_init(&tp->tl, bottom_half, (unsigned long)tp); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 3/7] r8152: replace lockflags with flags
Replace lockflags with flags. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 48 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index a18f02d..41b99ce 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -769,7 +769,7 @@ static struct net_device_stats *rtl8152_get_stats(struct net_device *dev) static void read_bulk_callback(struct urb *urb) { struct net_device *netdev; - unsigned long lockflags; + unsigned long flags; int status = urb->status; struct rx_agg *agg; struct r8152 *tp; @@ -798,9 +798,9 @@ static void read_bulk_callback(struct urb *urb) if (urb->actual_length < ETH_ZLEN) break; - spin_lock_irqsave(&tp->rx_lock, lockflags); + spin_lock_irqsave(&tp->rx_lock, flags); list_add_tail(&agg->list, &tp->rx_done); - spin_unlock_irqrestore(&tp->rx_lock, lockflags); + spin_unlock_irqrestore(&tp->rx_lock, flags); tasklet_schedule(&tp->tl); return; case -ESHUTDOWN: @@ -821,9 +821,9 @@ static void read_bulk_callback(struct urb *urb) if (result == -ENODEV) { netif_device_detach(tp->netdev); } else if (result) { - spin_lock_irqsave(&tp->rx_lock, lockflags); + spin_lock_irqsave(&tp->rx_lock, flags); list_add_tail(&agg->list, &tp->rx_done); - spin_unlock_irqrestore(&tp->rx_lock, lockflags); + spin_unlock_irqrestore(&tp->rx_lock, flags); tasklet_schedule(&tp->tl); } } @@ -831,7 +831,7 @@ static void read_bulk_callback(struct urb *urb) static void write_bulk_callback(struct urb *urb) { struct net_device_stats *stats; - unsigned long lockflags; + unsigned long flags; struct tx_agg *agg; struct r8152 *tp; int status = urb->status; @@ -853,9 +853,9 @@ static void write_bulk_callback(struct urb *urb) stats->tx_bytes += agg->skb_len; } - spin_lock_irqsave(&tp->tx_lock, lockflags); + spin_lock_irqsave(&tp->tx_lock, flags); list_add_tail(&agg->list, &tp->tx_free); - spin_unlock_irqrestore(&tp->tx_lock, lockflags); + spin_unlock_irqrestore(&tp->tx_lock, flags); if (!netif_carrier_ok(tp->netdev)) return; @@ -1119,7 +1119,7 @@ static void rx_bottom(struct r8152 *tp) struct net_device *netdev; struct rx_agg *agg; struct rx_desc *rx_desc; - unsigned long lockflags; + unsigned long flags; struct list_head *cursor, *next; struct sk_buff *skb; struct urb *urb; @@ -1132,16 +1132,16 @@ static void rx_bottom(struct r8152 *tp) stats = rtl8152_get_stats(netdev); - spin_lock_irqsave(&tp->rx_lock, lockflags); + spin_lock_irqsave(&tp->rx_lock, flags); list_for_each_safe(cursor, next, &tp->rx_done) { list_del_init(cursor); - spin_unlock_irqrestore(&tp->rx_lock, lockflags); + spin_unlock_irqrestore(&tp->rx_lock, flags); agg = list_entry(cursor, struct rx_agg, list); urb = agg->urb; if (urb->actual_length < ETH_ZLEN) { ret = r8152_submit_rx(tp, agg, GFP_ATOMIC); - spin_lock_irqsave(&tp->rx_lock, lockflags); + spin_lock_irqsave(&tp->rx_lock, flags); if (ret && ret != -ENODEV) { list_add_tail(&agg->list, next); tasklet_schedule(&tp->tl); @@ -1182,13 +1182,13 @@ static void rx_bottom(struct r8152 *tp) } ret = r8152_submit_rx(tp, agg, GFP_ATOMIC); - spin_lock_irqsave(&tp->rx_lock, lockflags); + spin_lock_irqsave(&tp->rx_lock, flags); if (ret && ret != -ENODEV) { list_add_tail(&agg->list, next); tasklet_schedule(&tp->tl); } } - spin_unlock_irqrestore(&tp->rx_lock, lockflags); + spin_unlock_irqrestore(&tp->rx_lock, flags); } static void tx_bottom(struct r8152 *tp) @@ -1196,7 +1196,7 @@ static void tx_bottom(struct r8152 *tp) struct net_device_stats *stats; struct net_device *netdev; struct tx_agg *agg; - unsigned long lockflags; + unsigned long flags; u32 remain, total; u8 *tx_data; int res; @@ -1205,
[PATCH net-next 5/7] r8152: move some declearation of variables
Move some declearation of variables in rx_bottom(). Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 29 ++--- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 4dee76b..0a88f64 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1133,25 +1133,19 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb) static void rx_bottom(struct r8152 *tp) { - struct net_device_stats *stats; - struct net_device *netdev; - struct rx_agg *agg; - struct rx_desc *rx_desc; unsigned long flags; struct list_head *cursor, *next; - struct sk_buff *skb; - struct urb *urb; - unsigned pkt_len; - int len_used; - u8 *rx_data; - int ret; - - netdev = tp->netdev; - - stats = rtl8152_get_stats(netdev); spin_lock_irqsave(&tp->rx_lock, flags); list_for_each_safe(cursor, next, &tp->rx_done) { + struct rx_desc *rx_desc; + struct rx_agg *agg; + unsigned pkt_len; + int len_used = 0; + struct urb *urb; + u8 *rx_data; + int ret; + list_del_init(cursor); spin_unlock_irqrestore(&tp->rx_lock, flags); @@ -1160,16 +1154,21 @@ static void rx_bottom(struct r8152 *tp) if (urb->actual_length < ETH_ZLEN) goto submit; - len_used = 0; rx_desc = agg->head; rx_data = agg->head; pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK; len_used += sizeof(struct rx_desc) + pkt_len; while (urb->actual_length >= len_used) { + struct net_device *netdev = tp->netdev; + struct net_device_stats *stats; + struct sk_buff *skb; + if (pkt_len < ETH_ZLEN) break; + stats = rtl8152_get_stats(netdev); + pkt_len -= 4; /* CRC */ rx_data += sizeof(struct rx_desc); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 6/7] r8152: adjust tx_bottom function
Split some parts of code into another function to simplify tx_bottom(). Use while loop to replace the goto loop. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 134 1 file changed, 68 insertions(+), 66 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 0a88f64..825edfe 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1131,6 +1131,51 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb) } } +static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) +{ + u32 remain; + u8 *tx_data; + + tx_data = agg->head; + agg->skb_num = agg->skb_len = 0; + remain = rx_buf_sz - sizeof(struct tx_desc); + + while (remain >= ETH_ZLEN) { + struct tx_desc *tx_desc; + struct sk_buff *skb; + unsigned int len; + + skb = skb_dequeue(&tp->tx_queue); + if (!skb) + break; + + len = skb->len; + if (remain < len) { + skb_queue_head(&tp->tx_queue, skb); + break; + } + + tx_desc = (struct tx_desc *)tx_data; + tx_data += sizeof(*tx_desc); + + r8152_tx_csum(tp, tx_desc, skb); + memcpy(tx_data, skb->data, len); + agg->skb_num++; + agg->skb_len += len; + dev_kfree_skb_any(skb); + + tx_data = tx_agg_align(tx_data + len); + remain = rx_buf_sz - sizeof(*tx_desc) - +(u32)((void *)tx_data - agg->head); + } + + usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), + agg->head, (int)(tx_data - (u8 *)agg->head), + (usb_complete_t)write_bulk_callback, agg); + + return usb_submit_urb(agg->urb, GFP_ATOMIC); +} + static void rx_bottom(struct r8152 *tp) { unsigned long flags; @@ -1204,82 +1249,39 @@ submit: static void tx_bottom(struct r8152 *tp) { - struct net_device_stats *stats; - struct net_device *netdev; - struct tx_agg *agg; - unsigned long flags; - u32 remain, total; - u8 *tx_data; int res; - netdev = tp->netdev; - -next_agg: - agg = NULL; - if (skb_queue_empty(&tp->tx_queue)) - return; + do { + struct tx_agg *agg; - agg = r8152_get_tx_agg(tp); - if (!agg) - return; - - tx_data = agg->head; - agg->skb_num = agg->skb_len = 0; - remain = rx_buf_sz - sizeof(struct tx_desc); - total = 0; - - while (remain >= ETH_ZLEN) { - struct tx_desc *tx_desc; - struct sk_buff *skb; - unsigned int len; - - skb = skb_dequeue(&tp->tx_queue); - if (!skb) + if (skb_queue_empty(&tp->tx_queue)) break; - len = skb->len; - if (remain < len) { - skb_queue_head(&tp->tx_queue, skb); + agg = r8152_get_tx_agg(tp); + if (!agg) break; - } - - tx_data = tx_agg_align(tx_data); - tx_desc = (struct tx_desc *)tx_data; - tx_data += sizeof(*tx_desc); - r8152_tx_csum(tp, tx_desc, skb); - memcpy(tx_data, skb->data, len); - agg->skb_num++; - agg->skb_len += len; - dev_kfree_skb_any(skb); - - tx_data += len; - remain = rx_buf_sz - sizeof(*tx_desc) - -(u32)(tx_agg_align(tx_data) - agg->head); - } - - usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), - agg->head, (int)(tx_data - (u8 *)agg->head), - (usb_complete_t)write_bulk_callback, agg); - res = usb_submit_urb(agg->urb, GFP_ATOMIC); + res = r8152_tx_agg_fill(tp, agg); + if (res) { + struct net_device_stats *stats; + struct net_device *netdev; + unsigned long flags; - stats = rtl8152_get_stats(netdev); + netdev = tp->netdev; + stats = rtl8152_get_stats(netdev); - if (res) { - /* Can we get/handle EPIPE here? */ - if (res == -ENODEV) { - netif_device_detach(netdev); - } else { - netif_warn(tp, tx_err, netdev, - "failed tx_urb %d\n", res); - stats-&
[PATCH net-next 7/7] r8152: add comments
Add comments. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 825edfe..f3fce41 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -790,6 +790,9 @@ static void read_bulk_callback(struct urb *urb) return; netdev = tp->netdev; + + /* When link down, the driver would cancel all bulks. */ + /* This avoid the re-submitting bulk */ if (!netif_carrier_ok(netdev)) return; @@ -1296,6 +1299,8 @@ static void bottom_half(unsigned long data) if (!test_bit(WORK_ENABLE, &tp->flags)) return; + /* When link down, the driver would cancel all bulks. */ + /* This avoid the re-submitting bulk */ if (!netif_carrier_ok(tp->netdev)) return; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 4/7] r8152: adjust some duplicated code
- Use r8152_get_tx_agg for getting tx agg list - Replace submit rx with goto submit Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 55 + 1 file changed, 28 insertions(+), 27 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 41b99ce..4dee76b 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1067,6 +1067,24 @@ err1: return -ENOMEM; } +static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp) +{ + struct tx_agg *agg = NULL; + unsigned long flags; + + spin_lock_irqsave(&tp->tx_lock, flags); + if (!list_empty(&tp->tx_free)) { + struct list_head *cursor; + + cursor = tp->tx_free.next; + list_del_init(cursor); + agg = list_entry(cursor, struct tx_agg, list); + } + spin_unlock_irqrestore(&tp->tx_lock, flags); + + return agg; +} + static void r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb) { @@ -1139,15 +1157,8 @@ static void rx_bottom(struct r8152 *tp) agg = list_entry(cursor, struct rx_agg, list); urb = agg->urb; - if (urb->actual_length < ETH_ZLEN) { - ret = r8152_submit_rx(tp, agg, GFP_ATOMIC); - spin_lock_irqsave(&tp->rx_lock, flags); - if (ret && ret != -ENODEV) { - list_add_tail(&agg->list, next); - tasklet_schedule(&tp->tl); - } - continue; - } + if (urb->actual_length < ETH_ZLEN) + goto submit; len_used = 0; rx_desc = agg->head; @@ -1181,6 +1192,7 @@ static void rx_bottom(struct r8152 *tp) len_used += sizeof(struct rx_desc) + pkt_len; } +submit: ret = r8152_submit_rx(tp, agg, GFP_ATOMIC); spin_lock_irqsave(&tp->rx_lock, flags); if (ret && ret != -ENODEV) { @@ -1205,16 +1217,10 @@ static void tx_bottom(struct r8152 *tp) next_agg: agg = NULL; - spin_lock_irqsave(&tp->tx_lock, flags); - if (!skb_queue_empty(&tp->tx_queue) && !list_empty(&tp->tx_free)) { - struct list_head *cursor; - - cursor = tp->tx_free.next; - list_del_init(cursor); - agg = list_entry(cursor, struct tx_agg, list); - } - spin_unlock_irqrestore(&tp->tx_lock, flags); + if (skb_queue_empty(&tp->tx_queue)) + return; + agg = r8152_get_tx_agg(tp); if (!agg) return; @@ -1382,15 +1388,10 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, skb_tx_timestamp(skb); - spin_lock_irqsave(&tp->tx_lock, flags); - if (!list_empty(&tp->tx_free) && skb_queue_empty(&tp->tx_queue)) { - struct list_head *cursor; - - cursor = tp->tx_free.next; - list_del_init(cursor); - agg = list_entry(cursor, struct tx_agg, list); - } - spin_unlock_irqrestore(&tp->tx_lock, flags); + /* If tx_queue is not empty, it means at least one previous packt */ + /* is waiting for sending. Don't send current one before it. */ + if (skb_queue_empty(&tp->tx_queue)) + agg = r8152_get_tx_agg(tp); if (!agg) { skb_queue_tail(&tp->tx_queue, skb); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 3/3] net/usb/r8152: adjust relative ocp function
- fix the conversion between cpu and __le32 - replace some pla_ocp and usb_ocp functions with generic_ocp function Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 66 + 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 93a7baa..252b61b 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -536,37 +536,31 @@ int usb_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) static u32 ocp_read_dword(struct r8152 *tp, u16 type, u16 index) { - u32 data; + __le32 data; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(data), &data, type); return __le32_to_cpu(data); } static void ocp_write_dword(struct r8152 *tp, u16 type, u16 index, u32 data) { - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); - else - usb_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); + __le32 tmp = __cpu_to_le32(data); + + generic_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(tmp), &tmp, type); } static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) { u32 data; + __le32 tmp; u8 shift = index & 2; index &= ~3; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - data = __le32_to_cpu(data); + data = __le32_to_cpu(tmp); data >>= (shift * 8); data &= 0x; @@ -575,7 +569,8 @@ static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) { - u32 tmp, mask = 0x; + u32 mask = 0x; + __le32 tmp; u16 byen = BYTE_EN_WORD; u8 shift = index & 2; @@ -588,34 +583,25 @@ static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(tmp), &tmp); - else - usb_ocp_read(tp, index, sizeof(tmp), &tmp); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - tmp = __le32_to_cpu(tmp) & ~mask; - tmp |= data; - tmp = __cpu_to_le32(tmp); + data |= __le32_to_cpu(tmp) & ~mask; + tmp = __cpu_to_le32(data); - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); - else - usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); + generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); } static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) { u32 data; + __le32 tmp; u8 shift = index & 3; index &= ~3; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - data = __le32_to_cpu(data); + data = __le32_to_cpu(tmp); data >>= (shift * 8); data &= 0xff; @@ -624,7 +610,8 @@ static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) { - u32 tmp, mask = 0xff; + u32 mask = 0xff; + __le32 tmp; u16 byen = BYTE_EN_BYTE; u8 shift = index & 3; @@ -637,19 +624,12 @@ static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(tmp), &tmp); - else - usb_ocp_read(tp, index, sizeof(tmp), &tmp); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - tmp = __le32_to_cpu(tmp) & ~mask; - tmp |= data; - tmp = __cpu_to_le32(tmp); + data |= __le32_to_cpu(tmp) & ~mask; + tmp = __cpu_to_le32(data); - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); - else - usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); + generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); } static void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 value) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v3 1/3] net/usb/r815x: replace USB buffer from stack to DMA-able
Allocate the transfer buffer in probe(), and use the buffer for usb control transfer. Signed-off-by: Hayes Wang --- drivers/net/usb/r815x.c | 117 +--- 1 file changed, 90 insertions(+), 27 deletions(-) diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c index 8523922..89ad63f 100644 --- a/drivers/net/usb/r815x.c +++ b/drivers/net/usb/r815x.c @@ -21,37 +21,52 @@ #define R815x_PHY_ID 32 #define REALTEK_VENDOR_ID 0x0bda +struct r815x { + struct mutex transfer_mutex; + __le32 *transfer_buf; +}; -static int pla_read_word(struct usb_device *udev, u16 index) +static int pla_read_word(struct usbnet *dev, u16 index) { - int data, ret; + struct r815x *tp = dev->driver_priv; + struct usb_device *udev = dev->udev; + int ret; u8 shift = index & 2; - __le32 ocp_data; + __le32 *tmp; + + mutex_lock(&tp->transfer_mutex); + tmp = tp->transfer_buf; index &= ~3; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, &ocp_data, sizeof(ocp_data), - 500); + index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); if (ret < 0) - return ret; + goto out2; - data = __le32_to_cpu(ocp_data); - data >>= (shift * 8); - data &= 0x; + ret = __le32_to_cpu(*tmp); + ret >>= (shift * 8); + ret &= 0x; - return data; +out2: + mutex_unlock(&tp->transfer_mutex); + return ret; } -static int pla_write_word(struct usb_device *udev, u16 index, u32 data) +static int pla_write_word(struct usbnet *dev, u16 index, u32 data) { - __le32 ocp_data; + struct r815x *tp = dev->driver_priv; + struct usb_device *udev = dev->udev; + __le32 *tmp; u32 mask = 0x; u16 byen = BYTE_EN_WORD; u8 shift = index & 2; int ret; + mutex_lock(&tp->transfer_mutex); + tmp = tp->transfer_buf; + data &= mask; if (shift) { @@ -63,19 +78,20 @@ static int pla_write_word(struct usb_device *udev, u16 index, u32 data) ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, &ocp_data, sizeof(ocp_data), - 500); + index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); if (ret < 0) - return ret; + goto out3; - data |= __le32_to_cpu(ocp_data) & ~mask; - ocp_data = __cpu_to_le32(data); + data |= __le32_to_cpu(*tmp) & ~mask; + *tmp = __cpu_to_le32(data); ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE, - index, MCU_TYPE_PLA | byen, &ocp_data, - sizeof(ocp_data), 500); + index, MCU_TYPE_PLA | byen, tmp, sizeof(*tmp), + 500); +out3: + mutex_unlock(&tp->transfer_mutex); return ret; } @@ -85,12 +101,12 @@ static int ocp_reg_read(struct usbnet *dev, u16 addr) int ret; ocp_base = addr & 0xf000; - ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); + ret = pla_write_word(dev, OCP_BASE, ocp_base); if (ret < 0) goto out; ocp_index = (addr & 0x0fff) | 0xb000; - ret = pla_read_word(dev->udev, ocp_index); + ret = pla_read_word(dev, ocp_index); out: return ret; @@ -102,12 +118,12 @@ static int ocp_reg_write(struct usbnet *dev, u16 addr, u16 data) int ret; ocp_base = addr & 0xf000; - ret = pla_write_word(dev->udev, OCP_BASE, ocp_base); + ret = pla_write_word(dev, OCP_BASE, ocp_base); if (ret < 0) goto out1; ocp_index = (addr & 0x0fff) | 0xb000; - ret = pla_write_word(dev->udev, ocp_index, data); + ret = pla_write_word(dev, ocp_index, data); out1: return ret; @@ -134,12 +150,59 @@ void r815x_mdio_write(struct net_device *netdev, int phy_id, int reg, int val) ocp_reg_write(dev, BASE_MII + reg * 2, val); } -static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) +static int r815x_bind(struct usbnet *dev, struct usb_interface *intf) { + struct r815x *tp; int status; + tp = kmalloc(sizeof(*tp), GFP_KERNEL); + if (!tp) + return -ENOMEM; + + memset(tp, 0, sizeof(*tp)); + + status = -ENOMEM; + + tp->transfer_buf = kmalloc(sizeof(*tp->transf
[PATCH v3 2/3] net/usb/r8152: replace USB buffer from stack to DMA-able
Allocate the required transfer buffer for usb_control_msg. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 91 +++-- 1 file changed, 66 insertions(+), 25 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ee13f9e..93a7baa 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -282,6 +282,8 @@ enum rtl_register_content { #define RTL8152_RMS(VLAN_ETH_FRAME_LEN + VLAN_HLEN) #define RTL8152_TX_TIMEOUT (HZ) +#define RTL8152_MAX_TRANSFER_SIZE 8 + /* rtl8152 flags */ enum rtl8152_flags { RTL8152_UNPLUG = 0, @@ -324,8 +326,10 @@ struct r8152 { struct sk_buff *tx_skb, *rx_skb; struct delayed_work schedule; struct mii_if_info mii; + struct mutex transfer_mutex; u32 msg_enable; u16 ocp_base; + u8 *transfer_buf; u8 version; u8 speed; }; @@ -344,17 +348,59 @@ static const int multicast_filter_limit = 32; static int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) { - return usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), + int ret; + void *tmp; + + if (size > RTL8152_MAX_TRANSFER_SIZE || !tp->transfer_buf) { + tmp = kmalloc(size, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + } else { + mutex_lock(&tp->transfer_mutex); + tmp = tp->transfer_buf; + } + + ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, - value, index, data, size, 500); + value, index, tmp, size, 500); + + memcpy(data, tmp, size); + + if (tmp == tp->transfer_buf) + mutex_unlock(&tp->transfer_mutex); + else + kfree(tmp); + + return ret; } static int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) { - return usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), + int ret; + void *tmp; + + if (size > RTL8152_MAX_TRANSFER_SIZE || !tp->transfer_buf) { + tmp = kmalloc(size, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + } else { + mutex_lock(&tp->transfer_mutex); + tmp = tp->transfer_buf; + } + + memcpy(tmp, data, size); + + ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, - value, index, data, size, 500); + value, index, tmp, size, 500); + + if (tmp == tp->transfer_buf) + mutex_unlock(&tp->transfer_mutex); + else + kfree(tmp); + + return ret; } static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, @@ -685,21 +731,14 @@ static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) static inline void set_ethernet_addr(struct r8152 *tp) { struct net_device *dev = tp->netdev; - u8 *node_id; - - node_id = kmalloc(sizeof(u8) * 8, GFP_KERNEL); - if (!node_id) { - netif_err(tp, probe, dev, "out of memory"); - return; - } + u8 node_id[8] = {0}; - if (pla_ocp_read(tp, PLA_IDR, sizeof(u8) * 8, node_id) < 0) + if (pla_ocp_read(tp, PLA_IDR, sizeof(node_id), node_id) < 0) netif_notice(tp, probe, dev, "inet addr fail\n"); else { memcpy(dev->dev_addr, node_id, dev->addr_len); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); } - kfree(node_id); } static int rtl8152_set_mac_address(struct net_device *netdev, void *p) @@ -882,15 +921,10 @@ static void rtl8152_set_rx_mode(struct net_device *netdev) static void _rtl8152_set_rx_mode(struct net_device *netdev) { struct r8152 *tp = netdev_priv(netdev); - u32 tmp, *mc_filter;/* Multicast hash filter */ + u32 mc_filter[2]; /* Multicast hash filter */ + __le32 tmp[2]; u32 ocp_data; - mc_filter = kmalloc(sizeof(u32) * 2, GFP_KERNEL); - if (!mc_filter) { - netif_err(tp, link, netdev, "out of memory"); - return; - } - clear_bit(RTL8152_SET_RX_MODE, &tp->flags); netif_stop_queue(netdev); ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); @@ -918,14 +952,12 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) } } - tmp = mc_filter[0]; - mc_filter[0] = __cpu_to_le32(swab32(mc_filter[1])); - mc_filter[1] = __cpu_to_le32(swab32(tmp)); + tmp[0] = __cpu_to_le32(sw
[PATCH v4 3/5] net/usb/r815x: change the return value for bind functions
Replace 0 with the result from usbnet_cdc_bind(). Signed-off-by: Hayes Wang --- drivers/net/usb/r815x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c index 1a80e76..2df2f4f 100644 --- a/drivers/net/usb/r815x.c +++ b/drivers/net/usb/r815x.c @@ -172,7 +172,7 @@ static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) dev->mii.phy_id = R815x_PHY_ID; dev->mii.supports_gmii = 1; - return 0; + return status; } static int r8152_bind(struct usbnet *dev, struct usb_interface *intf) @@ -191,7 +191,7 @@ static int r8152_bind(struct usbnet *dev, struct usb_interface *intf) dev->mii.phy_id = R815x_PHY_ID; dev->mii.supports_gmii = 0; - return 0; + return status; } static const struct driver_info r8152_info = { -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 1/5] net/usb/r815x: replace USB buffer from stack to DMA-able
Some USB buffers use stack which may not be DMA-able. Use the buffers from kmalloc to replace those one. Signed-off-by: Hayes Wang --- drivers/net/usb/r815x.c | 44 +++- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c index 8523922..e9b99ba 100644 --- a/drivers/net/usb/r815x.c +++ b/drivers/net/usb/r815x.c @@ -24,34 +24,43 @@ static int pla_read_word(struct usb_device *udev, u16 index) { - int data, ret; + int ret; u8 shift = index & 2; - __le32 ocp_data; + __le32 *tmp; + + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; index &= ~3; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, &ocp_data, sizeof(ocp_data), - 500); + index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); if (ret < 0) - return ret; + goto out2; - data = __le32_to_cpu(ocp_data); - data >>= (shift * 8); - data &= 0x; + ret = __le32_to_cpu(*tmp); + ret >>= (shift * 8); + ret &= 0x; - return data; +out2: + kfree(tmp); + return ret; } static int pla_write_word(struct usb_device *udev, u16 index, u32 data) { - __le32 ocp_data; + __le32 *tmp; u32 mask = 0x; u16 byen = BYTE_EN_WORD; u8 shift = index & 2; int ret; + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + data &= mask; if (shift) { @@ -63,19 +72,20 @@ static int pla_write_word(struct usb_device *udev, u16 index, u32 data) ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, &ocp_data, sizeof(ocp_data), - 500); + index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); if (ret < 0) - return ret; + goto out3; - data |= __le32_to_cpu(ocp_data) & ~mask; - ocp_data = __cpu_to_le32(data); + data |= __le32_to_cpu(*tmp) & ~mask; + *tmp = __cpu_to_le32(data); ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE, - index, MCU_TYPE_PLA | byen, &ocp_data, - sizeof(ocp_data), 500); + index, MCU_TYPE_PLA | byen, tmp, sizeof(*tmp), + 500); +out3: + kfree(tmp); return ret; } -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 2/5] net/usb/r815x: avoid to call mdio functions for runtime-suspended device
Don't replace the usb_control_msg() with usbnet_{read,write}_cmd() which couldn't be called inside suspend/resume callback. Keep the basic functions unlimited. Instead, using usb_autopm_get_interface() and usb_autopm_put_interface() in r815x_mdio_{read,write}(). Signed-off-by: Hayes Wang --- drivers/net/usb/r815x.c | 14 +- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c index e9b99ba..1a80e76 100644 --- a/drivers/net/usb/r815x.c +++ b/drivers/net/usb/r815x.c @@ -126,11 +126,18 @@ out1: static int r815x_mdio_read(struct net_device *netdev, int phy_id, int reg) { struct usbnet *dev = netdev_priv(netdev); + int ret; if (phy_id != R815x_PHY_ID) return -EINVAL; - return ocp_reg_read(dev, BASE_MII + reg * 2); + if (usb_autopm_get_interface(dev->intf) < 0) + return -ENODEV; + + ret = ocp_reg_read(dev, BASE_MII + reg * 2); + + usb_autopm_put_interface(dev->intf); + return ret; } static @@ -141,7 +148,12 @@ void r815x_mdio_write(struct net_device *netdev, int phy_id, int reg, int val) if (phy_id != R815x_PHY_ID) return; + if (usb_autopm_get_interface(dev->intf) < 0) + return; + ocp_reg_write(dev, BASE_MII + reg * 2, val); + + usb_autopm_put_interface(dev->intf); } static int r8153_bind(struct usbnet *dev, struct usb_interface *intf) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 5/5] net/usb/r8152: adjust relative ocp function
- fix the conversion between cpu and __le32 - replace some pla_ocp and usb_ocp functions with generic_ocp function Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 66 + 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ef033ab..11c51f2 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -514,37 +514,31 @@ int usb_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) static u32 ocp_read_dword(struct r8152 *tp, u16 type, u16 index) { - u32 data; + __le32 data; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(data), &data, type); return __le32_to_cpu(data); } static void ocp_write_dword(struct r8152 *tp, u16 type, u16 index, u32 data) { - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); - else - usb_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); + __le32 tmp = __cpu_to_le32(data); + + generic_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(tmp), &tmp, type); } static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) { u32 data; + __le32 tmp; u8 shift = index & 2; index &= ~3; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - data = __le32_to_cpu(data); + data = __le32_to_cpu(tmp); data >>= (shift * 8); data &= 0x; @@ -553,7 +547,8 @@ static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) { - u32 tmp, mask = 0x; + u32 mask = 0x; + __le32 tmp; u16 byen = BYTE_EN_WORD; u8 shift = index & 2; @@ -566,34 +561,25 @@ static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(tmp), &tmp); - else - usb_ocp_read(tp, index, sizeof(tmp), &tmp); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - tmp = __le32_to_cpu(tmp) & ~mask; - tmp |= data; - tmp = __cpu_to_le32(tmp); + data |= __le32_to_cpu(tmp) & ~mask; + tmp = __cpu_to_le32(data); - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); - else - usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); + generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); } static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) { u32 data; + __le32 tmp; u8 shift = index & 3; index &= ~3; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - data = __le32_to_cpu(data); + data = __le32_to_cpu(tmp); data >>= (shift * 8); data &= 0xff; @@ -602,7 +588,8 @@ static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) { - u32 tmp, mask = 0xff; + u32 mask = 0xff; + __le32 tmp; u16 byen = BYTE_EN_BYTE; u8 shift = index & 3; @@ -615,19 +602,12 @@ static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(tmp), &tmp); - else - usb_ocp_read(tp, index, sizeof(tmp), &tmp); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - tmp = __le32_to_cpu(tmp) & ~mask; - tmp |= data; - tmp = __cpu_to_le32(tmp); + data |= __le32_to_cpu(tmp) & ~mask; + tmp = __cpu_to_le32(data); - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); - else - usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); + generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); } static void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 value) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v4 4/5] net/usb/r8152: make sure the USB buffer is DMA-able
Allocate the required memory before calling usb_control_msg. And the additional memory copy is necessary. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 60 - 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ee13f9e..ef033ab 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -344,17 +344,41 @@ static const int multicast_filter_limit = 32; static int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) { - return usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), + int ret; + void *tmp; + + tmp = kmalloc(size, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, - value, index, data, size, 500); + value, index, tmp, size, 500); + + memcpy(data, tmp, size); + kfree(tmp); + + return ret; } static int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) { - return usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), + int ret; + void *tmp; + + tmp = kmalloc(size, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + memcpy(tmp, data, size); + + ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, - value, index, data, size, 500); + value, index, tmp, size, 500); + + kfree(tmp); + return ret; } static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, @@ -685,21 +709,14 @@ static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) static inline void set_ethernet_addr(struct r8152 *tp) { struct net_device *dev = tp->netdev; - u8 *node_id; + u8 node_id[8] = {0}; - node_id = kmalloc(sizeof(u8) * 8, GFP_KERNEL); - if (!node_id) { - netif_err(tp, probe, dev, "out of memory"); - return; - } - - if (pla_ocp_read(tp, PLA_IDR, sizeof(u8) * 8, node_id) < 0) + if (pla_ocp_read(tp, PLA_IDR, sizeof(node_id), node_id) < 0) netif_notice(tp, probe, dev, "inet addr fail\n"); else { memcpy(dev->dev_addr, node_id, dev->addr_len); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); } - kfree(node_id); } static int rtl8152_set_mac_address(struct net_device *netdev, void *p) @@ -882,15 +899,10 @@ static void rtl8152_set_rx_mode(struct net_device *netdev) static void _rtl8152_set_rx_mode(struct net_device *netdev) { struct r8152 *tp = netdev_priv(netdev); - u32 tmp, *mc_filter;/* Multicast hash filter */ + u32 mc_filter[2]; /* Multicast hash filter */ + __le32 tmp[2]; u32 ocp_data; - mc_filter = kmalloc(sizeof(u32) * 2, GFP_KERNEL); - if (!mc_filter) { - netif_err(tp, link, netdev, "out of memory"); - return; - } - clear_bit(RTL8152_SET_RX_MODE, &tp->flags); netif_stop_queue(netdev); ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); @@ -918,14 +930,12 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) } } - tmp = mc_filter[0]; - mc_filter[0] = __cpu_to_le32(swab32(mc_filter[1])); - mc_filter[1] = __cpu_to_le32(swab32(tmp)); + tmp[0] = __cpu_to_le32(swab32(mc_filter[1])); + tmp[1] = __cpu_to_le32(swab32(mc_filter[0])); - pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(u32) * 2, mc_filter); + pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(tmp), tmp); ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); netif_wake_queue(netdev); - kfree(mc_filter); } static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 1/3] net/usb/r815x: replace USB buffer from stack to DMA-able
Some USB buffers use stack which may not be DMA-able. Use the buffers from kmalloc to replace those one. Signed-off-by: Hayes Wang --- drivers/net/usb/r815x.c | 44 +++- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/drivers/net/usb/r815x.c b/drivers/net/usb/r815x.c index 8523922..e9b99ba 100644 --- a/drivers/net/usb/r815x.c +++ b/drivers/net/usb/r815x.c @@ -24,34 +24,43 @@ static int pla_read_word(struct usb_device *udev, u16 index) { - int data, ret; + int ret; u8 shift = index & 2; - __le32 ocp_data; + __le32 *tmp; + + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; index &= ~3; ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, &ocp_data, sizeof(ocp_data), - 500); + index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); if (ret < 0) - return ret; + goto out2; - data = __le32_to_cpu(ocp_data); - data >>= (shift * 8); - data &= 0x; + ret = __le32_to_cpu(*tmp); + ret >>= (shift * 8); + ret &= 0x; - return data; +out2: + kfree(tmp); + return ret; } static int pla_write_word(struct usb_device *udev, u16 index, u32 data) { - __le32 ocp_data; + __le32 *tmp; u32 mask = 0x; u16 byen = BYTE_EN_WORD; u8 shift = index & 2; int ret; + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return -ENOMEM; + data &= mask; if (shift) { @@ -63,19 +72,20 @@ static int pla_write_word(struct usb_device *udev, u16 index, u32 data) ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), RTL815x_REQ_GET_REGS, RTL815x_REQT_READ, - index, MCU_TYPE_PLA, &ocp_data, sizeof(ocp_data), - 500); + index, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); if (ret < 0) - return ret; + goto out3; - data |= __le32_to_cpu(ocp_data) & ~mask; - ocp_data = __cpu_to_le32(data); + data |= __le32_to_cpu(*tmp) & ~mask; + *tmp = __cpu_to_le32(data); ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RTL815x_REQ_SET_REGS, RTL815x_REQT_WRITE, - index, MCU_TYPE_PLA | byen, &ocp_data, - sizeof(ocp_data), 500); + index, MCU_TYPE_PLA | byen, tmp, sizeof(*tmp), + 500); +out3: + kfree(tmp); return ret; } -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 2/3] net/usb/r8152: make sure the USB buffer is DMA-able
Allocate the required memory before calling usb_control_msg. And the additional memory copy is necessary. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 60 - 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ee13f9e..ef033ab 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -344,17 +344,41 @@ static const int multicast_filter_limit = 32; static int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) { - return usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), + int ret; + void *tmp; + + tmp = kmalloc(size, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + ret = usb_control_msg(tp->udev, usb_rcvctrlpipe(tp->udev, 0), RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, - value, index, data, size, 500); + value, index, tmp, size, 500); + + memcpy(data, tmp, size); + kfree(tmp); + + return ret; } static int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) { - return usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), + int ret; + void *tmp; + + tmp = kmalloc(size, GFP_KERNEL); + if (!tmp) + return -ENOMEM; + + memcpy(tmp, data, size); + + ret = usb_control_msg(tp->udev, usb_sndctrlpipe(tp->udev, 0), RTL8152_REQ_SET_REGS, RTL8152_REQT_WRITE, - value, index, data, size, 500); + value, index, tmp, size, 500); + + kfree(tmp); + return ret; } static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size, @@ -685,21 +709,14 @@ static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) static inline void set_ethernet_addr(struct r8152 *tp) { struct net_device *dev = tp->netdev; - u8 *node_id; + u8 node_id[8] = {0}; - node_id = kmalloc(sizeof(u8) * 8, GFP_KERNEL); - if (!node_id) { - netif_err(tp, probe, dev, "out of memory"); - return; - } - - if (pla_ocp_read(tp, PLA_IDR, sizeof(u8) * 8, node_id) < 0) + if (pla_ocp_read(tp, PLA_IDR, sizeof(node_id), node_id) < 0) netif_notice(tp, probe, dev, "inet addr fail\n"); else { memcpy(dev->dev_addr, node_id, dev->addr_len); memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len); } - kfree(node_id); } static int rtl8152_set_mac_address(struct net_device *netdev, void *p) @@ -882,15 +899,10 @@ static void rtl8152_set_rx_mode(struct net_device *netdev) static void _rtl8152_set_rx_mode(struct net_device *netdev) { struct r8152 *tp = netdev_priv(netdev); - u32 tmp, *mc_filter;/* Multicast hash filter */ + u32 mc_filter[2]; /* Multicast hash filter */ + __le32 tmp[2]; u32 ocp_data; - mc_filter = kmalloc(sizeof(u32) * 2, GFP_KERNEL); - if (!mc_filter) { - netif_err(tp, link, netdev, "out of memory"); - return; - } - clear_bit(RTL8152_SET_RX_MODE, &tp->flags); netif_stop_queue(netdev); ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR); @@ -918,14 +930,12 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) } } - tmp = mc_filter[0]; - mc_filter[0] = __cpu_to_le32(swab32(mc_filter[1])); - mc_filter[1] = __cpu_to_le32(swab32(tmp)); + tmp[0] = __cpu_to_le32(swab32(mc_filter[1])); + tmp[1] = __cpu_to_le32(swab32(mc_filter[0])); - pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(u32) * 2, mc_filter); + pla_ocp_write(tp, PLA_MAR, BYTE_EN_DWORD, sizeof(tmp), tmp); ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); netif_wake_queue(netdev); - kfree(mc_filter); } static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2 3/3] net/usb/r8152: adjust relative ocp function
- fix the conversion between cpu and __le32 - replace some pla_ocp and usb_ocp functions with generic_ocp function Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 66 + 1 file changed, 23 insertions(+), 43 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ef033ab..11c51f2 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -514,37 +514,31 @@ int usb_ocp_write(struct r8152 *tp, u16 index, u16 byteen, u16 size, void *data) static u32 ocp_read_dword(struct r8152 *tp, u16 type, u16 index) { - u32 data; + __le32 data; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(data), &data, type); return __le32_to_cpu(data); } static void ocp_write_dword(struct r8152 *tp, u16 type, u16 index, u32 data) { - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); - else - usb_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(data), &data); + __le32 tmp = __cpu_to_le32(data); + + generic_ocp_write(tp, index, BYTE_EN_DWORD, sizeof(tmp), &tmp, type); } static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) { u32 data; + __le32 tmp; u8 shift = index & 2; index &= ~3; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - data = __le32_to_cpu(data); + data = __le32_to_cpu(tmp); data >>= (shift * 8); data &= 0x; @@ -553,7 +547,8 @@ static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 index) static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) { - u32 tmp, mask = 0x; + u32 mask = 0x; + __le32 tmp; u16 byen = BYTE_EN_WORD; u8 shift = index & 2; @@ -566,34 +561,25 @@ static void ocp_write_word(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(tmp), &tmp); - else - usb_ocp_read(tp, index, sizeof(tmp), &tmp); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - tmp = __le32_to_cpu(tmp) & ~mask; - tmp |= data; - tmp = __cpu_to_le32(tmp); + data |= __le32_to_cpu(tmp) & ~mask; + tmp = __cpu_to_le32(data); - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); - else - usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); + generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); } static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) { u32 data; + __le32 tmp; u8 shift = index & 3; index &= ~3; - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(data), &data); - else - usb_ocp_read(tp, index, sizeof(data), &data); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - data = __le32_to_cpu(data); + data = __le32_to_cpu(tmp); data >>= (shift * 8); data &= 0xff; @@ -602,7 +588,8 @@ static u8 ocp_read_byte(struct r8152 *tp, u16 type, u16 index) static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) { - u32 tmp, mask = 0xff; + u32 mask = 0xff; + __le32 tmp; u16 byen = BYTE_EN_BYTE; u8 shift = index & 3; @@ -615,19 +602,12 @@ static void ocp_write_byte(struct r8152 *tp, u16 type, u16 index, u32 data) index &= ~3; } - if (type == MCU_TYPE_PLA) - pla_ocp_read(tp, index, sizeof(tmp), &tmp); - else - usb_ocp_read(tp, index, sizeof(tmp), &tmp); + generic_ocp_read(tp, index, sizeof(tmp), &tmp, type); - tmp = __le32_to_cpu(tmp) & ~mask; - tmp |= data; - tmp = __cpu_to_le32(tmp); + data |= __le32_to_cpu(tmp) & ~mask; + tmp = __cpu_to_le32(data); - if (type == MCU_TYPE_PLA) - pla_ocp_write(tp, index, byen, sizeof(tmp), &tmp); - else - usb_ocp_write(tp, index, byen, sizeof(tmp), &tmp); + generic_ocp_write(tp, index, byen, sizeof(tmp), &tmp, type); } static void r8152_mdio_write(struct r8152 *tp, u32 reg_addr, u32 value) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 3/3] net/usb/r8152: enable interrupt transfer
Use the interrupt transfer to replace polling link status. Delay to update the link down status, because some of them result from the change of speed. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 134 ++-- 1 file changed, 107 insertions(+), 27 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 5d9d949..32af41a 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -272,6 +272,9 @@ enum rtl_register_content { #define RTL8152_MAX_TX 10 #define RTL8152_MAX_RX 10 +#define INTBUFSIZE 2 + +#define INTR_LINK 0x0004 #define RTL8152_REQT_READ 0xc0 #define RTL8152_REQT_WRITE 0x40 @@ -292,7 +295,8 @@ enum rtl_register_content { enum rtl8152_flags { RTL8152_UNPLUG = 0, RTL8152_SET_RX_MODE, - WORK_ENABLE + WORK_ENABLE, + RTL8152_LINK_CHG, }; /* Define these values to match your device */ @@ -349,7 +353,9 @@ struct r8152 { unsigned long flags; struct usb_device *udev; struct tasklet_struct tl; + struct usb_interface *intf; struct net_device *netdev; + struct urb *intr_urb; struct tx_agg tx_info[RTL8152_MAX_TX]; struct rx_agg rx_info[RTL8152_MAX_RX]; struct list_head rx_done, tx_free; @@ -357,8 +363,10 @@ struct r8152 { spinlock_t rx_lock, tx_lock; struct delayed_work schedule; struct mii_if_info mii; + int intr_interval; u32 msg_enable; u16 ocp_base; + u8 *intr_buff; u8 version; u8 speed; }; @@ -855,6 +863,56 @@ static void write_bulk_callback(struct urb *urb) tasklet_schedule(&tp->tl); } +static void intr_callback(struct urb *urb) +{ + struct r8152 *tp; + __u16 *d; + int status = urb->status; + int res; + + tp = urb->context; + if (!tp) + return; + + switch (status) { + case 0: /* success */ + break; + case -ECONNRESET: /* unlink */ + case -ESHUTDOWN: + netif_device_detach(tp->netdev); + case -ENOENT: + return; + case -EOVERFLOW: + netif_info(tp, intr, tp->netdev, "intr status -EOVERFLOW\n"); + goto resubmit; + /* -EPIPE: should clear the halt */ + default: + netif_info(tp, intr, tp->netdev, "intr status %d\n", status); + goto resubmit; + } + + d = urb->transfer_buffer; + if (INTR_LINK & __le16_to_cpu(d[0])) { + if (!(tp->speed & LINK_STATUS)) { + set_bit(RTL8152_LINK_CHG, &tp->flags); + schedule_delayed_work(&tp->schedule, 0); + } + } else { + if (tp->speed & LINK_STATUS) { + set_bit(RTL8152_LINK_CHG, &tp->flags); + schedule_delayed_work(&tp->schedule, 5 * HZ); + } + } + +resubmit: + res = usb_submit_urb(urb, GFP_ATOMIC); + if (res == -ENODEV) + netif_device_detach(tp->netdev); + else if (res) + netif_err(tp, intr, tp->netdev, + "can't resubmit intr, status %d\n", res); +} + static inline void *rx_agg_align(void *data) { return (void *)ALIGN((uintptr_t)data, 8); @@ -894,11 +952,24 @@ static void free_all_mem(struct r8152 *tp) tp->tx_info[i].head = tp->tx_info[i].data = NULL; } } + + if (tp->intr_urb) { + usb_free_urb(tp->intr_urb); + tp->intr_urb = NULL; + } + + if (tp->intr_buff) { + kfree(tp->intr_buff); + tp->intr_buff = NULL; + } } static int alloc_all_mem(struct r8152 *tp) { struct net_device *netdev = tp->netdev; + struct usb_interface *intf = tp->intf; + struct usb_host_interface *alt = intf->cur_altsetting; + struct usb_host_endpoint *ep_intr = alt->endpoint + 2; struct urb *urb; int node, i; u8 *buf; @@ -964,6 +1035,19 @@ static int alloc_all_mem(struct r8152 *tp) list_add_tail(&tp->tx_info[i].list, &tp->tx_free); } + tp->intr_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!tp->intr_urb) + goto err1; + + tp->intr_buff = kmalloc(INTBUFSIZE, GFP_KERNEL); + if (!tp->intr_buff) + goto err1; + + tp->intr_interval = (int)ep_intr->desc.bInterval; + usb_fill_int_urb(tp->intr_urb, tp->udev, usb_rcvintpipe(tp->udev, 3), +tp->intr_buff, INTBUFSIZE, intr_callback, +tp, tp->intr_interval); + return 0;
[PATCH net-next 2/3] net/usb/r8152: enable tx checksum
Enable tx checksum. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 63 + 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index c6c5aa2..5d9d949 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -20,6 +20,8 @@ #include #include #include +#include +#include /* Version Information */ #define DRIVER_VERSION "v1.01.0 (2013/08/12)" @@ -314,8 +316,13 @@ struct tx_desc { u32 opts1; #define TX_FS (1 << 31) /* First segment of a packet */ #define TX_LS (1 << 30) /* Final segment of a packet */ -#define TX_LEN_MASK0x +#define TX_LEN_MASK0x3 + u32 opts2; +#define UDP_CS (1 << 31) /* Calculate UDP/IP checksum */ +#define TCP_CS (1 << 30) /* Calculate TCP/IP checksum */ +#define IPV4_CS(1 << 29) /* Calculate IPv4 checksum */ +#define IPV6_CS(1 << 28) /* Calculate IPv6 checksum */ }; struct rx_agg { @@ -964,6 +971,51 @@ err1: return -ENOMEM; } +static void +r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb) +{ + memset(desc, 0, sizeof(*desc)); + + desc->opts1 = cpu_to_le32((skb->len & TX_LEN_MASK) | TX_FS | TX_LS); + + if (skb->ip_summed == CHECKSUM_PARTIAL) { + __be16 protocol; + u8 ip_protocol; + u32 opts2 = 0; + + if (skb->protocol == htons(ETH_P_8021Q)) + protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; + else + protocol = skb->protocol; + + switch (protocol) { + case htons(ETH_P_IP): + opts2 |= IPV4_CS; + ip_protocol = ip_hdr(skb)->protocol; + break; + + case htons(ETH_P_IPV6): + opts2 |= IPV6_CS; + ip_protocol = ipv6_hdr(skb)->nexthdr; + break; + + default: + ip_protocol = IPPROTO_RAW; + break; + } + + if (ip_protocol == IPPROTO_TCP) { + opts2 |= TCP_CS; + opts2 |= (skb_transport_offset(skb) & 0x7fff) << 17; + } else if (ip_protocol == IPPROTO_UDP) { + opts2 |= UDP_CS; + } else + WARN_ON_ONCE(1); + + desc->opts2 = cpu_to_le32(opts2); + } +} + static void rx_bottom(struct r8152 *tp) { struct net_device_stats *stats; @@ -1100,8 +1152,7 @@ next_agg: tx_desc = (struct tx_desc *)agg->data; agg->data += sizeof(*tx_desc); - tx_desc->opts1 = cpu_to_le32((skb->len & TX_LEN_MASK) | TX_FS | -TX_LS); + r8152_tx_csum(tp, tx_desc, skb); memcpy(agg->data, skb->data, len); agg->skb_num++; agg->skb_len += len; @@ -1249,7 +1300,7 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, agg->skb_num = agg->skb_len = 0; len = skb->len; - tx_desc->opts1 = cpu_to_le32((skb->len & TX_LEN_MASK) | TX_FS | TX_LS); + r8152_tx_csum(tp, tx_desc, skb); memcpy(agg->data, skb->data, len); dev_kfree_skb_any(skb); agg->skb_num++; @@ -1957,7 +2008,9 @@ static int rtl8152_probe(struct usb_interface *intf, tp->netdev = netdev; netdev->netdev_ops = &rtl8152_netdev_ops; netdev->watchdog_timeo = RTL8152_TX_TIMEOUT; - netdev->features &= ~NETIF_F_IP_CSUM; + + netdev->features |= NETIF_F_IP_CSUM; + netdev->hw_features = NETIF_F_IP_CSUM; SET_ETHTOOL_OPS(netdev, &ops); tp->speed = 0; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 1/3] net/usb/r8152: support aggregation
Enable the tx/rx aggregation which could contain one or more packets for each bulk in/out. This could reduce the loading of the host controller by sending less bulk transfer. The rx packets in the bulk in buffer should be 8-byte aligned, and the tx packets in the bulk out buffer should be 4-byte aligned. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 627 +++- 1 file changed, 466 insertions(+), 161 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 11c51f2..c6c5aa2 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -19,9 +19,10 @@ #include #include #include +#include /* Version Information */ -#define DRIVER_VERSION "v1.0.0 (2013/05/03)" +#define DRIVER_VERSION "v1.01.0 (2013/08/12)" #define DRIVER_AUTHOR "Realtek linux nic maintainers " #define DRIVER_DESC "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" #define MODULENAME "r8152" @@ -267,6 +268,9 @@ enum rtl_register_content { FULL_DUP= 0x01, }; +#define RTL8152_MAX_TX 10 +#define RTL8152_MAX_RX 10 + #define RTL8152_REQT_READ 0xc0 #define RTL8152_REQT_WRITE 0x40 #define RTL8152_REQ_GET_REGS 0x05 @@ -285,7 +289,6 @@ enum rtl_register_content { /* rtl8152 flags */ enum rtl8152_flags { RTL8152_UNPLUG = 0, - RX_URB_FAIL, RTL8152_SET_RX_MODE, WORK_ENABLE }; @@ -315,13 +318,36 @@ struct tx_desc { u32 opts2; }; +struct rx_agg { + struct list_head list; + struct urb *urb; + void *context; + void *buffer; + void *head; + u8 *data; +}; + +struct tx_agg { + struct list_head list; + struct urb *urb; + void *context; + void *buffer; + void *head; + u8 *data; + u32 skb_num; + u32 skb_len; +}; + struct r8152 { unsigned long flags; struct usb_device *udev; struct tasklet_struct tl; struct net_device *netdev; - struct urb *rx_urb, *tx_urb; - struct sk_buff *tx_skb, *rx_skb; + struct tx_agg tx_info[RTL8152_MAX_TX]; + struct rx_agg rx_info[RTL8152_MAX_RX]; + struct list_head rx_done, tx_free; + struct sk_buff_head tx_queue; + spinlock_t rx_lock, tx_lock; struct delayed_work schedule; struct mii_if_info mii; u32 msg_enable; @@ -340,6 +366,7 @@ enum rtl_version { * The RTL chips use a 64 element hash table based on the Ethernet CRC. */ static const int multicast_filter_limit = 32; +static unsigned int rx_buf_sz = 16384; static int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) @@ -686,6 +713,9 @@ static void ocp_reg_write(struct r8152 *tp, u16 addr, u16 data) ocp_write_word(tp, MCU_TYPE_PLA, ocp_index, data); } +static +int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags); + static inline void set_ethernet_addr(struct r8152 *tp) { struct net_device *dev = tp->netdev; @@ -716,26 +746,6 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p) return 0; } -static int alloc_all_urbs(struct r8152 *tp) -{ - tp->rx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!tp->rx_urb) - return 0; - tp->tx_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!tp->tx_urb) { - usb_free_urb(tp->rx_urb); - return 0; - } - - return 1; -} - -static void free_all_urbs(struct r8152 *tp) -{ - usb_free_urb(tp->rx_urb); - usb_free_urb(tp->tx_urb); -} - static struct net_device_stats *rtl8152_get_stats(struct net_device *dev) { return &dev->stats; @@ -743,129 +753,417 @@ static struct net_device_stats *rtl8152_get_stats(struct net_device *dev) static void read_bulk_callback(struct urb *urb) { - struct r8152 *tp; - unsigned pkt_len; - struct sk_buff *skb; struct net_device *netdev; - struct net_device_stats *stats; + unsigned long lockflags; int status = urb->status; + struct rx_agg *agg; + struct r8152 *tp; int result; - struct rx_desc *rx_desc; - tp = urb->context; + agg = urb->context; + if (!agg) + return; + + tp = agg->context; if (!tp) return; + if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; + netdev = tp->netdev; if (!netif_device_present(netdev)) return; - stats = rtl8152_get_stats(netdev); switch (status) { case 0: - break; + if (urb->actual_length < ETH_ZLEN) + break; + + spin_lock_irqsave(&tp->rx_lock, lockflags); + list_add_tail(&agg->list, &tp->rx_done); + spin_unlo
[PATCH v2 net-next] net/usb: new driver for RTL8152
Add new driver for supporting Realtek RTL8152 Based USB 2.0 Ethernet Adapters Signed-off-by: Hayes Wang Cc: Realtek linux nic maintainers --- drivers/net/usb/Kconfig | 11 + drivers/net/usb/Makefile|1 + drivers/net/usb/cdc_ether.c | 10 + drivers/net/usb/r8152.c | 1773 +++ 4 files changed, 1795 insertions(+) create mode 100644 drivers/net/usb/r8152.c diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 7c769d8..287cc62 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -93,6 +93,17 @@ config USB_RTL8150 To compile this driver as a module, choose M here: the module will be called rtl8150. +config USB_RTL8152 + tristate "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" + select NET_CORE + select MII + help + This option adds support for Realtek RTL8152 based USB 2.0 + 10/100 Ethernet adapters. + + To compile this driver as a module, choose M here: the + module will be called r8152. + config USB_USBNET tristate "Multi-purpose USB Networking Framework" select NET_CORE diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 119b06c..9ab5c9d 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_USB_CATC) += catc.o obj-$(CONFIG_USB_KAWETH) += kaweth.o obj-$(CONFIG_USB_PEGASUS) += pegasus.o obj-$(CONFIG_USB_RTL8150) += rtl8150.o +obj-$(CONFIG_USB_RTL8152) += r8152.o obj-$(CONFIG_USB_HSO) += hso.o obj-$(CONFIG_USB_NET_AX8817X) += asix.o asix-y := asix_devices.o asix_common.o ax88172a.o diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 4ff71d6..24fbec2 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -479,6 +479,7 @@ static const struct driver_info wwan_info = { #define NOVATEL_VENDOR_ID 0x1410 #define ZTE_VENDOR_ID 0x19D2 #define DELL_VENDOR_ID 0x413C +#define REALTEK_VENDOR_ID 0x0bda static const struct usb_device_id products [] = { /* @@ -619,6 +620,15 @@ static const struct usb_device_id products [] = { .driver_info = 0, }, +/* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */ +#if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE) +{ + USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, +#endif + /* * WHITELIST!!! * diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c new file mode 100644 index 000..33d4a9a --- /dev/null +++ b/drivers/net/usb/r8152.c @@ -0,0 +1,1773 @@ +/* + * Copyright (c) 2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Version Information */ +#define DRIVER_VERSION "v1.0.0 (2013/04/25)" +#define DRIVER_AUTHOR "Realtek linux nic maintainers " +#define DRIVER_DESC "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" +#define MODULENAME "r8152" + +#define PATENTS"This product is covered by one or more of the " \ + "following patents:\n" \ + "\t\tUS6,570,884, US6,115,776, and US6,327,625.\n" + +#define R8152_PHY_ID 32 + +#define PLA_IDR0xc000 +#define PLA_RCR0xc010 +#define PLA_RMS0xc016 +#define PLA_RXFIFO_CTRL0 0xc0a0 +#define PLA_RXFIFO_CTRL1 0xc0a4 +#define PLA_RXFIFO_CTRL2 0xc0a8 +#define PLA_FMC0xc0b4 +#define PLA_CFG_WOL0xc0b6 +#define PLA_MAR0xcd00 +#define PAL_BDC_CR 0xd1a0 +#define PLA_LEDSEL 0xdd90 +#define PLA_LED_FEATURE0xdd92 +#define PLA_PHYAR 0xde00 +#define PLA_GPHY_INTR_IMR 0xe022 +#define PLA_EEE_CR 0xe040 +#define PLA_EEEP_CR0xe080 +#define PLA_MAC_PWR_CTRL 0xe0c0 +#define PLA_TCR0 0xe610 +#define PLA_TCR1 0xe612 +#define PLA_TXFIFO_CTRL0xe618 +#define PLA_RSTTELLY 0xe800 +#define PLA_CR 0xe813 +#define PLA_CRWECR 0xe81c +#define PLA_CONFIG50xe822 +#define PLA_PHY_PWR0xe84c +#define PLA_OOB_CTRL 0xe84f +#define PLA_CPCR 0xe
[PATCH v3 net-next] net/usb: new driver for RTL8152
Add new driver for supporting Realtek RTL8152 Based USB 2.0 Ethernet Adapters Signed-off-by: Hayes Wang Cc: Realtek linux nic maintainers --- drivers/net/usb/Kconfig | 11 + drivers/net/usb/Makefile|1 + drivers/net/usb/cdc_ether.c | 10 + drivers/net/usb/r8152.c | 1767 +++ 4 files changed, 1789 insertions(+) create mode 100644 drivers/net/usb/r8152.c diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 7c769d8..287cc62 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -93,6 +93,17 @@ config USB_RTL8150 To compile this driver as a module, choose M here: the module will be called rtl8150. +config USB_RTL8152 + tristate "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" + select NET_CORE + select MII + help + This option adds support for Realtek RTL8152 based USB 2.0 + 10/100 Ethernet adapters. + + To compile this driver as a module, choose M here: the + module will be called r8152. + config USB_USBNET tristate "Multi-purpose USB Networking Framework" select NET_CORE diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 119b06c..9ab5c9d 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_USB_CATC) += catc.o obj-$(CONFIG_USB_KAWETH) += kaweth.o obj-$(CONFIG_USB_PEGASUS) += pegasus.o obj-$(CONFIG_USB_RTL8150) += rtl8150.o +obj-$(CONFIG_USB_RTL8152) += r8152.o obj-$(CONFIG_USB_HSO) += hso.o obj-$(CONFIG_USB_NET_AX8817X) += asix.o asix-y := asix_devices.o asix_common.o ax88172a.o diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 4ff71d6..24fbec2 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -479,6 +479,7 @@ static const struct driver_info wwan_info = { #define NOVATEL_VENDOR_ID 0x1410 #define ZTE_VENDOR_ID 0x19D2 #define DELL_VENDOR_ID 0x413C +#define REALTEK_VENDOR_ID 0x0bda static const struct usb_device_id products [] = { /* @@ -619,6 +620,15 @@ static const struct usb_device_id products [] = { .driver_info = 0, }, +/* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */ +#if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE) +{ + USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, +#endif + /* * WHITELIST!!! * diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c new file mode 100644 index 000..14e5198 --- /dev/null +++ b/drivers/net/usb/r8152.c @@ -0,0 +1,1767 @@ +/* + * Copyright (c) 2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Version Information */ +#define DRIVER_VERSION "v1.0.0 (2013/05/03)" +#define DRIVER_AUTHOR "Realtek linux nic maintainers " +#define DRIVER_DESC "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" +#define MODULENAME "r8152" + +#define R8152_PHY_ID 32 + +#define PLA_IDR0xc000 +#define PLA_RCR0xc010 +#define PLA_RMS0xc016 +#define PLA_RXFIFO_CTRL0 0xc0a0 +#define PLA_RXFIFO_CTRL1 0xc0a4 +#define PLA_RXFIFO_CTRL2 0xc0a8 +#define PLA_FMC0xc0b4 +#define PLA_CFG_WOL0xc0b6 +#define PLA_MAR0xcd00 +#define PAL_BDC_CR 0xd1a0 +#define PLA_LEDSEL 0xdd90 +#define PLA_LED_FEATURE0xdd92 +#define PLA_PHYAR 0xde00 +#define PLA_GPHY_INTR_IMR 0xe022 +#define PLA_EEE_CR 0xe040 +#define PLA_EEEP_CR0xe080 +#define PLA_MAC_PWR_CTRL 0xe0c0 +#define PLA_TCR0 0xe610 +#define PLA_TCR1 0xe612 +#define PLA_TXFIFO_CTRL0xe618 +#define PLA_RSTTELLY 0xe800 +#define PLA_CR 0xe813 +#define PLA_CRWECR 0xe81c +#define PLA_CONFIG50xe822 +#define PLA_PHY_PWR0xe84c +#define PLA_OOB_CTRL 0xe84f +#define PLA_CPCR 0xe854 +#define PLA_MISC_0 0xe858 +#define PLA_MISC_1 0xe85a +#define PLA_OCP_GPHY_BASE 0xe86c +#define PLA_TELLYCNT 0xe890 +#define PLA_SFF_STS_7 0xe8de +#define PLA_PHYSTATUS 0xe908 +#define PLA_BP_BA 0xfc26 +#define PLA_BP_0 0xfc28 +#define PLA_BP_1 0xf
[PATCH net-next] net/usb: new driver for RTL8152
Add new driver for supporting Realtek RTL8152 Based USB 2.0 Ethernet Adapters Signed-off-by: Hayes Wang Cc: Realtek linux nic maintainers --- drivers/net/usb/Kconfig | 11 + drivers/net/usb/Makefile|1 + drivers/net/usb/cdc_ether.c | 10 + drivers/net/usb/r8152.c | 1751 +++ 4 files changed, 1773 insertions(+) create mode 100644 drivers/net/usb/r8152.c diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index 7c769d8..287cc62 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -93,6 +93,17 @@ config USB_RTL8150 To compile this driver as a module, choose M here: the module will be called rtl8150. +config USB_RTL8152 + tristate "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" + select NET_CORE + select MII + help + This option adds support for Realtek RTL8152 based USB 2.0 + 10/100 Ethernet adapters. + + To compile this driver as a module, choose M here: the + module will be called r8152. + config USB_USBNET tristate "Multi-purpose USB Networking Framework" select NET_CORE diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile index 119b06c..9ab5c9d 100644 --- a/drivers/net/usb/Makefile +++ b/drivers/net/usb/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_USB_CATC) += catc.o obj-$(CONFIG_USB_KAWETH) += kaweth.o obj-$(CONFIG_USB_PEGASUS) += pegasus.o obj-$(CONFIG_USB_RTL8150) += rtl8150.o +obj-$(CONFIG_USB_RTL8152) += r8152.o obj-$(CONFIG_USB_HSO) += hso.o obj-$(CONFIG_USB_NET_AX8817X) += asix.o asix-y := asix_devices.o asix_common.o ax88172a.o diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c index 4ff71d6..24fbec2 100644 --- a/drivers/net/usb/cdc_ether.c +++ b/drivers/net/usb/cdc_ether.c @@ -479,6 +479,7 @@ static const struct driver_info wwan_info = { #define NOVATEL_VENDOR_ID 0x1410 #define ZTE_VENDOR_ID 0x19D2 #define DELL_VENDOR_ID 0x413C +#define REALTEK_VENDOR_ID 0x0bda static const struct usb_device_id products [] = { /* @@ -619,6 +620,15 @@ static const struct usb_device_id products [] = { .driver_info = 0, }, +/* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */ +#if defined(CONFIG_USB_RTL8152) || defined(CONFIG_USB_RTL8152_MODULE) +{ + USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM, + USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE), + .driver_info = 0, +}, +#endif + /* * WHITELIST!!! * diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c new file mode 100644 index 000..8031c48 --- /dev/null +++ b/drivers/net/usb/r8152.c @@ -0,0 +1,1751 @@ +/* + * Copyright (c) 2013 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This product is covered by one or more of the following patents: + * US6,570,884, US6,115,776, and US6,327,625. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Version Information */ +#define DRIVER_VERSION "v1.0.0 (2013/04/25)" +#define DRIVER_AUTHOR "Realtek linux nic maintainers " +#define DRIVER_DESC "Realtek RTL8152 Based USB 2.0 Ethernet Adapters" +#define MODULENAME "r8152" + +#define PATENTS"This product is covered by one or more of the " \ + "following patents:\n" \ + "\t\tUS6,570,884, US6,115,776, and US6,327,625.\n" + +#define R8152_PHY_ID 32 + +#define PLA_IDR0xc000 +#define PLA_RCR0xc010 +#define PLA_RMS0xc016 +#define PLA_RXFIFO_CTRL0 0xc0a0 +#define PLA_RXFIFO_CTRL1 0xc0a4 +#define PLA_RXFIFO_CTRL2 0xc0a8 +#define PLA_FMC0xc0b4 +#define PLA_CFG_WOL0xc0b6 +#define PLA_MAR0xcd00 +#define PAL_BDC_CR 0xd1a0 +#define PLA_LEDSEL 0xdd90 +#define PLA_LED_FEATURE0xdd92 +#define PLA_PHYAR 0xde00 +#define PLA_GPHY_INTR_IMR 0xe022 +#define PLA_EEE_CR 0xe040 +#define PLA_EEEP_CR0xe080 +#define PLA_MAC_PWR_CTRL 0xe0c0 +#define PLA_TCR0 0xe610 +#define PLA_TCR1 0xe612 +#define PLA_TXFIFO_CTRL0xe618 +#define PLA_RSTTELLY 0xe800 +#define PLA_CR 0xe813 +#define PLA_CRWECR 0xe81c +#define PLA_CONFIG50xe822 +#define PLA_PHY_PWR0xe84c +#define PLA_OOB_CTRL 0xe84f +#define PLA_CPCR 0xe
[PATCH] r8169: fix auto speed down issue
It would cause no link after suspending or shutdowning when the nic changes the speed to 10M and connects to a link partner which forces the speed to 100M. Check the link partner ability to determine if to change the speed to 10M when suspending or shutdowning. Regardless of keeping the speed to giga for power saving. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 19 --- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 28fb50a..a9eedf7 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3818,6 +3818,21 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp) } } +static void rtl_speed_down(struct rtl8169_private *tp) +{ + u32 adv; + int lpa; + + rtl_writephy(tp, 0x1f, 0x); + lpa = rtl_readphy(tp, MII_LPA); + + adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; + if (!(lpa & (ADVERTISE_10HALF | ADVERTISE_10FULL))) + adv |= ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; + + rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_100, DUPLEX_FULL, adv); +} + static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -3848,9 +3863,7 @@ static bool rtl_wol_pll_power_down(struct rtl8169_private *tp) if (!(__rtl8169_get_wol(tp) & WAKE_ANY)) return false; - rtl_writephy(tp, 0x1f, 0x); - rtl_writephy(tp, MII_BMCR, 0x); - + rtl_speed_down(tp); rtl_wol_suspend_quirk(tp); return true; -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH v2] r8169: fix auto speed down issue
It would cause no link after suspending or shutdowning when the nic changes the speed to 10M and connects to a link partner which forces the speed to 100M. Check the link partner ability to determine which speed to set. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 28 +--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 28fb50a..bdc03a9 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3818,6 +3818,30 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp) } } +static void rtl_speed_down(struct rtl8169_private *tp) +{ + u32 adv; + int lpa; + + rtl_writephy(tp, 0x1f, 0x); + lpa = rtl_readphy(tp, MII_LPA); + + if (lpa & (LPA_10HALF | LPA_10FULL)) + adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full; + else if (lpa & (LPA_100HALF | LPA_100FULL)) + adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full; + else + adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | + (tp->mii.supports_gmii ? + ADVERTISED_1000baseT_Half | + ADVERTISED_1000baseT_Full : 0); + + rtl8169_set_speed(tp->dev, AUTONEG_ENABLE, SPEED_1000, DUPLEX_FULL, + adv); +} + static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) { void __iomem *ioaddr = tp->mmio_addr; @@ -3848,9 +3872,7 @@ static bool rtl_wol_pll_power_down(struct rtl8169_private *tp) if (!(__rtl8169_get_wol(tp) & WAKE_ANY)) return false; - rtl_writephy(tp, 0x1f, 0x); - rtl_writephy(tp, MII_BMCR, 0x); - + rtl_speed_down(tp); rtl_wol_suspend_quirk(tp); return true; -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 1/7] r8169: Remove firmware code
Some codes are belong to binary codes and should be removed. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 26 -- 1 file changed, 26 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 28fb50a..d36aa76 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -3368,32 +3368,6 @@ static void rtl8411_hw_phy_config(struct rtl8169_private *tp) static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) { - 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, 0x, 0xc602, - - 0xbe00, 0x, 0xc602, 0xbe00, - 0x, 0xc602, 0xbe00, 0x, - 0xc602, 0xbe00, 0x, 0xc602, - 0xbe00, 0x, 0xc602, 0xbe00, - - 0x, 0x, 0x, 0x - }; - u32 i; - - /* Patch code for GPHY reset */ - 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); - rtl_apply_firmware(tp); if (r8168_phy_ocp_read(tp, 0xa460) & 0x0100) -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 2/7] r8169: Update PHY settings of RTL8111G
- Replace the current settings with rtl_writephy and rtl_readphy. For the hardware, the settings are same with previous ones. This make the setting method like the previous chips. - Add new PHY settings. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 72 +--- 1 file changed, 51 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index d36aa76..b8b59a9 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1024,14 +1024,6 @@ static u16 r8168_phy_ocp_read(struct rtl8169_private *tp, u32 reg) (RTL_R32(GPHY_OCP) & 0x) : ~0; } -static void rtl_w1w0_phy_ocp(struct rtl8169_private *tp, int reg, int p, int m) -{ - int val; - - val = r8168_phy_ocp_read(tp, reg); - r8168_phy_ocp_write(tp, reg, (val | p) & ~m); -} - static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) { void __iomem *ioaddr = tp->mmio_addr; @@ -3370,23 +3362,61 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) { rtl_apply_firmware(tp); - if (r8168_phy_ocp_read(tp, 0xa460) & 0x0100) - rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x, 0x8000); - else - rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x8000, 0x); + rtl_writephy(tp, 0x1f, 0x0a46); + if (rtl_readphy(tp, 0x10) & 0x0100) { + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x12, 0x, 0x8000); + } else { + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x12, 0x8000, 0x); + } - if (r8168_phy_ocp_read(tp, 0xa466) & 0x0100) - rtl_w1w0_phy_ocp(tp, 0xc41a, 0x0002, 0x); - else - rtl_w1w0_phy_ocp(tp, 0xbcc4, 0x, 0x0002); + rtl_writephy(tp, 0x1f, 0x0a46); + if (rtl_readphy(tp, 0x13) & 0x0100) { + rtl_writephy(tp, 0x1f, 0x0c41); + rtl_w1w0_phy(tp, 0x15, 0x0002, 0x); + } else { + rtl_writephy(tp, 0x1f, 0x0c41); + rtl_w1w0_phy(tp, 0x15, 0x, 0x0002); + } - rtl_w1w0_phy_ocp(tp, 0xa442, 0x000c, 0x); - rtl_w1w0_phy_ocp(tp, 0xa4b2, 0x0004, 0x); + /* Enable PHY auto speed down */ + rtl_writephy(tp, 0x1f, 0x0a44); + rtl_w1w0_phy(tp, 0x11, 0x000c, 0x); + + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x14, 0x0100, 0x); + rtl_writephy(tp, 0x1f, 0x0a44); + rtl_w1w0_phy(tp, 0x11, 0x00c0, 0x); + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_writephy(tp, 0x13, 0x8084); + rtl_w1w0_phy(tp, 0x14, 0x, 0x6000); + rtl_w1w0_phy(tp, 0x10, 0x1003, 0x); + + /* EEE auto-fallback function */ + rtl_writephy(tp, 0x1f, 0x0a4b); + rtl_w1w0_phy(tp, 0x11, 0x0004, 0x); + + /* Enable UC LPF tune function */ + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_writephy(tp, 0x13, 0x8012); + rtl_w1w0_phy(tp, 0x14, 0x8000, 0x); + + rtl_writephy(tp, 0x1f, 0x0c42); + rtl_w1w0_phy(tp, 0x11, 0x4000, 0x2000); - r8168_phy_ocp_write(tp, 0xa436, 0x8012); - rtl_w1w0_phy_ocp(tp, 0xa438, 0x8000, 0x); + /* Improve SWR Efficiency */ + rtl_writephy(tp, 0x1f, 0x0bcd); + rtl_writephy(tp, 0x14, 0x5065); + rtl_writephy(tp, 0x14, 0xd065); + rtl_writephy(tp, 0x1f, 0x0bc8); + rtl_writephy(tp, 0x11, 0x5655); + rtl_writephy(tp, 0x1f, 0x0bcd); + rtl_writephy(tp, 0x14, 0x1065); + rtl_writephy(tp, 0x14, 0x9065); + rtl_writephy(tp, 0x14, 0x1065); - rtl_w1w0_phy_ocp(tp, 0xc422, 0x4000, 0x2000); + rtl_writephy(tp, 0x1f, 0x); } static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 6/7] r8169: add a new chip for RTL8106E
- add a new chip for RTL8106E series. - move rtl_set_rx_tx_desc_registers to avoid the tx/rx are enabled before setting desc registers. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 25 +++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 8d41508..876e088 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -49,6 +49,7 @@ #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" #define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw" #define FIRMWARE_8168G_3 "rtl_nic/rtl8168g-3.fw" +#define FIRMWARE_8106E_2 "rtl_nic/rtl8106e-2.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -142,6 +143,7 @@ enum mac_version { RTL_GIGA_MAC_VER_40, RTL_GIGA_MAC_VER_41, RTL_GIGA_MAC_VER_42, + RTL_GIGA_MAC_VER_43, RTL_GIGA_MAC_NONE = 0xff, }; @@ -271,6 +273,9 @@ static const struct { [RTL_GIGA_MAC_VER_42] = _R("RTL8168g/8111g",RTL_TD_1, FIRMWARE_8168G_3, JUMBO_9K, false), + [RTL_GIGA_MAC_VER_43] = + _R("RTL8106e", RTL_TD_1, FIRMWARE_8106E_2, + JUMBO_1K, true), }; #undef _R @@ -824,6 +829,7 @@ MODULE_FIRMWARE(FIRMWARE_8411_1); MODULE_FIRMWARE(FIRMWARE_8106E_1); MODULE_FIRMWARE(FIRMWARE_8168G_2); MODULE_FIRMWARE(FIRMWARE_8168G_3); +MODULE_FIRMWARE(FIRMWARE_8106E_2); static void rtl_lock_work(struct rtl8169_private *tp) { @@ -2133,6 +2139,10 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, netif_notice(tp, probe, dev, "unknown MAC, using family default\n"); tp->mac_version = default_version; + } else if (tp->mac_version == RTL_GIGA_MAC_VER_42) { + tp->mac_version = tp->mii.supports_gmii ? + RTL_GIGA_MAC_VER_42 : + RTL_GIGA_MAC_VER_43; } } @@ -3709,6 +3719,7 @@ static void rtl_hw_phy_config(struct net_device *dev) rtl8168g_1_hw_phy_config(tp); break; case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_43: rtl8168g_2_hw_phy_config(tp); break; @@ -3920,6 +3931,7 @@ static void rtl_init_mdio_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_43: ops->write = r8168g_mdio_write; ops->read = r8168g_mdio_read; break; @@ -3948,6 +3960,7 @@ static void rtl_wol_suspend_quirk(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_43: RTL_W32(RxConfig, RTL_R32(RxConfig) | AcceptBroadcast | AcceptMulticast | AcceptMyPhys); break; @@ -4183,6 +4196,7 @@ static void rtl_init_pll_power_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_30: case RTL_GIGA_MAC_VER_37: case RTL_GIGA_MAC_VER_39: + case RTL_GIGA_MAC_VER_43: ops->down = r810x_pll_power_down; ops->up = r810x_pll_power_up; break; @@ -4256,6 +4270,7 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_43: RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF); break; default: @@ -4415,6 +4430,7 @@ static void rtl_init_jumbo_ops(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_40: case RTL_GIGA_MAC_VER_41: case RTL_GIGA_MAC_VER_42: + case RTL_GIGA_MAC_VER_43: default: ops->disable= NULL; ops->enable = NULL; @@ -4523,6 +4539,7 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp) tp->mac_version == RTL_GIGA_MAC_VER_40 || tp->mac_version == RTL_GIGA_MAC_VER_41 || tp->mac_version == RTL_GIGA_MAC_VER_42 || + tp->mac_version == RTL_GIGA_MAC_VER_43 || tp->mac_version == RTL_GIGA_MAC_VER_38) { RTL_W8(ChipCmd, RTL_R8(ChipCmd) | StopReq); rtl_udelay_loop_wait_high(tp, &rtl_txcfg_empty_cond, 100, 666); @@ -5560,6 +5577,8 @@ static void rtl_hw_start_8101(struct net_device *dev) RTL_W8(Cfg9346, Cfg9346_Unlock); + rtl_set_rx_tx_desc_registers(tp, ioaddr); + switch (tp->ma
[PATCH net-next 7/7] r8169: fix could not dump registers
For new version of Fedora and Ubuntu, we see all 0xff when dumping the hw regs through ethtool. Using a loop to read registers could fix it. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 876e088..c9cd64c 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1889,12 +1889,16 @@ static void rtl8169_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p) { struct rtl8169_private *tp = netdev_priv(dev); + void __iomem *ioaddr = tp->mmio_addr; + u8 *d = (u8 *)p; + int i; if (regs->len > R8169_REGS_SIZE) regs->len = R8169_REGS_SIZE; rtl_lock_work(tp); - memcpy_fromio(p, tp->mmio_addr, regs->len); + for (i = 0; i < regs->len; i++) + *d++ = RTL_R8(i); rtl_unlock_work(tp); } -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 3/7] r8169: Modify the method for setting firmware
Remove useless action PHY_READ_EFUSE, PHY_READ_MAC_BYTE, PHY_WRITE_MAC_BYTE, PHY_WRITE_ERI_WORD. And define the new action PHY_MDIO_CHG. PHY_MDIO_CHG is used to modify the mdio operation. By the way, the firmware could support setting mac ocp. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 45 +--- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index b8b59a9..e7e7d37 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1069,6 +1069,21 @@ static int r8168g_mdio_read(struct rtl8169_private *tp, int reg) return r8168_phy_ocp_read(tp, tp->ocp_base + reg * 2); } +static void mac_mcu_write(struct rtl8169_private *tp, int reg, int value) +{ + if (reg == 0x1f) { + tp->ocp_base = value << 4; + return; + } + + r8168_mac_ocp_write(tp, tp->ocp_base + reg, value); +} + +static int mac_mcu_read(struct rtl8169_private *tp, int reg) +{ + return r8168_mac_ocp_read(tp, tp->ocp_base + reg); +} + DECLARE_RTL_COND(rtl_phyar_cond) { void __iomem *ioaddr = tp->mmio_addr; @@ -2134,9 +2149,7 @@ static void rtl_writephy_batch(struct rtl8169_private *tp, #define PHY_DATA_OR0x1000 #define PHY_DATA_AND 0x2000 #define PHY_BJMPN 0x3000 -#define PHY_READ_EFUSE 0x4000 -#define PHY_READ_MAC_BYTE 0x5000 -#define PHY_WRITE_MAC_BYTE 0x6000 +#define PHY_MDIO_CHG 0x4000 #define PHY_CLEAR_READCOUNT0x7000 #define PHY_WRITE 0x8000 #define PHY_READCOUNT_EQ_SKIP 0x9000 @@ -2145,7 +2158,6 @@ static void rtl_writephy_batch(struct rtl8169_private *tp, #define PHY_WRITE_PREVIOUS 0xc000 #define PHY_SKIPN 0xd000 #define PHY_DELAY_MS 0xe000 -#define PHY_WRITE_ERI_WORD 0xf000 struct fw_info { u32 magic; @@ -,7 +2234,7 @@ static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev, case PHY_READ: case PHY_DATA_OR: case PHY_DATA_AND: - case PHY_READ_EFUSE: + case PHY_MDIO_CHG: case PHY_CLEAR_READCOUNT: case PHY_WRITE: case PHY_WRITE_PREVIOUS: @@ -2253,9 +2265,6 @@ static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev, } break; - case PHY_READ_MAC_BYTE: - case PHY_WRITE_MAC_BYTE: - case PHY_WRITE_ERI_WORD: default: netif_err(tp, ifup, tp->dev, "Invalid action 0x%08x\n", action); @@ -2286,10 +2295,13 @@ out: static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) { struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; + struct mdio_ops org, *ops = &tp->mdio_ops; u32 predata, count; size_t index; predata = count = 0; + org.write = ops->write; + org.read = ops->read; for (index = 0; index < pa->size; ) { u32 action = le32_to_cpu(pa->code[index]); @@ -2316,8 +2328,15 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) case PHY_BJMPN: index -= regno; break; - case PHY_READ_EFUSE: - predata = rtl8168d_efuse_read(tp, regno); + case PHY_MDIO_CHG: + if (data == 0) { + ops->write = org.write; + ops->read = org.read; + } else if (data == 1) { + ops->write = mac_mcu_write; + ops->read = mac_mcu_read; + } + index++; break; case PHY_CLEAR_READCOUNT: @@ -2353,13 +2372,13 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) index++; break; - case PHY_READ_MAC_BYTE: - case PHY_WRITE_MAC_BYTE: - case PHY_WRITE_ERI_WORD: default: BUG(); } } + + ops->write = org.write; + ops->read = org.read; } static void rtl_release_firmware(struct rtl8169_private *tp) -- 1.8.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 4/7] r8169: Update the RTL8111G parameters
- replace rtl8168g-1.fw with rtl8168g-2.fw which support new method. - fix PHY power down is useless. - disable rx early which causes the rx abnormal. - enable auto fifo. - set 10M IFG to default value. - fix the conflict between jumbo frame and flow control. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 29 + 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index e7e7d37..0211836 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -47,7 +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" +#define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -262,7 +262,7 @@ static const struct { _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, + _R("RTL8168g/8111g",RTL_TD_1, FIRMWARE_8168G_2, JUMBO_9K, false), [RTL_GIGA_MAC_VER_41] = _R("RTL8168g/8111g",RTL_TD_1, NULL, JUMBO_9K, false), @@ -329,6 +329,7 @@ enum rtl_registers { #defineRXCFG_FIFO_SHIFT13 /* No threshold before first PCI xfer */ #defineRX_FIFO_THRESH (7 << RXCFG_FIFO_SHIFT) +#defineRX_EARLY_OFF(1 << 11) #defineRXCFG_DMA_SHIFT 8 /* Unlimited maximum PCI burst. */ #defineRX_DMA_BURST(7 << RXCFG_DMA_SHIFT) @@ -814,7 +815,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); +MODULE_FIRMWARE(FIRMWARE_8168G_2); static void rtl_lock_work(struct rtl8169_private *tp) { @@ -3967,6 +3968,8 @@ static void r8168_phy_power_down(struct rtl8169_private *tp) switch (tp->mac_version) { case RTL_GIGA_MAC_VER_32: case RTL_GIGA_MAC_VER_33: + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE | BMCR_PDOWN); break; @@ -4028,6 +4031,11 @@ static void r8168_pll_power_down(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_33: RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + rtl_w1w0_eri(tp, 0x1a8, ERIAR_MASK_, 0x, +0xfc00, ERIAR_EXGMAC); + break; } } @@ -4045,6 +4053,11 @@ static void r8168_pll_power_up(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_33: RTL_W8(PMCH, RTL_R8(PMCH) | 0x80); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + rtl_w1w0_eri(tp, 0x1a8, ERIAR_MASK_, 0xfc00, +0x, ERIAR_EXGMAC); + break; } r8168_phy_power_up(tp); @@ -4150,6 +4163,10 @@ static void rtl_init_rxcfg(struct rtl8169_private *tp) case RTL_GIGA_MAC_VER_34: RTL_W32(RxConfig, RX128_INT_EN | RX_MULTI_EN | RX_DMA_BURST); break; + case RTL_GIGA_MAC_VER_40: + case RTL_GIGA_MAC_VER_41: + RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST | RX_EARLY_OFF); + break; default: RTL_W32(RxConfig, RX128_INT_EN | RX_DMA_BURST); break; @@ -5128,6 +5145,8 @@ 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_W32(TxConfig, RTL_R32(TxConfig) | TXCFG_AUTO_FIFO); + 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); @@ -5139,6 +5158,7 @@ static void rtl_hw_start_8168g_1(struct rtl8169_private *tp) 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, 0x2f8, ERIAR_MASK_0011, 0x1d8f, ERIAR_EXGMAC); RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb); RTL_W32(MISC, RTL_R32(MISC) & ~
[PATCH net-next 5/7] r8169: add a new chip for RTL8111G
Add a new chip for RTL8111G series. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 115 +++ 1 file changed, 115 insertions(+) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 0211836..8d41508 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -48,6 +48,7 @@ #define FIRMWARE_8411_1"rtl_nic/rtl8411-1.fw" #define FIRMWARE_8106E_1 "rtl_nic/rtl8106e-1.fw" #define FIRMWARE_8168G_2 "rtl_nic/rtl8168g-2.fw" +#define FIRMWARE_8168G_3 "rtl_nic/rtl8168g-3.fw" #ifdef RTL8169_DEBUG #define assert(expr) \ @@ -140,6 +141,7 @@ enum mac_version { RTL_GIGA_MAC_VER_39, RTL_GIGA_MAC_VER_40, RTL_GIGA_MAC_VER_41, + RTL_GIGA_MAC_VER_42, RTL_GIGA_MAC_NONE = 0xff, }; @@ -266,6 +268,9 @@ static const struct { JUMBO_9K, false), [RTL_GIGA_MAC_VER_41] = _R("RTL8168g/8111g",RTL_TD_1, NULL, JUMBO_9K, false), + [RTL_GIGA_MAC_VER_42] = + _R("RTL8168g/8111g",RTL_TD_1, FIRMWARE_8168G_3, + JUMBO_9K, false), }; #undef _R @@ -514,6 +519,7 @@ enum rtl_register_content { PMEnable= (1 << 0), /* Power Management Enable */ /* Config2 register p. 25 */ + ClkReqEn= (1 << 7), /* Clock Request Enable */ MSIEnable = (1 << 5), /* 8169 only. Reserved in the 8168. */ PCI_Clock_66MHz = 0x01, PCI_Clock_33MHz = 0x00, @@ -534,6 +540,7 @@ enum rtl_register_content { Spi_en = (1 << 3), LanWake = (1 << 1), /* LanWake enable/disable */ PMEStatus = (1 << 0), /* PME status can be reset by PCI RST# */ + ASPM_en = (1 << 0), /* ASPM enable */ /* TBICSR p.28 */ TBIReset= 0x8000, @@ -816,6 +823,7 @@ MODULE_FIRMWARE(FIRMWARE_8402_1); MODULE_FIRMWARE(FIRMWARE_8411_1); MODULE_FIRMWARE(FIRMWARE_8106E_1); MODULE_FIRMWARE(FIRMWARE_8168G_2); +MODULE_FIRMWARE(FIRMWARE_8168G_3); static void rtl_lock_work(struct rtl8169_private *tp) { @@ -2036,6 +2044,7 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp, int mac_version; } mac_info[] = { /* 8168G family. */ + { 0x7cf0, 0x5090, RTL_GIGA_MAC_VER_42 }, { 0x7cf0, 0x4c10, RTL_GIGA_MAC_VER_41 }, { 0x7cf0, 0x4c00, RTL_GIGA_MAC_VER_40 }, @@ -3439,6 +3448,81 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) rtl_writephy(tp, 0x1f, 0x); } +static void rtl8168g_2_hw_phy_config(struct rtl8169_private *tp) +{ + rtl_apply_firmware(tp); + + rtl_writephy(tp, 0x1f, 0x0bcc); + rtl_w1w0_phy(tp, 0x14, 0x, 0x0100); + rtl_writephy(tp, 0x1f, 0x0a44); + rtl_w1w0_phy(tp, 0x11, 0x00c0, 0x); + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_writephy(tp, 0x13, 0x8084); + rtl_w1w0_phy(tp, 0x14, 0x, 0x6000); + rtl_w1w0_phy(tp, 0x10, 0x1003, 0x); + + /* Enable UC LPF tune function */ + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_writephy(tp, 0x13, 0x8012); + rtl_w1w0_phy(tp, 0x14, 0x8000, 0x); + + rtl_writephy(tp, 0x1f, 0x0bce); + rtl_writephy(tp, 0x12, 0x8860); + + /* Channel Estimation: master */ + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_writephy(tp, 0x13, 0x80f3); + rtl_w1w0_phy(tp, 0x14, 0x8b00, 0x7400); + rtl_writephy(tp, 0x13, 0x80f0); + rtl_w1w0_phy(tp, 0x14, 0x3a00, 0xc500); + rtl_writephy(tp, 0x13, 0x80ef); + rtl_w1w0_phy(tp, 0x14, 0x0500, 0xfa00); + rtl_writephy(tp, 0x13, 0x80f6); + rtl_w1w0_phy(tp, 0x14, 0x6e00, 0x9100); + rtl_writephy(tp, 0x13, 0x80ec); + rtl_w1w0_phy(tp, 0x14, 0x6800, 0x9700); + rtl_writephy(tp, 0x13, 0x80ed); + rtl_w1w0_phy(tp, 0x14, 0x7c00, 0x8300); + rtl_writephy(tp, 0x13, 0x80f2); + rtl_w1w0_phy(tp, 0x14, 0xf400, 0x0b00); + rtl_writephy(tp, 0x13, 0x80f4); + rtl_w1w0_phy(tp, 0x14, 0x8500, 0x7a00); + + /* Channel Estimation: slave */ + rtl_writephy(tp, 0x1f, 0x0a43); + rtl_writephy(tp, 0x13, 0x8110); + rtl_w1w0_phy(tp, 0x14, 0xa800, 0x5700); + rtl_writephy(tp, 0x13, 0x810f); + rtl_w1w0_phy(tp, 0x14, 0x1d00, 0xe200); + rtl_writephy(tp, 0x13, 0x8111); + rtl_w1w0_phy(tp, 0x14, 0xf500, 0x0a00); + rtl_writephy(tp, 0x13, 0x8113); + rtl_w1w0_phy(tp, 0x14, 0x6100, 0x9e00); + rtl_writephy(tp, 0x13, 0x8115); + rtl_w1w0_phy(tp, 0x14, 0x9200, 0x6d00); + rtl_writephy(tp, 0x13, 0x810e); + rtl_w1w0_phy(tp
Re: [PATCH net-next 6/6] r8169: support RTL8168G
fix incorrct argument in rtl_hw_init_8168g. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c |4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 7ff3423..c29c5fb 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -6753,14 +6753,14 @@ 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, 0xe8de); + data = r8168_mac_ocp_read(tp, 0xe8de); data &= ~(1 << 14); r8168_mac_ocp_write(tp, 0xe8de, data); if (!rtl_udelay_loop_wait_high(tp, &rtl_link_list_ready_cond, 100, 42)) return; - data = r8168_mac_ocp_read(ioaddr, 0xe8de); + data = r8168_mac_ocp_read(tp, 0xe8de); data |= (1 << 15); r8168_mac_ocp_write(tp, 0xe8de, data); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH net-next 6/6] r8169: support RTL8168G
1. Remove rtl_ocpdr_cond. No waiting is needed for mac_ocp_{write / read}. 2. Set ocp_base to OCP_STD_PHY_BASE after rtl8168g_1_hw_phy_config. --- drivers/net/ethernet/realtek/r8169.c | 14 +++--- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index c29c5fb..7269175 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1043,13 +1043,6 @@ 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; @@ -1058,8 +1051,6 @@ static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) return; RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data); - - rtl_udelay_loop_wait_low(tp, &rtl_ocpdr_cond, 25, 10); } static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) @@ -1071,8 +1062,7 @@ static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) RTL_W32(OCPDR, reg << 15); - return rtl_udelay_loop_wait_high(tp, &rtl_ocpdr_cond, 25, 10) ? - RTL_R32(OCPDR) : ~0; + return RTL_R32(OCPDR); } #define OCP_STD_PHY_BASE 0xa400 @@ -3417,6 +3407,8 @@ static void rtl8168g_1_hw_phy_config(struct rtl8169_private *tp) rtl_w1w0_phy_ocp(tp, 0xa438, 0x8000, 0x); rtl_w1w0_phy_ocp(tp, 0xc422, 0x4000, 0x2000); + + rtl_writephy(tp, 0x1f, 0x); } static void rtl8102e_hw_phy_config(struct rtl8169_private *tp) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH firmware] rtl_nic: update firmware for RTL8168G
File: rtl_nic/rtl8168g-1.fw Version: 0.0.2 Change the ocp_base of linux driver to OCP_STD_PHY_BASE after setting firmware. The firmware would modify the ocp_base, and that results the driver uses the wrong ocp_base to access standard phy after setting firmware. Signed-off-by: Hayes Wang --- WHENCE|2 +- rtl_nic/rtl8168g-1.fw | Bin 4272 -> 4272 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/WHENCE b/WHENCE index 1fb7951..f46c842 100644 --- a/WHENCE +++ b/WHENCE @@ -1817,7 +1817,7 @@ File: rtl_nic/rtl8106e-1.fw Version: 0.0.1 File: rtl_nic/rtl8168g-1.fw -Version: 0.0.1 +Version: 0.0.2 Licence: * Copyright © 2011, Realtek Semiconductor Corporation diff --git a/rtl_nic/rtl8168g-1.fw b/rtl_nic/rtl8168g-1.fw index dace1ea98c66de08107ee0857d8a8680d57d7898..bc03a5d28fd07d99a6cc89aa115d8ef8942629a6 100644 GIT binary patch delta 78 zcmdm>xIs~u0SJmpax4tZEYfui;|=r-^o$e?%=HZo^$m?cl0c9E#6m0#40#iERoN}A WOw6oI3^qo33-CB_$u|JyzyJVS1PxdK delta 78 zcmdm>xIs~u0SJmpax4tZEYfui;|=r-^b8dY%=C>c^$m?cl0c9E#DXjg3}F*>RoTs~ Qj7)%NW2CnL4@eRQ08i5lSO5S3 -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next] r8169: Remove rtl_ocpdr_cond
No waiting is needed for mac_ocp_{write / read}. And the bit 31 of OCPDR would not change, so rtl_udelay_loop_wait_high always return false. That is, the r8168_mac_ocp_read always retuen ~0. Signed-off-by: Hayes Wang --- drivers/net/ethernet/realtek/r8169.c | 12 +--- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index c29c5fb..1f27318 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -1043,13 +1043,6 @@ 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; @@ -1058,8 +1051,6 @@ static void r8168_mac_ocp_write(struct rtl8169_private *tp, u32 reg, u32 data) return; RTL_W32(OCPDR, OCPAR_FLAG | (reg << 15) | data); - - rtl_udelay_loop_wait_low(tp, &rtl_ocpdr_cond, 25, 10); } static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) @@ -1071,8 +1062,7 @@ static u16 r8168_mac_ocp_read(struct rtl8169_private *tp, u32 reg) RTL_W32(OCPDR, reg << 15); - return rtl_udelay_loop_wait_high(tp, &rtl_ocpdr_cond, 25, 10) ? - RTL_R32(OCPDR) : ~0; + return RTL_R32(OCPDR); } #define OCP_STD_PHY_BASE 0xa400 -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH firmware 1/4] rtl_nic: update firmware for RTL8168F
File: rtl_nic/rtl8168f-1.fw Version: 0.0.5 Signed-off-by: Hayes Wang --- WHENCE|2 +- rtl_nic/rtl8168f-1.fw | Bin 3136 -> 3424 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/WHENCE b/WHENCE index 13cbcab..676ebb1 100644 --- a/WHENCE +++ b/WHENCE @@ -1802,7 +1802,7 @@ File: rtl_nic/rtl8168e-3.fw Version: 0.0.4 File: rtl_nic/rtl8168f-1.fw -Version: 0.0.4 +Version: 0.0.5 File: rtl_nic/rtl8168f-2.fw Version: 0.0.4 diff --git a/rtl_nic/rtl8168f-1.fw b/rtl_nic/rtl8168f-1.fw index 41822b54ef44c37400db3ddac26d0e6655e1faa7..bf7883163e3dbed22420dec369ed51a3ee8247d4 100644 GIT binary patch delta 487 zcmZuuJxc>Y6uex*5QyRjDq^7#zab`j7d#Ie(Z)hSv9hxh0;$A8M9Cne3RVFdK??;z zG${E2T3MUY$_vCgor;J!CkhrWEbqP9dGls>?|Os26-#S#EAKm=zcJ~oo3u$!C5@MH z{EXv(k(@@b&?4=ol-zW18y^mXx;P}OQi-9~_L#+i{1LH-Y(0jH99s#z74T5Y9ynlcifV2#<0SrL?Whttp://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH firmware 2/4] rtl_nic: update firmware for RTL8411
File: rtl_nic/rtl8411-1.fw Version: 0.0.3 Signed-off-by: Hayes Wang --- WHENCE |2 +- rtl_nic/rtl8411-1.fw | Bin 1840 -> 2112 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/WHENCE b/WHENCE index 676ebb1..c7a3e98 100644 --- a/WHENCE +++ b/WHENCE @@ -1808,7 +1808,7 @@ File: rtl_nic/rtl8168f-2.fw Version: 0.0.4 File: rtl_nic/rtl8411-1.fw -Version: 0.0.2 +Version: 0.0.3 File: rtl_nic/rtl8402-1.fw Version: 0.0.1 diff --git a/rtl_nic/rtl8411-1.fw b/rtl_nic/rtl8411-1.fw index 1bd9e7cdd5605e34e0322c0df185c53e46d6a34b..72772dbc8343c8cef8eac61f704377fc3fb6c7b3 100644 GIT binary patch delta 430 zcmZ{fze@sP7{~8U`4Wj`Q4Iy9WLe;k_wMStjzDN>X^@6!a}JuKp{*}UOVSiH7DS^R zg*4kA(2!HBf)TW|m6Sx!NkK~wyga|3@8`W9xQi7uvE98Lcfm9>W>IBT){ZMDXSzAl z3VMMBL!Y{)O=uhIj-}k9rA$jX%FSAF)Akl^&s^4yFO$LSP2pZ2E7w6|1x$FL-T-@f zzGfMly5W~ ztmeT;Tr{c@N5R1vFeR}+B-+E^Z5oXFU`aImXQ}mpk5UUsEp6a{-50PE7Jv_FZVP|_ zHAS#B0*;CgAR4k%p9I%3|HGza?ja{PBC_L(;Fi37FnKPZ!95GKf8fUjz8wRtijefg X=D>LwO211kzk2%3-~Q$&7btxL90!Z? delta 157 zcmX>guz@dt0SJmpax6>?4RsCU4fG83j1&xv^^MH+4UIr@AOKRdg^_{5mLbT;%*enZ z-pIhv$iUdhP{Gj5%EZjd)PSLPi3&(%_y3InXBfqr_OmrGtz&CYv|?*uyvWu7=5O3= o#1zKJRHL)Gihttp://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH firmware 4/4] rtl_nic: add new firmware for RTL8168G
File: rtl_nic/rtl8168g-1.fw Version: 0.0.1 Signed-off-by: Hayes Wang --- WHENCE|3 +++ rtl_nic/rtl8168g-1.fw | Bin 0 -> 4272 bytes 2 files changed, 3 insertions(+) create mode 100644 rtl_nic/rtl8168g-1.fw diff --git a/WHENCE b/WHENCE index 8f2b610..1fb7951 100644 --- a/WHENCE +++ b/WHENCE @@ -1816,6 +1816,9 @@ Version: 0.0.1 File: rtl_nic/rtl8106e-1.fw Version: 0.0.1 +File: rtl_nic/rtl8168g-1.fw +Version: 0.0.1 + Licence: * Copyright ?? 2011, Realtek Semiconductor Corporation * diff --git a/rtl_nic/rtl8168g-1.fw b/rtl_nic/rtl8168g-1.fw new file mode 100644 index ..dace1ea98c66de08107ee0857d8a8680d57d7898 GIT binary patch literal 4272 zcma)=4Q!QH8OP6kds{wM$}K%Y`HbYuZ+~EWhvW6)o*;>z3c!QeBg%P1LolUbS|4yt?kDnlJF*JodEuCT}Pc zV`BWv{_m0O*tAECNvo>fn0UPjI`1}St1DCSXug(l^wlSMq#t1)yg*+Kf-uAxewES$oEGwzeX_} zu`-vr@6nI>{&(mHzTZwi;`?8p;NotrwNkUp%B}dRPGddZ=H_;S>rs4kjg77N{%Xi( zE#pJXFU0R(l~&}JRvPxe-xK8SaQ+t>t*pjw#0e{lvCBgakniR@t$eq}%3b$csmCuM z?#;y5hOLeZ{P<+Gl~!+4Og9|XNaNvbgj4Y2L5Nj z5%qrYVSZ8kny^>9IG92_FEbvS24g<8fPdtmi`iOl<*1L_hhA+0ZxeW%wokB$VxzI2 zYP}xYdiLJ@*2?^&aPvBOUck=dC?!tpDcWW@uX4HmSDcY>`N01ft8ymi1FlX{&!&gw z{miTM!C`(!J7(p`YslZzz-2~~-|s_2_u*l5f1sf=?2XPxS-(o>s4V=Fi?fKm{mp0bBS#Q8yRGEZ9Q*uSAu$xokB8}th@U23 zSVudD&Bs|+-aS@kv6gv18^U4gIkVX6-8H`pJ#+CMm!q8XHV=$FU@RDhF?)u*U4$56 zz3%=rHOije3r<~sob`uws&j$&(Y(q@jQMhM=IY}cIIpy=*b8$v(dw~HfG_6#PlM^u zXvfVDJvYL9!sk_<3*l*6gIi0y&FyIwYr2oMtYW zbCl0~6?k&z4{czri!8dGaeaXt%9#U?FIHws-R zx-O6Xaisd^;>fM-9j({bPFUNM{QFga{0kgLksppA7V`B1xImt|$U1V~zRry$vXM9H zz&KF{S!RIZEFRkJXe#Cxd;Gqw@n3H8CwE3bBd z5#HXaV6M>09n7h3CwNspdfdqm@z?QQ-XWEv-*z(gZzs2WU}XdPsSzh{zro4-iK+Va z#c(e-1Vpqn{X|&o=hq$~E>S%AC(t%AGZstHMep zakAJi5SRTP%=2fLrzo6%*UC=jHBLX6&k^UkoWxR`(JQ>8)Ic%3RZ}}B^1q(+^@x=x8#!P5uwnmR%dv@KW2k`<;446G zK0tlnPF!kO<5p_i>8zpI#XUpZwVIE8nA?vHat^Ybx(;4+e99U2YaQ!@^T~6qyof9z zUOn-FWTa(nM*5pj$Nt$(W zF9a2Q>*BBT7g?ju&tN{g?!3Jg>HxRCKw_E2?YxjL|^t}0h&o$e*#YYk_8!F(RO zMsg+l;H|;&a}|!2_rW`W^>;3`k`L|&@$G(uF?VWS#L7g*8P=(LJKU#VIgJnFlzd+e z*Q%T{pIyJ!7yJyKr3&iY<3GnbZv~^Cv0m&`d7LRf*GJ7PWbQQBG)@)gC3y~v#O@_m zidqY8yRq%%o=Z_Hp)QS1xsG4N?<^SLr<=8A`9S8@OIULy!absAcZ!wwI~<>SPD(f@ z9cj3MJLO8>k8bXuPHHJ1uCn7>IR9Wskh4;;k~5PS;xEnJ)685&h^N`%$<{t`b2$z^ z<~{-AV#UJQKMNMU8+Cv6Ea_O^6CLY1vvGaSz{l13?3?$#yGxVc?+4G>N{2DSxeNDJ z@5SSsTjk+n&aV2M+y!^6b>d%Xf1|xaJB7^%xcsS$IiG$Mn+wmO_wlYBb8nMjf12UO zJb+|h%`)O*Yu@Axss781RnME!F$&3@pOxfOyROr`&B&v1=En1FsJ`Gd?N(+Vhttp://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH firmware 3/4] rtl_nic: add new firmware for RTL8106E
File: rtl_nic/rtl8106e-1.fw Version: 0.0.1 Signed-off-by: Hayes Wang --- WHENCE|3 +++ rtl_nic/rtl8106e-1.fw | Bin 0 -> 1856 bytes 2 files changed, 3 insertions(+) create mode 100644 rtl_nic/rtl8106e-1.fw diff --git a/WHENCE b/WHENCE index c7a3e98..8f2b610 100644 --- a/WHENCE +++ b/WHENCE @@ -1813,6 +1813,9 @@ Version: 0.0.3 File: rtl_nic/rtl8402-1.fw Version: 0.0.1 +File: rtl_nic/rtl8106e-1.fw +Version: 0.0.1 + Licence: * Copyright ?? 2011, Realtek Semiconductor Corporation * diff --git a/rtl_nic/rtl8106e-1.fw b/rtl_nic/rtl8106e-1.fw new file mode 100644 index ..85694cb6bf5f0a1807356392497703a779b5148e GIT binary patch literal 1856 zcmZ{lYlxIp7{||CawkZ3{NN2d?SMix&;G)KF7QP>}FL6lNbnrS12B-}AD=L<0}cdCz&C|MPz? z=ZtgCjcgfys1kJ#Jy5Ad^P~BdQq;Ymx@bYA%9(z30TdPKuYSdkM zur@fdaqG}XsnXLME$m&`*zx-LHfOQ zZA$GuhC z?8G<5gzK@Ux5F2SOKjPfuy>=#bJQ?kjI;O7>A;Wr%g)$S>Sn;Z|IHRwi@5PD@U3|`@FQ~qzcKU*^d|TYpc`C^l#?vV|Z6cUdI`DlEw;pzX}b{CUNrYiHCZ1$C5aW6mxLW zFPK$@6>ZjS&9r&5}>9=zKzZr{X0xab>PTV+7OI+1+UR&Ms zvU>?1#Ty7dE%UCLrM-4fOy1@A{*puM-R-1j6M_F~-G|V#4(`?Z@U5QZ_7Eq`(TCLQ zy7Tr5`d762cMW}QA2x0H@eIP@GH3Z$!+m)QyaQooS!eJWZJD=im%RNBp89o_y7b}S zLk(sv@pfWyQY-ECh5U6_G>fVJ;dT1^leeY#=XZO1q`};fkKPO6)$x5Byz*lSmcGm6 zrtcK9{T;ea+!R06pAcs;Z`S?bFAMKb1FS53vT*H3_7Eqvm(Ia6?Pmw;Kfs+p-VAoy zlif_T-k`rpQNR9&Yj$1&q>@|DB(7KK0+C`P6&z8TRpP*1i4t9hl^%|1p=HW0C&LwC49OflNUk literal 0 HcmV?d1 -- 1.7.10.2 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net 3/5] r8152: move PHY settings to hw_phy_cfg
Move the PHY relative settings together to hw_phy_cfg(). Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 14 -- 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index dbf11ba..9ce5bd5 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -2632,6 +2632,10 @@ static void rtl8152_disable(struct r8152 *tp) static void r8152b_hw_phy_cfg(struct r8152 *tp) { + r8152b_enable_eee(tp); + r8152_aldps_en(tp, true); + r8152b_enable_fc(tp); + set_bit(PHY_RESET, &tp->flags); } @@ -2839,6 +2843,10 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) sram_write(tp, SRAM_10M_AMP1, 0x00af); sram_write(tp, SRAM_10M_AMP2, 0x0208); + r8153_enable_eee(tp); + r8153_aldps_en(tp, true); + r8152b_enable_fc(tp); + set_bit(PHY_RESET, &tp->flags); } @@ -3369,9 +3377,6 @@ static void r8152b_init(struct r8152 *tp) SPDWN_RXDV_MSK | SPDWN_LINKCHG_MSK; ocp_write_word(tp, MCU_TYPE_PLA, PLA_GPHY_INTR_IMR, ocp_data); - r8152b_enable_eee(tp); - r8152_aldps_en(tp, true); - r8152b_enable_fc(tp); rtl_tally_reset(tp); /* enable rx aggregation */ @@ -3490,9 +3495,6 @@ static void r8153_init(struct r8152 *tp) ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0); ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0); - r8153_enable_eee(tp); - r8153_aldps_en(tp, true); - r8152b_enable_fc(tp); rtl_tally_reset(tp); r8153_u2p3en(tp, true); } -- 2.7.4
[PATCH net 5/5] r8152: disable ALDPS and EEE before setting PHY
Disable ALDPS and EEE to avoid the possible failure when setting the PHY. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 10 -- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index e7a05dd..3c3cdb4 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -32,7 +32,7 @@ #define NETNEXT_VERSION"08" /* Information for net */ -#define NET_VERSION"5" +#define NET_VERSION"6" #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION #define DRIVER_AUTHOR "Realtek linux nic maintainers " @@ -2808,6 +2808,13 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) u32 ocp_data; u16 data; + /* disable ALDPS before updating the PHY parameters */ + r8153_aldps_en(tp, false); + + /* disable EEE before updating the PHY parameters */ + r8153_eee_en(tp, false); + ocp_reg_write(tp, OCP_EEE_ADV, 0); + if (tp->version == RTL_VER_03) { data = ocp_reg_read(tp, OCP_EEE_CFG); data &= ~CTAP_SHORT_EN; @@ -3390,7 +3397,6 @@ static void r8153_init(struct r8152 *tp) if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; - r8153_aldps_en(tp, false); r8153_u1u2en(tp, false); for (i = 0; i < 500; i++) { -- 2.7.4
[PATCH net 2/5] r8152: move enabling PHY
Move enabling PHY to init(), otherwise some other settings may fail. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 43 +-- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index ae7db46..dbf11ba 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -2632,14 +2632,6 @@ static void rtl8152_disable(struct r8152 *tp) static void r8152b_hw_phy_cfg(struct r8152 *tp) { - u16 data; - - data = r8152_mdio_read(tp, MII_BMCR); - if (data & BMCR_PDOWN) { - data &= ~BMCR_PDOWN; - r8152_mdio_write(tp, MII_BMCR, data); - } - set_bit(PHY_RESET, &tp->flags); } @@ -2818,16 +2810,6 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) u32 ocp_data; u16 data; - if (tp->version == RTL_VER_03 || tp->version == RTL_VER_04 || - tp->version == RTL_VER_05) - ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L); - - data = r8152_mdio_read(tp, MII_BMCR); - if (data & BMCR_PDOWN) { - data &= ~BMCR_PDOWN; - r8152_mdio_write(tp, MII_BMCR, data); - } - if (tp->version == RTL_VER_03) { data = ocp_reg_read(tp, OCP_EEE_CFG); data &= ~CTAP_SHORT_EN; @@ -3355,10 +3337,17 @@ static void rtl_tally_reset(struct r8152 *tp) static void r8152b_init(struct r8152 *tp) { u32 ocp_data; + u16 data; if (test_bit(RTL8152_UNPLUG, &tp->flags)) return; + data = r8152_mdio_read(tp, MII_BMCR); + if (data & BMCR_PDOWN) { + data &= ~BMCR_PDOWN; + r8152_mdio_write(tp, MII_BMCR, data); + } + r8152_aldps_en(tp, false); if (tp->version == RTL_VER_01) { @@ -3394,6 +3383,7 @@ static void r8152b_init(struct r8152 *tp) static void r8153_init(struct r8152 *tp) { u32 ocp_data; + u16 data; int i; if (test_bit(RTL8152_UNPLUG, &tp->flags)) @@ -3416,6 +3406,23 @@ static void r8153_init(struct r8152 *tp) msleep(20); } + if (tp->version == RTL_VER_03 || tp->version == RTL_VER_04 || + tp->version == RTL_VER_05) + ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L); + + data = r8152_mdio_read(tp, MII_BMCR); + if (data & BMCR_PDOWN) { + data &= ~BMCR_PDOWN; + r8152_mdio_write(tp, MII_BMCR, data); + } + + for (i = 0; i < 500; i++) { + ocp_data = ocp_reg_read(tp, OCP_PHY_STATUS) & PHY_STAT_MASK; + if (ocp_data == PHY_STAT_LAN_ON) + break; + msleep(20); + } + usb_disable_lpm(tp->udev); r8153_u2p3en(tp, false); -- 2.7.4
[PATCH net 4/5] r8152: remove r8153_enable_eee
Remove r8153_enable_eee(). Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 10 +++--- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 9ce5bd5..e7a05dd 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -2803,12 +2803,6 @@ static void r8153_eee_en(struct r8152 *tp, bool enable) ocp_reg_write(tp, OCP_EEE_CFG, config); } -static void r8153_enable_eee(struct r8152 *tp) -{ - r8153_eee_en(tp, true); - ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); -} - static void r8153_hw_phy_cfg(struct r8152 *tp) { u32 ocp_data; @@ -2843,7 +2837,9 @@ static void r8153_hw_phy_cfg(struct r8152 *tp) sram_write(tp, SRAM_10M_AMP1, 0x00af); sram_write(tp, SRAM_10M_AMP2, 0x0208); - r8153_enable_eee(tp); + r8153_eee_en(tp, true); + ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); + r8153_aldps_en(tp, true); r8152b_enable_fc(tp); -- 2.7.4
[PATCH net 1/5] r8152: move some functions
Move the following functions forward. r8152_mmd_indirect() r8152_mmd_read() r8152_mmd_write() r8152_eee_en() r8152b_enable_eee() r8153_eee_en() r8153_enable_eee() r8152b_enable_fc() r8153_aldps_en() Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 224 1 file changed, 112 insertions(+), 112 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index f41a8ad..ae7db46 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -2552,6 +2552,77 @@ static void r8152_aldps_en(struct r8152 *tp, bool enable) } } +static inline void r8152_mmd_indirect(struct r8152 *tp, u16 dev, u16 reg) +{ + ocp_reg_write(tp, OCP_EEE_AR, FUN_ADDR | dev); + ocp_reg_write(tp, OCP_EEE_DATA, reg); + ocp_reg_write(tp, OCP_EEE_AR, FUN_DATA | dev); +} + +static u16 r8152_mmd_read(struct r8152 *tp, u16 dev, u16 reg) +{ + u16 data; + + r8152_mmd_indirect(tp, dev, reg); + data = ocp_reg_read(tp, OCP_EEE_DATA); + ocp_reg_write(tp, OCP_EEE_AR, 0x); + + return data; +} + +static void r8152_mmd_write(struct r8152 *tp, u16 dev, u16 reg, u16 data) +{ + r8152_mmd_indirect(tp, dev, reg); + ocp_reg_write(tp, OCP_EEE_DATA, data); + ocp_reg_write(tp, OCP_EEE_AR, 0x); +} + +static void r8152_eee_en(struct r8152 *tp, bool enable) +{ + u16 config1, config2, config3; + u32 ocp_data; + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); + config1 = ocp_reg_read(tp, OCP_EEE_CONFIG1) & ~sd_rise_time_mask; + config2 = ocp_reg_read(tp, OCP_EEE_CONFIG2); + config3 = ocp_reg_read(tp, OCP_EEE_CONFIG3) & ~fast_snr_mask; + + if (enable) { + ocp_data |= EEE_RX_EN | EEE_TX_EN; + config1 |= EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | RX_QUIET_EN; + config1 |= sd_rise_time(1); + config2 |= RG_DACQUIET_EN | RG_LDVQUIET_EN; + config3 |= fast_snr(42); + } else { + ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); + config1 &= ~(EEE_10_CAP | EEE_NWAY_EN | TX_QUIET_EN | +RX_QUIET_EN); + config1 |= sd_rise_time(7); + config2 &= ~(RG_DACQUIET_EN | RG_LDVQUIET_EN); + config3 |= fast_snr(511); + } + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); + ocp_reg_write(tp, OCP_EEE_CONFIG1, config1); + ocp_reg_write(tp, OCP_EEE_CONFIG2, config2); + ocp_reg_write(tp, OCP_EEE_CONFIG3, config3); +} + +static void r8152b_enable_eee(struct r8152 *tp) +{ + r8152_eee_en(tp, true); + r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, MDIO_EEE_100TX); +} + +static void r8152b_enable_fc(struct r8152 *tp) +{ + u16 anar; + + anar = r8152_mdio_read(tp, MII_ADVERTISE); + anar |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM; + r8152_mdio_write(tp, MII_ADVERTISE, anar); +} + static void rtl8152_disable(struct r8152 *tp) { r8152_aldps_en(tp, false); @@ -2701,6 +2772,47 @@ static void r8152b_enter_oob(struct r8152 *tp) ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); } +static void r8153_aldps_en(struct r8152 *tp, bool enable) +{ + u16 data; + + data = ocp_reg_read(tp, OCP_POWER_CFG); + if (enable) { + data |= EN_ALDPS; + ocp_reg_write(tp, OCP_POWER_CFG, data); + } else { + data &= ~EN_ALDPS; + ocp_reg_write(tp, OCP_POWER_CFG, data); + msleep(20); + } +} + +static void r8153_eee_en(struct r8152 *tp, bool enable) +{ + u32 ocp_data; + u16 config; + + ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR); + config = ocp_reg_read(tp, OCP_EEE_CFG); + + if (enable) { + ocp_data |= EEE_RX_EN | EEE_TX_EN; + config |= EEE10_EN; + } else { + ocp_data &= ~(EEE_RX_EN | EEE_TX_EN); + config &= ~EEE10_EN; + } + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEE_CR, ocp_data); + ocp_reg_write(tp, OCP_EEE_CFG, config); +} + +static void r8153_enable_eee(struct r8152 *tp) +{ + r8153_eee_en(tp, true); + ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX); +} + static void r8153_hw_phy_cfg(struct r8152 *tp) { u32 ocp_data; @@ -2866,21 +2978,6 @@ static void r8153_enter_oob(struct r8152 *tp) ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data); } -static void r8153_aldps_en(struct r8152 *tp, bool enable) -{ - u16 data; - - data = ocp_reg_read(tp, OCP_POWER_CFG); - if (enable) { - data |= EN_ALDPS; - ocp_reg_write(tp, OCP_POWER_CFG, data); - } else { - data &= ~EN_ALDPS; - ocp_reg_write(tp, OCP_POWER_C
[PATCH net 0/5] r8152: correct the flow of PHY
First, to enable the PHY as early as possible. Some settings may fail if the PHY is power down. Move the other PHY settings to hw_phy_cfg() to make sure the order is correct. Finally, disable ALDPS and EEE before updating the PHY for RTL8153. Hayes Wang (5): r8152: move some functions r8152: move enabling PHY r8152: move PHY settings to hw_phy_cfg r8152: remove r8153_enable_eee r8152: disable ALDPS and EEE before setting PHY drivers/net/usb/r8152.c | 281 +--- 1 file changed, 146 insertions(+), 135 deletions(-) -- 2.7.4
[PATCH net-next 0/3] r8152: configuration setting
Some people prefer to use ECM mode rather than vendor mode. Therefore, I add CONFIG_RTL8152_CONFIG_VALUE in Kconfig. Then, the users could choose the USB configuration value which they want. The default is to support vendor mode only. Hayes Wang (3): r8152: check hw version first r8152: support ECM mode r8152: add CONFIG_RTL8152_CONFIG_VALUE drivers/net/usb/Kconfig | 13 ++ drivers/net/usb/r8152.c | 383 +--- 2 files changed, 345 insertions(+), 51 deletions(-) -- 2.7.4
[PATCH net-next 2/3] r8152: support ECM mode
If CONFIG_USB_NET_CDCETHER is enabled, support ECM mode through cdc_ether driver. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 255 ++-- 1 file changed, 247 insertions(+), 8 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 8468704..c4e8339 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -27,6 +27,7 @@ #include #include #include +#include /* Information for net-next */ #define NETNEXT_VERSION"08" @@ -4402,6 +4403,243 @@ static void rtl8152_disconnect(struct usb_interface *intf) } } +static int rtl_usbnet_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + switch (id->bInterfaceClass) { + case USB_CLASS_VENDOR_SPEC: + return rtl8152_probe(intf, id); +#if IS_ENABLED(CONFIG_USB_NET_CDCETHER) + case USB_CLASS_COMM: + if (id->bInterfaceSubClass == USB_CDC_SUBCLASS_ETHERNET && + id->bInterfaceProtocol == USB_CDC_PROTO_NONE) + return usbnet_probe(intf, id); +#endif + default: + return -ENODEV; + } +} + +static void rtl_usbnet_disconnect(struct usb_interface *intf) +{ + struct usb_host_interface *alt = intf->cur_altsetting; + + switch (alt->desc.bInterfaceClass) { + case USB_CLASS_VENDOR_SPEC: + rtl8152_disconnect(intf); + break; +#if IS_ENABLED(CONFIG_USB_NET_CDCETHER) + case USB_CLASS_COMM: + if (alt->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_ETHERNET && + alt->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE) { + usbnet_disconnect(intf); + break; + } +#endif + default: + break; + } +} + +static int rtl_usbnet_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct usb_host_interface *alt = intf->cur_altsetting; + + switch (alt->desc.bInterfaceClass) { + case USB_CLASS_VENDOR_SPEC: + return rtl8152_suspend(intf, message); +#if IS_ENABLED(CONFIG_USB_NET_CDCETHER) + case USB_CLASS_COMM: + if (alt->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_ETHERNET && + alt->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE) + return usbnet_suspend(intf, message); +#endif + default: + return -ENODEV; + } +} + +static int rtl_usbnet_resume(struct usb_interface *intf) +{ + struct usb_host_interface *alt = intf->cur_altsetting; + + switch (alt->desc.bInterfaceClass) { + case USB_CLASS_VENDOR_SPEC: + return rtl8152_resume(intf); +#if IS_ENABLED(CONFIG_USB_NET_CDCETHER) + case USB_CLASS_COMM: + if (alt->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_ETHERNET && + alt->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE) + return usbnet_resume(intf); +#endif + default: + return -ENODEV; + } +} + +static int rtl_usbnet_reset_resume(struct usb_interface *intf) +{ + struct usb_host_interface *alt = intf->cur_altsetting; + + switch (alt->desc.bInterfaceClass) { + case USB_CLASS_VENDOR_SPEC: + return rtl8152_reset_resume(intf); +#if IS_ENABLED(CONFIG_USB_NET_CDCETHER) + case USB_CLASS_COMM: + if (alt->desc.bInterfaceSubClass == USB_CDC_SUBCLASS_ETHERNET && + alt->desc.bInterfaceProtocol == USB_CDC_PROTO_NONE) + return usbnet_resume(intf); +#endif + default: + return -ENODEV; + } +} + +static int rtl_usbnet_pre_reset(struct usb_interface *intf) +{ + struct usb_host_interface *alt = intf->cur_altsetting; + + if (!usb_get_intfdata(intf)) + return 0; + + switch (alt->desc.bInterfaceClass) { + case USB_CLASS_VENDOR_SPEC: + return rtl8152_pre_reset(intf); + default: + return 1; + } +} + +static int rtl_usbnet_post_reset(struct usb_interface *intf) +{ + struct usb_host_interface *alt = intf->cur_altsetting; + + if (!usb_get_intfdata(intf)) + return 0; + + switch (alt->desc.bInterfaceClass) { + case USB_CLASS_VENDOR_SPEC: + return rtl8152_post_reset(intf); + default: + return 1; + } +} + +#if IS_ENABLED(CONFIG_USB_NET_CDCETHER) + +static int r815x_mdio_read(struct net_device *netdev, int phy_id, int reg) +{ + struct usbnet *dev = netdev_priv(netdev); + __le32 tmp; + u16 index; + u8 shift; + int err; + + if (phy_id != R8152_PHY_ID) + return -EINVAL; + + index = 0xB400 + reg * 2; +
[PATCH net-next 1/3] r8152: check hw version first
Check hw version first in probe(). Do nothing if the driver doesn't support the chips. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 102 ++-- 1 file changed, 63 insertions(+), 39 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 9338f58..8468704 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -4142,44 +4142,6 @@ static const struct net_device_ops rtl8152_netdev_ops = { .ndo_features_check = rtl8152_features_check, }; -static void r8152b_get_version(struct r8152 *tp) -{ - u32 ocp_data; - u16 version; - - ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1); - version = (u16)(ocp_data & VERSION_MASK); - - switch (version) { - case 0x4c00: - tp->version = RTL_VER_01; - break; - case 0x4c10: - tp->version = RTL_VER_02; - break; - case 0x5c00: - tp->version = RTL_VER_03; - tp->mii.supports_gmii = 1; - break; - case 0x5c10: - tp->version = RTL_VER_04; - tp->mii.supports_gmii = 1; - break; - case 0x5c20: - tp->version = RTL_VER_05; - tp->mii.supports_gmii = 1; - break; - case 0x5c30: - tp->version = RTL_VER_06; - tp->mii.supports_gmii = 1; - break; - default: - netif_info(tp, probe, tp->netdev, - "Unknown version 0x%04x\n", version); - break; - } -} - static void rtl8152_unload(struct r8152 *tp) { if (test_bit(RTL8152_UNPLUG, &tp->flags)) @@ -4244,14 +4206,66 @@ static int rtl_ops_init(struct r8152 *tp) return ret; } +static u8 rtl_get_version(struct usb_interface *intf) +{ + struct usb_device *udev = interface_to_usbdev(intf); + u32 ocp_data = 0; + __le32 *tmp; + u8 version; + int ret; + + tmp = kmalloc(sizeof(*tmp), GFP_KERNEL); + if (!tmp) + return 0; + + ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), + RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, + PLA_TCR0, MCU_TYPE_PLA, tmp, sizeof(*tmp), 500); + if (ret > 0) + ocp_data = (__le32_to_cpu(*tmp) >> 16) & VERSION_MASK; + + kfree(tmp); + + switch (ocp_data) { + case 0x4c00: + version = RTL_VER_01; + break; + case 0x4c10: + version = RTL_VER_02; + break; + case 0x5c00: + version = RTL_VER_03; + break; + case 0x5c10: + version = RTL_VER_04; + break; + case 0x5c20: + version = RTL_VER_05; + break; + case 0x5c30: + version = RTL_VER_06; + break; + default: + version = RTL_VER_UNKNOWN; + dev_info(&intf->dev, "Unknown version 0x%04x\n", ocp_data); + break; + } + + return version; +} + static int rtl8152_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev = interface_to_usbdev(intf); + u8 version = rtl_get_version(intf); struct r8152 *tp; struct net_device *netdev; int ret; + if (version == RTL_VER_UNKNOWN) + return -ENODEV; + if (udev->actconfig->desc.bConfigurationValue != 1) { usb_driver_set_configuration(udev, 1); return -ENODEV; @@ -4271,8 +4285,18 @@ static int rtl8152_probe(struct usb_interface *intf, tp->udev = udev; tp->netdev = netdev; tp->intf = intf; + tp->version = version; + + switch (version) { + case RTL_VER_01: + case RTL_VER_02: + tp->mii.supports_gmii = 0; + break; + default: + tp->mii.supports_gmii = 1; + break; + } - r8152b_get_version(tp); ret = rtl_ops_init(tp); if (ret) goto out; -- 2.7.4
[PATCH net-next 3/3] r8152: add CONFIG_RTL8152_CONFIG_VALUE
According to CONFIG_RTL8152_CONFIG_VALUE, to determine which mode the driver supports. The value 0 means to support both vendor mode and ECM mode. The value 1 means to support vendor mode only. The value 2 means to support ECM mode only. Signed-off-by: Hayes Wang --- drivers/net/usb/Kconfig | 13 + drivers/net/usb/r8152.c | 30 -- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig index cdde590..3d2fd09 100644 --- a/drivers/net/usb/Kconfig +++ b/drivers/net/usb/Kconfig @@ -106,6 +106,19 @@ config USB_RTL8152 To compile this driver as a module, choose M here: the module will be called r8152. +config RTL8152_CONFIG_VALUE + depends on USB_RTL8152 + int "RTL8152/RTL8153 USB Configuration Value" + default 1 + help + This is used to select the USB configuration value of RTL8152/RTL8153. + 0: support all configuration values. It means the user could + change the configuration value. However, it may have problem + if you change the configuration value frequently. Don't set + this value unless you really know what you want. + 1: use vendor mode only. (recommended) + 2: use ECM mode only. + config USB_LAN78XX tristate "Microchip LAN78XX Based USB Ethernet Adapters" select MII diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index c4e8339..480af78 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -30,7 +30,7 @@ #include /* Information for net-next */ -#define NETNEXT_VERSION"08" +#define NETNEXT_VERSION"09" /* Information for net */ #define NET_VERSION"5" @@ -4267,11 +4267,6 @@ static int rtl8152_probe(struct usb_interface *intf, if (version == RTL_VER_UNKNOWN) return -ENODEV; - if (udev->actconfig->desc.bConfigurationValue != 1) { - usb_driver_set_configuration(udev, 1); - return -ENODEV; - } - usb_reset_device(udev); netdev = alloc_etherdev(sizeof(struct r8152)); if (!netdev) { @@ -4403,9 +4398,32 @@ static void rtl8152_disconnect(struct usb_interface *intf) } } +static bool rtl_change_config(struct usb_interface *intf) +{ + struct usb_device *udev = interface_to_usbdev(intf); + u8 actconfig = udev->actconfig->desc.bConfigurationValue; + + if (CONFIG_RTL8152_CONFIG_VALUE <= 0 || + udev->descriptor.bNumConfigurations < CONFIG_RTL8152_CONFIG_VALUE || + actconfig == CONFIG_RTL8152_CONFIG_VALUE) + return false; + + if (CONFIG_RTL8152_CONFIG_VALUE == 1 && !rtl_get_version(intf)) + return false; + + return true; +} + static int rtl_usbnet_probe(struct usb_interface *intf, const struct usb_device_id *id) { + if (rtl_change_config(intf)) { + struct usb_device *udev = interface_to_usbdev(intf); + + usb_driver_set_configuration(udev, CONFIG_RTL8152_CONFIG_VALUE); + return -ENODEV; + } + switch (id->bInterfaceClass) { case USB_CLASS_VENDOR_SPEC: return rtl8152_probe(intf, id); -- 2.7.4
RE: [PATCH net-next 0/3] r8152: configuration setting
Bjørn Mork [mailto:bj...@mork.no] > Sent: Wednesday, September 07, 2016 9:51 PM [...] > So this adds a lot of code to work around the issues you introduced by > unnecessarily blacklisting the CDC ECM configuration earlier, and still > makes the r8152 driver handle the device even in ECM mode. I suggest to use vendor mode only, but some people ask me to submit such patches. If these patches are rejected, I have enough reasons to tell them it is unacceptable rather than I don't do it. > Just remove the completely unnecessary blacklist, and let the cdc_ether > driver handle the device if the user selects the ECM configuration. > That't how the USB system works. There is no need for any code in r8152 > to do that. The pure cdc_ether driver couldn't change the speed of the ethernet, because it doesn't know how to access the PHY of the device. Therefore, I add relative code in r8152 driver. Best Regards, Hayes
RE: [PATCH net-next 0/3] r8152: configuration setting
David Miller [mailto:da...@davemloft.net] > Sent: Thursday, September 08, 2016 8:38 AM [...] > By forcing a certain mode via a Kconfig value, you are basically making it > impossible for distributions to do something reasonable here. The request is always from some manufacturers, not end users. They always ask the driver to control everything. And I don't think the end user knows or cares about how the device is set. That is why I try to satisfy them via Kconfig. I think you have rejected this way. I would think if there is any other method. Thanks. Best Regards, Hayes
RE: [PATCH net-next 0/3] r8152: configuration setting
Bjørn Mork [mailto:bj...@mork.no] > Sent: Thursday, September 08, 2016 3:55 PM [...] > Yes, I see that. But is that strictly necessary? Couldn't you just say: > "CDC ECM is supported by cdc_ether and therefore limited to the features > implemented by cdc_ether. If you want feature X, then please use our > vendor specific mode with the r8152 driver?" My customs have a case that they must force the speed to 100M for some reasons. I also wish to implement the driver as simple as possible, but I don't think I could determine this. I accept you reject my patches. However, I couldn't deny the requests from the boss or customs without doing anything. I must prove the way is unacceptable. [...] > Each USB configuation comes with a set of descriptors identifying the > functions, and USB interface drivers attach to the functions they > support. The user can dynamically switch the device from e.g. cfg #1 to > cfg #3 by writing "3" to /sys/bus/usb/devices//bConfigurationValue > This will cause the ECM and ACM USB interfaces to disappear, and the > associated class drivers will unbind, and new vendor specific USB > interfaces appear instead, causing a matching vendor specific driver to > load and bind. > > Naturally, end users will not switch configurations all the time. They > will select the configuration providing the set of functions they want. > If this is different from the default configuration selected by the > Linux USB core, then that's a simple udev rule to update the > bConfigurationValue sysfs attribute on device disceovery. I tested above method before. And I found that the cdc_ether was loaded before switching the configuration. The behavior of loading one driver and changing to another driver has opportunity to let our some previous chips become abnormal. To switch configuration is fine. However, it may have problem to switch driver. That is why the current kernel only supports vendor mode. If the method works fine, I have no trouble now. Best Regards, Hayes
[PATCH net-next] r8152: fix the coding style with checkpatch.pl
check the coding style with checkpatch.pl and fix the warnings and errors. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 11 +-- 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index f41a8ad..8915848 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1076,8 +1076,7 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) return -ENODEV; if (obj->type != ACPI_TYPE_BUFFER || obj->string.length != 0x17) { netif_warn(tp, probe, tp->netdev, - "Invalid buffer when reading pass-thru MAC addr: " - "(%d, %d)\n", + "Invalid buffer for pass-thru MAC addr: (%d, %d)\n", obj->type, obj->string.length); goto amacout; } @@ -1090,8 +1089,8 @@ static int vendor_mac_passthru_addr_read(struct r8152 *tp, struct sockaddr *sa) ret = hex2bin(buf, obj->string.pointer + 9, 6); if (!(ret == 0 && is_valid_ether_addr(buf))) { netif_warn(tp, probe, tp->netdev, - "Invalid MAC when reading pass-thru MAC addr: " - "%d, %pM\n", ret, buf); + "Invalid MAC for pass-thru MAC addr: %d, %pM\n", + ret, buf); ret = -EINVAL; goto amacout; } @@ -,9 +1110,9 @@ static int set_ethernet_addr(struct r8152 *tp) struct sockaddr sa; int ret; - if (tp->version == RTL_VER_01) + if (tp->version == RTL_VER_01) { ret = pla_ocp_read(tp, PLA_IDR, 8, sa.sa_data); - else { + } else { /* if this is not an RTL8153-AD, no eFuse mac pass thru set, * or system doesn't provide valid _SB.AMAC this will be * be expected to non-zero -- 2.7.4
[PATCH net-next] r8152: correct the definition
Replace VLAN_HLEN and CRC_SIZE with ETH_FCS_LEN. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 22 +++--- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 8bc4573..6cfffef 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -569,7 +569,6 @@ enum rtl_register_content { #define RTL8152_MAX_TX 4 #define RTL8152_MAX_RX 10 #define INTBUFSIZE 2 -#define CRC_SIZE 4 #define TX_ALIGN 4 #define RX_ALIGN 8 @@ -588,12 +587,13 @@ enum rtl_register_content { #define BYTE_EN_END_MASK 0xf0 #define RTL8153_MAX_PACKET 9216 /* 9K */ -#define RTL8153_MAX_MTU(RTL8153_MAX_PACKET - VLAN_ETH_HLEN - VLAN_HLEN) -#define RTL8152_RMS(VLAN_ETH_FRAME_LEN + VLAN_HLEN) +#define RTL8153_MAX_MTU(RTL8153_MAX_PACKET - VLAN_ETH_HLEN - \ +ETH_FCS_LEN) +#define RTL8152_RMS(VLAN_ETH_FRAME_LEN + ETH_FCS_LEN) #define RTL8153_RMSRTL8153_MAX_PACKET #define RTL8152_TX_TIMEOUT (5 * HZ) #define RTL8152_NAPI_WEIGHT64 -#define rx_reserved_size(x)((x) + VLAN_ETH_HLEN + CRC_SIZE + \ +#define rx_reserved_size(x)((x) + VLAN_ETH_HLEN + ETH_FCS_LEN + \ sizeof(struct rx_desc) + RX_ALIGN) /* rtl8152 flags */ @@ -770,7 +770,7 @@ static const int multicast_filter_limit = 32; static unsigned int agg_buf_sz = 16384; #define RTL_LIMITED_TSO_SIZE (agg_buf_sz - sizeof(struct tx_desc) - \ -VLAN_ETH_HLEN - VLAN_HLEN) +VLAN_ETH_HLEN - ETH_FCS_LEN) static int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data) @@ -1928,7 +1928,7 @@ static int rx_bottom(struct r8152 *tp, int budget) if (urb->actual_length < len_used) break; - pkt_len -= CRC_SIZE; + pkt_len -= ETH_FCS_LEN; rx_data += sizeof(struct rx_desc); skb = napi_alloc_skb(napi, pkt_len); @@ -1952,7 +1952,7 @@ static int rx_bottom(struct r8152 *tp, int budget) } find_next_rx: - rx_data = rx_agg_align(rx_data + pkt_len + CRC_SIZE); + rx_data = rx_agg_align(rx_data + pkt_len + ETH_FCS_LEN); rx_desc = (struct rx_desc *)rx_data; len_used = (int)(rx_data - (u8 *)agg->head); len_used += sizeof(struct rx_desc); @@ -2242,7 +2242,7 @@ static void set_tx_qlen(struct r8152 *tp) { struct net_device *netdev = tp->netdev; - tp->tx_qlen = agg_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + VLAN_HLEN + + tp->tx_qlen = agg_buf_sz / (netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN + sizeof(struct tx_desc)); } @@ -3439,7 +3439,7 @@ static void r8153_first_init(struct r8152 *tp) rtl_rx_vlan_en(tp, tp->netdev->features & NETIF_F_HW_VLAN_CTAG_RX); - ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + CRC_SIZE; + ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data); ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO); @@ -3489,7 +3489,7 @@ static void r8153_enter_oob(struct r8152 *tp) usleep_range(1000, 2000); } - ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + CRC_SIZE; + ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data); switch (tp->version) { @@ -4957,7 +4957,7 @@ static int rtl8152_change_mtu(struct net_device *dev, int new_mtu) dev->mtu = new_mtu; if (netif_running(dev)) { - u32 rms = new_mtu + VLAN_ETH_HLEN + CRC_SIZE; + u32 rms = new_mtu + VLAN_ETH_HLEN + ETH_FCS_LEN; ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, rms); -- 2.7.4
[PATCH net 0/2] fix the autoresume may fail
Fix the autosuspend issues which occur about linking change. Hayes Wang (2): r8152: split DRIVER_VERSION r8152: fix the runtime suspend issues drivers/net/usb/r8152.c | 66 ++--- 1 file changed, 63 insertions(+), 3 deletions(-) -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net 2/2] r8152: fix the runtime suspend issues
Fix the runtime suspend issues result from the linking change. Case 1: a) link down occurs. b) driver disable tx/rx. c) autosuspend occurs. d) hw linking up. e) device suspends without enabling tx/rx. f) couldn't wake up when receiving packets. Case 2: a) Nway results in linking down. b) autosuspend occurs. c) device suspends. d) device may not wake up when linking up. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 59 +++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 6bb48bc..d9427ca 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -30,7 +30,7 @@ #define NETNEXT_VERSION"08" /* Information for net */ -#define NET_VERSION"1" +#define NET_VERSION"2" #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION #define DRIVER_AUTHOR "Realtek linux nic maintainers " @@ -148,6 +148,7 @@ #define OCP_EEE_ABLE 0xa5c4 #define OCP_EEE_ADV0xa5d0 #define OCP_EEE_LPABLE 0xa5d2 +#define OCP_PHY_STATE 0xa708 /* nway state for 8153 */ #define OCP_ADC_CFG0xbc06 /* SRAM Register */ @@ -432,6 +433,10 @@ /* OCP_DOWN_SPEED */ #define EN_10M_BGOFF 0x0080 +/* OCP_PHY_STATE */ +#define TXDIS_STATE0x01 +#define ABD_STATE 0x02 + /* OCP_ADC_CFG */ #define CKADSEL_L 0x0100 #define ADC_EN 0x0080 @@ -609,6 +614,7 @@ struct r8152 { void (*unload)(struct r8152 *); int (*eee_get)(struct r8152 *, struct ethtool_eee *); int (*eee_set)(struct r8152 *, struct ethtool_eee *); + bool (*in_nway)(struct r8152 *); } rtl_ops; int intr_interval; @@ -2946,6 +2952,32 @@ static void rtl8153_down(struct r8152 *tp) r8153_enable_aldps(tp); } +static bool rtl8152_in_nway(struct r8152 *tp) +{ + u16 nway_state; + + ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, 0x2000); + tp->ocp_base = 0x2000; + ocp_write_byte(tp, MCU_TYPE_PLA, 0xb014, 0x4c); /* phy state */ + nway_state = ocp_read_word(tp, MCU_TYPE_PLA, 0xb01a); + + /* bit 15: TXDIS_STATE, bit 14: ABD_STATE */ + if (nway_state & 0xc000) + return false; + else + return true; +} + +static bool rtl8153_in_nway(struct r8152 *tp) +{ + u16 phy_state = ocp_reg_read(tp, OCP_PHY_STATE) & 0xff; + + if (phy_state == TXDIS_STATE || phy_state == ABD_STATE) + return false; + else + return true; +} + static void set_carrier(struct r8152 *tp) { struct net_device *netdev = tp->netdev; @@ -3410,6 +3442,27 @@ static int rtl8152_post_reset(struct usb_interface *intf) return 0; } +static bool delay_autosuspend(struct r8152 *tp) +{ + bool sw_linking = !!netif_carrier_ok(tp->netdev); + bool hw_linking = !!(rtl8152_get_speed(tp) & LINK_STATUS); + + /* This means a linking change occurs and the driver doesn't detect it, +* yet. If the driver has disabled tx/rx and hw is linking on, the +* device wouldn't wake up by receiving any packet. +*/ + if (work_busy(&tp->schedule.work) || sw_linking != hw_linking) + return true; + + /* If the linking down is occurred by nway, the device may miss the +* linking change event. And it wouldn't wake when linking on. +*/ + if (!sw_linking && tp->rtl_ops.in_nway(tp)) + return true; + else + return false; +} + static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) { struct r8152 *tp = usb_get_intfdata(intf); @@ -3419,7 +3472,7 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message) mutex_lock(&tp->control); if (PMSG_IS_AUTO(message)) { - if (netif_running(netdev) && work_busy(&tp->schedule.work)) { + if (netif_running(netdev) && delay_autosuspend(tp)) { ret = -EBUSY; goto out1; } @@ -4049,6 +4102,7 @@ static int rtl_ops_init(struct r8152 *tp) ops->unload = rtl8152_unload; ops->eee_get= r8152_get_eee; ops->eee_set= r8152_set_eee; + ops->in_nway= rtl8152_in_nway; break; case RTL_VER_03: @@ -4063,6 +4117,7 @@ static int rtl_ops_init(struct r8152 *tp) ops->unload = rtl8153_unload; ops->eee_get= r8153_get_eee; ops->eee_set= r8153_set_eee; +
[PATCH net 1/2] r8152: split DRIVER_VERSION
Split DRIVER_VERSION into NETNEXT_VERSION and NET_VERSION. Then, according to the value of DRIVER_VERSION, we could know which patches are used generally without comparing the source code. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index fe4ec32..6bb48bc 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -26,8 +26,13 @@ #include #include -/* Version Information */ -#define DRIVER_VERSION "v1.08.1 (2015/07/28)" +/* Information for net-next */ +#define NETNEXT_VERSION"08" + +/* Information for net */ +#define NET_VERSION"1" + +#define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION #define DRIVER_AUTHOR "Realtek linux nic maintainers " #define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" #define MODULENAME "r8152" -- 2.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH v2] r8152: disable RX aggregation on Dell TB16 dock
[...] > > r8153 on Dell TB15/16 dock corrupts rx packets. > > > > This change is suggested by Realtek. They guess that the XHCI > > controller doesn't have enough buffer, and their guesswork is correct, > > once the RX aggregation gets disabled, the issue is gone. > > > > ASMedia is currently working on a real sulotion for this issue. > > > > Dell and ODM confirm the bcdDevice and iSerialNumber is unique for TB16. > > > > Note that TB15 has different bcdDevice and iSerialNumber, which are > > not unique values. If you still have TB15, please contact Dell to > > replace it with TB16. Excuse me. I don't understand why this patch is for specific USB nic rather than xHCI. It seems to make the specific USB nic working and the other ones keeping error. Best Regards, Hayes
RE: r8152: data corruption in various scenarios
Monday, January 07, 2019 5:17 AM [...] >> This is probably an xHC bug. A similar issue is fixed by commit 9da5a1092b13 >> ("xhci: Bad Ethernet performance plugged in ASM1042A host”). >> >>> I just got that exact message above, with the r8152 in my 1-day old WD15 >>> dock, >>> with the TB16 "workaround" enabled in Linux kernel 4.20.0. >> >> Is the xHC WD15 connected an ASMedia one? > > I don't know. I *think* it identifies as a DSL6340 (see below). > According to our record, it is relative to the asmedia. Best Regards, Hayes
[PATCH net] r8152: support ndo_features_check
Support ndo_features_check to avoid: - the transport offset is more than the hw limitation when using hw checksum. - the skb->len of a GSO packet is more than the limitation. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 17 + 1 file changed, 17 insertions(+) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 2d1c77e..57ec23e 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1897,6 +1897,22 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev) netif_wake_queue(netdev); } +static netdev_features_t +rtl8152_features_check(struct sk_buff *skb, struct net_device *dev, + netdev_features_t features) +{ + u32 mss = skb_shinfo(skb)->gso_size; + int max_offset = mss ? GTTCPHO_MAX : TCPHO_MAX; + int offset = skb_transport_offset(skb); + + if ((mss || skb->ip_summed == CHECKSUM_PARTIAL) && offset > max_offset) + features &= ~(NETIF_F_ALL_CSUM | NETIF_F_GSO_MASK); + else if ((skb->len + sizeof(struct tx_desc)) > agg_buf_sz) + features &= ~NETIF_F_GSO_MASK; + + return features; +} + static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb, struct net_device *netdev) { @@ -3706,6 +3722,7 @@ static const struct net_device_ops rtl8152_netdev_ops = { .ndo_set_mac_address= rtl8152_set_mac_address, .ndo_change_mtu = rtl8152_change_mtu, .ndo_validate_addr = eth_validate_addr, + .ndo_features_check = rtl8152_features_check, }; static void r8152b_get_version(struct r8152 *tp) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
RE: [PATCH net-next 1/7] r8152: adjust rx_bottom
David Miller [mailto:da...@davemloft.net] > Sent: Sunday, January 25, 2015 2:44 PM [...] > What keeps rtl_start_rx() from running in parallel with > r8152_submit_rx(), or any other accessor of the RX agg->list? Forgive my poor English. I would try to describe them clearly. The steps about the rx agg->list would be 1. carrier on or autoresume occurs. 2. Call rtl_start_rx(). 3. Rx agg->list flows between device and tp->rx_done. 4. carrier off or autosuspend occurs. 5. call rtl_stop_rx(). The rtl_start_rx() would only be called when the linking status is changed from off to on or the auto resume occurs. And rtl_start_rx() would reinitialize the tp->rx_done and all of the rx agg->list. After step 2, the rx agg->list would flow between the usb host controller and the driver. If r8152_submit_rx() is success, the driver wouldn't own the rx agg->list until it is returned from the usb host controller. If r8152_submit_rx() is fail, the driver would still own the rx agg->list, and queue it to the tp->rx_done with spin lock for next try. If the status stays in step 3, only the rx_bottom() would submit the rx agg. The rtl_start_rx() wouldn't be called suddenly, unless the linking down or auto suspend occur first and linking on or auto resume occur again. If linking down or auto suspend occur, rtl_stop_rx() would be called (step 5). After this step, rx_bottom() wouldn't submit rx, and all rx agg->list would stop flowing. That is, the tp->rx_done and all rx agg->list wouldn't be changed until the next rtl_start_rx() is called. Therefore, the flow for each rx agg->list would be a. submittd by rtl_start_rx(). b. goto step c if success, otherwise goto step d. c. completed by usb host controller. d. queued to tp->rx_done with spin lock. e. dequeue from tp->rx_done with spin lock by rx_botoom(). f. goto step i if link down, otherwise goto step g. g. submitted by rx_botoom(). h. goto step b. i. goto step a if link on. And the patch change the step g to g1. g1. submitted by rx_botoom() if (!ret), otherwise goto step d. Best Regards, Hayes > > You also keep using different terminology from me when > discussing what lists do or do not need protection, and that > is going to make it difficult for anyone to follow our > conversation at all. > > We're talking specifically about RX agg->list objects and > whether access to them need synchronization or not. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next v2 0/2 RESEND] r8152: adjust r8152_submit_rx
v2: Replace the patch #1 with "call rtl_start_rx after netif_carrier_on". For patch #2, replace checking tp->speed with netif_carrier_ok. v1: Avoid r8152_submit_rx() from submitting rx during unexpected moment. This could reduce the time of stopping rx. For patch #1, the tp->speed should be updated early. Then, the patch #2 could use it to check the current linking status. Hayes Wang (2): r8152: call rtl_start_rx after netif_carrier_on r8152: check the status before submitting rx drivers/net/usb/r8152.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next v2 1/2 RESEND] r8152: call rtl_start_rx after netif_carrier_on
Remove rtl_start_rx() from rtl_enable() and put it after calling netif_carrier_on(). Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 57ec23e..cd93388 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -2059,7 +2059,7 @@ static int rtl_enable(struct r8152 *tp) rxdy_gated_en(tp, false); - return rtl_start_rx(tp); + return 0; } static int rtl8152_enable(struct r8152 *tp) @@ -2874,6 +2874,7 @@ static void set_carrier(struct r8152 *tp) tp->rtl_ops.enable(tp); set_bit(RTL8152_SET_RX_MODE, &tp->flags); netif_carrier_on(netdev); + rtl_start_rx(tp); } } else { if (tp->speed & LINK_STATUS) { -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next v2 2/2 RESEND] r8152: check the status before submitting rx
Don't submit the rx if the device is unplugged, stopped, or linking down. Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index cd93388..b23426e 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1789,6 +1789,11 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags) { int ret; + /* The rx would be stopped, so skip submitting */ + if (test_bit(RTL8152_UNPLUG, &tp->flags) || + !test_bit(WORK_ENABLE, &tp->flags) || !netif_carrier_ok(tp->netdev)) + return 0; + usb_fill_bulk_urb(agg->urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1), agg->head, agg_buf_sz, (usb_complete_t)read_bulk_callback, agg); -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next] r8152: replace tasklet with NAPI
Replace tasklet with NAPI. Add rx_queue to queue the remaining rx packets if the number of the rx packets is more than the request from poll(). Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 120 ++-- 1 file changed, 85 insertions(+), 35 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index b23426e..50387fe 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -27,7 +27,7 @@ #include /* Version Information */ -#define DRIVER_VERSION "v1.07.0 (2014/10/09)" +#define DRIVER_VERSION "v1.08.0 (2015/01/13)" #define DRIVER_AUTHOR "Realtek linux nic maintainers " #define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters" #define MODULENAME "r8152" @@ -448,6 +448,7 @@ enum rtl_register_content { #define RTL8152_RMS(VLAN_ETH_FRAME_LEN + VLAN_HLEN) #define RTL8153_RMSRTL8153_MAX_PACKET #define RTL8152_TX_TIMEOUT (5 * HZ) +#define RTL8152_NAPI_WEIGHT64 /* rtl8152 flags */ enum rtl8152_flags { @@ -457,7 +458,7 @@ enum rtl8152_flags { RTL8152_LINK_CHG, SELECTIVE_SUSPEND, PHY_RESET, - SCHEDULE_TASKLET, + SCHEDULE_NAPI, }; /* Define these values to match your device */ @@ -549,14 +550,14 @@ struct tx_agg { struct r8152 { unsigned long flags; struct usb_device *udev; - struct tasklet_struct tl; + struct napi_struct napi; struct usb_interface *intf; struct net_device *netdev; struct urb *intr_urb; struct tx_agg tx_info[RTL8152_MAX_TX]; struct rx_agg rx_info[RTL8152_MAX_RX]; struct list_head rx_done, tx_free; - struct sk_buff_head tx_queue; + struct sk_buff_head tx_queue, rx_queue; spinlock_t rx_lock, tx_lock; struct delayed_work schedule; struct mii_if_info mii; @@ -1062,7 +1063,7 @@ static void read_bulk_callback(struct urb *urb) spin_lock(&tp->rx_lock); list_add_tail(&agg->list, &tp->rx_done); spin_unlock(&tp->rx_lock); - tasklet_schedule(&tp->tl); + napi_schedule(&tp->napi); return; case -ESHUTDOWN: set_bit(RTL8152_UNPLUG, &tp->flags); @@ -1126,7 +1127,7 @@ static void write_bulk_callback(struct urb *urb) return; if (!skb_queue_empty(&tp->tx_queue)) - tasklet_schedule(&tp->tl); + napi_schedule(&tp->napi); } static void intr_callback(struct urb *urb) @@ -1245,6 +1246,7 @@ static int alloc_all_mem(struct r8152 *tp) spin_lock_init(&tp->tx_lock); INIT_LIST_HEAD(&tp->tx_free); skb_queue_head_init(&tp->tx_queue); + skb_queue_head_init(&tp->rx_queue); for (i = 0; i < RTL8152_MAX_RX; i++) { buf = kmalloc_node(agg_buf_sz, GFP_KERNEL, node); @@ -1649,13 +1651,32 @@ return_result: return checksum; } -static void rx_bottom(struct r8152 *tp) +static int rx_bottom(struct r8152 *tp, int budget) { unsigned long flags; struct list_head *cursor, *next, rx_queue; + int work_done = 0; + + if (!skb_queue_empty(&tp->rx_queue)) { + while (work_done < budget) { + struct sk_buff *skb = __skb_dequeue(&tp->rx_queue); + struct net_device *netdev = tp->netdev; + struct net_device_stats *stats = &netdev->stats; + unsigned int pkt_len; + + if (!skb) + break; + + pkt_len = skb->len; + napi_gro_receive(&tp->napi, skb); + work_done++; + stats->rx_packets++; + stats->rx_bytes += pkt_len; + } + } if (list_empty(&tp->rx_done)) - return; + goto out1; INIT_LIST_HEAD(&rx_queue); spin_lock_irqsave(&tp->rx_lock, flags); @@ -1708,9 +1729,14 @@ static void rx_bottom(struct r8152 *tp) skb_put(skb, pkt_len); skb->protocol = eth_type_trans(skb, netdev); rtl_rx_vlan_tag(rx_desc, skb); - netif_receive_skb(skb); - stats->rx_packets++; - stats->rx_bytes += pkt_len; + if (work_done < budget) { + napi_gro_receive(&tp->napi, skb); + work_done++; + stats->rx_packets++; + stats->rx_bytes += pkt_len; + } else
[PATCH net-next 6/7] r8152: replace get_protocol with vlan_get_protocol
vlan_get_protocol() has been defined and use it to replace get_protocol(). Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 16 ++-- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index f66ffbd..46440ed 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -1342,18 +1342,6 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp) return agg; } -static inline __be16 get_protocol(struct sk_buff *skb) -{ - __be16 protocol; - - if (skb->protocol == htons(ETH_P_8021Q)) - protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto; - else - protocol = skb->protocol; - - return protocol; -} - /* r8152_csum_workaround() * The hw limites the value the transport offset. When the offset is out of the * range, calculate the checksum by sw. @@ -1459,7 +1447,7 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, goto unavailable; } - switch (get_protocol(skb)) { + switch (vlan_get_protocol(skb)) { case htons(ETH_P_IP): opts1 |= GTSENDV4; break; @@ -1490,7 +1478,7 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, goto unavailable; } - switch (get_protocol(skb)) { + switch (vlan_get_protocol(skb)) { case htons(ETH_P_IP): opts2 |= IPV4_CS; ip_protocol = ip_hdr(skb)->protocol; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH net-next 7/7] r8152: use BIT macro
Use BIT macro to replace (1 << bits). Signed-off-by: Hayes Wang --- drivers/net/usb/r8152.c | 34 +- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 46440ed..c3a0224 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c @@ -489,16 +489,16 @@ struct rx_desc { #define RX_LEN_MASK0x7fff __le32 opts2; -#define RD_UDP_CS (1 << 23) -#define RD_TCP_CS (1 << 22) -#define RD_IPV6_CS (1 << 20) -#define RD_IPV4_CS (1 << 19) +#define RD_UDP_CS BIT(23) +#define RD_TCP_CS BIT(22) +#define RD_IPV6_CS BIT(20) +#define RD_IPV4_CS BIT(19) __le32 opts3; -#define IPF(1 << 23) /* IP checksum fail */ -#define UDPF (1 << 22) /* UDP checksum fail */ -#define TCPF (1 << 21) /* TCP checksum fail */ -#define RX_VLAN_TAG(1 << 16) +#define IPFBIT(23) /* IP checksum fail */ +#define UDPF BIT(22) /* UDP checksum fail */ +#define TCPF BIT(21) /* TCP checksum fail */ +#define RX_VLAN_TAGBIT(16) __le32 opts4; __le32 opts5; @@ -507,24 +507,24 @@ struct rx_desc { struct tx_desc { __le32 opts1; -#define TX_FS (1 << 31) /* First segment of a packet */ -#define TX_LS (1 << 30) /* Final segment of a packet */ -#define GTSENDV4 (1 << 28) -#define GTSENDV6 (1 << 27) +#define TX_FS BIT(31) /* First segment of a packet */ +#define TX_LS BIT(30) /* Final segment of a packet */ +#define GTSENDV4 BIT(28) +#define GTSENDV6 BIT(27) #define GTTCPHO_SHIFT 18 #define GTTCPHO_MAX0x7fU #define TX_LEN_MAX 0x3U __le32 opts2; -#define UDP_CS (1 << 31) /* Calculate UDP/IP checksum */ -#define TCP_CS (1 << 30) /* Calculate TCP/IP checksum */ -#define IPV4_CS(1 << 29) /* Calculate IPv4 checksum */ -#define IPV6_CS(1 << 28) /* Calculate IPv6 checksum */ +#define UDP_CS BIT(31) /* Calculate UDP/IP checksum */ +#define TCP_CS BIT(30) /* Calculate TCP/IP checksum */ +#define IPV4_CSBIT(29) /* Calculate IPv4 checksum */ +#define IPV6_CSBIT(28) /* Calculate IPv6 checksum */ #define MSS_SHIFT 17 #define MSS_MAX0x7ffU #define TCPHO_SHIFT17 #define TCPHO_MAX 0x7ffU -#define TX_VLAN_TAG(1 << 16) +#define TX_VLAN_TAGBIT(16) }; struct r8152; -- 2.1.0 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/