RE: [PATCH net-next 4/6] r8152: support new chips

2021-04-20 Thread Hayes Wang
Jakub Kicinski 
> Sent: Saturday, April 17, 2021 5:50 AM
> > +   switch (tp->version) {
> > +   case RTL_VER_10:
> > +   data = ocp_reg_read(tp, 0xad40);
> > +   data &= ~0x3ff;
> > +   data |= BIT(7) | BIT(2);
> > +   ocp_reg_write(tp, 0xad40, data);
> > +
> > +   data = ocp_reg_read(tp, 0xad4e);
> > +   data |= BIT(4);
> > +   ocp_reg_write(tp, 0xad4e, data);
> > +   data = ocp_reg_read(tp, 0xad16);
> > +   data &= ~0x3ff;
> > +   data |= 0x6;
> > +   ocp_reg_write(tp, 0xad16, data);
> > +   data = ocp_reg_read(tp, 0xad32);
> > +   data &= ~0x3f;
> > +   data |= 6;
> > +   ocp_reg_write(tp, 0xad32, data);
> > +   data = ocp_reg_read(tp, 0xac08);
> > +   data &= ~(BIT(12) | BIT(8));
> > +   ocp_reg_write(tp, 0xac08, data);
> > +   data = ocp_reg_read(tp, 0xac8a);
> > +   data |= BIT(12) | BIT(13) | BIT(14);
> > +   data &= ~BIT(15);
> > +   ocp_reg_write(tp, 0xac8a, data);
> > +   data = ocp_reg_read(tp, 0xad18);
> > +   data |= BIT(10);
> > +   ocp_reg_write(tp, 0xad18, data);
> > +   data = ocp_reg_read(tp, 0xad1a);
> > +   data |= 0x3ff;
> > +   ocp_reg_write(tp, 0xad1a, data);
> > +   data = ocp_reg_read(tp, 0xad1c);
> > +   data |= 0x3ff;
> > +   ocp_reg_write(tp, 0xad1c, data);
> > +
> > +   data = sram_read(tp, 0x80ea);
> > +   data &= ~0xff00;
> > +   data |= 0xc400;
> > +   sram_write(tp, 0x80ea, data);
> > +   data = sram_read(tp, 0x80eb);
> > +   data &= ~0x0700;
> > +   data |= 0x0300;
> > +   sram_write(tp, 0x80eb, data);
> > +   data = sram_read(tp, 0x80f8);
> > +   data &= ~0xff00;
> > +   data |= 0x1c00;
> > +   sram_write(tp, 0x80f8, data);
> > +   data = sram_read(tp, 0x80f1);
> > +   data &= ~0xff00;
> > +   data |= 0x3000;
> > +   sram_write(tp, 0x80f1, data);

These are the parameters of PHY.
Some are used for speed down about power saving.
And some are used for performance.

> > +   switch (tp->version) {
> > +   case RTL_VER_12:
> > +   ocp_reg_write(tp, 0xbf86, 0x9000);
> > +   data = ocp_reg_read(tp, 0xc402);
> > +   data |= BIT(10);
> > +   ocp_reg_write(tp, 0xc402, data);
> > +   data &= ~BIT(10);
> > +   ocp_reg_write(tp, 0xc402, data);
> > +   ocp_reg_write(tp, 0xbd86, 0x1010);
> > +   ocp_reg_write(tp, 0xbd88, 0x1010);
> > +   data = ocp_reg_read(tp, 0xbd4e);
> > +   data &= ~(BIT(10) | BIT(11));
> > +   data |= BIT(11);
> > +   ocp_reg_write(tp, 0xbd4e, data);
> > +   data = ocp_reg_read(tp, 0xbf46);
> > +   data &= ~0xf00;
> > +   data |= 0x700;
> > +   ocp_reg_write(tp, 0xbf46, data);

These are used to adjust the clock of GPHY.
It influences the linking.

> > +   data = r8153_phy_status(tp, 0);
> > +   switch (data) {
> > +   case PHY_STAT_EXT_INIT:
> > +   rtl8152_apply_firmware(tp, true);
> > +
> > +   data = ocp_reg_read(tp, 0xa466);
> > +   data &= ~BIT(0);
> > +   ocp_reg_write(tp, 0xa466, data);

These let the PHY exit PHY_STAT_EXT_INIT state.

> What are all these magic constants? :(

I think it is difficult for me to make all magic values meaningful.
The PHY setting is very complex. Only PHY engineers know
what are the settings mean.

> > @@ -6878,7 +8942,11 @@ static int rtl8152_probe(struct usb_interface
> *intf,
> > set_ethernet_addr(tp);
> >
> > usb_set_intfdata(intf, tp);
> > -   netif_napi_add(netdev, &tp->napi, r8152_poll, RTL8152_NAPI_WEIGHT);
> > +
> > +   if (tp->support_2500full)
> > +   netif_napi_add(netdev, &tp->napi, r8152_poll, 256);
> 
> why 256? We have 100G+ drivers all using 64 what's special here?
> 
> > +   else
> > +   netif_napi_add(netdev, &tp->napi, r8152_poll, 64);

We test 2.5G Ethernet on some embedded platform.
And we find 64 is not large enough, and the performance
couldn't reach 2.5 G bits/s.

Best Regards,
Hayes



[PATCH net-next 4/6] r8152: support new chips

2021-04-16 Thread Hayes Wang
Support RTL8153C, RTL8153D, RTL8156A, and RTL8156B. The RTL8156A
and RTL8156B are the 2.5G ethernet.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 2634 +++
 1 file changed, 2359 insertions(+), 275 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 3f465242a4f0..72b8ef0ad5a1 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -43,10 +43,14 @@
 
 #define PLA_IDR0xc000
 #define PLA_RCR0xc010
+#define PLA_RCR1   0xc012
 #define PLA_RMS0xc016
 #define PLA_RXFIFO_CTRL0   0xc0a0
+#define PLA_RXFIFO_FULL0xc0a2
 #define PLA_RXFIFO_CTRL1   0xc0a4
+#define PLA_RX_FIFO_FULL   0xc0a6
 #define PLA_RXFIFO_CTRL2   0xc0a8
+#define PLA_RX_FIFO_EMPTY  0xc0aa
 #define PLA_DMY_REG0   0xc0b0
 #define PLA_FMC0xc0b4
 #define PLA_CFG_WOL0xc0b6
@@ -63,6 +67,8 @@
 #define PLA_MACDBG_PRE 0xd38c  /* RTL_VER_04 only */
 #define PLA_MACDBG_POST0xd38e  /* RTL_VER_04 only */
 #define PLA_EXTRA_STATUS   0xd398
+#define PLA_GPHY_CTRL  0xd3ae
+#define PLA_POL_GPIO_CTRL  0xdc6a
 #define PLA_EFUSE_DATA 0xdd00
 #define PLA_EFUSE_CMD  0xdd02
 #define PLA_LEDSEL 0xdd90
@@ -72,6 +78,8 @@
 #define PLA_LWAKE_CTRL_REG 0xe007
 #define PLA_GPHY_INTR_IMR  0xe022
 #define PLA_EEE_CR 0xe040
+#define PLA_EEE_TXTWSYS0xe04c
+#define PLA_EEE_TXTWSYS_2P5G   0xe058
 #define PLA_EEEP_CR0xe080
 #define PLA_MAC_PWR_CTRL   0xe0c0
 #define PLA_MAC_PWR_CTRL2  0xe0ca
@@ -82,6 +90,7 @@
 #define PLA_TCR1   0xe612
 #define PLA_MTPS   0xe615
 #define PLA_TXFIFO_CTRL0xe618
+#define PLA_TXFIFO_FULL0xe61a
 #define PLA_RSTTALLY   0xe800
 #define PLA_CR 0xe813
 #define PLA_CRWECR 0xe81c
@@ -98,6 +107,7 @@
 #define PLA_SFF_STS_7  0xe8de
 #define PLA_PHYSTATUS  0xe908
 #define PLA_CONFIG60xe90a /* CONFIG6 */
+#define PLA_USB_CFG0xe952
 #define PLA_BP_BA  0xfc26
 #define PLA_BP_0   0xfc28
 #define PLA_BP_1   0xfc2a
@@ -112,6 +122,7 @@
 #define USB_USB2PHY0xb41e
 #define USB_SSPHYLINK1 0xb426
 #define USB_SSPHYLINK2 0xb428
+#define USB_L1_CTRL0xb45e
 #define USB_U2P3_CTRL  0xb460
 #define USB_CSR_DUMMY1 0xb464
 #define USB_CSR_DUMMY2 0xb466
@@ -122,7 +133,12 @@
 #define USB_FW_FIX_EN0 0xcfca
 #define USB_FW_FIX_EN1 0xcfcc
 #define USB_LPM_CONFIG 0xcfd8
+#define USB_ECM_OPTION 0xcfee
 #define USB_CSTMR  0xcfef  /* RTL8153A */
+#define USB_MISC_2 0xcfff
+#define USB_ECM_OP 0xd26b
+#define USB_GPHY_CTRL  0xd284
+#define USB_SPEED_OPTION   0xd32a
 #define USB_FW_CTRL0xd334  /* RTL8153B */
 #define USB_FC_TIMER   0xd340
 #define USB_USB_CTRL   0xd406
@@ -136,16 +152,20 @@
 #define USB_RX_EXTRA_AGGR_TMR  0xd432  /* RTL8153B */
 #define USB_TX_DMA 0xd434
 #define USB_UPT_RXDMA_OWN  0xd437
+#define USB_UPHY3_MDCMDIO  0xd480
 #define USB_TOLERANCE  0xd490
 #define USB_LPM_CTRL   0xd41a
 #define USB_BMU_RESET  0xd4b0
+#define USB_BMU_CONFIG 0xd4b4
 #define USB_U1U2_TIMER 0xd4da
 #define USB_FW_TASK0xd4e8  /* RTL8153B */
+#define USB_RX_AGGR_NUM0xd4ee
 #define USB_UPS_CTRL   0xd800
 #define USB_POWER_CUT  0xd80a
 #define USB_MISC_0 0xd81a
 #define USB_MISC_1 0xd81f
 #define USB_AFE_CTRL2  0xd824
+#define USB_UPHY_XTAL  0xd826
 #define USB_UPS_CFG0xd842
 #define USB_UPS_FLAGS  0xd848
 #define USB_WDT1_CTRL  0xe404
@@ -188,6 +208,9 @@
 #define OCP_EEE_ABLE   0xa5c4
 #define OCP_EEE_ADV0xa5d0
 #define OCP_EEE_LPABLE 0xa5d2
+#define OCP_10GBT_CTRL 0xa5d4
+#define OCP_10GBT_STAT 0xa5d6
+#define OCP_EEE_ADV2   0xa6d4
 #define OCP_PHY_STATE  0xa708  /* nway state for 8153 */
 #define OCP_PHY_PATCH_STAT 0xb800
 #define OCP_PHY_PATCH_CMD  0xb820
@@ -199,6 +222,7 @@
 /* SRAM Register */
 #define SRAM_GREEN_CFG 0x8011
 #define SRAM_LPF_CFG   0x8012
+#define SRAM_GPHY_FW_VER   0x801e
 #define SRAM_10M_AMP1  0x8080
 #define SRAM_10M_AMP2  0x8082
 #define SRAM_IMPEDANCE 0x8084
@@ -210,11 +234,19 @@
 #define RCR_AM 0x0004
 #define RCR_AB 0x0008
 #define RCR_ACPT_ALL   (RCR_AAP | RCR_APM | RCR_AM | RCR_AB)
+#define SLOT_ENBIT(11)
+
+/* PLA_RCR1 */
+#define OUTER_VLAN BIT(7)
+#define INNER_VLAN BIT(6

[PATCH net-next 5/6] r8152: support PHY firmware for RTL8156 series

2021-04-16 Thread Hayes Wang
Support new firmware type and method for RTL8156 series.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 563 +++-
 1 file changed, 561 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 72b8ef0ad5a1..34c1ee61af01 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -974,8 +974,60 @@ enum rtl8152_fw_flags {
FW_FLAGS_START,
FW_FLAGS_STOP,
FW_FLAGS_NC,
+   FW_FLAGS_NC1,
+   FW_FLAGS_NC2,
+   FW_FLAGS_UC2,
+   FW_FLAGS_UC,
+   FW_FLAGS_SPEED_UP,
+   FW_FLAGS_VER,
 };
 
+enum rtl8152_fw_fixup_cmd {
+   FW_FIXUP_AND = 0,
+   FW_FIXUP_OR,
+   FW_FIXUP_NOT,
+   FW_FIXUP_XOR,
+};
+
+struct fw_phy_set {
+   __le16 addr;
+   __le16 data;
+} __packed;
+
+struct fw_phy_speed_up {
+   struct fw_block blk_hdr;
+   __le16 fw_offset;
+   __le16 version;
+   __le16 fw_reg;
+   __le16 reserved;
+   char info[];
+} __packed;
+
+struct fw_phy_ver {
+   struct fw_block blk_hdr;
+   struct fw_phy_set ver;
+   __le32 reserved;
+} __packed;
+
+struct fw_phy_fixup {
+   struct fw_block blk_hdr;
+   struct fw_phy_set setting;
+   __le16 bit_cmd;
+   __le16 reserved;
+} __packed;
+
+struct fw_phy_union {
+   struct fw_block blk_hdr;
+   __le16 fw_offset;
+   __le16 fw_reg;
+   struct fw_phy_set pre_set[2];
+   struct fw_phy_set bp[8];
+   struct fw_phy_set bp_en;
+   u8 pre_num;
+   u8 bp_num;
+   char info[];
+} __packed;
+
 /**
  * struct fw_mac - a firmware block used by RTL_FW_PLA and RTL_FW_USB.
  * The layout of the firmware block is:
@@ -1080,6 +1132,15 @@ enum rtl_fw_type {
RTL_FW_PHY_START,
RTL_FW_PHY_STOP,
RTL_FW_PHY_NC,
+   RTL_FW_PHY_FIXUP,
+   RTL_FW_PHY_UNION_NC,
+   RTL_FW_PHY_UNION_NC1,
+   RTL_FW_PHY_UNION_NC2,
+   RTL_FW_PHY_UNION_UC2,
+   RTL_FW_PHY_UNION_UC,
+   RTL_FW_PHY_UNION_MISC,
+   RTL_FW_PHY_SPEED_UP,
+   RTL_FW_PHY_VER,
 };
 
 enum rtl_version {
@@ -3999,6 +4060,162 @@ static int rtl_post_ram_code(struct r8152 *tp, u16 
key_addr, bool wait)
return 0;
 }
 
+static bool rtl8152_is_fw_phy_speed_up_ok(struct r8152 *tp, struct 
fw_phy_speed_up *phy)
+{
+   u16 fw_offset;
+   u32 length;
+   bool rc = false;
+
+   switch (tp->version) {
+   case RTL_VER_01:
+   case RTL_VER_02:
+   case RTL_VER_03:
+   case RTL_VER_04:
+   case RTL_VER_05:
+   case RTL_VER_06:
+   case RTL_VER_07:
+   case RTL_VER_08:
+   case RTL_VER_09:
+   case RTL_VER_10:
+   case RTL_VER_11:
+   case RTL_VER_12:
+   case RTL_VER_14:
+   goto out;
+   case RTL_VER_13:
+   case RTL_VER_15:
+   default:
+   break;
+   }
+
+   fw_offset = __le16_to_cpu(phy->fw_offset);
+   length = __le32_to_cpu(phy->blk_hdr.length);
+   if (fw_offset < sizeof(*phy) || length <= fw_offset) {
+   dev_err(&tp->intf->dev, "invalid fw_offset\n");
+   goto out;
+   }
+
+   length -= fw_offset;
+   if (length & 3) {
+   dev_err(&tp->intf->dev, "invalid block length\n");
+   goto out;
+   }
+
+   if (__le16_to_cpu(phy->fw_reg) != 0x9A00) {
+   dev_err(&tp->intf->dev, "invalid register to load firmware\n");
+   goto out;
+   }
+
+   rc = true;
+out:
+   return rc;
+}
+
+static bool rtl8152_is_fw_phy_ver_ok(struct r8152 *tp, struct fw_phy_ver *ver)
+{
+   bool rc = false;
+
+   switch (tp->version) {
+   case RTL_VER_10:
+   case RTL_VER_11:
+   case RTL_VER_12:
+   case RTL_VER_13:
+   case RTL_VER_15:
+   break;
+   default:
+   goto out;
+   }
+
+   if (__le32_to_cpu(ver->blk_hdr.length) != sizeof(*ver)) {
+   dev_err(&tp->intf->dev, "invalid block length\n");
+   goto out;
+   }
+
+   if (__le16_to_cpu(ver->ver.addr) != SRAM_GPHY_FW_VER) {
+   dev_err(&tp->intf->dev, "invalid phy ver addr\n");
+   goto out;
+   }
+
+   rc = true;
+out:
+   return rc;
+}
+
+static bool rtl8152_is_fw_phy_fixup_ok(struct r8152 *tp, struct fw_phy_fixup 
*fix)
+{
+   bool rc = false;
+
+   switch (tp->version) {
+   case RTL_VER_10:
+   case RTL_VER_11:
+   case RTL_VER_12:
+   case RTL_VER_13:
+   case RTL_VER_15:
+   break;
+   default:
+   goto out;
+   }
+
+   if (__le32_to_cpu(fix->blk_hdr.length) != sizeof(*fix)) {
+   dev_err(&tp->intf->dev, "invalid block length\n");
+   goto out;
+   }
+
+   if (__le16_to_cpu(fix->setting.addr) != OCP_PHY

[PATCH net-next 2/6] r8152: adjust rtl8152_check_firmware function

2021-04-16 Thread Hayes Wang
Use bits operations to record and check the firmware.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 51 +++--
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 10db48f4ed77..28c9b4dc1a60 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -874,6 +874,14 @@ struct fw_header {
struct fw_block blocks[];
 } __packed;
 
+enum rtl8152_fw_flags {
+   FW_FLAGS_USB = 0,
+   FW_FLAGS_PLA,
+   FW_FLAGS_START,
+   FW_FLAGS_STOP,
+   FW_FLAGS_NC,
+};
+
 /**
  * struct fw_mac - a firmware block used by RTL_FW_PLA and RTL_FW_USB.
  * The layout of the firmware block is:
@@ -3800,10 +3808,7 @@ static long rtl8152_check_firmware(struct r8152 *tp, 
struct rtl_fw *rtl_fw)
 {
const struct firmware *fw = rtl_fw->fw;
struct fw_header *fw_hdr = (struct fw_header *)fw->data;
-   struct fw_mac *pla = NULL, *usb = NULL;
-   struct fw_phy_patch_key *start = NULL;
-   struct fw_phy_nc *phy_nc = NULL;
-   struct fw_block *stop = NULL;
+   unsigned long fw_flags = 0;
long ret = -EFAULT;
int i;
 
@@ -3832,50 +3837,52 @@ static long rtl8152_check_firmware(struct r8152 *tp, 
struct rtl_fw *rtl_fw)
goto fail;
goto fw_end;
case RTL_FW_PLA:
-   if (pla) {
+   if (test_bit(FW_FLAGS_PLA, &fw_flags)) {
dev_err(&tp->intf->dev,
"multiple PLA firmware encountered");
goto fail;
}
 
-   pla = (struct fw_mac *)block;
-   if (!rtl8152_is_fw_mac_ok(tp, pla)) {
+   if (!rtl8152_is_fw_mac_ok(tp, (struct fw_mac *)block)) {
dev_err(&tp->intf->dev,
"check PLA firmware failed\n");
goto fail;
}
+   __set_bit(FW_FLAGS_PLA, &fw_flags);
break;
case RTL_FW_USB:
-   if (usb) {
+   if (test_bit(FW_FLAGS_USB, &fw_flags)) {
dev_err(&tp->intf->dev,
"multiple USB firmware encountered");
goto fail;
}
 
-   usb = (struct fw_mac *)block;
-   if (!rtl8152_is_fw_mac_ok(tp, usb)) {
+   if (!rtl8152_is_fw_mac_ok(tp, (struct fw_mac *)block)) {
dev_err(&tp->intf->dev,
"check USB firmware failed\n");
goto fail;
}
+   __set_bit(FW_FLAGS_USB, &fw_flags);
break;
case RTL_FW_PHY_START:
-   if (start || phy_nc || stop) {
+   if (test_bit(FW_FLAGS_START, &fw_flags) ||
+   test_bit(FW_FLAGS_NC, &fw_flags) ||
+   test_bit(FW_FLAGS_STOP, &fw_flags)) {
dev_err(&tp->intf->dev,
"check PHY_START fail\n");
goto fail;
}
 
-   if (__le32_to_cpu(block->length) != sizeof(*start)) {
+   if (__le32_to_cpu(block->length) != sizeof(struct 
fw_phy_patch_key)) {
dev_err(&tp->intf->dev,
"Invalid length for PHY_START\n");
goto fail;
}
-
-   start = (struct fw_phy_patch_key *)block;
+   __set_bit(FW_FLAGS_START, &fw_flags);
break;
case RTL_FW_PHY_STOP:
-   if (stop || !start) {
+   if (test_bit(FW_FLAGS_STOP, &fw_flags) ||
+   !test_bit(FW_FLAGS_START, &fw_flags)) {
dev_err(&tp->intf->dev,
"Check PHY_STOP fail\n");
goto fail;
@@ -3886,28 +3893,28 @@ static long rtl8152_check_firmware(struct r8152 *tp, 
struct rtl_fw *rtl_fw)
"Invalid length for PHY_STOP\n");
goto fail;
}
-
-   stop = block;
+   __set_bit(FW_FLAGS_STOP, &fw_flags);
   

[PATCH net-next 6/6] r8152: search the configuration of vendor mode

2021-04-16 Thread Hayes Wang
The vendor mode is not always at config #1, so it is necessary to
set the correct configuration number.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 39 +++
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 34c1ee61af01..9119a860e9bd 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -29,7 +29,7 @@
 #include 
 
 /* Information for net-next */
-#define NETNEXT_VERSION"11"
+#define NETNEXT_VERSION"12"
 
 /* Information for net */
 #define NET_VERSION"11"
@@ -8107,6 +8107,39 @@ static void r8156b_init(struct r8152 *tp)
tp->coalesce = 15000;   /* 15 us */
 }
 
+static bool rtl_vendor_mode(struct usb_interface *intf)
+{
+   struct usb_host_interface *alt = intf->cur_altsetting;
+   struct usb_device *udev;
+   struct usb_host_config *c;
+   int i, num_configs;
+
+   if (alt->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC)
+   return true;
+
+   /* The vendor mode is not always config #1, so to find it out. */
+   udev = interface_to_usbdev(intf);
+   c = udev->config;
+   num_configs = udev->descriptor.bNumConfigurations;
+   for (i = 0; i < num_configs; (i++, c++)) {
+   struct usb_interface_descriptor *desc = NULL;
+
+   if (c->desc.bNumInterfaces > 0)
+   desc = &c->intf_cache[0]->altsetting->desc;
+   else
+   continue;
+
+   if (desc->bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
+   usb_driver_set_configuration(udev, 
c->desc.bConfigurationValue);
+   break;
+   }
+   }
+
+   WARN_ON_ONCE(i == num_configs);
+
+   return false;
+}
+
 static int rtl8152_pre_reset(struct usb_interface *intf)
 {
struct r8152 *tp = usb_get_intfdata(intf);
@@ -9345,10 +9378,8 @@ 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);
+   if (!rtl_vendor_mode(intf))
return -ENODEV;
-   }
 
if (intf->cur_altsetting->desc.bNumEndpoints < 3)
return -ENODEV;
-- 
2.26.3



[PATCH net-next 1/6] r8152: set inter fram gap time depending on speed

2021-04-16 Thread Hayes Wang
Set the maximum inter frame gap time (144ns) for speed 10M/half and
100M/half. It improves the performance for those speeds. And, there
is no effect for the other speeds.

For 10M/half and 100M/half, the fast inter frame gap time let the
device couldn't use the feature of the aggregation effectively,
because the transfer would be completed fastly. Therefore, use the
maximum value to improve the effect of the aggregation. However, you
may not feel the improvement for fast CPUs, because they compensate
for the effect of the aggregation.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 28 
 1 file changed, 28 insertions(+)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 20fb5638ac65..10db48f4ed77 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -249,6 +249,9 @@
 
 /* PLA_TCR1 */
 #define VERSION_MASK   0x7cf0
+#define IFG_MASK   (BIT(3) | BIT(9) | BIT(8))
+#define IFG_144NS  BIT(9)
+#define IFG_96NS   (BIT(9) | BIT(8))
 
 /* PLA_MTPS */
 #define MTPS_JUMBO (12 * 1024 / 64)
@@ -2747,6 +2750,29 @@ static int rtl_stop_rx(struct r8152 *tp)
return 0;
 }
 
+static void rtl_set_ifg(struct r8152 *tp, u16 speed)
+{
+   u32 ocp_data;
+
+   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR1);
+   ocp_data &= ~IFG_MASK;
+   if ((speed & (_10bps | _100bps)) && !(speed & FULL_DUP)) {
+   ocp_data |= IFG_144NS;
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data);
+
+   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4);
+   ocp_data &= ~TX10MIDLE_EN;
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data);
+   } else {
+   ocp_data |= IFG_96NS;
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_TCR1, ocp_data);
+
+   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4);
+   ocp_data |= TX10MIDLE_EN;
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, ocp_data);
+   }
+}
+
 static inline void r8153b_rx_agg_chg_indicate(struct r8152 *tp)
 {
ocp_write_byte(tp, MCU_TYPE_USB, USB_UPT_RXDMA_OWN,
@@ -2850,6 +2876,8 @@ static int rtl8153_enable(struct r8152 *tp)
r8153_set_rx_early_timeout(tp);
r8153_set_rx_early_size(tp);
 
+   rtl_set_ifg(tp, rtl8152_get_speed(tp));
+
if (tp->version == RTL_VER_09) {
u32 ocp_data;
 
-- 
2.26.3



[PATCH net-next 3/6] r8152: add help function to change mtu

2021-04-16 Thread Hayes Wang
The different chips may have different requests when changing mtu.
Therefore, add a new help function of rtl_ops to change mtu. Besides,
reset the tx/rx after changing mtu.

Additionally, add mtu_to_size() and size_to_mtu() macros to simplify
the code.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 53 -
 1 file changed, 31 insertions(+), 22 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 28c9b4dc1a60..3f465242a4f0 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -657,15 +657,13 @@ enum rtl_register_content {
 
 #define INTR_LINK  0x0004
 
-#define RTL8153_MAX_PACKET 9216 /* 9K */
-#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 + ETH_FCS_LEN + \
-sizeof(struct rx_desc) + RX_ALIGN)
+#define mtu_to_size(m) ((m) + VLAN_ETH_HLEN + ETH_FCS_LEN)
+#define size_to_mtu(s) ((s) - VLAN_ETH_HLEN - ETH_FCS_LEN)
+#define rx_reserved_size(x)(mtu_to_size(x) + sizeof(struct rx_desc) + 
RX_ALIGN)
 
 /* rtl8152 flags */
 enum rtl8152_flags {
@@ -795,6 +793,7 @@ struct r8152 {
bool (*in_nway)(struct r8152 *tp);
void (*hw_phy_cfg)(struct r8152 *tp);
void (*autosuspend_en)(struct r8152 *tp, bool enable);
+   void (*change_mtu)(struct r8152 *tp);
} rtl_ops;
 
struct ups_info {
@@ -1021,8 +1020,7 @@ enum tx_csum_stat {
 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 - ETH_FCS_LEN)
+#define RTL_LIMITED_TSO_SIZE   (size_to_mtu(agg_buf_sz) - sizeof(struct 
tx_desc))
 
 static
 int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
@@ -2632,10 +2630,7 @@ static void rtl8152_nic_reset(struct r8152 *tp)
 
 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 + ETH_FCS_LEN +
-   sizeof(struct tx_desc));
+   tp->tx_qlen = agg_buf_sz / (mtu_to_size(tp->netdev->mtu) + 
sizeof(struct tx_desc));
 }
 
 static inline u8 rtl8152_get_speed(struct r8152 *tp)
@@ -4724,6 +4719,12 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp)
set_bit(PHY_RESET, &tp->flags);
 }
 
+static void rtl8153_change_mtu(struct r8152 *tp)
+{
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu));
+   ocp_write_byte(tp, MCU_TYPE_PLA, PLA_MTPS, MTPS_JUMBO);
+}
+
 static void r8153_first_init(struct r8152 *tp)
 {
u32 ocp_data;
@@ -4756,9 +4757,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 + 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);
+   rtl8153_change_mtu(tp);
 
ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TCR0);
ocp_data |= TCR0_AUTO_FIFO;
@@ -4793,8 +4792,7 @@ static void r8153_enter_oob(struct r8152 *tp)
 
wait_oob_link_list_ready(tp);
 
-   ocp_data = tp->netdev->mtu + VLAN_ETH_HLEN + ETH_FCS_LEN;
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, ocp_data);
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, mtu_to_size(tp->netdev->mtu));
 
switch (tp->version) {
case RTL_VER_03:
@@ -6494,12 +6492,21 @@ 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 + ETH_FCS_LEN;
-
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, rms);
+   if (tp->rtl_ops.change_mtu)
+   tp->rtl_ops.change_mtu(tp);
 
-   if (netif_carrier_ok(dev))
-   r8153_set_rx_early_size(tp);
+   if (netif_carrier_ok(dev)) {
+   netif_stop_queue(dev);
+   napi_disable(&tp->napi);
+   tasklet_disable(&tp->tx_tl);
+   tp->rtl_ops.disable(tp);
+   tp->rtl_ops.enable(tp);
+   rtl_start_rx(tp);
+   tasklet_enable(&tp->tx_tl);
+   napi_enable(&tp->napi);
+   rtl8152_set_rx_mode(dev);
+   netif_wake_q

[PATCH net-next 0/6] r8152: support new chips

2021-04-16 Thread Hayes Wang
Support new RTL8153 and RTL8156 series.

Hayes Wang (6):
  r8152: set inter fram gap time depending on speed
  r8152: adjust rtl8152_check_firmware function
  r8152: add help function to change mtu
  r8152: support new chips
  r8152: support PHY firmware for RTL8156 series
  r8152: search the configuration of vendor mode

 drivers/net/usb/r8152.c | 3180 ---
 1 file changed, 2949 insertions(+), 231 deletions(-)

-- 
2.26.3



[PATCH net] r8152: limit the RX buffer size of RTL8153A for USB 2.0

2021-03-19 Thread Hayes Wang
If the USB host controller is EHCI, the throughput is reduced from
300Mb/s to 60Mb/s, when the rx buffer size is modified from 16K to
32K.

According to the EHCI spec, the maximum size of the qTD is 20K.
Therefore, when the driver uses more than 20K buffer, the latency
time of EHCI would be increased. And, it let the RTL8153A get worse
throughput.

However, the driver uses alloc_pages() for rx buffer, so I limit
the rx buffer to 16K rather than 20K.

BugLink: https://bugzilla.kernel.org/show_bug.cgi?id=205923
Fixes: ec5791c202ac ("r8152: separate the rx buffer size")
Reported-by: Robert Davies 
Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 90f1c0200042..20fb5638ac65 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -6553,7 +6553,10 @@ static int rtl_ops_init(struct r8152 *tp)
ops->in_nway= rtl8153_in_nway;
ops->hw_phy_cfg = r8153_hw_phy_cfg;
ops->autosuspend_en = rtl8153_runtime_enable;
-   tp->rx_buf_sz   = 32 * 1024;
+   if (tp->udev->speed < USB_SPEED_SUPER)
+   tp->rx_buf_sz   = 16 * 1024;
+   else
+   tp->rx_buf_sz   = 32 * 1024;
tp->eee_en  = true;
tp->eee_adv = MDIO_EEE_1000T | MDIO_EEE_100TX;
break;
-- 
2.26.2



[PATCH net] r8169: fix r8168fp_adjust_ocp_cmd function

2021-03-05 Thread Hayes Wang
The (0xBAF7 & 0x00FFF000) << 6 should be (0xf70 << 18).

Fixes: 561535b0f239 ("r8169: fix OCP access on RTL8117")
Signed-off-by: Hayes Wang 
---
 drivers/net/ethernet/realtek/r8169_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/realtek/r8169_main.c 
b/drivers/net/ethernet/realtek/r8169_main.c
index f704da3f214c..7aad0ba53372 100644
--- a/drivers/net/ethernet/realtek/r8169_main.c
+++ b/drivers/net/ethernet/realtek/r8169_main.c
@@ -767,7 +767,7 @@ static void r8168fp_adjust_ocp_cmd(struct rtl8169_private 
*tp, u32 *cmd, int typ
if (type == ERIAR_OOB &&
(tp->mac_version == RTL_GIGA_MAC_VER_52 ||
 tp->mac_version == RTL_GIGA_MAC_VER_53))
-   *cmd |= 0x7f0 << 18;
+   *cmd |= 0xf70 << 18;
 }
 
 DECLARE_RTL_COND(rtl_eriar_cond)
-- 
2.26.2



[PATCH net] Revert "r8152: adjust the settings about MAC clock speed down for RTL8153"

2021-03-03 Thread Hayes Wang
This reverts commit 134f98bcf1b898fb9d6f2b91bc85dd2e5478b4b8.

The r8153_mac_clk_spd() is used for RTL8153A only, because the register
table of RTL8153B is different from RTL8153A. However, this function would
be called when RTL8153B calls r8153_first_init() and r8153_enter_oob().
That causes RTL8153B becomes unstable when suspending and resuming. The
worst case may let the device stop working.

Besides, revert this commit to disable MAC clock speed down for RTL8153A.
It would avoid the known issue when enabling U1. The data of the first
control transfer may be wrong when exiting U1.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 35 ++-
 1 file changed, 6 insertions(+), 29 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b246817f3405..90f1c0200042 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3021,29 +3021,6 @@ static void __rtl_set_wol(struct r8152 *tp, u32 wolopts)
device_set_wakeup_enable(&tp->udev->dev, false);
 }
 
-static void r8153_mac_clk_spd(struct r8152 *tp, bool enable)
-{
-   /* MAC clock speed down */
-   if (enable) {
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL,
-  ALDPS_SPDWN_RATIO);
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2,
-  EEE_SPDWN_RATIO);
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3,
-  PKT_AVAIL_SPDWN_EN | SUSPEND_SPDWN_EN |
-  U1U2_SPDWN_EN | L1_SPDWN_EN);
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4,
-  PWRSAVE_SPDWN_EN | RXDV_SPDWN_EN | TX10MIDLE_EN |
-  TP100_SPDWN_EN | TP500_SPDWN_EN | EEE_SPDWN_EN |
-  TP1000_SPDWN_EN);
-   } else {
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0);
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, 0);
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL3, 0);
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL4, 0);
-   }
-}
-
 static void r8153_u1u2en(struct r8152 *tp, bool enable)
 {
u8 u1u2[8];
@@ -3338,11 +3315,9 @@ static void rtl8153_runtime_enable(struct r8152 *tp, 
bool enable)
if (enable) {
r8153_u1u2en(tp, false);
r8153_u2p3en(tp, false);
-   r8153_mac_clk_spd(tp, true);
rtl_runtime_suspend_enable(tp, true);
} else {
rtl_runtime_suspend_enable(tp, false);
-   r8153_mac_clk_spd(tp, false);
 
switch (tp->version) {
case RTL_VER_03:
@@ -4718,7 +4693,6 @@ static void r8153_first_init(struct r8152 *tp)
 {
u32 ocp_data;
 
-   r8153_mac_clk_spd(tp, false);
rxdy_gated_en(tp, true);
r8153_teredo_off(tp);
 
@@ -4769,8 +4743,6 @@ static void r8153_enter_oob(struct r8152 *tp)
 {
u32 ocp_data;
 
-   r8153_mac_clk_spd(tp, true);
-
ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
ocp_data &= ~NOW_IS_OOB;
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
@@ -5496,10 +5468,15 @@ static void r8153_init(struct r8152 *tp)
 
ocp_write_word(tp, MCU_TYPE_USB, USB_CONNECT_TIMER, 0x0001);
 
+   /* MAC clock speed down */
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL, 0);
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_MAC_PWR_CTRL2, 0);
+   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_power_cut_en(tp, false);
rtl_runtime_suspend_enable(tp, false);
r8153_u1u2en(tp, true);
-   r8153_mac_clk_spd(tp, false);
usb_enable_lpm(tp->udev);
 
ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6);
-- 
2.26.2



RE: [PATCH net] r8152: move r8153_mac_clk_spd

2021-02-21 Thread Hayes Wang
Jakub Kicinski 
> Sent: Saturday, February 20, 2021 2:23 AM
[...] 
> Any word on what user-visible misbehavior this causes?
I think it influences the power saving for suspending.
I am checking it with our engineers.

> Can you provide a Fixes tag?
Yes. I will add it when I updating this patch.

Best Regards,
Hayes



[PATCH net] r8152: move r8153_mac_clk_spd

2021-02-19 Thread Hayes Wang
Move calling r8153_mac_clk_spd() from r8153_first_init() to rtl8153_up(),
and from r8153_enter_oob() to rtl8153_down().

r8153_mac_clk_spd() is used for RTL8153A. However, RTL8153B use
r8153_first_init() and r8153_enter_oob(), too. Therefore,
r8153_mac_clk_spd() needs to be moved.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 67cd6986634f..ec29878db566 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -4678,7 +4678,6 @@ static void r8153_first_init(struct r8152 *tp)
 {
u32 ocp_data;
 
-   r8153_mac_clk_spd(tp, false);
rxdy_gated_en(tp, true);
r8153_teredo_off(tp);
 
@@ -4729,8 +4728,6 @@ static void r8153_enter_oob(struct r8152 *tp)
 {
u32 ocp_data;
 
-   r8153_mac_clk_spd(tp, true);
-
ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
ocp_data &= ~NOW_IS_OOB;
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
@@ -4956,6 +4953,7 @@ static void rtl8153_up(struct r8152 *tp)
r8153_u1u2en(tp, false);
r8153_u2p3en(tp, false);
r8153_aldps_en(tp, false);
+   r8153_mac_clk_spd(tp, false);
r8153_first_init(tp);
 
ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG6);
@@ -5003,6 +5001,7 @@ static void rtl8153_down(struct r8152 *tp)
r8153_u2p3en(tp, false);
r8153_power_cut_en(tp, false);
r8153_aldps_en(tp, false);
+   r8153_mac_clk_spd(tp, true);
r8153_enter_oob(tp);
r8153_aldps_en(tp, true);
 }
-- 
2.26.2



[PATCH net-next 0/4] r8152: minor adjustments

2021-02-19 Thread Hayes Wang
These patches are used to adjust the code.

Hayes Wang (4):
  r8152: enable U1/U2 for USB_SPEED_SUPER
  r8152: check if the pointer of the function exists
  r8152: replace netif_err with dev_err
  r8152: spilt rtl_set_eee_plus and r8153b_green_en

 drivers/net/usb/r8152.c | 67 -
 1 file changed, 46 insertions(+), 21 deletions(-)

-- 
2.26.2



[PATCH net-next 4/4] r8152: spilt rtl_set_eee_plus and r8153b_green_en

2021-02-19 Thread Hayes Wang
Add rtl_eee_plus_en() and rtl_green_en().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 43 ++---
 1 file changed, 27 insertions(+), 16 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 82a129264e31..b246817f3405 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -2632,21 +2632,24 @@ static inline u8 rtl8152_get_speed(struct r8152 *tp)
return ocp_read_byte(tp, MCU_TYPE_PLA, PLA_PHYSTATUS);
 }
 
-static void rtl_set_eee_plus(struct r8152 *tp)
+static void rtl_eee_plus_en(struct r8152 *tp, bool enable)
 {
u32 ocp_data;
-   u8 speed;
 
-   speed = rtl8152_get_speed(tp);
-   if (speed & _10bps) {
-   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR);
+   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR);
+   if (enable)
ocp_data |= EEEP_CR_EEEP_TX;
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data);
-   } else {
-   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR);
+   else
ocp_data &= ~EEEP_CR_EEEP_TX;
-   ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data);
-   }
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_EEEP_CR, ocp_data);
+}
+
+static void rtl_set_eee_plus(struct r8152 *tp)
+{
+   if (rtl8152_get_speed(tp) & _10bps)
+   rtl_eee_plus_en(tp, true);
+   else
+   rtl_eee_plus_en(tp, false);
 }
 
 static void rxdy_gated_en(struct r8152 *tp, bool enable)
@@ -3150,10 +3153,22 @@ static void r8153b_ups_flags(struct r8152 *tp)
ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags);
 }
 
-static void r8153b_green_en(struct r8152 *tp, bool enable)
+static void rtl_green_en(struct r8152 *tp, bool enable)
 {
u16 data;
 
+   data = sram_read(tp, SRAM_GREEN_CFG);
+   if (enable)
+   data |= GREEN_ETH_EN;
+   else
+   data &= ~GREEN_ETH_EN;
+   sram_write(tp, SRAM_GREEN_CFG, data);
+
+   tp->ups_info.green = enable;
+}
+
+static void r8153b_green_en(struct r8152 *tp, bool enable)
+{
if (enable) {
sram_write(tp, 0x8045, 0);  /* 10M abiq&ldvbias */
sram_write(tp, 0x804d, 0x1222); /* 100M short abiq&ldvbias */
@@ -3164,11 +3179,7 @@ static void r8153b_green_en(struct r8152 *tp, bool 
enable)
sram_write(tp, 0x805d, 0x2444); /* 1000M short abiq&ldvbias */
}
 
-   data = sram_read(tp, SRAM_GREEN_CFG);
-   data |= GREEN_ETH_EN;
-   sram_write(tp, SRAM_GREEN_CFG, data);
-
-   tp->ups_info.green = enable;
+   rtl_green_en(tp, true);
 }
 
 static u16 r8153_phy_status(struct r8152 *tp, u16 desired)
-- 
2.26.2



[PATCH net-next 3/4] r8152: replace netif_err with dev_err

2021-02-19 Thread Hayes Wang
Some messages are before calling register_netdev(), so replace
netif_err() with dev_err().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index baa63ea2590a..82a129264e31 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -6590,7 +6590,7 @@ static int rtl_ops_init(struct r8152 *tp)
 
default:
ret = -ENODEV;
-   netif_err(tp, probe, tp->netdev, "Unknown Device\n");
+   dev_err(&tp->intf->dev, "Unknown Device\n");
break;
}
 
@@ -6847,7 +6847,7 @@ static int rtl8152_probe(struct usb_interface *intf,
 
ret = register_netdev(netdev);
if (ret != 0) {
-   netif_err(tp, probe, netdev, "couldn't register the device\n");
+   dev_err(&intf->dev, "couldn't register the device\n");
goto out1;
}
 
-- 
2.26.2



[PATCH net-next 2/4] r8152: check if the pointer of the function exists

2021-02-19 Thread Hayes Wang
Return error code if autosuspend_en, eee_get, or eee_set don't exist.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 4bfee289aa6f..baa63ea2590a 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -5757,6 +5757,9 @@ static int rtl8152_runtime_suspend(struct r8152 *tp)
struct net_device *netdev = tp->netdev;
int ret = 0;
 
+   if (!tp->rtl_ops.autosuspend_en)
+   return -EBUSY;
+
set_bit(SELECTIVE_SUSPEND, &tp->flags);
smp_mb__after_atomic();
 
@@ -6156,6 +6159,11 @@ rtl_ethtool_get_eee(struct net_device *net, struct 
ethtool_eee *edata)
struct r8152 *tp = netdev_priv(net);
int ret;
 
+   if (!tp->rtl_ops.eee_get) {
+   ret = -EOPNOTSUPP;
+   goto out;
+   }
+
ret = usb_autopm_get_interface(tp->intf);
if (ret < 0)
goto out;
@@ -6178,6 +6186,11 @@ rtl_ethtool_set_eee(struct net_device *net, struct 
ethtool_eee *edata)
struct r8152 *tp = netdev_priv(net);
int ret;
 
+   if (!tp->rtl_ops.eee_set) {
+   ret = -EOPNOTSUPP;
+   goto out;
+   }
+
ret = usb_autopm_get_interface(tp->intf);
if (ret < 0)
goto out;
-- 
2.26.2



[PATCH net-next 1/4] r8152: enable U1/U2 for USB_SPEED_SUPER

2021-02-19 Thread Hayes Wang
U1/U2 shoued be enabled for USB 3.0 or later. The USB 2.0 doesn't
support it.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 2d7cc63bef89..4bfee289aa6f 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3360,7 +3360,7 @@ static void rtl8153b_runtime_enable(struct r8152 *tp, 
bool enable)
r8153b_ups_en(tp, false);
r8153_queue_wake(tp, false);
rtl_runtime_suspend_enable(tp, false);
-   if (tp->udev->speed != USB_SPEED_HIGH)
+   if (tp->udev->speed >= USB_SPEED_SUPER)
r8153b_u1u2en(tp, true);
}
 }
@@ -5056,7 +5056,7 @@ static void rtl8153b_up(struct r8152 *tp)
 
r8153_aldps_en(tp, true);
 
-   if (tp->udev->speed != USB_SPEED_HIGH)
+   if (tp->udev->speed >= USB_SPEED_SUPER)
r8153b_u1u2en(tp, true);
 }
 
@@ -5572,8 +5572,9 @@ static void r8153b_init(struct r8152 *tp)
ocp_data |= POLL_LINK_CHG;
ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data);
 
-   if (tp->udev->speed != USB_SPEED_HIGH)
+   if (tp->udev->speed >= USB_SPEED_SUPER)
r8153b_u1u2en(tp, true);
+
usb_enable_lpm(tp->udev);
 
/* MAC clock speed down */
-- 
2.26.2



[PATCH net-next 1/2] r8152: replace several functions about phy patch request

2021-02-03 Thread Hayes Wang
Replace r8153_patch_request() with rtl_phy_patch_request().
Replace r8153_pre_ram_code() with rtl_pre_ram_code().
Replace r8153_post_ram_code() with rtl_post_ram_code().
Add rtl_patch_key_set().

The new functions have an additional parameter. It is used to wait
the patch request command finished. When the PHY is resumed from
the state of power cut, the PHY is at a safe mode and the
OCP_PHY_PATCH_STAT wouldn't be updated. For this situation, it is
safe to set patch request command without waiting OCP_PHY_PATCH_STAT.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 84 -
 1 file changed, 50 insertions(+), 34 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 67cd6986634f..e792c1c69f14 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3470,59 +3470,76 @@ static void rtl_clear_bp(struct r8152 *tp, u16 type)
ocp_write_word(tp, type, PLA_BP_BA, 0);
 }
 
-static int r8153_patch_request(struct r8152 *tp, bool request)
+static int rtl_phy_patch_request(struct r8152 *tp, bool request, bool wait)
 {
-   u16 data;
+   u16 data, check;
int i;
 
data = ocp_reg_read(tp, OCP_PHY_PATCH_CMD);
-   if (request)
+   if (request) {
data |= PATCH_REQUEST;
-   else
+   check = 0;
+   } else {
data &= ~PATCH_REQUEST;
+   check = PATCH_READY;
+   }
ocp_reg_write(tp, OCP_PHY_PATCH_CMD, data);
 
-   for (i = 0; request && i < 5000; i++) {
+   for (i = 0; wait && i < 5000; i++) {
+   u32 ocp_data;
+
usleep_range(1000, 2000);
-   if (ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)
+   ocp_data = ocp_reg_read(tp, OCP_PHY_PATCH_STAT);
+   if ((ocp_data & PATCH_READY) ^ check)
break;
}
 
-   if (request && !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) {
-   netif_err(tp, drv, tp->netdev, "patch request fail\n");
-   r8153_patch_request(tp, false);
+   if (request && wait &&
+   !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) {
+   dev_err(&tp->intf->dev, "PHY patch request fail\n");
+   rtl_phy_patch_request(tp, false, false);
return -ETIME;
} else {
return 0;
}
 }
 
-static int r8153_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key)
+static void rtl_patch_key_set(struct r8152 *tp, u16 key_addr, u16 patch_key)
 {
-   if (r8153_patch_request(tp, true)) {
-   dev_err(&tp->intf->dev, "patch request fail\n");
-   return -ETIME;
-   }
+   if (patch_key && key_addr) {
+   sram_write(tp, key_addr, patch_key);
+   sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK);
+   } else if (key_addr) {
+   u16 data;
 
-   sram_write(tp, key_addr, patch_key);
-   sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK);
+   sram_write(tp, 0x, 0x);
 
-   return 0;
+   data = ocp_reg_read(tp, OCP_PHY_LOCK);
+   data &= ~PATCH_LOCK;
+   ocp_reg_write(tp, OCP_PHY_LOCK, data);
+
+   sram_write(tp, key_addr, 0x);
+   } else {
+   WARN_ON_ONCE(1);
+   }
 }
 
-static int r8153_post_ram_code(struct r8152 *tp, u16 key_addr)
+static int
+rtl_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key, bool wait)
 {
-   u16 data;
+   if (rtl_phy_patch_request(tp, true, wait))
+   return -ETIME;
 
-   sram_write(tp, 0x, 0x);
+   rtl_patch_key_set(tp, key_addr, patch_key);
 
-   data = ocp_reg_read(tp, OCP_PHY_LOCK);
-   data &= ~PATCH_LOCK;
-   ocp_reg_write(tp, OCP_PHY_LOCK, data);
+   return 0;
+}
 
-   sram_write(tp, key_addr, 0x);
+static int rtl_post_ram_code(struct r8152 *tp, u16 key_addr, bool wait)
+{
+   rtl_patch_key_set(tp, key_addr, 0);
 
-   r8153_patch_request(tp, false);
+   rtl_phy_patch_request(tp, false, wait);
 
ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base);
 
@@ -4007,7 +4024,7 @@ static void rtl8152_fw_mac_apply(struct r8152 *tp, struct 
fw_mac *mac)
dev_dbg(&tp->intf->dev, "successfully applied %s\n", mac->info);
 }
 
-static void rtl8152_apply_firmware(struct r8152 *tp)
+static void rtl8152_apply_firmware(struct r8152 *tp, bool power_cut)
 {
struct rtl_fw *rtl_fw = &tp->rtl_fw;
const struct firmware *fw;
@@ -4038,12 +4055,11 @@ static void rtl8152_apply_firmware(struct r8152 *tp)
case RTL_FW_PHY_START:
key = (struct fw_phy_patch_key *)block;
  

[PATCH net-next 2/2] r8152: adjust the flow of power cut for RTL8153B

2021-02-03 Thread Hayes Wang
For runtime resuming, the RTL8153B may be resumed from the state
of power cut, when enabling the feature of UPS. Then, the PHY
would be reset, so it is necessary to be initailized again.

Besides, the USB_U1U2_TIMER also has to be set again, so I move
it from r8153b_init() to r8153b_hw_phy_cfg().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 68 -
 1 file changed, 40 insertions(+), 28 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index e792c1c69f14..d0048ebc114a 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1371,6 +1371,10 @@ void write_mii_word(struct net_device *netdev, int 
phy_id, int reg, int val)
 static int
 r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags);
 
+static int
+rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 duplex,
+ u32 advertising);
+
 static int rtl8152_set_mac_address(struct net_device *netdev, void *p)
 {
struct r8152 *tp = netdev_priv(netdev);
@@ -3207,8 +3211,6 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable)
ocp_data |= BIT(0);
ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data);
} else {
-   u16 data;
-
ocp_data &= ~(UPS_EN | USP_PREWAKE);
ocp_write_byte(tp, MCU_TYPE_USB, USB_POWER_CUT, ocp_data);
 
@@ -3216,31 +3218,20 @@ static void r8153b_ups_en(struct r8152 *tp, bool enable)
ocp_data &= ~BIT(0);
ocp_write_byte(tp, MCU_TYPE_USB, 0xcfff, ocp_data);
 
-   ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0);
-   ocp_data &= ~PCUT_STATUS;
-   ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data);
-
-   data = r8153_phy_status(tp, 0);
-
-   switch (data) {
-   case PHY_STAT_PWRDN:
-   case PHY_STAT_EXT_INIT:
-   r8153b_green_en(tp,
-   test_bit(GREEN_ETHERNET, &tp->flags));
+   if (ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0) & PCUT_STATUS) {
+   int i;
 
-   data = r8152_mdio_read(tp, MII_BMCR);
-   data &= ~BMCR_PDOWN;
-   data |= BMCR_RESET;
-   r8152_mdio_write(tp, MII_BMCR, data);
+   for (i = 0; i < 500; i++) {
+   if (ocp_read_word(tp, MCU_TYPE_PLA, 
PLA_BOOT_CTRL) &
+   AUTOLOAD_DONE)
+   break;
+   msleep(20);
+   }
 
-   data = r8153_phy_status(tp, PHY_STAT_LAN_ON);
-   fallthrough;
+   tp->rtl_ops.hw_phy_cfg(tp);
 
-   default:
-   if (data != PHY_STAT_LAN_ON)
-   netif_warn(tp, link, tp->netdev,
-  "PHY not ready");
-   break;
+   rtl8152_set_speed(tp, tp->autoneg, tp->speed,
+ tp->duplex, tp->advertising);
}
}
 }
@@ -4614,13 +4605,37 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp)
u32 ocp_data;
u16 data;
 
+   ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_MISC_0);
+   if (ocp_data & PCUT_STATUS) {
+   ocp_data &= ~PCUT_STATUS;
+   ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data);
+   }
+
/* disable ALDPS before updating the PHY parameters */
r8153_aldps_en(tp, false);
 
/* disable EEE before updating the PHY parameters */
rtl_eee_enable(tp, false);
 
-   rtl8152_apply_firmware(tp, false);
+   /* U1/U2/L1 idle timer. 500 us */
+   ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500);
+
+   data = r8153_phy_status(tp, 0);
+
+   switch (data) {
+   case PHY_STAT_PWRDN:
+   case PHY_STAT_EXT_INIT:
+   rtl8152_apply_firmware(tp, true);
+
+   data = r8152_mdio_read(tp, MII_BMCR);
+   data &= ~BMCR_PDOWN;
+   r8152_mdio_write(tp, MII_BMCR, data);
+   break;
+   case PHY_STAT_LAN_ON:
+   default:
+   rtl8152_apply_firmware(tp, false);
+   break;
+   }
 
r8153b_green_en(tp, test_bit(GREEN_ETHERNET, &tp->flags));
 
@@ -5546,9 +5561,6 @@ static void r8153b_init(struct r8152 *tp)
/* MSC timer = 0xfff * 8ms = 32760 ms */
ocp_write_word(tp, MCU_TYPE_USB, USB_MSC_TIMER, 0x0fff);
 
-   /* U1/U2/L1 idle timer. 500 us */
-   ocp_write_word(tp, MCU_TYPE_USB, USB_U1U2_TIMER, 500);
-
r8153b_power_cut_en(tp, false);
r8153b_ups_en(tp, false);
r8153_queue_wake(tp, false);
-- 
2.26.2



[PATCH net-next 0/2] r8152: adjust flow for power cut

2021-02-03 Thread Hayes Wang
The two patches are used to adjust the flow about resuming from
the state of power cut. For the purpose, some functions have to
be updated first.

Hayes Wang (2):
  r8152: replace several functions about phy patch request
  r8152: adjust the flow of power cut for RTL8153B

 drivers/net/usb/r8152.c | 150 
 1 file changed, 89 insertions(+), 61 deletions(-)

-- 
2.26.2



RE: [PATCH net] net: usb: cdc_ncm: don't spew notifications

2021-01-19 Thread Hayes Wang
Grant Grundler 
> Sent: Wednesday, January 20, 2021 9:12 AM
> Subject: [PATCH net] net: usb: cdc_ncm: don't spew notifications
> 
> RTL8156 sends notifications about every 32ms.
> Only display/log notifications when something changes.
> 
> This issue has been reported by others:
>   https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1832472
>   https://lkml.org/lkml/2020/8/27/1083
> 
> ...
> [785962.779840] usb 1-1: new high-speed USB device number 5 using xhci_hcd
> [785962.929944] usb 1-1: New USB device found, idVendor=0bda,
> idProduct=8156, bcdDevice=30.00
> [785962.929949] usb 1-1: New USB device strings: Mfr=1, Product=2,
> SerialNumber=6
> [785962.929952] usb 1-1: Product: USB 10/100/1G/2.5G LAN
> [785962.929954] usb 1-1: Manufacturer: Realtek
> [785962.929956] usb 1-1: SerialNumber: 1
> [785962.991755] usbcore: registered new interface driver cdc_ether
> [785963.017068] cdc_ncm 1-1:2.0: MAC-Address: 00:24:27:88:08:15
> [785963.017072] cdc_ncm 1-1:2.0: setting rx_max = 16384
> [785963.017169] cdc_ncm 1-1:2.0: setting tx_max = 16384
> [785963.017682] cdc_ncm 1-1:2.0 usb0: register 'cdc_ncm' at
> usb-:00:14.0-1, CDC NCM, 00:24:27:88:08:15
> [785963.019211] usbcore: registered new interface driver cdc_ncm
> [785963.023856] usbcore: registered new interface driver cdc_wdm
> [785963.025461] usbcore: registered new interface driver cdc_mbim
> [785963.038824] cdc_ncm 1-1:2.0 enx002427880815: renamed from usb0
> [785963.089586] cdc_ncm 1-1:2.0 enx002427880815: network connection:
> disconnected
> [785963.121673] cdc_ncm 1-1:2.0 enx002427880815: network connection:
> disconnected
> [785963.153682] cdc_ncm 1-1:2.0 enx002427880815: network connection:
> disconnected
> ...
> 
> This is about 2KB per second and will overwrite all contents of a 1MB
> dmesg buffer in under 10 minutes rendering them useless for debugging
> many kernel problems.
> 
> This is also an extra 180 MB/day in /var/logs (or 1GB per week) rendering
> the majority of those logs useless too.
> 
> When the link is up (expected state), spew amount is >2x higher:
> ...
> [786139.600992] cdc_ncm 2-1:2.0 enx002427880815: network connection:
> connected
> [786139.632997] cdc_ncm 2-1:2.0 enx002427880815: 2500 mbit/s downlink
> 2500 mbit/s uplink
> [786139.665097] cdc_ncm 2-1:2.0 enx002427880815: network connection:
> connected
> [786139.697100] cdc_ncm 2-1:2.0 enx002427880815: 2500 mbit/s downlink
> 2500 mbit/s uplink
> [786139.729094] cdc_ncm 2-1:2.0 enx002427880815: network connection:
> connected
> [786139.761108] cdc_ncm 2-1:2.0 enx002427880815: 2500 mbit/s downlink
> 2500 mbit/s uplink
> ...
> 
> Chrome OS cannot support RTL8156 until this is fixed.
> 
> Signed-off-by: Grant Grundler 

Reviewed-by: Hayes Wang 

Best Regards,
Hayes



RE: [PATCH 3/3] net: usb: cdc_ncm: don't spew notifications

2021-01-18 Thread Hayes Wang
Grant Grundler 
> Sent: Tuesday, January 19, 2021 6:03 AM
> Subject: Re: [PATCH 3/3] net: usb: cdc_ncm: don't spew notifications
[...]
> > RTL8156 sends notifications about every 32ms.
> > Only display/log notifications when something changes.
> >
> > This issue has been reported by others:
> > https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1832472
> > https://lkml.org/lkml/2020/8/27/1083
> >
> > ...
> > [785962.779840] usb 1-1: new high-speed USB device number 5 using
> xhci_hcd
> > [785962.929944] usb 1-1: New USB device found, idVendor=0bda,
> idProduct=8156, bcdDevice=30.00
> > [785962.929949] usb 1-1: New USB device strings: Mfr=1, Product=2,
> SerialNumber=6
> > [785962.929952] usb 1-1: Product: USB 10/100/1G/2.5G LAN
> > [785962.929954] usb 1-1: Manufacturer: Realtek
> > [785962.929956] usb 1-1: SerialNumber: 1
> > [785962.991755] usbcore: registered new interface driver cdc_ether
> > [785963.017068] cdc_ncm 1-1:2.0: MAC-Address: 00:24:27:88:08:15
> > [785963.017072] cdc_ncm 1-1:2.0: setting rx_max = 16384
> > [785963.017169] cdc_ncm 1-1:2.0: setting tx_max = 16384
> > [785963.017682] cdc_ncm 1-1:2.0 usb0: register 'cdc_ncm' at
> usb-:00:14.0-1, CDC NCM, 00:24:27:88:08:15
> > [785963.019211] usbcore: registered new interface driver cdc_ncm
> > [785963.023856] usbcore: registered new interface driver cdc_wdm
> > [785963.025461] usbcore: registered new interface driver cdc_mbim
> > [785963.038824] cdc_ncm 1-1:2.0 enx002427880815: renamed from usb0
> > [785963.089586] cdc_ncm 1-1:2.0 enx002427880815: network connection:
> disconnected
> > [785963.121673] cdc_ncm 1-1:2.0 enx002427880815: network connection:
> disconnected
> > [785963.153682] cdc_ncm 1-1:2.0 enx002427880815: network connection:
> disconnected
> > ...
> >
> > This is about 2KB per second and will overwrite all contents of a 1MB
> > dmesg buffer in under 10 minutes rendering them useless for debugging
> > many kernel problems.
> >
> > This is also an extra 180 MB/day in /var/logs (or 1GB per week) rendering
> > the majority of those logs useless too.
> >
> > When the link is up (expected state), spew amount is >2x higher:
> > ...
> > [786139.600992] cdc_ncm 2-1:2.0 enx002427880815: network connection:
> connected
> > [786139.632997] cdc_ncm 2-1:2.0 enx002427880815: 2500 mbit/s downlink
> 2500 mbit/s uplink
> > [786139.665097] cdc_ncm 2-1:2.0 enx002427880815: network connection:
> connected
> > [786139.697100] cdc_ncm 2-1:2.0 enx002427880815: 2500 mbit/s downlink
> 2500 mbit/s uplink
> > [786139.729094] cdc_ncm 2-1:2.0 enx002427880815: network connection:
> connected
> > [786139.761108] cdc_ncm 2-1:2.0 enx002427880815: 2500 mbit/s downlink
> 2500 mbit/s uplink
> > ...
> >
> > Chrome OS cannot support RTL8156 until this is fixed.
> >
> > Signed-off-by: Grant Grundler 

Reviewed-by: Hayes Wang 

Best Regards,
Hayes



[PATCH net-next v2] r8153_ecm: avoid to be prior to r8152 driver

2020-11-17 Thread Hayes Wang
Avoid r8153_ecm is compiled as built-in, if r8152 driver is compiled
as modules. Otherwise, the r8153_ecm would be used, even though the
device is supported by r8152 driver.

Fixes: c1aedf015ebd ("net/usb/r8153_ecm: support ECM mode for RTL8153")
Reported-by: Marek Szyprowski 
Signed-off-by: Hayes Wang 
---
v2:
Use a separate Kconfig entry for r8153_ecm with proper dependencies.

 drivers/net/usb/Kconfig  | 9 +
 drivers/net/usb/Makefile | 3 ++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index b46993d5f997..1e3719028780 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -628,4 +628,13 @@ config USB_NET_AQC111
  This driver should work with at least the following devices:
  * Aquantia AQtion USB to 5GbE
 
+config USB_RTL8153_ECM
+   tristate "RTL8153 ECM support"
+   depends on USB_NET_CDCETHER && (USB_RTL8152 || USB_RTL8152=n)
+   default y
+   help
+ This option supports ECM mode for RTL8153 ethernet adapter, when
+ CONFIG_USB_RTL8152 is not set, or the RTL8153 device is not
+ supported by r8152 driver.
+
 endif # USB_NET_DRIVERS
diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 99381e6bea78..4964f7b326fb 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_USB_LAN78XX) += lan78xx.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 r8153_ecm.o
+obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
 obj-$(CONFIG_USB_NET_SR9700)   += sr9700.o
@@ -41,3 +41,4 @@ obj-$(CONFIG_USB_NET_QMI_WWAN)+= qmi_wwan.o
 obj-$(CONFIG_USB_NET_CDC_MBIM) += cdc_mbim.o
 obj-$(CONFIG_USB_NET_CH9200)   += ch9200.o
 obj-$(CONFIG_USB_NET_AQC111)   += aqc111.o
+obj-$(CONFIG_USB_RTL8153_ECM)  += r8153_ecm.o
-- 
2.26.2



RE: [PATCH net-next] r8153_ecm: avoid to be prior to r8152 driver

2020-11-17 Thread Hayes Wang
Jakub Kicinski 
> Sent: Wednesday, November 18, 2020 12:12 AM
[...]
> Something like this?
> 
> config USB_RTL8153_ECM
>   tristate 
>   select MII
>   select USB_NET_CDCETHER
>   depends on USB_RTL8152 || USB_RTL8152=n
>   help
>   
> 
> 
> select clauses will pull in the dependencies you need, and the
> dependency on RTL8152 will be satisfied either when RTL8152's code
> is reachable (both are modules or RTL8152 is built in) or when RTL8152
> is not built at all.
> 
> Does that help?

Thanks a lot.
I would test it.

Best Regards,
Hayes



RE: [PATCH net-next] r8153_ecm: avoid to be prior to r8152 driver

2020-11-16 Thread Hayes Wang
Jakub Kicinski 
> Sent: Tuesday, November 17, 2020 1:03 AM
[...]
> > Yes, this fixes this issue, although I would prefer a separate Kconfig
> > entry for r8153_ecm with proper dependencies instead of this ifdefs in
> > Makefile.
> 
> Agreed, this is what dependency resolution is for.
> 
> Let's just make this a separate Kconfig entry.

Excuse me. I am not familiar with Kconfig.

I wish r8153_ecm could be used, even
CONFIG_USB_RTL8152 is not defined.

How should set it in Kconfig? 

Best Regards,
Hayes



[PATCH net-next] r8153_ecm: avoid to be prior to r8152 driver

2020-11-15 Thread Hayes Wang
Avoid r8153_ecm is compiled as built-in, if r8152 driver is compiled
as modules. Otherwise, the r8153_ecm would be used, even though the
device is supported by r8152 driver.

Fixes: c1aedf015ebd ("net/usb/r8153_ecm: support ECM mode for RTL8153")
Reported-by: Marek Szyprowski 
Signed-off-by: Hayes Wang 
---
 drivers/net/usb/Makefile | 10 +-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 99381e6bea78..98f4c100955e 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_USB_LAN78XX) += lan78xx.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 r8153_ecm.o
+obj-$(CONFIG_USB_NET_CDCETHER) += cdc_ether.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
 obj-$(CONFIG_USB_NET_SR9700)   += sr9700.o
@@ -41,3 +41,11 @@ obj-$(CONFIG_USB_NET_QMI_WWAN)   += qmi_wwan.o
 obj-$(CONFIG_USB_NET_CDC_MBIM) += cdc_mbim.o
 obj-$(CONFIG_USB_NET_CH9200)   += ch9200.o
 obj-$(CONFIG_USB_NET_AQC111)   += aqc111.o
+
+ifdef CONFIG_USB_NET_CDCETHER
+ifeq ($(CONFIG_USB_RTL8152), m)
+obj-$(CONFIG_USB_RTL8152)  += r8153_ecm.o
+else
+obj-$(CONFIG_USB_NET_CDCETHER) += r8153_ecm.o
+endif
+endif
-- 
2.26.2



[PATCH net-next v2 RESEND] net/usb/r8153_ecm: support ECM mode for RTL8153

2020-11-03 Thread Hayes Wang
Support ECM mode based on cdc_ether with relative mii functions,
when CONFIG_USB_RTL8152 is not set, or the device is not supported
by r8152 driver.

Both r8152 and r8153_ecm would check the return value of
rtl8152_get_version() in porbe(). If rtl8152_get_version()
return none zero value, the r8152 is used for the device
with vendor mode. Otherwise, the r8153_ecm is used for the
device with ECM mode.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/Makefile|   2 +-
 drivers/net/usb/r8152.c |  30 +--
 drivers/net/usb/r8153_ecm.c | 162 
 include/linux/usb/r8152.h   |  37 
 4 files changed, 204 insertions(+), 27 deletions(-)
 create mode 100644 drivers/net/usb/r8153_ecm.c
 create mode 100644 include/linux/usb/r8152.h

diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 99fd12be2111..99381e6bea78 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_USB_LAN78XX) += lan78xx.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 r8153_ecm.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
 obj-$(CONFIG_USB_NET_SR9700)   += sr9700.o
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b9b3d19a2e98..c448d6089821 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Information for net-next */
 #define NETNEXT_VERSION"11"
@@ -653,18 +654,6 @@ enum rtl_register_content {
 
 #define INTR_LINK  0x0004
 
-#define RTL8152_REQT_READ  0xc0
-#define RTL8152_REQT_WRITE 0x40
-#define RTL8152_REQ_GET_REGS   0x05
-#define RTL8152_REQ_SET_REGS   0x05
-
-#define BYTE_EN_DWORD  0xff
-#define BYTE_EN_WORD   0x33
-#define BYTE_EN_BYTE   0x11
-#define BYTE_EN_SIX_BYTES  0x3f
-#define BYTE_EN_START_MASK 0x0f
-#define BYTE_EN_END_MASK   0xf0
-
 #define RTL8153_MAX_PACKET 9216 /* 9K */
 #define RTL8153_MAX_MTU(RTL8153_MAX_PACKET - VLAN_ETH_HLEN - \
 ETH_FCS_LEN)
@@ -689,21 +678,9 @@ enum rtl8152_flags {
LENOVO_MACPASSTHRU,
 };
 
-/* Define these values to match your device */
-#define VENDOR_ID_REALTEK  0x0bda
-#define VENDOR_ID_MICROSOFT0x045e
-#define VENDOR_ID_SAMSUNG  0x04e8
-#define VENDOR_ID_LENOVO   0x17ef
-#define VENDOR_ID_LINKSYS  0x13b1
-#define VENDOR_ID_NVIDIA   0x0955
-#define VENDOR_ID_TPLINK   0x2357
-
 #define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2  0x3082
 #define DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2 0xa387
 
-#define MCU_TYPE_PLA   0x0100
-#define MCU_TYPE_USB   0x
-
 struct tally_counter {
__le64  tx_packets;
__le64  rx_packets;
@@ -6621,7 +6598,7 @@ static int rtl_fw_init(struct r8152 *tp)
return 0;
 }
 
-static u8 rtl_get_version(struct usb_interface *intf)
+u8 rtl8152_get_version(struct usb_interface *intf)
 {
struct usb_device *udev = interface_to_usbdev(intf);
u32 ocp_data = 0;
@@ -6679,12 +6656,13 @@ static u8 rtl_get_version(struct usb_interface *intf)
 
return version;
 }
+EXPORT_SYMBOL_GPL(rtl8152_get_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);
+   u8 version = rtl8152_get_version(intf);
struct r8152 *tp;
struct net_device *netdev;
int ret;
diff --git a/drivers/net/usb/r8153_ecm.c b/drivers/net/usb/r8153_ecm.c
new file mode 100644
index ..2c3fabd38b16
--- /dev/null
+++ b/drivers/net/usb/r8153_ecm.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define OCP_BASE   0xe86c
+
+static int pla_read_word(struct usbnet *dev, u16 index)
+{
+   u16 byen = BYTE_EN_WORD;
+   u8 shift = index & 2;
+   __le32 tmp;
+   int ret;
+
+   if (shift)
+   byen <<= shift;
+
+   index &= ~3;
+
+   ret = usbnet_read_cmd(dev, RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, 
index,
+ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp));
+   if (ret < 0)
+   goto out;
+
+   ret = __le32_to_cpu(tmp);
+   ret >>= (shift * 8);
+   ret &= 0x;
+
+out:
+   return ret;
+}
+
+static int pla_write_word(struct usbnet *dev, u16 index, u32 data)
+{
+   u32 mask = 0x;
+   u16 byen = BYTE_EN_WORD;
+   u8 shift = index

RE: [PATCH net-next v2] net/usb/r8153_ecm: support ECM mode for RTL8153

2020-11-03 Thread Hayes Wang
Jakub Kicinski 
> Sent: Wednesday, November 4, 2020 12:16 AM
[...]
> > So no, please do not create such a common file, it is not needed or a
> > good idea.
> 
> I wouldn't go that far, PCI subsystem just doesn't want everyone to add
> IDs to the shared file unless there is a reason.
> 
>  *Do not add new entries to this file unless the definitions
>  *are shared between multiple drivers.
> 
> Which seems quite reasonable. But it is most certainly your call :)

Do I have to resend this patch?

Best Regards,
Hayes




RE: [PATCH net-next v2] net/usb/r8153_ecm: support ECM mode for RTL8153

2020-11-03 Thread Hayes Wang
Greg Kroah-Hartman 
> Sent: Tuesday, November 3, 2020 5:33 PM
[...]
> There is a reason, it's a nightmare to maintain and handle merges for,
> just don't do it.
> 
> Read the comments at the top of the pci_ids.h file if you are curious
> why we don't even do this for PCI device ids anymore for the past 10+
> years.
> 
> So no, please do not create such a common file, it is not needed or a
> good idea.

Oops. I have sent it.


[PATCH net-next v3 1/2] include/linux/usb: new header file for the vendor ID of USB devices

2020-11-03 Thread Hayes Wang
Add a new header file usb_vendor_id.h to consolidate the definitions
of the vendor ID of USB devices which may be used by cdc_ether and
r8152 driver.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/cdc_ether.c   | 139 +-
 drivers/net/usb/r8152.c   |  48 +--
 include/linux/usb/usb_vendor_id.h |  51 +++
 3 files changed, 133 insertions(+), 105 deletions(-)
 create mode 100644 include/linux/usb/usb_vendor_id.h

diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
index 8c1d61c2cbac..1f6d9b46883a 100644
--- a/drivers/net/usb/cdc_ether.c
+++ b/drivers/net/usb/cdc_ether.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 
 #if IS_ENABLED(CONFIG_USB_NET_RNDIS_HOST)
@@ -540,22 +541,6 @@ static const struct driver_info wwan_info = {
 
 /*-*/
 
-#define HUAWEI_VENDOR_ID   0x12D1
-#define NOVATEL_VENDOR_ID  0x1410
-#define ZTE_VENDOR_ID  0x19D2
-#define DELL_VENDOR_ID 0x413C
-#define REALTEK_VENDOR_ID  0x0bda
-#define SAMSUNG_VENDOR_ID  0x04e8
-#define LENOVO_VENDOR_ID   0x17ef
-#define LINKSYS_VENDOR_ID  0x13b1
-#define NVIDIA_VENDOR_ID   0x0955
-#define HP_VENDOR_ID   0x03f0
-#define MICROSOFT_VENDOR_ID0x045e
-#define UBLOX_VENDOR_ID0x1546
-#define TPLINK_VENDOR_ID   0x2357
-#define AQUANTIA_VENDOR_ID 0x2eca
-#define ASIX_VENDOR_ID 0x0b95
-
 static const struct usb_device_id  products[] = {
 /* BLACKLIST !!
  *
@@ -661,49 +646,49 @@ static const struct usb_device_id products[] = {
 
 /* Novatel USB551L and MC551 - handled by qmi_wwan */
 {
-   USB_DEVICE_AND_INTERFACE_INFO(NOVATEL_VENDOR_ID, 0xB001, USB_CLASS_COMM,
-   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+   USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_NOVATEL, 0xB001, 
USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_ETHERNET, 
USB_CDC_PROTO_NONE),
.driver_info = 0,
 },
 
 /* Novatel E362 - handled by qmi_wwan */
 {
-   USB_DEVICE_AND_INTERFACE_INFO(NOVATEL_VENDOR_ID, 0x9010, USB_CLASS_COMM,
-   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+   USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_NOVATEL, 0x9010, 
USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_ETHERNET, 
USB_CDC_PROTO_NONE),
.driver_info = 0,
 },
 
 /* Dell Wireless 5800 (Novatel E362) - handled by qmi_wwan */
 {
-   USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, 0x8195, USB_CLASS_COMM,
-   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+   USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_DELL, 0x8195, 
USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_ETHERNET, 
USB_CDC_PROTO_NONE),
.driver_info = 0,
 },
 
 /* Dell Wireless 5800 (Novatel E362) - handled by qmi_wwan */
 {
-   USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, 0x8196, USB_CLASS_COMM,
-   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+   USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_DELL, 0x8196, 
USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_ETHERNET, 
USB_CDC_PROTO_NONE),
.driver_info = 0,
 },
 
 /* Dell Wireless 5804 (Novatel E371) - handled by qmi_wwan */
 {
-   USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, 0x819b, USB_CLASS_COMM,
-   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+   USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_DELL, 0x819b, 
USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_ETHERNET, 
USB_CDC_PROTO_NONE),
.driver_info = 0,
 },
 
 /* Novatel Expedite E371 - handled by qmi_wwan */
 {
-   USB_DEVICE_AND_INTERFACE_INFO(NOVATEL_VENDOR_ID, 0x9011, USB_CLASS_COMM,
-   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE),
+   USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_NOVATEL, 0x9011, 
USB_CLASS_COMM,
+ USB_CDC_SUBCLASS_ETHERNET, 
USB_CDC_PROTO_NONE),
.driver_info = 0,
 },
 
 /* HP lt2523 (Novatel E371) - handled by qmi_wwan */
 {
-   USB_DEVICE_AND_INTERFACE_INFO(HP_VENDOR_ID, 0x421d, USB_CLASS_COMM,
+   USB_DEVICE_AND_INTERFACE_INFO(USB_VENDOR_ID_HP, 0x421d, USB_CLASS_COMM,
  USB_CDC_SUBCLASS_ETHERNET, 
USB_CDC_PROTO_NONE),
.driver_info = 0,
 },
@@ -717,127 +702,127 @@ static const struct usb_device_id   products[] = {
 
 /* Huawei E1820 - handled by qmi_wwan */
 {
-   USB_DEVICE_INTERFACE_NUMBER(HUAWEI_VENDOR_ID, 0x14ac, 1),
+   USB_DEVICE_INTERFACE_NUMBER(USB_VENDOR_ID_HUAWEI, 0x14ac, 1),
.driver_info = 0,
 },
 
 /* Realtek RTL8152 Based USB 2.0 Ethernet Adapters */
 {
-   USB_DEVICE_AND_INTERFACE_INFO(REALTEK_VENDOR_ID, 0x8152, USB_CLASS_COMM,
-   USB_CDC_SUBCLASS_ETHERNET, USB_CDC_PROTO_NONE

[PATCH net-next v3 0/2] drivers/net/usb: support ECM mode for RTL8153

2020-11-03 Thread Hayes Wang
v3:
Move original patch to #2. And add a new patch #1 to consolidate vendor ID
of USB devices.

v2:
Add include/linux/usb/r8152.h to avoid the warning about
no previous prototype for rtl8152_get_version.

Hayes Wang (2):
  include/linux/usb: new header file for the vendor ID of USB devices
  net/usb/r8153_ecm: support ECM mode for RTL8153

 drivers/net/usb/Makefile  |   2 +-
 drivers/net/usb/cdc_ether.c   |  93 +++--
 drivers/net/usb/r8152.c   |  68 +
 drivers/net/usb/r8153_ecm.c   | 162 ++
 include/linux/usb/r8152.h |  30 ++
 include/linux/usb/usb_vendor_id.h |  51 ++
 6 files changed, 306 insertions(+), 100 deletions(-)
 create mode 100644 drivers/net/usb/r8153_ecm.c
 create mode 100644 include/linux/usb/r8152.h
 create mode 100644 include/linux/usb/usb_vendor_id.h

-- 
2.26.2



[PATCH net-next v3 2/2] net/usb/r8153_ecm: support ECM mode for RTL8153

2020-11-03 Thread Hayes Wang
Support ECM mode based on cdc_ether with relative mii
functions, when CONFIG_USB_RTL8152 is not set, or the
device is not supported by r8152 driver.

Both r8152 and r8153_ecm would check the return value of
rtl8152_get_version() in porbe(). If rtl8152_get_version()
return none zero value, the r8152 is used for the device
with vendor mode. Otherwise, the r8153_ecm is used for the
device with ECM mode.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/Makefile|   2 +-
 drivers/net/usb/r8152.c |  22 +
 drivers/net/usb/r8153_ecm.c | 162 
 include/linux/usb/r8152.h   |  30 +++
 4 files changed, 197 insertions(+), 19 deletions(-)
 create mode 100644 drivers/net/usb/r8153_ecm.c
 create mode 100644 include/linux/usb/r8152.h

diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 99fd12be2111..99381e6bea78 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_USB_LAN78XX) += lan78xx.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 r8153_ecm.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
 obj-$(CONFIG_USB_NET_SR9700)   += sr9700.o
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index d8ae89aa470c..41b803729996 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -26,7 +26,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 
 /* Information for net-next */
 #define NETNEXT_VERSION"11"
@@ -654,18 +654,6 @@ enum rtl_register_content {
 
 #define INTR_LINK  0x0004
 
-#define RTL8152_REQT_READ  0xc0
-#define RTL8152_REQT_WRITE 0x40
-#define RTL8152_REQ_GET_REGS   0x05
-#define RTL8152_REQ_SET_REGS   0x05
-
-#define BYTE_EN_DWORD  0xff
-#define BYTE_EN_WORD   0x33
-#define BYTE_EN_BYTE   0x11
-#define BYTE_EN_SIX_BYTES  0x3f
-#define BYTE_EN_START_MASK 0x0f
-#define BYTE_EN_END_MASK   0xf0
-
 #define RTL8153_MAX_PACKET 9216 /* 9K */
 #define RTL8153_MAX_MTU(RTL8153_MAX_PACKET - VLAN_ETH_HLEN - \
 ETH_FCS_LEN)
@@ -693,9 +681,6 @@ enum rtl8152_flags {
 #define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2  0x3082
 #define DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2 0xa387
 
-#define MCU_TYPE_PLA   0x0100
-#define MCU_TYPE_USB   0x
-
 struct tally_counter {
__le64  tx_packets;
__le64  rx_packets;
@@ -6607,7 +6592,7 @@ static int rtl_fw_init(struct r8152 *tp)
return 0;
 }
 
-static u8 rtl_get_version(struct usb_interface *intf)
+u8 rtl8152_get_version(struct usb_interface *intf)
 {
struct usb_device *udev = interface_to_usbdev(intf);
u32 ocp_data = 0;
@@ -6665,12 +6650,13 @@ static u8 rtl_get_version(struct usb_interface *intf)
 
return version;
 }
+EXPORT_SYMBOL_GPL(rtl8152_get_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);
+   u8 version = rtl8152_get_version(intf);
struct r8152 *tp;
struct net_device *netdev;
int ret;
diff --git a/drivers/net/usb/r8153_ecm.c b/drivers/net/usb/r8153_ecm.c
new file mode 100644
index ..13eba7a72633
--- /dev/null
+++ b/drivers/net/usb/r8153_ecm.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define OCP_BASE   0xe86c
+
+static int pla_read_word(struct usbnet *dev, u16 index)
+{
+   u16 byen = BYTE_EN_WORD;
+   u8 shift = index & 2;
+   __le32 tmp;
+   int ret;
+
+   if (shift)
+   byen <<= shift;
+
+   index &= ~3;
+
+   ret = usbnet_read_cmd(dev, RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, 
index,
+ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp));
+   if (ret < 0)
+   goto out;
+
+   ret = __le32_to_cpu(tmp);
+   ret >>= (shift * 8);
+   ret &= 0x;
+
+out:
+   return ret;
+}
+
+static int pla_write_word(struct usbnet *dev, u16 index, u32 data)
+{
+   u32 mask = 0x;
+   u16 byen = BYTE_EN_WORD;
+   u8 shift = index & 2;
+   __le32 tmp;
+   int ret;
+
+   data &= mask;
+
+   if (shift) {
+   byen <<= shift;
+   mask <<= (shift * 8);
+   data <<= (shift * 8);
+   }
+
+   index &= ~3;
+
+   ret = usbnet_read_cmd(dev, RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, 
index,
+ MCU_TYPE_PLA | byen, &tmp, si

RE: [PATCH net-next v2] net/usb/r8153_ecm: support ECM mode for RTL8153

2020-11-01 Thread Hayes Wang
Jakub Kicinski 
[...]
> Can you describe the use case in more detail?
> 
> AFAICT r8152 defines a match for the exact same device.
> Does it not mean that which driver is used will be somewhat random
> if both are built?

I export rtl_get_version() from r8152. It would return none zero
value if r8152 could support this device. Both r8152 and r8153_ecm
would check the return value of rtl_get_version() in porbe().
Therefore, if rtl_get_version() return none zero value, the r8152
is used for the device with vendor mode. Otherwise, the r8153_ecm
is used for the device with ECM mode.

> > +/* Define these values to match your device */
> > +#define VENDOR_ID_REALTEK  0x0bda
> > +#define VENDOR_ID_MICROSOFT0x045e
> > +#define VENDOR_ID_SAMSUNG  0x04e8
> > +#define VENDOR_ID_LENOVO   0x17ef
> > +#define VENDOR_ID_LINKSYS  0x13b1
> > +#define VENDOR_ID_NVIDIA   0x0955
> > +#define VENDOR_ID_TPLINK   0x2357
> 
> $ git grep 0x2357 | grep -i tplink
> drivers/net/usb/cdc_ether.c:#define TPLINK_VENDOR_ID  0x2357
> drivers/net/usb/r8152.c:#define VENDOR_ID_TPLINK  0x2357
> drivers/usb/serial/option.c:#define TPLINK_VENDOR_ID  0x2357
> 
> $ git grep 0x17ef | grep -i lenovo
> drivers/hid/hid-ids.h:#define USB_VENDOR_ID_LENOVO0x17ef
> drivers/hid/wacom.h:#define USB_VENDOR_ID_LENOVO  0x17ef
> drivers/net/usb/cdc_ether.c:#define LENOVO_VENDOR_ID  0x17ef
> drivers/net/usb/r8152.c:#define VENDOR_ID_LENOVO  0x17ef
> 
> Time to consolidate those vendor id defines perhaps?

It seems that there is no such header file which I could include
or add the new vendor IDs.

Best Regards,
Hayes





[PATCH net-next v2] net/usb/r8153_ecm: support ECM mode for RTL8153

2020-10-29 Thread Hayes Wang
Support ECM mode based on cdc_ether with relative mii functions,
when CONFIG_USB_RTL8152 is not set, or the device is not supported
by r8152 driver.

Signed-off-by: Hayes Wang 
---
v2:
Add include/linux/usb/r8152.h to avoid the warning about
no previous prototype for rtl8152_get_version.

 drivers/net/usb/Makefile|   2 +-
 drivers/net/usb/r8152.c |  30 +--
 drivers/net/usb/r8153_ecm.c | 162 
 include/linux/usb/r8152.h   |  37 
 4 files changed, 204 insertions(+), 27 deletions(-)
 create mode 100644 drivers/net/usb/r8153_ecm.c
 create mode 100644 include/linux/usb/r8152.h

diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 99fd12be2111..99381e6bea78 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_USB_LAN78XX) += lan78xx.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 r8153_ecm.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
 obj-$(CONFIG_USB_NET_SR9700)   += sr9700.o
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b1770489aca5..7d2523d96c51 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -26,6 +26,7 @@
 #include 
 #include 
 #include 
+#include 
 
 /* Information for net-next */
 #define NETNEXT_VERSION"11"
@@ -653,18 +654,6 @@ enum rtl_register_content {
 
 #define INTR_LINK  0x0004
 
-#define RTL8152_REQT_READ  0xc0
-#define RTL8152_REQT_WRITE 0x40
-#define RTL8152_REQ_GET_REGS   0x05
-#define RTL8152_REQ_SET_REGS   0x05
-
-#define BYTE_EN_DWORD  0xff
-#define BYTE_EN_WORD   0x33
-#define BYTE_EN_BYTE   0x11
-#define BYTE_EN_SIX_BYTES  0x3f
-#define BYTE_EN_START_MASK 0x0f
-#define BYTE_EN_END_MASK   0xf0
-
 #define RTL8153_MAX_PACKET 9216 /* 9K */
 #define RTL8153_MAX_MTU(RTL8153_MAX_PACKET - VLAN_ETH_HLEN - \
 ETH_FCS_LEN)
@@ -689,21 +678,9 @@ enum rtl8152_flags {
LENOVO_MACPASSTHRU,
 };
 
-/* Define these values to match your device */
-#define VENDOR_ID_REALTEK  0x0bda
-#define VENDOR_ID_MICROSOFT0x045e
-#define VENDOR_ID_SAMSUNG  0x04e8
-#define VENDOR_ID_LENOVO   0x17ef
-#define VENDOR_ID_LINKSYS  0x13b1
-#define VENDOR_ID_NVIDIA   0x0955
-#define VENDOR_ID_TPLINK   0x2357
-
 #define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2  0x3082
 #define DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2 0xa387
 
-#define MCU_TYPE_PLA   0x0100
-#define MCU_TYPE_USB   0x
-
 struct tally_counter {
__le64  tx_packets;
__le64  rx_packets;
@@ -6615,7 +6592,7 @@ static int rtl_fw_init(struct r8152 *tp)
return 0;
 }
 
-static u8 rtl_get_version(struct usb_interface *intf)
+u8 rtl8152_get_version(struct usb_interface *intf)
 {
struct usb_device *udev = interface_to_usbdev(intf);
u32 ocp_data = 0;
@@ -6673,12 +6650,13 @@ static u8 rtl_get_version(struct usb_interface *intf)
 
return version;
 }
+EXPORT_SYMBOL_GPL(rtl8152_get_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);
+   u8 version = rtl8152_get_version(intf);
struct r8152 *tp;
struct net_device *netdev;
int ret;
diff --git a/drivers/net/usb/r8153_ecm.c b/drivers/net/usb/r8153_ecm.c
new file mode 100644
index ..2c3fabd38b16
--- /dev/null
+++ b/drivers/net/usb/r8153_ecm.c
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0-only
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define OCP_BASE   0xe86c
+
+static int pla_read_word(struct usbnet *dev, u16 index)
+{
+   u16 byen = BYTE_EN_WORD;
+   u8 shift = index & 2;
+   __le32 tmp;
+   int ret;
+
+   if (shift)
+   byen <<= shift;
+
+   index &= ~3;
+
+   ret = usbnet_read_cmd(dev, RTL8152_REQ_GET_REGS, RTL8152_REQT_READ, 
index,
+ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp));
+   if (ret < 0)
+   goto out;
+
+   ret = __le32_to_cpu(tmp);
+   ret >>= (shift * 8);
+   ret &= 0x;
+
+out:
+   return ret;
+}
+
+static int pla_write_word(struct usbnet *dev, u16 index, u32 data)
+{
+   u32 mask = 0x;
+   u16 byen = BYTE_EN_WORD;
+   u8 shift = index & 2;
+   __le32 tmp;
+   int ret;
+
+   data &= mask;
+
+   if (shift) {
+   byen <<= shift;
+   ma

[PATCH] net/usb/r8153_ecm: support ECM mode for RTL8153

2020-10-29 Thread Hayes Wang
Support ECM mode based on cdc_ether with relative mii functions,
when CONFIG_USB_RTL8152 is not set, or the device is not supported
by r8152 driver.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/Makefile|   2 +-
 drivers/net/usb/r8152.c |   5 +-
 drivers/net/usb/r8153_ecm.c | 174 
 3 files changed, 178 insertions(+), 3 deletions(-)
 create mode 100644 drivers/net/usb/r8153_ecm.c

diff --git a/drivers/net/usb/Makefile b/drivers/net/usb/Makefile
index 99fd12be2111..99381e6bea78 100644
--- a/drivers/net/usb/Makefile
+++ b/drivers/net/usb/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_USB_LAN78XX) += lan78xx.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 r8153_ecm.o
 obj-$(CONFIG_USB_NET_CDC_EEM)  += cdc_eem.o
 obj-$(CONFIG_USB_NET_DM9601)   += dm9601.o
 obj-$(CONFIG_USB_NET_SR9700)   += sr9700.o
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b1770489aca5..1b5d10f1de5f 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -6615,7 +6615,7 @@ static int rtl_fw_init(struct r8152 *tp)
return 0;
 }
 
-static u8 rtl_get_version(struct usb_interface *intf)
+u8 rtl8152_get_version(struct usb_interface *intf)
 {
struct usb_device *udev = interface_to_usbdev(intf);
u32 ocp_data = 0;
@@ -6673,12 +6673,13 @@ static u8 rtl_get_version(struct usb_interface *intf)
 
return version;
 }
+EXPORT_SYMBOL_GPL(rtl8152_get_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);
+   u8 version = rtl8152_get_version(intf);
struct r8152 *tp;
struct net_device *netdev;
int ret;
diff --git a/drivers/net/usb/r8153_ecm.c b/drivers/net/usb/r8153_ecm.c
new file mode 100644
index ..723841525a6a
--- /dev/null
+++ b/drivers/net/usb/r8153_ecm.c
@@ -0,0 +1,174 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define RTL8153_CMD0X05
+#define RTL8153_REQT_READ  0xc0
+#define RTL8153_REQT_WRITE 0x40
+
+#define MCU_TYPE_PLA   0x0100
+#define OCP_BASE   0xe86c
+
+#define BYTE_EN_WORD   0x33
+
+#define REALTEK_VENDOR_ID  0x0bda
+
+#if IS_REACHABLE(CONFIG_USB_RTL8152)
+extern u8 rtl8152_get_version(struct usb_interface *intf);
+#endif
+
+static int pla_read_word(struct usbnet *dev, u16 index)
+{
+   u16 byen = BYTE_EN_WORD;
+   u8 shift = index & 2;
+   __le32 tmp;
+   int ret;
+
+   if (shift)
+   byen <<= shift;
+
+   index &= ~3;
+
+   ret = usbnet_read_cmd(dev, RTL8153_CMD, RTL8153_REQT_READ, index,
+ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp));
+   if (ret < 0)
+   goto out;
+
+   ret = __le32_to_cpu(tmp);
+   ret >>= (shift * 8);
+   ret &= 0x;
+
+out:
+   return ret;
+}
+
+static int pla_write_word(struct usbnet *dev, u16 index, u32 data)
+{
+   u32 mask = 0x;
+   u16 byen = BYTE_EN_WORD;
+   u8 shift = index & 2;
+   __le32 tmp;
+   int ret;
+
+   data &= mask;
+
+   if (shift) {
+   byen <<= shift;
+   mask <<= (shift * 8);
+   data <<= (shift * 8);
+   }
+
+   index &= ~3;
+
+   ret = usbnet_read_cmd(dev, RTL8153_CMD, RTL8153_REQT_READ, index,
+ MCU_TYPE_PLA | byen, &tmp, sizeof(tmp));
+
+   if (ret < 0)
+   goto out;
+
+   data |= __le32_to_cpu(tmp) & ~mask;
+   tmp = __cpu_to_le32(data);
+
+   ret = usbnet_write_cmd(dev, RTL8153_CMD, RTL8153_REQT_WRITE, index,
+  MCU_TYPE_PLA | byen, &tmp, sizeof(tmp));
+
+out:
+   return ret;
+}
+
+static int r8153_ecm_mdio_read(struct net_device *netdev, int phy_id, int reg)
+{
+   struct usbnet *dev = netdev_priv(netdev);
+   int ret;
+
+   ret = pla_write_word(dev, OCP_BASE, 0xa000);
+   if (ret < 0)
+   goto out;
+
+   ret = pla_read_word(dev, 0xb400 + reg * 2);
+
+out:
+   return ret;
+}
+
+static void r8153_ecm_mdio_write(struct net_device *netdev, int phy_id, int 
reg, int val)
+{
+   struct usbnet *dev = netdev_priv(netdev);
+   int ret;
+
+   ret = pla_write_word(dev, OCP_BASE, 0xa000);
+   if (ret < 0)
+   return;
+
+   ret = pla_write_word(dev, 0xb400 + reg * 2, val);
+}
+
+static int r8153_bind(struct usbnet *dev, struct usb_interface *intf)
+{
+   int status;
+
+   status = usbnet_cdc_bind(dev, intf);
+   if (status < 0)
+  

RE: [PATCH net-next] r8152: support request_firmware for RTL8153

2019-10-23 Thread Hayes Wang
Marek Szyprowski [mailto:m.szyprow...@samsung.com]
> Sent: Wednesday, October 23, 2019 6:23 PM
[...]
> >> This patch (which landed in linux-next last days) causes a following
> >> kernel oops on the ARM 32bit Exynos5422 SoC based Odroid XU4 board:
> > Please try the following patch.
> 
> Yes, this fixes the issue. I've applied those changes manually on top of
> Linux next-20191022, due to some differences in the context. When you
> prepare a final patch, feel free to add:
> 
> Reported-by: Marek Szyprowski 
> Fixes: 9370f2d05a2a ("r8152: support request_firmware for RTL8153")
> Tested-by: Marek Szyprowski 

Thanks

Best Regards,
Hayes





RE: [PATCH net-next] r8152: support request_firmware for RTL8153

2019-10-23 Thread Hayes Wang
Marek Szyprowski [mailto:m.szyprow...@samsung.com]
> Sent: Wednesday, October 23, 2019 5:17 PM
> Subject: Re: [PATCH net-next] r8152: support request_firmware for RTL8153
> 
> Hi Hayes,
> 
> On 16.10.2019 05:02, Hayes Wang wrote:
> > This patch supports loading additional firmware file through
> > request_firmware().
> >
> > A firmware file may include a header followed by several blocks
> > which have different types of firmware. Currently, the supported
> > types are RTL_FW_END, RTL_FW_PLA, and RTL_FW_USB.
> >
> > The firmware is used to fix some compatible or hardware issues. For
> > example, the device couldn't be found after rebooting several times.
> >
> > The supported chips are
> > RTL_VER_04 (rtl8153a-2.fw)
> > RTL_VER_05 (rtl8153a-3.fw)
> > RTL_VER_06 (rtl8153a-4.fw)
> > RTL_VER_09 (rtl8153b-2.fw)
> >
> > Signed-off-by: Hayes Wang 
> > Reviewed-by: Prashant Malani 
> 
> This patch (which landed in linux-next last days) causes a following
> kernel oops on the ARM 32bit Exynos5422 SoC based Odroid XU4 board:

Please try the following patch.

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index d3c30ccc8577..283b35a76cf0 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -4000,8 +4000,8 @@ static void rtl8152_fw_mac_apply(struct r8152 *tp, struct 
fw_mac *mac)
 static void rtl8152_apply_firmware(struct r8152 *tp)
 {
struct rtl_fw *rtl_fw = &tp->rtl_fw;
-   const struct firmware *fw = rtl_fw->fw;
-   struct fw_header *fw_hdr = (struct fw_header *)fw->data;
+   const struct firmware *fw;
+   struct fw_header *fw_hdr;
struct fw_phy_patch_key *key;
u16 key_addr = 0;
int i;
@@ -4009,6 +4009,9 @@ static void rtl8152_apply_firmware(struct r8152 *tp)
if (IS_ERR_OR_NULL(rtl_fw->fw))
return;
 
+   fw = rtl_fw->fw;
+   fw_hdr = (struct fw_header *)fw->data;
+
if (rtl_fw->pre_fw)
rtl_fw->pre_fw(tp);

> > +static void rtl8152_apply_firmware(struct r8152 *tp)
> > +{
> > +   struct rtl_fw *rtl_fw = &tp->rtl_fw;
> > +   const struct firmware *fw = rtl_fw->fw;
> > +   struct fw_header *fw_hdr = (struct fw_header *)fw->data;
> > +   int i;
> > +
> > +   if (IS_ERR_OR_NULL(rtl_fw->fw))
> > +   return;
> > +
> > +   if (rtl_fw->pre_fw)
> > +   rtl_fw->pre_fw(tp);
> > +

Best Regards,
Hayes




RE: [PATCH net-next 4/4] r8152: support firmware of PHY NC for RTL8153A

2019-10-21 Thread Hayes Wang
Jakub Kicinski [mailto:jakub.kicin...@netronome.com]
> Sent: Tuesday, October 22, 2019 11:36 AM
> To: Hayes Wang
> Cc: net...@vger.kernel.org; nic_swsd; linux-kernel@vger.kernel.org;
> pmal...@chromium.org; grund...@chromium.org
> Subject: Re: [PATCH net-next 4/4] r8152: support firmware of PHY NC for
> RTL8153A
> 
> On Mon, 21 Oct 2019 11:41:13 +0800, Hayes Wang wrote:
> > Support the firmware of PHY NC which is used to fix the issue found
> > for PHY. Currently, only RTL_VER_04, RTL_VER_05, and RTL_VER_06 need
> > it.
> >
> > The order of loading PHY firmware would be
> >
> > RTL_FW_PHY_START
> > RTL_FW_PHY_NC
> 
> Perhaps that's obvious to others, but what's NC? :)

The PHY has several micro controllers which deal with different features.
The NC is our internal name helping us to know which one is specified.

Best Regards,
Hayes




[PATCH net-next 1/4] r8152: rename fw_type_1 with fw_mac

2019-10-20 Thread Hayes Wang
The struct fw_type_1 is used by MAC only, so rename it to a meaningful one.

Besides, adjust two messages. Replace "load xxx fail" with "check xxx fail"

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 82 -
 1 file changed, 41 insertions(+), 41 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 55d0bcb00aef..55a7674a0c06 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -867,11 +867,11 @@ struct fw_header {
 } __packed;
 
 /**
- * struct fw_type_1 - a firmware block used by RTL_FW_PLA and RTL_FW_USB.
+ * struct fw_mac - a firmware block used by RTL_FW_PLA and RTL_FW_USB.
  * The layout of the firmware block is:
- *  +  + .
+ *  +  + .
  * @fw_offset: offset of the firmware binary data. The start address of
- * the data would be the address of struct fw_type_1 + @fw_offset.
+ * the data would be the address of struct fw_mac + @fw_offset.
  * @fw_reg: the register to load the firmware. Depends on chip.
  * @bp_ba_addr: the register to write break point base address. Depends on
  * chip.
@@ -888,7 +888,7 @@ struct fw_header {
  * @info: additional information for debugging, and is followed by the
  * binary data of firmware.
  */
-struct fw_type_1 {
+struct fw_mac {
struct fw_block blk_hdr;
__le16 fw_offset;
__le16 fw_reg;
@@ -3397,14 +3397,14 @@ static void rtl_clear_bp(struct r8152 *tp, u16 type)
ocp_write_word(tp, type, PLA_BP_BA, 0);
 }
 
-static bool rtl8152_is_fw_type1_ok(struct r8152 *tp, struct fw_type_1 *type1)
+static bool rtl8152_is_fw_mac_ok(struct r8152 *tp, struct fw_mac *mac)
 {
u16 fw_reg, bp_ba_addr, bp_en_addr, bp_start;
bool rc = false;
u32 length, type;
int i, max_bp;
 
-   type = __le32_to_cpu(type1->blk_hdr.type);
+   type = __le32_to_cpu(mac->blk_hdr.type);
if (type == RTL_FW_PLA) {
switch (tp->version) {
case RTL_VER_01:
@@ -3461,46 +3461,46 @@ static bool rtl8152_is_fw_type1_ok(struct r8152 *tp, 
struct fw_type_1 *type1)
goto out;
}
 
-   length = __le32_to_cpu(type1->blk_hdr.length);
-   if (length < __le16_to_cpu(type1->fw_offset)) {
+   length = __le32_to_cpu(mac->blk_hdr.length);
+   if (length < __le16_to_cpu(mac->fw_offset)) {
dev_err(&tp->intf->dev, "invalid fw_offset\n");
goto out;
}
 
-   length -= __le16_to_cpu(type1->fw_offset);
+   length -= __le16_to_cpu(mac->fw_offset);
if (length < 4 || (length & 3)) {
dev_err(&tp->intf->dev, "invalid block length\n");
goto out;
}
 
-   if (__le16_to_cpu(type1->fw_reg) != fw_reg) {
+   if (__le16_to_cpu(mac->fw_reg) != fw_reg) {
dev_err(&tp->intf->dev, "invalid register to load firmware\n");
goto out;
}
 
-   if (__le16_to_cpu(type1->bp_ba_addr) != bp_ba_addr) {
+   if (__le16_to_cpu(mac->bp_ba_addr) != bp_ba_addr) {
dev_err(&tp->intf->dev, "invalid base address register\n");
goto out;
}
 
-   if (__le16_to_cpu(type1->bp_en_addr) != bp_en_addr) {
+   if (__le16_to_cpu(mac->bp_en_addr) != bp_en_addr) {
dev_err(&tp->intf->dev, "invalid enabled mask register\n");
goto out;
}
 
-   if (__le16_to_cpu(type1->bp_start) != bp_start) {
+   if (__le16_to_cpu(mac->bp_start) != bp_start) {
dev_err(&tp->intf->dev,
"invalid start register of break point\n");
goto out;
}
 
-   if (__le16_to_cpu(type1->bp_num) > max_bp) {
+   if (__le16_to_cpu(mac->bp_num) > max_bp) {
dev_err(&tp->intf->dev, "invalid break point number\n");
goto out;
}
 
-   for (i = __le16_to_cpu(type1->bp_num); i < max_bp; i++) {
-   if (type1->bp[i]) {
+   for (i = __le16_to_cpu(mac->bp_num); i < max_bp; i++) {
+   if (mac->bp[i]) {
dev_err(&tp->intf->dev, "unused bp%u is not zero\n", i);
goto out;
}
@@ -3566,7 +3566,7 @@ static long rtl8152_check_firmware(struct r8152 *tp, 
struct rtl_fw *rtl_fw)
 {
const struct firmware *fw = rtl_fw->fw;
struct fw_header *fw_hdr = (struct fw_header *)fw->data;
-   struct fw_type_1 *pla = NULL, *usb = NULL;
+   struct fw_mac *pla = NULL, *usb = NULL;
long ret = -EFAULT;
int i;
 
@@ -3601,10 +3601,10 @@ static long rtl8152_check_firmware(struct r8152 *tp, 
struct rtl_fw *rtl_fw)
   

[PATCH net-next 0/4] r8152: PHY firmware

2019-10-20 Thread Hayes Wang
Support loading the firmware of the PHY with the type of RTL_FW_PHY_NC.

Hayes Wang (4):
  r8152: rename fw_type_1 with fw_mac
  r8152: add checking fw_offset field of struct fw_mac
  r8152: move r8153_patch_request forward
  r8152: support firmware of PHY NC for RTL8153A

 drivers/net/usb/r8152.c | 428 +---
 1 file changed, 357 insertions(+), 71 deletions(-)

-- 
2.21.0



[PATCH net-next 3/4] r8152: move r8153_patch_request forward

2019-10-20 Thread Hayes Wang
Move r8153_patch_request() forward for later patch.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 54 -
 1 file changed, 27 insertions(+), 27 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 090ddd5fb973..ab57c672c4ca 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3397,6 +3397,33 @@ static void rtl_clear_bp(struct r8152 *tp, u16 type)
ocp_write_word(tp, type, PLA_BP_BA, 0);
 }
 
+static int r8153_patch_request(struct r8152 *tp, bool request)
+{
+   u16 data;
+   int i;
+
+   data = ocp_reg_read(tp, OCP_PHY_PATCH_CMD);
+   if (request)
+   data |= PATCH_REQUEST;
+   else
+   data &= ~PATCH_REQUEST;
+   ocp_reg_write(tp, OCP_PHY_PATCH_CMD, data);
+
+   for (i = 0; request && i < 5000; i++) {
+   usleep_range(1000, 2000);
+   if (ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)
+   break;
+   }
+
+   if (request && !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) {
+   netif_err(tp, drv, tp->netdev, "patch request fail\n");
+   r8153_patch_request(tp, false);
+   return -ETIME;
+   } else {
+   return 0;
+   }
+}
+
 static bool rtl8152_is_fw_mac_ok(struct r8152 *tp, struct fw_mac *mac)
 {
u16 fw_reg, bp_ba_addr, bp_en_addr, bp_start, fw_offset;
@@ -4056,33 +4083,6 @@ static void r8152b_enter_oob(struct r8152 *tp)
ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
 }
 
-static int r8153_patch_request(struct r8152 *tp, bool request)
-{
-   u16 data;
-   int i;
-
-   data = ocp_reg_read(tp, OCP_PHY_PATCH_CMD);
-   if (request)
-   data |= PATCH_REQUEST;
-   else
-   data &= ~PATCH_REQUEST;
-   ocp_reg_write(tp, OCP_PHY_PATCH_CMD, data);
-
-   for (i = 0; request && i < 5000; i++) {
-   usleep_range(1000, 2000);
-   if (ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)
-   break;
-   }
-
-   if (request && !(ocp_reg_read(tp, OCP_PHY_PATCH_STAT) & PATCH_READY)) {
-   netif_err(tp, drv, tp->netdev, "patch request fail\n");
-   r8153_patch_request(tp, false);
-   return -ETIME;
-   } else {
-   return 0;
-   }
-}
-
 static int r8153_pre_firmware_1(struct r8152 *tp)
 {
int i;
-- 
2.21.0



[PATCH net-next 4/4] r8152: support firmware of PHY NC for RTL8153A

2019-10-20 Thread Hayes Wang
Support the firmware of PHY NC which is used to fix the issue found
for PHY. Currently, only RTL_VER_04, RTL_VER_05, and RTL_VER_06 need
it.

The order of loading PHY firmware would be

RTL_FW_PHY_START
RTL_FW_PHY_NC
RTL_FW_PHY_STOP

The RTL_FW_PHY_START/RTL_FW_PHY_STOP are used to lock/unlock the PHY,
and set/clear the patch key from the firmware file.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 284 +++-
 1 file changed, 282 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ab57c672c4ca..d3c30ccc8577 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -187,6 +187,7 @@
 #define OCP_PHY_STATE  0xa708  /* nway state for 8153 */
 #define OCP_PHY_PATCH_STAT 0xb800
 #define OCP_PHY_PATCH_CMD  0xb820
+#define OCP_PHY_LOCK   0xb82e
 #define OCP_ADC_IOFFSET0xbcfc
 #define OCP_ADC_CFG0xbc06
 #define OCP_SYSCLK_CFG 0xc416
@@ -197,6 +198,7 @@
 #define SRAM_10M_AMP1  0x8080
 #define SRAM_10M_AMP2  0x8082
 #define SRAM_IMPEDANCE 0x8084
+#define SRAM_PHY_LOCK  0xb82e
 
 /* PLA_RCR */
 #define RCR_AAP0x0001
@@ -577,6 +579,9 @@ enum spd_duplex {
 /* OCP_PHY_PATCH_CMD */
 #define PATCH_REQUEST  BIT(4)
 
+/* OCP_PHY_LOCK */
+#define PATCH_LOCK BIT(0)
+
 /* OCP_ADC_CFG */
 #define CKADSEL_L  0x0100
 #define ADC_EN 0x0080
@@ -601,6 +606,9 @@ enum spd_duplex {
 /* SRAM_IMPEDANCE */
 #define RX_DRIVING_MASK0x6000
 
+/* SRAM_PHY_LOCK */
+#define PHY_PATCH_LOCK 0x0001
+
 /* MAC PASSTHRU */
 #define AD_MASK0xfee0
 #define BND_MASK   0x0004
@@ -905,10 +913,65 @@ struct fw_mac {
char info[0];
 } __packed;
 
+/**
+ * struct fw_phy_patch_key - a firmware block used by RTL_FW_PHY_START.
+ * This is used to set patch key when loading the firmware of PHY.
+ * @key_reg: the register to write the patch key.
+ * @key_data: patch key.
+ */
+struct fw_phy_patch_key {
+   struct fw_block blk_hdr;
+   __le16 key_reg;
+   __le16 key_data;
+   __le32 reserved;
+} __packed;
+
+/**
+ * struct fw_phy_nc - a firmware block used by RTL_FW_PHY_NC.
+ * The layout of the firmware block is:
+ *  +  + .
+ * @fw_offset: offset of the firmware binary data. The start address of
+ * the data would be the address of struct fw_phy_nc + @fw_offset.
+ * @fw_reg: the register to load the firmware. Depends on chip.
+ * @ba_reg: the register to write the base address. Depends on chip.
+ * @ba_data: base address. Depends on chip.
+ * @patch_en_addr: the register of enabling patch mode. Depends on chip.
+ * @patch_en_value: patch mode enabled mask. Depends on the firmware.
+ * @mode_reg: the regitster of switching the mode.
+ * @mod_pre: the mode needing to be set before loading the firmware.
+ * @mod_post: the mode to be set when finishing to load the firmware.
+ * @bp_start: the start register of break points. Depends on chip.
+ * @bp_num: the break point number which needs to be set for this firmware.
+ * Depends on the firmware.
+ * @bp: break points. Depends on firmware.
+ * @info: additional information for debugging, and is followed by the
+ * binary data of firmware.
+ */
+struct fw_phy_nc {
+   struct fw_block blk_hdr;
+   __le16 fw_offset;
+   __le16 fw_reg;
+   __le16 ba_reg;
+   __le16 ba_data;
+   __le16 patch_en_addr;
+   __le16 patch_en_value;
+   __le16 mode_reg;
+   __le16 mode_pre;
+   __le16 mode_post;
+   __le16 reserved;
+   __le16 bp_start;
+   __le16 bp_num;
+   __le16 bp[4];
+   char info[0];
+} __packed;
+
 enum rtl_fw_type {
RTL_FW_END = 0,
RTL_FW_PLA,
RTL_FW_USB,
+   RTL_FW_PHY_START,
+   RTL_FW_PHY_STOP,
+   RTL_FW_PHY_NC,
 };
 
 enum rtl_version {
@@ -3424,6 +3487,114 @@ static int r8153_patch_request(struct r8152 *tp, bool 
request)
}
 }
 
+static int r8153_pre_ram_code(struct r8152 *tp, u16 key_addr, u16 patch_key)
+{
+   if (r8153_patch_request(tp, true)) {
+   dev_err(&tp->intf->dev, "patch request fail\n");
+   return -ETIME;
+   }
+
+   sram_write(tp, key_addr, patch_key);
+   sram_write(tp, SRAM_PHY_LOCK, PHY_PATCH_LOCK);
+
+   return 0;
+}
+
+static int r8153_post_ram_code(struct r8152 *tp, u16 key_addr)
+{
+   u16 data;
+
+   sram_write(tp, 0x, 0x);
+
+   data = ocp_reg_read(tp, OCP_PHY_LOCK);
+   data &= ~PATCH_LOCK;
+   ocp_reg_write(tp, OCP_PHY_LOCK, data);
+
+   sram_write(tp, key_addr, 0x);
+
+   r8153_patch_request(tp, false);
+
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_OCP_GPHY_BASE, tp->ocp_base);
+
+   return 0;
+}
+
+static bool rtl8152_is_fw_phy_nc_ok(struct r8152 *tp, struct fw_

[PATCH net-next 2/4] r8152: add checking fw_offset field of struct fw_mac

2019-10-20 Thread Hayes Wang
Make sure @fw_offset field of struct fw_mac is more than the size
of struct fw_mac.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 55a7674a0c06..090ddd5fb973 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3399,7 +3399,7 @@ static void rtl_clear_bp(struct r8152 *tp, u16 type)
 
 static bool rtl8152_is_fw_mac_ok(struct r8152 *tp, struct fw_mac *mac)
 {
-   u16 fw_reg, bp_ba_addr, bp_en_addr, bp_start;
+   u16 fw_reg, bp_ba_addr, bp_en_addr, bp_start, fw_offset;
bool rc = false;
u32 length, type;
int i, max_bp;
@@ -3461,13 +3461,19 @@ static bool rtl8152_is_fw_mac_ok(struct r8152 *tp, 
struct fw_mac *mac)
goto out;
}
 
+   fw_offset = __le16_to_cpu(mac->fw_offset);
+   if (fw_offset < sizeof(*mac)) {
+   dev_err(&tp->intf->dev, "fw_offset too small\n");
+   goto out;
+   }
+
length = __le32_to_cpu(mac->blk_hdr.length);
-   if (length < __le16_to_cpu(mac->fw_offset)) {
+   if (length < fw_offset) {
dev_err(&tp->intf->dev, "invalid fw_offset\n");
goto out;
}
 
-   length -= __le16_to_cpu(mac->fw_offset);
+   length -= fw_offset;
if (length < 4 || (length & 3)) {
dev_err(&tp->intf->dev, "invalid block length\n");
goto out;
-- 
2.21.0



[PATCH net-next] r8152: support request_firmware for RTL8153

2019-10-15 Thread Hayes Wang
This patch supports loading additional firmware file through
request_firmware().

A firmware file may include a header followed by several blocks
which have different types of firmware. Currently, the supported
types are RTL_FW_END, RTL_FW_PLA, and RTL_FW_USB.

The firmware is used to fix some compatible or hardware issues. For
example, the device couldn't be found after rebooting several times.

The supported chips are
RTL_VER_04 (rtl8153a-2.fw)
RTL_VER_05 (rtl8153a-3.fw)
RTL_VER_06 (rtl8153a-4.fw)
RTL_VER_09 (rtl8153b-2.fw)

Signed-off-by: Hayes Wang 
Reviewed-by: Prashant Malani 
---
 drivers/net/usb/r8152.c | 768 +++-
 1 file changed, 756 insertions(+), 12 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 54a83f734ede..55d0bcb00aef 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -24,9 +24,11 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 
 /* Information for net-next */
-#define NETNEXT_VERSION"10"
+#define NETNEXT_VERSION"11"
 
 /* Information for net */
 #define NET_VERSION"10"
@@ -54,8 +56,11 @@
 #define PLA_BDC_CR 0xd1a0
 #define PLA_TEREDO_TIMER   0xd2cc
 #define PLA_REALWOW_TIMER  0xd2e8
+#define PLA_UPHY_TIMER 0xd388
 #define PLA_SUSPEND_FLAG   0xd38a
 #define PLA_INDICATE_FALG  0xd38c
+#define PLA_MACDBG_PRE 0xd38c  /* RTL_VER_04 only */
+#define PLA_MACDBG_POST0xd38e  /* RTL_VER_04 only */
 #define PLA_EXTRA_STATUS   0xd398
 #define PLA_EFUSE_DATA 0xdd00
 #define PLA_EFUSE_CMD  0xdd02
@@ -110,7 +115,12 @@
 #define USB_CONNECT_TIMER  0xcbf8
 #define USB_MSC_TIMER  0xcbfc
 #define USB_BURST_SIZE 0xcfc0
+#define USB_FW_FIX_EN0 0xcfca
+#define USB_FW_FIX_EN1 0xcfcc
 #define USB_LPM_CONFIG 0xcfd8
+#define USB_CSTMR  0xcfef  /* RTL8153A */
+#define USB_FW_CTRL0xd334  /* RTL8153B */
+#define USB_FC_TIMER   0xd340
 #define USB_USB_CTRL   0xd406
 #define USB_PHY_CTRL   0xd408
 #define USB_TX_AGG 0xd40a
@@ -126,6 +136,7 @@
 #define USB_LPM_CTRL   0xd41a
 #define USB_BMU_RESET  0xd4b0
 #define USB_U1U2_TIMER 0xd4da
+#define USB_FW_TASK0xd4e8  /* RTL8153B */
 #define USB_UPS_CTRL   0xd800
 #define USB_POWER_CUT  0xd80a
 #define USB_MISC_0 0xd81a
@@ -133,18 +144,19 @@
 #define USB_AFE_CTRL2  0xd824
 #define USB_UPS_CFG0xd842
 #define USB_UPS_FLAGS  0xd848
+#define USB_WDT1_CTRL  0xe404
 #define USB_WDT11_CTRL 0xe43c
-#define USB_BP_BA  0xfc26
-#define USB_BP_0   0xfc28
-#define USB_BP_1   0xfc2a
-#define USB_BP_2   0xfc2c
-#define USB_BP_3   0xfc2e
-#define USB_BP_4   0xfc30
-#define USB_BP_5   0xfc32
-#define USB_BP_6   0xfc34
-#define USB_BP_7   0xfc36
-#define USB_BP_EN  0xfc38
-#define USB_BP_8   0xfc38
+#define USB_BP_BA  PLA_BP_BA
+#define USB_BP_0   PLA_BP_0
+#define USB_BP_1   PLA_BP_1
+#define USB_BP_2   PLA_BP_2
+#define USB_BP_3   PLA_BP_3
+#define USB_BP_4   PLA_BP_4
+#define USB_BP_5   PLA_BP_5
+#define USB_BP_6   PLA_BP_6
+#define USB_BP_7   PLA_BP_7
+#define USB_BP_EN  PLA_BP_EN   /* RTL8153A */
+#define USB_BP_8   0xfc38  /* RTL8153B */
 #define USB_BP_9   0xfc3a
 #define USB_BP_10  0xfc3c
 #define USB_BP_11  0xfc3e
@@ -346,7 +358,12 @@
 /* PLA_INDICATE_FALG */
 #define UPCOMING_RUNTIME_D3BIT(0)
 
+/* PLA_MACDBG_PRE and PLA_MACDBG_POST */
+#define DEBUG_OE   BIT(0)
+#define DEBUG_LTSSM0x0082
+
 /* PLA_EXTRA_STATUS */
+#define U3P3_CHECK_EN  BIT(7)  /* RTL_VER_05 only */
 #define LINK_CHANGE_FLAG   BIT(8)
 
 /* USB_USB2PHY */
@@ -368,6 +385,12 @@
 #define STAT_SPEED_HIGH0x
 #define STAT_SPEED_FULL0x0002
 
+/* USB_FW_FIX_EN0 */
+#define FW_FIX_SUSPEND BIT(14)
+
+/* USB_FW_FIX_EN1 */
+#define FW_IP_RESET_EN BIT(9)
+
 /* USB_LPM_CONFIG */
 #define LPM_U1U2_ENBIT(0)
 
@@ -392,12 +415,24 @@
 #define OWN_UPDATE BIT(0)
 #define OWN_CLEAR  BIT(1)
 
+/* USB_FW_TASK */
+#define FC_PATCH_TASK  BIT(1)
+
 /* USB_UPS_CTRL */
 #define POWER_CUT  0x0100
 
 /* USB_PM_CTRL_STATUS */
 #define RESUME_INDICATE0x0001
 
+/* USB_CSTMR */
+#define FORCE_SUPERBIT(0)
+
+/* USB_FW_CTRL */
+#define FLOW_CTRL_PATCH_OPTBIT(1)
+
+/* USB_FC_TIMER */
+#define CTRL_TIMER_EN  BIT(15)
+
 /* USB_USB_CTRL */
 #define RX_AGG_DISABLE

[PATCH net-next v2] r8152: adjust the settings of ups flags

2019-09-04 Thread Hayes Wang
The UPS feature only works for runtime suspend, so UPS flags only
need to be set before enabling runtime suspend. Therefore, I create
a struct to record relative information, and use it before runtime
suspend.

All chips could record such information, even though not all of
them support the feature of UPS. Then, some functions could be
combined.

Signed-off-by: Hayes Wang 
---
v2:
Fix the conflicts after commit 771efeda3936 ("r8152: modify
rtl8152_set_speed function") is applied.
---
 drivers/net/usb/r8152.c | 208 +++-
 1 file changed, 120 insertions(+), 88 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ec23c166e67b..08726090570e 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -445,18 +445,18 @@
 #define UPS_FLAGS_250M_CKDIV   BIT(2)
 #define UPS_FLAGS_EN_ALDPS BIT(3)
 #define UPS_FLAGS_CTAP_SHORT_DIS   BIT(4)
-#define UPS_FLAGS_SPEED_MASK   (0xf << 16)
 #define ups_flags_speed(x) ((x) << 16)
 #define UPS_FLAGS_EN_EEE   BIT(20)
 #define UPS_FLAGS_EN_500M_EEE  BIT(21)
 #define UPS_FLAGS_EN_EEE_CKDIV BIT(22)
+#define UPS_FLAGS_EEE_PLLOFF_100   BIT(23)
 #define UPS_FLAGS_EEE_PLLOFF_GIGA  BIT(24)
 #define UPS_FLAGS_EEE_CMOD_LV_EN   BIT(25)
 #define UPS_FLAGS_EN_GREEN BIT(26)
 #define UPS_FLAGS_EN_FLOW_CTR  BIT(27)
 
 enum spd_duplex {
-   NWAY_10M_HALF = 1,
+   NWAY_10M_HALF,
NWAY_10M_FULL,
NWAY_100M_HALF,
NWAY_100M_FULL,
@@ -749,6 +749,23 @@ struct r8152 {
void (*autosuspend_en)(struct r8152 *tp, bool enable);
} rtl_ops;
 
+   struct ups_info {
+   u32 _10m_ckdiv:1;
+   u32 _250m_ckdiv:1;
+   u32 aldps:1;
+   u32 lite_mode:2;
+   u32 speed_duplex:4;
+   u32 eee:1;
+   u32 eee_lite:1;
+   u32 eee_ckdiv:1;
+   u32 eee_plloff_100:1;
+   u32 eee_plloff_giga:1;
+   u32 eee_cmod_lv:1;
+   u32 green:1;
+   u32 flow_control:1;
+   u32 ctap_short_off:1;
+   } ups_info;
+
atomic_t rx_count;
 
bool eee_en;
@@ -2865,14 +2882,76 @@ static void r8153_u2p3en(struct r8152 *tp, bool enable)
ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data);
 }
 
-static void r8153b_ups_flags_w1w0(struct r8152 *tp, u32 set, u32 clear)
+static void r8153b_ups_flags(struct r8152 *tp)
 {
-   u32 ocp_data;
+   u32 ups_flags = 0;
+
+   if (tp->ups_info.green)
+   ups_flags |= UPS_FLAGS_EN_GREEN;
+
+   if (tp->ups_info.aldps)
+   ups_flags |= UPS_FLAGS_EN_ALDPS;
+
+   if (tp->ups_info.eee)
+   ups_flags |= UPS_FLAGS_EN_EEE;
+
+   if (tp->ups_info.flow_control)
+   ups_flags |= UPS_FLAGS_EN_FLOW_CTR;
+
+   if (tp->ups_info.eee_ckdiv)
+   ups_flags |= UPS_FLAGS_EN_EEE_CKDIV;
+
+   if (tp->ups_info.eee_cmod_lv)
+   ups_flags |= UPS_FLAGS_EEE_CMOD_LV_EN;
+
+   if (tp->ups_info._10m_ckdiv)
+   ups_flags |= UPS_FLAGS_EN_10M_CKDIV;
+
+   if (tp->ups_info.eee_plloff_100)
+   ups_flags |= UPS_FLAGS_EEE_PLLOFF_100;
 
-   ocp_data = ocp_read_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS);
-   ocp_data &= ~clear;
-   ocp_data |= set;
-   ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ocp_data);
+   if (tp->ups_info.eee_plloff_giga)
+   ups_flags |= UPS_FLAGS_EEE_PLLOFF_GIGA;
+
+   if (tp->ups_info._250m_ckdiv)
+   ups_flags |= UPS_FLAGS_250M_CKDIV;
+
+   if (tp->ups_info.ctap_short_off)
+   ups_flags |= UPS_FLAGS_CTAP_SHORT_DIS;
+
+   switch (tp->ups_info.speed_duplex) {
+   case NWAY_10M_HALF:
+   ups_flags |= ups_flags_speed(1);
+   break;
+   case NWAY_10M_FULL:
+   ups_flags |= ups_flags_speed(2);
+   break;
+   case NWAY_100M_HALF:
+   ups_flags |= ups_flags_speed(3);
+   break;
+   case NWAY_100M_FULL:
+   ups_flags |= ups_flags_speed(4);
+   break;
+   case NWAY_1000M_FULL:
+   ups_flags |= ups_flags_speed(5);
+   break;
+   case FORCE_10M_HALF:
+   ups_flags |= ups_flags_speed(6);
+   break;
+   case FORCE_10M_FULL:
+   ups_flags |= ups_flags_speed(7);
+   break;
+   case FORCE_100M_HALF:
+   ups_flags |= ups_flags_speed(8);
+   break;
+   case FORCE_100M_FULL:
+   ups_flags |= ups_flags_speed(9);
+   break;
+   default:
+   break;
+   }
+
+   ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags);
 }
 
 static void r8153b_green_en(struct r8152 *tp, bool enable)
@@ -

[PATCH net-next] r8152: adjust the settings of ups flags

2019-09-04 Thread Hayes Wang
The UPS feature only works for runtime suspend, so UPS flags only
need to be set before enabling runtime suspend. Therefore, I create
a struct to record relative information, and use it before runtime
suspend.

All chips could record such information, even though not all of
them support the feature of UPS. Then, some functions could be
combined.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 215 +++-
 1 file changed, 125 insertions(+), 90 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 778d27d1fb15..86c403d12b6b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -445,18 +445,18 @@
 #define UPS_FLAGS_250M_CKDIV   BIT(2)
 #define UPS_FLAGS_EN_ALDPS BIT(3)
 #define UPS_FLAGS_CTAP_SHORT_DIS   BIT(4)
-#define UPS_FLAGS_SPEED_MASK   (0xf << 16)
 #define ups_flags_speed(x) ((x) << 16)
 #define UPS_FLAGS_EN_EEE   BIT(20)
 #define UPS_FLAGS_EN_500M_EEE  BIT(21)
 #define UPS_FLAGS_EN_EEE_CKDIV BIT(22)
+#define UPS_FLAGS_EEE_PLLOFF_100   BIT(23)
 #define UPS_FLAGS_EEE_PLLOFF_GIGA  BIT(24)
 #define UPS_FLAGS_EEE_CMOD_LV_EN   BIT(25)
 #define UPS_FLAGS_EN_GREEN BIT(26)
 #define UPS_FLAGS_EN_FLOW_CTR  BIT(27)
 
 enum spd_duplex {
-   NWAY_10M_HALF = 1,
+   NWAY_10M_HALF,
NWAY_10M_FULL,
NWAY_100M_HALF,
NWAY_100M_FULL,
@@ -749,6 +749,23 @@ struct r8152 {
void (*autosuspend_en)(struct r8152 *tp, bool enable);
} rtl_ops;
 
+   struct ups_info {
+   u32 _10m_ckdiv:1;
+   u32 _250m_ckdiv:1;
+   u32 aldps:1;
+   u32 lite_mode:2;
+   u32 speed_duplex:4;
+   u32 eee:1;
+   u32 eee_lite:1;
+   u32 eee_ckdiv:1;
+   u32 eee_plloff_100:1;
+   u32 eee_plloff_giga:1;
+   u32 eee_cmod_lv:1;
+   u32 green:1;
+   u32 flow_control:1;
+   u32 ctap_short_off:1;
+   } ups_info;
+
atomic_t rx_count;
 
bool eee_en;
@@ -2857,14 +2874,76 @@ static void r8153_u2p3en(struct r8152 *tp, bool enable)
ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data);
 }
 
-static void r8153b_ups_flags_w1w0(struct r8152 *tp, u32 set, u32 clear)
+static void r8153b_ups_flags(struct r8152 *tp)
 {
-   u32 ocp_data;
+   u32 ups_flags = 0;
+
+   if (tp->ups_info.green)
+   ups_flags |= UPS_FLAGS_EN_GREEN;
+
+   if (tp->ups_info.aldps)
+   ups_flags |= UPS_FLAGS_EN_ALDPS;
+
+   if (tp->ups_info.eee)
+   ups_flags |= UPS_FLAGS_EN_EEE;
+
+   if (tp->ups_info.flow_control)
+   ups_flags |= UPS_FLAGS_EN_FLOW_CTR;
+
+   if (tp->ups_info.eee_ckdiv)
+   ups_flags |= UPS_FLAGS_EN_EEE_CKDIV;
+
+   if (tp->ups_info.eee_cmod_lv)
+   ups_flags |= UPS_FLAGS_EEE_CMOD_LV_EN;
+
+   if (tp->ups_info._10m_ckdiv)
+   ups_flags |= UPS_FLAGS_EN_10M_CKDIV;
+
+   if (tp->ups_info.eee_plloff_100)
+   ups_flags |= UPS_FLAGS_EEE_PLLOFF_100;
+
+   if (tp->ups_info.eee_plloff_giga)
+   ups_flags |= UPS_FLAGS_EEE_PLLOFF_GIGA;
+
+   if (tp->ups_info._250m_ckdiv)
+   ups_flags |= UPS_FLAGS_250M_CKDIV;
+
+   if (tp->ups_info.ctap_short_off)
+   ups_flags |= UPS_FLAGS_CTAP_SHORT_DIS;
+
+   switch (tp->ups_info.speed_duplex) {
+   case NWAY_10M_HALF:
+   ups_flags |= ups_flags_speed(1);
+   break;
+   case NWAY_10M_FULL:
+   ups_flags |= ups_flags_speed(2);
+   break;
+   case NWAY_100M_HALF:
+   ups_flags |= ups_flags_speed(3);
+   break;
+   case NWAY_100M_FULL:
+   ups_flags |= ups_flags_speed(4);
+   break;
+   case NWAY_1000M_FULL:
+   ups_flags |= ups_flags_speed(5);
+   break;
+   case FORCE_10M_HALF:
+   ups_flags |= ups_flags_speed(6);
+   break;
+   case FORCE_10M_FULL:
+   ups_flags |= ups_flags_speed(7);
+   break;
+   case FORCE_100M_HALF:
+   ups_flags |= ups_flags_speed(8);
+   break;
+   case FORCE_100M_FULL:
+   ups_flags |= ups_flags_speed(9);
+   break;
+   default:
+   break;
+   }
 
-   ocp_data = ocp_read_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS);
-   ocp_data &= ~clear;
-   ocp_data |= set;
-   ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ocp_data);
+   ocp_write_dword(tp, MCU_TYPE_USB, USB_UPS_FLAGS, ups_flags);
 }
 
 static void r8153b_green_en(struct r8152 *tp, bool enable)
@@ -2885,7 +2964,7 @@ static void r8153b_green_en(struct r8152 *tp, bool enable)
data |= GREEN

RE: [PATCH net-next] r8152: modify rtl8152_set_speed function

2019-09-03 Thread Hayes Wang
Heiner Kallweit [mailto:hkallwe...@gmail.com]
> Sent: Tuesday, September 03, 2019 3:13 PM
[...]
> > Some of our chips support the feature of UPS. When satisfying certain
> > condition, the hw would recover the settings of speed. Therefore, I have
> > to record the settings of the speed, and set them to hw.
> >
> Not knowing the UPS feature in detail:
> In net-next I changed the software "PHY speed-down" implementation to
> be more generic. It stores the old advertised settings in a new
> phy_device member adv_old, and restores them in phy_speed_up().
> Maybe what you need is similar.

It is a feature about power saving. When some conditions are
satisfied, the power of PHY would be cut. And the hw would
restore the PHY settings including the speed automatically,
when leaving power saving mode.

Best Regards,
Hayes




RE: [PATCH net-next] r8152: modify rtl8152_set_speed function

2019-09-02 Thread Hayes Wang
Heiner Kallweit [mailto:hkallwe...@gmail.com]
> Sent: Tuesday, September 03, 2019 2:45 PM
[...]
> > Besides, I have a question. I think I don't need rtl8152_set_speed()
> > if I implement phylib. However, I need to record some information
> > according to the settings of speed. For now, I do it in rtl8152_set_speed().
> > Do you have any idea about how I should do it with phylib without
> > rtl8152_set_speed()?
> >
> When saying "record some information", what kind of information?

Some of our chips support the feature of UPS. When satisfying certain
condition, the hw would recover the settings of speed. Therefore, I have
to record the settings of the speed, and set them to hw.

> The speed itself is stored in struct phy_device, if you need to adjust
> certain chip settings depending on negotiated speed, then you can do
> this in a callback (parameter handler of phy_connect_direct).
> See e.g. r8169_phylink_handler()

Thanks. I would study it.

Best Regards,
Hayes




RE: [PATCH net-next] r8152: modify rtl8152_set_speed function

2019-09-02 Thread Hayes Wang
Heiner Kallweit [mailto:hkallwe...@gmail.com]
> Sent: Tuesday, September 03, 2019 2:14 PM
[...]
> >> Seeing all this code it might be a good idea to switch this driver
> >> to phylib, similar to what I did with r8169 some time ago.
> >
> > It is too complex to be completed for me at the moment.
> > If this patch is unacceptable, I would submit other
> > patches first. Thanks.
> >
> My remark isn't directly related to your patch and wasn't
> meant as an immediate ToDo. It's just a hint, because I think
> using phylib could help to significantly simplify the driver.

I would schedule this in my work. Maybe I finish submitting
the other patches later.

Besides, I have a question. I think I don't need rtl8152_set_speed()
if I implement phylib. However, I need to record some information
according to the settings of speed. For now, I do it in rtl8152_set_speed().
Do you have any idea about how I should do it with phylib without
rtl8152_set_speed()?

Best Regards,
Hayes




RE: [PATCH net-next] r8152: modify rtl8152_set_speed function

2019-09-02 Thread Hayes Wang
Heiner Kallweit [mailto:hkallwe...@gmail.com]
> Sent: Tuesday, September 03, 2019 2:37 AM
[...]
> Seeing all this code it might be a good idea to switch this driver
> to phylib, similar to what I did with r8169 some time ago.

It is too complex to be completed for me at the moment.
If this patch is unacceptable, I would submit other
patches first. Thanks.

Best Regards,
Hayes




[PATCH net-next] r8152: modify rtl8152_set_speed function

2019-09-02 Thread Hayes Wang
First, for AUTONEG_DISABLE, we only need to modify MII_BMCR.

Second, add advertising parameter for rtl8152_set_speed(). Add
RTL_ADVERTISED_xxx for advertising parameter of rtl8152_set_speed().
Then, the advertising settings from ethtool could be saved.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 196 +++-
 1 file changed, 132 insertions(+), 64 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c6fa0c17c13d..5d49d8dd93e1 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -757,6 +757,7 @@ struct r8152 {
u32 msg_enable;
u32 tx_qlen;
u32 coalesce;
+   u32 advertising;
u32 rx_buf_sz;
u32 rx_copybreak;
u32 rx_pending;
@@ -790,6 +791,13 @@ enum tx_csum_stat {
TX_CSUM_NONE
 };
 
+#define RTL_ADVERTISED_10_HALF BIT(0)
+#define RTL_ADVERTISED_10_FULL BIT(1)
+#define RTL_ADVERTISED_100_HALFBIT(2)
+#define RTL_ADVERTISED_100_FULLBIT(3)
+#define RTL_ADVERTISED_1000_HALF   BIT(4)
+#define RTL_ADVERTISED_1000_FULL   BIT(5)
+
 /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
  * The RTL chips use a 64 element hash table based on the Ethernet CRC.
  */
@@ -3801,90 +3809,117 @@ static void rtl8153b_disable(struct r8152 *tp)
r8153b_aldps_en(tp, true);
 }
 
-static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 
duplex)
+static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u32 speed, u8 
duplex,
+u32 advertising)
 {
-   u16 bmcr, anar, gbcr;
enum spd_duplex speed_duplex;
+   u16 bmcr;
int ret = 0;
 
-   anar = r8152_mdio_read(tp, MII_ADVERTISE);
-   anar &= ~(ADVERTISE_10HALF | ADVERTISE_10FULL |
- ADVERTISE_100HALF | ADVERTISE_100FULL);
-   if (tp->mii.supports_gmii) {
-   gbcr = r8152_mdio_read(tp, MII_CTRL1000);
-   gbcr &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
-   } else {
-   gbcr = 0;
-   }
-
if (autoneg == AUTONEG_DISABLE) {
-   if (speed == SPEED_10) {
-   bmcr = 0;
-   anar |= ADVERTISE_10HALF | ADVERTISE_10FULL;
-   speed_duplex = FORCE_10M_HALF;
-   } else if (speed == SPEED_100) {
-   bmcr = BMCR_SPEED100;
-   anar |= ADVERTISE_100HALF | ADVERTISE_100FULL;
-   speed_duplex = FORCE_100M_HALF;
-   } else if (speed == SPEED_1000 && tp->mii.supports_gmii) {
-   bmcr = BMCR_SPEED1000;
-   gbcr |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
-   speed_duplex = NWAY_1000M_FULL;
-   } else {
-   ret = -EINVAL;
-   goto out;
-   }
+   if (duplex != DUPLEX_HALF && duplex != DUPLEX_FULL)
+   return -EINVAL;
 
-   if (duplex == DUPLEX_FULL) {
-   bmcr |= BMCR_FULLDPLX;
-   if (speed != SPEED_1000)
-   speed_duplex++;
-   }
-   } else {
-   if (speed == SPEED_10) {
+   switch (speed) {
+   case SPEED_10:
+   bmcr = BMCR_SPEED10;
if (duplex == DUPLEX_FULL) {
-   anar |= ADVERTISE_10HALF | ADVERTISE_10FULL;
-   speed_duplex = NWAY_10M_FULL;
+   bmcr |= BMCR_FULLDPLX;
+   speed_duplex = FORCE_10M_FULL;
} else {
-   anar |= ADVERTISE_10HALF;
-   speed_duplex = NWAY_10M_HALF;
+   speed_duplex = FORCE_10M_HALF;
}
-   } else if (speed == SPEED_100) {
+   break;
+   case SPEED_100:
+   bmcr = BMCR_SPEED100;
if (duplex == DUPLEX_FULL) {
-   anar |= ADVERTISE_10HALF | ADVERTISE_10FULL;
-   anar |= ADVERTISE_100HALF | ADVERTISE_100FULL;
-   speed_duplex = NWAY_100M_FULL;
+   bmcr |= BMCR_FULLDPLX;
+   speed_duplex = FORCE_100M_FULL;
} else {
-   anar |= ADVERTISE_10HALF;
-   anar |= ADVERTISE_100HALF;
-   speed_duplex = NWAY_100M_HALF;
+   speed_duplex = FORCE_100M_HALF;
}
-   } else if (speed == SPEED_1000 && tp->mii.supports_g

RE: [PATCH net-next] r8152: fix accessing skb after napi_gro_receive

2019-09-01 Thread Hayes Wang
Eric Dumazet [mailto:eric.duma...@gmail.com]
> Sent: Friday, August 30, 2019 12:32 AM
> To: Hayes Wang; net...@vger.kernel.org
> Cc: nic_swsd; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH net-next] r8152: fix accessing skb after napi_gro_receive
> 
> On 8/19/19 5:15 AM, Hayes Wang wrote:
> > Fix accessing skb after napi_gro_receive which is caused by
> > commit 47922fcde536 ("r8152: support skb_add_rx_frag").
> >
> > Fixes: 47922fcde536 ("r8152: support skb_add_rx_frag")
> > Signed-off-by: Hayes Wang 
> > ---
> 
> It is customary to add a tag to credit the reporter...
> 
> Something like :
> 
> Reported-by: 
> 
> Thanks.

Sorry. It's my mistake.
I would note that next time.

Best Regards,
Hayes




RE: [PATCH net v4 0/2] r8152: fix side effect

2019-08-28 Thread Hayes Wang
David Miller [mailto:da...@davemloft.net]
> Sent: Thursday, August 29, 2019 7:18 AM
[...]
> > v4:
> > Add Fixes tag for both patch #1 and #2.
> 
> I applied v3, sorry.
> 
> I think it is OK as I will backport things to v5.2 -stable anyways.

Thanks.

Best Regards,
Hayes




[PATCH net v4 1/2] Revert "r8152: napi hangup fix after disconnect"

2019-08-28 Thread Hayes Wang
This reverts commit 0ee1f4734967af8321ecebaf9c74221ace34f2d5.

The commit 0ee1f4734967 ("r8152: napi hangup fix after
disconnect") adds a check about RTL8152_UNPLUG to determine
if calling napi_disable() is invalid in rtl8152_close(),
when rtl8152_disconnect() is called. This avoids to use
napi_disable() after calling netif_napi_del().

However, commit ffa9fec30ca0 ("r8152: set RTL8152_UNPLUG
only for real disconnection") causes that RTL8152_UNPLUG
is not always set when calling rtl8152_disconnect().
Therefore, I have to revert commit 0ee1f4734967 ("r8152:
napi hangup fix after disconnect"), first. And submit
another patch to fix it.

Fixes: ffa9fec30ca0 ("r8152: set RTL8152_UNPLUG only for real disconnection")
Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index eee0f5007ee3..ad3abe26b51b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -4021,8 +4021,7 @@ static int rtl8152_close(struct net_device *netdev)
 #ifdef CONFIG_PM_SLEEP
unregister_pm_notifier(&tp->pm_notifier);
 #endif
-   if (!test_bit(RTL8152_UNPLUG, &tp->flags))
-   napi_disable(&tp->napi);
+   napi_disable(&tp->napi);
clear_bit(WORK_ENABLE, &tp->flags);
usb_kill_urb(tp->intr_urb);
cancel_delayed_work_sync(&tp->schedule);
-- 
2.21.0



[PATCH net v4 2/2] r8152: remove calling netif_napi_del

2019-08-28 Thread Hayes Wang
Remove unnecessary use of netif_napi_del. This also avoids to call
napi_disable() after netif_napi_del().

Fixes: ffa9fec30ca0 ("r8152: set RTL8152_UNPLUG only for real disconnection")
Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ad3abe26b51b..04137ac373b0 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -5352,7 +5352,6 @@ static int rtl8152_probe(struct usb_interface *intf,
return 0;
 
 out1:
-   netif_napi_del(&tp->napi);
usb_set_intfdata(intf, NULL);
 out:
free_netdev(netdev);
@@ -5367,7 +5366,6 @@ static void rtl8152_disconnect(struct usb_interface *intf)
if (tp) {
rtl_set_unplug(tp);
 
-   netif_napi_del(&tp->napi);
unregister_netdev(tp->netdev);
cancel_delayed_work_sync(&tp->hw_phy_work);
tp->rtl_ops.unload(tp);
-- 
2.21.0



[PATCH net v4 0/2] r8152: fix side effect

2019-08-28 Thread Hayes Wang
v4:
Add Fixes tag for both patch #1 and #2.

v3:
Update the commit message for patch #1.

v2:
Replace patch #2 with "r8152: remove calling netif_napi_del".

v1:
The commit 0ee1f4734967 ("r8152: napi hangup fix after disconnect")
add a check to avoid using napi_disable after netif_napi_del. However,
the commit ffa9fec30ca0 ("r8152: set RTL8152_UNPLUG only for real
disconnection") let the check useless.

Therefore, I revert commit 0ee1f4734967 ("r8152: napi hangup fix
after disconnect") first, and add another patch to fix it.

Hayes Wang (2):
  Revert "r8152: napi hangup fix after disconnect"
  r8152: remove calling netif_napi_del

 drivers/net/usb/r8152.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

-- 
2.21.0



[PATCH net v3 2/2] r8152: remove calling netif_napi_del

2019-08-27 Thread Hayes Wang
Remove unnecessary use of netif_napi_del. This also avoids to call
napi_disable() after netif_napi_del().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ad3abe26b51b..04137ac373b0 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -5352,7 +5352,6 @@ static int rtl8152_probe(struct usb_interface *intf,
return 0;
 
 out1:
-   netif_napi_del(&tp->napi);
usb_set_intfdata(intf, NULL);
 out:
free_netdev(netdev);
@@ -5367,7 +5366,6 @@ static void rtl8152_disconnect(struct usb_interface *intf)
if (tp) {
rtl_set_unplug(tp);
 
-   netif_napi_del(&tp->napi);
unregister_netdev(tp->netdev);
cancel_delayed_work_sync(&tp->hw_phy_work);
tp->rtl_ops.unload(tp);
-- 
2.21.0



[PATCH net v3 1/2] Revert "r8152: napi hangup fix after disconnect"

2019-08-27 Thread Hayes Wang
This reverts commit 0ee1f4734967af8321ecebaf9c74221ace34f2d5.

The commit 0ee1f4734967 ("r8152: napi hangup fix after
disconnect") adds a check about RTL8152_UNPLUG to determine
if calling napi_disable() is invalid in rtl8152_close(),
when rtl8152_disconnect() is called. This avoids to use
napi_disable() after calling netif_napi_del().

Howver, commit ffa9fec30ca0 ("r8152: set RTL8152_UNPLUG
only for real disconnection") causes that RTL8152_UNPLUG
is not always set when calling rtl8152_disconnect().
Therefore, I have to revert commit 0ee1f4734967 ("r8152:
napi hangup fix after disconnect"), first. And submit
another patch to fix it.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index eee0f5007ee3..ad3abe26b51b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -4021,8 +4021,7 @@ static int rtl8152_close(struct net_device *netdev)
 #ifdef CONFIG_PM_SLEEP
unregister_pm_notifier(&tp->pm_notifier);
 #endif
-   if (!test_bit(RTL8152_UNPLUG, &tp->flags))
-   napi_disable(&tp->napi);
+   napi_disable(&tp->napi);
clear_bit(WORK_ENABLE, &tp->flags);
usb_kill_urb(tp->intr_urb);
cancel_delayed_work_sync(&tp->schedule);
-- 
2.21.0



[PATCH net v3 0/2] r8152: fix side effect

2019-08-27 Thread Hayes Wang
v3:
Update the commit message for patch #1.

v2:
Replace patch #2 with "r8152: remove calling netif_napi_del".

v1:
The commit 0ee1f4734967 ("r8152: napi hangup fix after disconnect")
add a check to avoid using napi_disable after netif_napi_del. However,
the commit ffa9fec30ca0 ("r8152: set RTL8152_UNPLUG only for real
disconnection") let the check useless.

Therefore, I revert commit 0ee1f4734967 ("r8152: napi hangup fix
after disconnect") first, and add another patch to fix it.

Hayes Wang (2):
  Revert "r8152: napi hangup fix after disconnect"
  r8152: remove calling netif_napi_del

 drivers/net/usb/r8152.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

-- 
2.21.0



RE: [PATCH net v2 1/2] Revert "r8152: napi hangup fix after disconnect"

2019-08-26 Thread Hayes Wang
Jiri Slaby [mailto:jsl...@suse.cz]
> Sent: Monday, August 26, 2019 4:55 PM
[...]
> Could you clarify *why* it conflicts? And how is the problem fixed by
> 0ee1f473496 avoided now?

In rtl8152_disconnect(), the flow would be as following.

static void rtl8152_disconnect(struct usb_interface *intf)
{
...
- netif_napi_del(&tp->napi);
- unregister_netdev(tp->netdev);
   - rtl8152_close
  - napi_disable

Therefore you add a checking of RTL8152_UNPLUG to avoid
calling napi_disable() after netif_napi_del(). However,
after commit ffa9fec30ca0 ("r8152: set RTL8152_UNPLUG
only for real disconnection"), RTL8152_UNPLUG is not
always set when calling rtl8152_disconnect(). That is,
napi_disable() would be called after netif_napi_del(),
if RTL8152_UNPLUG is not set.

The best way is to avoid calling netif_napi_del() before
calling unregister_netdev(). And I has submitted such
patch following this one.

Best Regards,
Hayes




[PATCH net v2 1/2] Revert "r8152: napi hangup fix after disconnect"

2019-08-26 Thread Hayes Wang
This reverts commit 0ee1f4734967af8321ecebaf9c74221ace34f2d5.

This conflicts with commit ffa9fec30ca0 ("r8152: set
RTL8152_UNPLUG only for real disconnection").

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index eee0f5007ee3..ad3abe26b51b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -4021,8 +4021,7 @@ static int rtl8152_close(struct net_device *netdev)
 #ifdef CONFIG_PM_SLEEP
unregister_pm_notifier(&tp->pm_notifier);
 #endif
-   if (!test_bit(RTL8152_UNPLUG, &tp->flags))
-   napi_disable(&tp->napi);
+   napi_disable(&tp->napi);
clear_bit(WORK_ENABLE, &tp->flags);
usb_kill_urb(tp->intr_urb);
cancel_delayed_work_sync(&tp->schedule);
-- 
2.21.0



[PATCH net v2 2/2] r8152: remove calling netif_napi_del

2019-08-26 Thread Hayes Wang
Remove unnecessary use of netif_napi_del. This also avoids to call
napi_disable() after netif_napi_del().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ad3abe26b51b..04137ac373b0 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -5352,7 +5352,6 @@ static int rtl8152_probe(struct usb_interface *intf,
return 0;
 
 out1:
-   netif_napi_del(&tp->napi);
usb_set_intfdata(intf, NULL);
 out:
free_netdev(netdev);
@@ -5367,7 +5366,6 @@ static void rtl8152_disconnect(struct usb_interface *intf)
if (tp) {
rtl_set_unplug(tp);
 
-   netif_napi_del(&tp->napi);
unregister_netdev(tp->netdev);
cancel_delayed_work_sync(&tp->hw_phy_work);
tp->rtl_ops.unload(tp);
-- 
2.21.0



[PATCH net v2 0/2] r8152: fix side effect

2019-08-26 Thread Hayes Wang
v2:
Replace patch #2 with "r8152: remove calling netif_napi_del".

v1:
The commit 0ee1f4734967 ("r8152: napi hangup fix after disconnect")
add a check to avoid using napi_disable after netif_napi_del. However,
the commit ffa9fec30ca0 ("r8152: set RTL8152_UNPLUG only for real
disconnection") let the check useless.

Therefore, I revert commit 0ee1f4734967 ("r8152: napi hangup fix
after disconnect") first, and add another patch to fix it.

Hayes Wang (2):
  Revert "r8152: napi hangup fix after disconnect"
  r8152: remove calling netif_napi_del

 drivers/net/usb/r8152.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

-- 
2.21.0



RE: [PATCH net-next v4 0/2] r8152: save EEE

2019-08-25 Thread Hayes Wang
Andrew Lunn [mailto:and...@lunn.ch]
> Sent: Friday, August 23, 2019 10:37 PM
[...]
> Hi Hayes
> 
> That was 3 revisions of the patches in less than 30 minutes. Slow
> down, take your time, review your work yourself before posting it,
> etc.
> 
> Aim for no more than one revision, posted to the list, per day.

Sorry. I would note that.


Best Regards,
Hayes




[PATCH net 1/2] Revert "r8152: napi hangup fix after disconnect"

2019-08-23 Thread Hayes Wang
This reverts commit 0ee1f4734967af8321ecebaf9c74221ace34f2d5.

This conflicts with commit ffa9fec30ca0 ("r8152: set
RTL8152_UNPLUG only for real disconnection").

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0cc03a9ff545..690a24d1ef82 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -4018,8 +4018,7 @@ static int rtl8152_close(struct net_device *netdev)
 #ifdef CONFIG_PM_SLEEP
unregister_pm_notifier(&tp->pm_notifier);
 #endif
-   if (!test_bit(RTL8152_UNPLUG, &tp->flags))
-   napi_disable(&tp->napi);
+   napi_disable(&tp->napi);
clear_bit(WORK_ENABLE, &tp->flags);
usb_kill_urb(tp->intr_urb);
cancel_delayed_work_sync(&tp->schedule);
-- 
2.21.0



[PATCH net 0/2] r8152: fix side effect

2019-08-23 Thread Hayes Wang
The commit 0ee1f4734967 ("r8152: napi hangup fix after disconnect")
add a check to avoid using napi_disable after netif_napi_del. However,
the commit ffa9fec30ca0 ("r8152: set RTL8152_UNPLUG only for real
disconnection") let the check useless.

Therefore, I revert commit 0ee1f4734967 ("r8152: napi hangup fix
after disconnect") first, and add another patch to fix it.

Hayes Wang (2):
  Revert "r8152: napi hangup fix after disconnect"
  r8152: avoid using napi_disable after netif_napi_del.

 drivers/net/usb/r8152.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

-- 
2.21.0



[PATCH net 2/2] r8152: avoid using napi_disable after netif_napi_del.

2019-08-23 Thread Hayes Wang
Exchange netif_napi_del() and unregister_netdev() in rtl8152_disconnect()
to avoid using napi_disable() after netif_napi_del().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 690a24d1ef82..29390eda5251 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -5364,8 +5364,8 @@ static void rtl8152_disconnect(struct usb_interface *intf)
if (tp) {
rtl_set_unplug(tp);
 
-   netif_napi_del(&tp->napi);
unregister_netdev(tp->netdev);
+   netif_napi_del(&tp->napi);
cancel_delayed_work_sync(&tp->hw_phy_work);
tp->rtl_ops.unload(tp);
free_netdev(tp->netdev);
-- 
2.21.0



[PATCH net-next v4 2/2] r8152: add a helper function about setting EEE

2019-08-23 Thread Hayes Wang
Add a helper function "rtl_eee_enable" for setting EEE. Besides, I
move r8153_eee_en() and r8153b_eee_en(). And, I remove r8152b_enable_eee(),
r8153_set_eee(), and r8153b_set_eee().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 168 ++--
 1 file changed, 77 insertions(+), 91 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index a7aa48bee732..17f0e9e98697 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3202,14 +3202,75 @@ static void r8152_eee_en(struct r8152 *tp, bool enable)
ocp_reg_write(tp, OCP_EEE_CONFIG3, config3);
 }
 
-static void r8152b_enable_eee(struct r8152 *tp)
+static void r8153_eee_en(struct r8152 *tp, bool enable)
 {
-   if (tp->eee_en) {
-   r8152_eee_en(tp, true);
-   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tp->eee_adv);
+   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 {
-   r8152_eee_en(tp, false);
-   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+   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 r8153b_eee_en(struct r8152 *tp, bool enable)
+{
+   r8153_eee_en(tp, enable);
+
+   if (enable)
+   r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_EEE, 0);
+   else
+   r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_EEE);
+}
+
+static void rtl_eee_enable(struct r8152 *tp, bool enable)
+{
+   switch (tp->version) {
+   case RTL_VER_01:
+   case RTL_VER_02:
+   case RTL_VER_07:
+   if (enable) {
+   r8152_eee_en(tp, true);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
+   tp->eee_adv);
+   } else {
+   r8152_eee_en(tp, false);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+   }
+   break;
+   case RTL_VER_03:
+   case RTL_VER_04:
+   case RTL_VER_05:
+   case RTL_VER_06:
+   if (enable) {
+   r8153_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   } else {
+   r8153_eee_en(tp, false);
+   ocp_reg_write(tp, OCP_EEE_ADV, 0);
+   }
+   break;
+   case RTL_VER_08:
+   case RTL_VER_09:
+   if (enable) {
+   r8153b_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   } else {
+   r8153b_eee_en(tp, false);
+   ocp_reg_write(tp, OCP_EEE_ADV, 0);
+   }
+   break;
+   default:
+   break;
}
 }
 
@@ -3231,7 +3292,7 @@ static void rtl8152_disable(struct r8152 *tp)
 
 static void r8152b_hw_phy_cfg(struct r8152 *tp)
 {
-   r8152b_enable_eee(tp);
+   rtl_eee_enable(tp, tp->eee_en);
r8152_aldps_en(tp, true);
r8152b_enable_fc(tp);
 
@@ -3425,36 +3486,6 @@ static void r8153b_aldps_en(struct r8152 *tp, bool 
enable)
r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_ALDPS);
 }
 
-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 r8153b_eee_en(struct r8152 *tp, bool enable)
-{
-   r8153_eee_en(tp, enable);
-
-   if (enable)
-   r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_EEE, 0);
-   else
-   r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_EEE);
-}
-
 static void r8153b_enable_fc(struct r8152 *tp)
 {
r8152b_enable_fc(tp);
@@ -3470,8 +3501,7 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
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);
+   rtl_eee_enable(tp, false);
 
if (tp->version == RTL_VER_03) {
data = ocp_reg_read(tp, OCP_EEE_CFG);
@@ -3502,10 +3532,8 @@ static void r8153_hw_phy_cfg(struct r8152

[PATCH net-next v4 0/2] r8152: save EEE

2019-08-23 Thread Hayes Wang
v4:
For patch #2, remove redundant calling of "ocp_reg_write(tp, OCP_EEE_ADV, 0)".

v3:
For patch #2, fix the mistake caused by copying and pasting.

v2:
Adjust patch #1. The EEE has been disabled in the beginning of
r8153_hw_phy_cfg() and r8153b_hw_phy_cfg(), so only check if
it is necessary to enable EEE.

Add the patch #2 for the helper function.

v1:
Saving the settings of EEE to avoid they become the default settings
after reset_resume().

Hayes Wang (2):
  r8152: saving the settings of EEE
  r8152: add a helper function about setting EEE

 drivers/net/usb/r8152.c | 182 +---
 1 file changed, 95 insertions(+), 87 deletions(-)

-- 
2.21.0



[PATCH net-next v4 1/2] r8152: saving the settings of EEE

2019-08-23 Thread Hayes Wang
Saving the settings of EEE to avoid they become the default settings
after reset_resume().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 80 +
 1 file changed, 50 insertions(+), 30 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 1aa61610f0bb..a7aa48bee732 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -751,6 +751,7 @@ struct r8152 {
 
atomic_t rx_count;
 
+   bool eee_en;
int intr_interval;
u32 saved_wolopts;
u32 msg_enable;
@@ -762,6 +763,7 @@ struct r8152 {
 
u16 ocp_base;
u16 speed;
+   u16 eee_adv;
u8 *intr_buff;
u8 version;
u8 duplex;
@@ -3202,8 +3204,13 @@ static void r8152_eee_en(struct r8152 *tp, bool enable)
 
 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);
+   if (tp->eee_en) {
+   r8152_eee_en(tp, true);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tp->eee_adv);
+   } else {
+   r8152_eee_en(tp, false);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+   }
 }
 
 static void r8152b_enable_fc(struct r8152 *tp)
@@ -3495,8 +3502,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_eee_en(tp, true);
-   ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
+   if (tp->eee_en) {
+   r8153_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   }
 
r8153_aldps_en(tp, true);
r8152b_enable_fc(tp);
@@ -3599,8 +3608,10 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp)
 
r8153b_ups_flags_w1w0(tp, ups_flags, 0);
 
-   r8153b_eee_en(tp, true);
-   ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
+   if (tp->eee_en) {
+   r8153b_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   }
 
r8153b_aldps_en(tp, true);
r8153b_enable_fc(tp);
@@ -4891,7 +4902,7 @@ static void rtl8152_get_strings(struct net_device *dev, 
u32 stringset, u8 *data)
 
 static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee)
 {
-   u32 ocp_data, lp, adv, supported = 0;
+   u32 lp, adv, supported = 0;
u16 val;
 
val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
@@ -4903,13 +4914,10 @@ static int r8152_get_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
lp = mmd_eee_adv_to_ethtool_adv_t(val);
 
-   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
-   ocp_data &= EEE_RX_EN | EEE_TX_EN;
-
-   eee->eee_enabled = !!ocp_data;
+   eee->eee_enabled = tp->eee_en;
eee->eee_active = !!(supported & adv & lp);
eee->supported = supported;
-   eee->advertised = adv;
+   eee->advertised = tp->eee_adv;
eee->lp_advertised = lp;
 
return 0;
@@ -4919,19 +4927,22 @@ static int r8152_set_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
 {
u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
 
-   r8152_eee_en(tp, eee->eee_enabled);
+   tp->eee_en = eee->eee_enabled;
+   tp->eee_adv = val;
 
-   if (!eee->eee_enabled)
-   val = 0;
+   r8152_eee_en(tp, eee->eee_enabled);
 
-   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+   if (eee->eee_enabled)
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+   else
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
 
return 0;
 }
 
 static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee)
 {
-   u32 ocp_data, lp, adv, supported = 0;
+   u32 lp, adv, supported = 0;
u16 val;
 
val = ocp_reg_read(tp, OCP_EEE_ABLE);
@@ -4943,13 +4954,10 @@ static int r8153_get_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
val = ocp_reg_read(tp, OCP_EEE_LPABLE);
lp = mmd_eee_adv_to_ethtool_adv_t(val);
 
-   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
-   ocp_data &= EEE_RX_EN | EEE_TX_EN;
-
-   eee->eee_enabled = !!ocp_data;
+   eee->eee_enabled = tp->eee_en;
eee->eee_active = !!(supported & adv & lp);
eee->supported = supported;
-   eee->advertised = adv;
+   eee->advertised = tp->eee_adv;
eee->lp_advertised = lp;
 
return 0;
@@ -4959,12 +4967,15 @@ static int r8153_set_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
 {
u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
 
-   r8153_eee_en(tp, eee->eee_enabled);
+   tp->eee_en = ee

[PATCH net-next v3 2/2] r8152: add a helper function about setting EEE

2019-08-23 Thread Hayes Wang
Add a helper funtion "rtl_eee_enable" for setting EEE. Besides, I
move r8153_eee_en() and r8153b_eee_en(). And, I remove r8152b_enable_eee(),
r8153_set_eee(), and r8153b_set_eee().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 166 +++-
 1 file changed, 77 insertions(+), 89 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index a7aa48bee732..a003591c3078 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3202,14 +3202,75 @@ static void r8152_eee_en(struct r8152 *tp, bool enable)
ocp_reg_write(tp, OCP_EEE_CONFIG3, config3);
 }
 
-static void r8152b_enable_eee(struct r8152 *tp)
+static void r8153_eee_en(struct r8152 *tp, bool enable)
 {
-   if (tp->eee_en) {
-   r8152_eee_en(tp, true);
-   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tp->eee_adv);
+   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 {
-   r8152_eee_en(tp, false);
-   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+   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 r8153b_eee_en(struct r8152 *tp, bool enable)
+{
+   r8153_eee_en(tp, enable);
+
+   if (enable)
+   r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_EEE, 0);
+   else
+   r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_EEE);
+}
+
+static void rtl_eee_enable(struct r8152 *tp, bool enable)
+{
+   switch (tp->version) {
+   case RTL_VER_01:
+   case RTL_VER_02:
+   case RTL_VER_07:
+   if (enable) {
+   r8152_eee_en(tp, true);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
+   tp->eee_adv);
+   } else {
+   r8152_eee_en(tp, false);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+   }
+   break;
+   case RTL_VER_03:
+   case RTL_VER_04:
+   case RTL_VER_05:
+   case RTL_VER_06:
+   if (enable) {
+   r8153_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   } else {
+   r8153_eee_en(tp, false);
+   ocp_reg_write(tp, OCP_EEE_ADV, 0);
+   }
+   break;
+   case RTL_VER_08:
+   case RTL_VER_09:
+   if (enable) {
+   r8153b_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   } else {
+   r8153b_eee_en(tp, false);
+   ocp_reg_write(tp, OCP_EEE_ADV, 0);
+   }
+   break;
+   default:
+   break;
}
 }
 
@@ -3231,7 +3292,7 @@ static void rtl8152_disable(struct r8152 *tp)
 
 static void r8152b_hw_phy_cfg(struct r8152 *tp)
 {
-   r8152b_enable_eee(tp);
+   rtl_eee_enable(tp, tp->eee_en);
r8152_aldps_en(tp, true);
r8152b_enable_fc(tp);
 
@@ -3425,36 +3486,6 @@ static void r8153b_aldps_en(struct r8152 *tp, bool 
enable)
r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_ALDPS);
 }
 
-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 r8153b_eee_en(struct r8152 *tp, bool enable)
-{
-   r8153_eee_en(tp, enable);
-
-   if (enable)
-   r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_EEE, 0);
-   else
-   r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_EEE);
-}
-
 static void r8153b_enable_fc(struct r8152 *tp)
 {
r8152b_enable_fc(tp);
@@ -3470,7 +3501,7 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
r8153_aldps_en(tp, false);
 
/* disable EEE before updating the PHY parameters */
-   r8153_eee_en(tp, false);
+   rtl_eee_enable(tp, false);
ocp_reg_write(tp, OCP_EEE_ADV, 0);
 
if (tp->version == RTL_VER_03) {
@@ -3502,10 +3533,8 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
sram_write(tp, SRAM_10M_AMP1, 0x0

[PATCH net-next v3 1/2] r8152: saving the settings of EEE

2019-08-23 Thread Hayes Wang
Saving the settings of EEE to avoid they become the default settings
after reset_resume().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 80 +
 1 file changed, 50 insertions(+), 30 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 1aa61610f0bb..a7aa48bee732 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -751,6 +751,7 @@ struct r8152 {
 
atomic_t rx_count;
 
+   bool eee_en;
int intr_interval;
u32 saved_wolopts;
u32 msg_enable;
@@ -762,6 +763,7 @@ struct r8152 {
 
u16 ocp_base;
u16 speed;
+   u16 eee_adv;
u8 *intr_buff;
u8 version;
u8 duplex;
@@ -3202,8 +3204,13 @@ static void r8152_eee_en(struct r8152 *tp, bool enable)
 
 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);
+   if (tp->eee_en) {
+   r8152_eee_en(tp, true);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tp->eee_adv);
+   } else {
+   r8152_eee_en(tp, false);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+   }
 }
 
 static void r8152b_enable_fc(struct r8152 *tp)
@@ -3495,8 +3502,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_eee_en(tp, true);
-   ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
+   if (tp->eee_en) {
+   r8153_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   }
 
r8153_aldps_en(tp, true);
r8152b_enable_fc(tp);
@@ -3599,8 +3608,10 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp)
 
r8153b_ups_flags_w1w0(tp, ups_flags, 0);
 
-   r8153b_eee_en(tp, true);
-   ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
+   if (tp->eee_en) {
+   r8153b_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   }
 
r8153b_aldps_en(tp, true);
r8153b_enable_fc(tp);
@@ -4891,7 +4902,7 @@ static void rtl8152_get_strings(struct net_device *dev, 
u32 stringset, u8 *data)
 
 static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee)
 {
-   u32 ocp_data, lp, adv, supported = 0;
+   u32 lp, adv, supported = 0;
u16 val;
 
val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
@@ -4903,13 +4914,10 @@ static int r8152_get_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
lp = mmd_eee_adv_to_ethtool_adv_t(val);
 
-   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
-   ocp_data &= EEE_RX_EN | EEE_TX_EN;
-
-   eee->eee_enabled = !!ocp_data;
+   eee->eee_enabled = tp->eee_en;
eee->eee_active = !!(supported & adv & lp);
eee->supported = supported;
-   eee->advertised = adv;
+   eee->advertised = tp->eee_adv;
eee->lp_advertised = lp;
 
return 0;
@@ -4919,19 +4927,22 @@ static int r8152_set_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
 {
u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
 
-   r8152_eee_en(tp, eee->eee_enabled);
+   tp->eee_en = eee->eee_enabled;
+   tp->eee_adv = val;
 
-   if (!eee->eee_enabled)
-   val = 0;
+   r8152_eee_en(tp, eee->eee_enabled);
 
-   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+   if (eee->eee_enabled)
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+   else
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
 
return 0;
 }
 
 static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee)
 {
-   u32 ocp_data, lp, adv, supported = 0;
+   u32 lp, adv, supported = 0;
u16 val;
 
val = ocp_reg_read(tp, OCP_EEE_ABLE);
@@ -4943,13 +4954,10 @@ static int r8153_get_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
val = ocp_reg_read(tp, OCP_EEE_LPABLE);
lp = mmd_eee_adv_to_ethtool_adv_t(val);
 
-   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
-   ocp_data &= EEE_RX_EN | EEE_TX_EN;
-
-   eee->eee_enabled = !!ocp_data;
+   eee->eee_enabled = tp->eee_en;
eee->eee_active = !!(supported & adv & lp);
eee->supported = supported;
-   eee->advertised = adv;
+   eee->advertised = tp->eee_adv;
eee->lp_advertised = lp;
 
return 0;
@@ -4959,12 +4967,15 @@ static int r8153_set_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
 {
u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
 
-   r8153_eee_en(tp, eee->eee_enabled);
+   tp->eee_en = ee

[PATCH net-next v3 0/2] r8152: save EEE

2019-08-23 Thread Hayes Wang
v3:
For patch #2, fix the mistake caused by copying and pasting.

v2:
Adjust patch #1. The EEE has been disabled in the beginning of
r8153_hw_phy_cfg() and r8153b_hw_phy_cfg(), so only check if
it is necessary to enable EEE.

Add the patch #2 for the helper function.

v1:
Saving the settings of EEE to avoid they become the default settings
after reset_resume().

Hayes Wang (2):
  r8152: saving the settings of EEE
  r8152: add a helper function about setting EEE

 drivers/net/usb/r8152.c | 182 +---
 1 file changed, 95 insertions(+), 87 deletions(-)

-- 
2.21.0



[PATCH net-next v2 2/2] r8152: add a helper function about setting EEE

2019-08-23 Thread Hayes Wang
Add a helper funtcion "rtl_eee_enable" for setting EEE. Besides, I
move r8153_eee_en() and r8153b_eee_en(). And, I remove r8152b_enable_eee(),
r8153_set_eee(), and r8153b_set_eee().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 166 +++-
 1 file changed, 77 insertions(+), 89 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index a7aa48bee732..220079a8882f 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3202,14 +3202,75 @@ static void r8152_eee_en(struct r8152 *tp, bool enable)
ocp_reg_write(tp, OCP_EEE_CONFIG3, config3);
 }
 
-static void r8152b_enable_eee(struct r8152 *tp)
+static void r8153_eee_en(struct r8152 *tp, bool enable)
 {
-   if (tp->eee_en) {
-   r8152_eee_en(tp, true);
-   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tp->eee_adv);
+   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 {
-   r8152_eee_en(tp, false);
-   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+   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 r8153b_eee_en(struct r8152 *tp, bool enable)
+{
+   r8153_eee_en(tp, enable);
+
+   if (enable)
+   r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_EEE, 0);
+   else
+   r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_EEE);
+}
+
+static void rtl_eee_enable(struct r8152 *tp, bool enable)
+{
+   switch (tp->version) {
+   case RTL_VER_01:
+   case RTL_VER_02:
+   case RTL_VER_07:
+   if (enable) {
+   r8152_eee_en(tp, true);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
+   tp->eee_adv);
+   } else {
+   r8152_eee_en(tp, false);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+   }
+   break;
+   case RTL_VER_03:
+   case RTL_VER_04:
+   case RTL_VER_05:
+   case RTL_VER_06:
+   if (enable) {
+   r8153_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   } else {
+   r8153_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, 0);
+   }
+   break;
+   case RTL_VER_08:
+   case RTL_VER_09:
+   if (enable) {
+   r8153b_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   } else {
+   r8153b_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, 0);
+   }
+   break;
+   default:
+   break;
}
 }
 
@@ -3231,7 +3292,7 @@ static void rtl8152_disable(struct r8152 *tp)
 
 static void r8152b_hw_phy_cfg(struct r8152 *tp)
 {
-   r8152b_enable_eee(tp);
+   rtl_eee_enable(tp, tp->eee_en);
r8152_aldps_en(tp, true);
r8152b_enable_fc(tp);
 
@@ -3425,36 +3486,6 @@ static void r8153b_aldps_en(struct r8152 *tp, bool 
enable)
r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_ALDPS);
 }
 
-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 r8153b_eee_en(struct r8152 *tp, bool enable)
-{
-   r8153_eee_en(tp, enable);
-
-   if (enable)
-   r8153b_ups_flags_w1w0(tp, UPS_FLAGS_EN_EEE, 0);
-   else
-   r8153b_ups_flags_w1w0(tp, 0, UPS_FLAGS_EN_EEE);
-}
-
 static void r8153b_enable_fc(struct r8152 *tp)
 {
r8152b_enable_fc(tp);
@@ -3470,7 +3501,7 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
r8153_aldps_en(tp, false);
 
/* disable EEE before updating the PHY parameters */
-   r8153_eee_en(tp, false);
+   rtl_eee_enable(tp, false);
ocp_reg_write(tp, OCP_EEE_ADV, 0);
 
if (tp->version == RTL_VER_03) {
@@ -3502,10 +3533,8 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
sram_write(tp, SRAM_10M_AMP1, 0x0

[PATCH net-next v2 1/2] r8152: saving the settings of EEE

2019-08-23 Thread Hayes Wang
Saving the settings of EEE to avoid they become the default settings
after reset_resume().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 80 +
 1 file changed, 50 insertions(+), 30 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 1aa61610f0bb..a7aa48bee732 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -751,6 +751,7 @@ struct r8152 {
 
atomic_t rx_count;
 
+   bool eee_en;
int intr_interval;
u32 saved_wolopts;
u32 msg_enable;
@@ -762,6 +763,7 @@ struct r8152 {
 
u16 ocp_base;
u16 speed;
+   u16 eee_adv;
u8 *intr_buff;
u8 version;
u8 duplex;
@@ -3202,8 +3204,13 @@ static void r8152_eee_en(struct r8152 *tp, bool enable)
 
 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);
+   if (tp->eee_en) {
+   r8152_eee_en(tp, true);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tp->eee_adv);
+   } else {
+   r8152_eee_en(tp, false);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+   }
 }
 
 static void r8152b_enable_fc(struct r8152 *tp)
@@ -3495,8 +3502,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_eee_en(tp, true);
-   ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
+   if (tp->eee_en) {
+   r8153_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   }
 
r8153_aldps_en(tp, true);
r8152b_enable_fc(tp);
@@ -3599,8 +3608,10 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp)
 
r8153b_ups_flags_w1w0(tp, ups_flags, 0);
 
-   r8153b_eee_en(tp, true);
-   ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
+   if (tp->eee_en) {
+   r8153b_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   }
 
r8153b_aldps_en(tp, true);
r8153b_enable_fc(tp);
@@ -4891,7 +4902,7 @@ static void rtl8152_get_strings(struct net_device *dev, 
u32 stringset, u8 *data)
 
 static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee)
 {
-   u32 ocp_data, lp, adv, supported = 0;
+   u32 lp, adv, supported = 0;
u16 val;
 
val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
@@ -4903,13 +4914,10 @@ static int r8152_get_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
lp = mmd_eee_adv_to_ethtool_adv_t(val);
 
-   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
-   ocp_data &= EEE_RX_EN | EEE_TX_EN;
-
-   eee->eee_enabled = !!ocp_data;
+   eee->eee_enabled = tp->eee_en;
eee->eee_active = !!(supported & adv & lp);
eee->supported = supported;
-   eee->advertised = adv;
+   eee->advertised = tp->eee_adv;
eee->lp_advertised = lp;
 
return 0;
@@ -4919,19 +4927,22 @@ static int r8152_set_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
 {
u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
 
-   r8152_eee_en(tp, eee->eee_enabled);
+   tp->eee_en = eee->eee_enabled;
+   tp->eee_adv = val;
 
-   if (!eee->eee_enabled)
-   val = 0;
+   r8152_eee_en(tp, eee->eee_enabled);
 
-   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+   if (eee->eee_enabled)
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+   else
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
 
return 0;
 }
 
 static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee)
 {
-   u32 ocp_data, lp, adv, supported = 0;
+   u32 lp, adv, supported = 0;
u16 val;
 
val = ocp_reg_read(tp, OCP_EEE_ABLE);
@@ -4943,13 +4954,10 @@ static int r8153_get_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
val = ocp_reg_read(tp, OCP_EEE_LPABLE);
lp = mmd_eee_adv_to_ethtool_adv_t(val);
 
-   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
-   ocp_data &= EEE_RX_EN | EEE_TX_EN;
-
-   eee->eee_enabled = !!ocp_data;
+   eee->eee_enabled = tp->eee_en;
eee->eee_active = !!(supported & adv & lp);
eee->supported = supported;
-   eee->advertised = adv;
+   eee->advertised = tp->eee_adv;
eee->lp_advertised = lp;
 
return 0;
@@ -4959,12 +4967,15 @@ static int r8153_set_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
 {
u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
 
-   r8153_eee_en(tp, eee->eee_enabled);
+   tp->eee_en = ee

[PATCH net-next v2 0/2] Save EEE

2019-08-23 Thread Hayes Wang
v2:
Adjust patch #1. The EEE has been disabled in the beginning of
r8153_hw_phy_cfg() and r8153b_hw_phy_cfg(), so only check if
it is necessary to enable EEE.

Add the patch #2 for the helper function.

v1:
Saving the settings of EEE to avoid they become the default settings
after reset_resume().

Hayes Wang (2):
  r8152: saving the settings of EEE
  r8152: add a helper function about setting EEE

 drivers/net/usb/r8152.c | 182 +---
 1 file changed, 95 insertions(+), 87 deletions(-)

-- 
2.21.0



[PATCH net-next] r8152: saving the settings of EEE

2019-08-22 Thread Hayes Wang
Saving the settings of EEE to avoid they become the default settings
after reset_resume().

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 86 +++--
 1 file changed, 56 insertions(+), 30 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 1aa61610f0bb..bbc65a94a83f 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -751,6 +751,7 @@ struct r8152 {
 
atomic_t rx_count;
 
+   bool eee_en;
int intr_interval;
u32 saved_wolopts;
u32 msg_enable;
@@ -762,6 +763,7 @@ struct r8152 {
 
u16 ocp_base;
u16 speed;
+   u16 eee_adv;
u8 *intr_buff;
u8 version;
u8 duplex;
@@ -3202,8 +3204,13 @@ static void r8152_eee_en(struct r8152 *tp, bool enable)
 
 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);
+   if (tp->eee_en) {
+   r8152_eee_en(tp, true);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, tp->eee_adv);
+   } else {
+   r8152_eee_en(tp, false);
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+   }
 }
 
 static void r8152b_enable_fc(struct r8152 *tp)
@@ -3495,8 +3502,13 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
sram_write(tp, SRAM_10M_AMP1, 0x00af);
sram_write(tp, SRAM_10M_AMP2, 0x0208);
 
-   r8153_eee_en(tp, true);
-   ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
+   if (tp->eee_en) {
+   r8153_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   } else {
+   r8153_eee_en(tp, false);
+   ocp_reg_write(tp, OCP_EEE_ADV, 0);
+   }
 
r8153_aldps_en(tp, true);
r8152b_enable_fc(tp);
@@ -3599,8 +3611,13 @@ static void r8153b_hw_phy_cfg(struct r8152 *tp)
 
r8153b_ups_flags_w1w0(tp, ups_flags, 0);
 
-   r8153b_eee_en(tp, true);
-   ocp_reg_write(tp, OCP_EEE_ADV, MDIO_EEE_1000T | MDIO_EEE_100TX);
+   if (tp->eee_en) {
+   r8153b_eee_en(tp, true);
+   ocp_reg_write(tp, OCP_EEE_ADV, tp->eee_adv);
+   } else {
+   r8153b_eee_en(tp, false);
+   ocp_reg_write(tp, OCP_EEE_ADV, 0);
+   }
 
r8153b_aldps_en(tp, true);
r8153b_enable_fc(tp);
@@ -4891,7 +4908,7 @@ static void rtl8152_get_strings(struct net_device *dev, 
u32 stringset, u8 *data)
 
 static int r8152_get_eee(struct r8152 *tp, struct ethtool_eee *eee)
 {
-   u32 ocp_data, lp, adv, supported = 0;
+   u32 lp, adv, supported = 0;
u16 val;
 
val = r8152_mmd_read(tp, MDIO_MMD_PCS, MDIO_PCS_EEE_ABLE);
@@ -4903,13 +4920,10 @@ static int r8152_get_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
val = r8152_mmd_read(tp, MDIO_MMD_AN, MDIO_AN_EEE_LPABLE);
lp = mmd_eee_adv_to_ethtool_adv_t(val);
 
-   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
-   ocp_data &= EEE_RX_EN | EEE_TX_EN;
-
-   eee->eee_enabled = !!ocp_data;
+   eee->eee_enabled = tp->eee_en;
eee->eee_active = !!(supported & adv & lp);
eee->supported = supported;
-   eee->advertised = adv;
+   eee->advertised = tp->eee_adv;
eee->lp_advertised = lp;
 
return 0;
@@ -4919,19 +4933,22 @@ static int r8152_set_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
 {
u16 val = ethtool_adv_to_mmd_eee_adv_t(eee->advertised);
 
-   r8152_eee_en(tp, eee->eee_enabled);
+   tp->eee_en = eee->eee_enabled;
+   tp->eee_adv = val;
 
-   if (!eee->eee_enabled)
-   val = 0;
+   r8152_eee_en(tp, eee->eee_enabled);
 
-   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+   if (eee->eee_enabled)
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, val);
+   else
+   r8152_mmd_write(tp, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
 
return 0;
 }
 
 static int r8153_get_eee(struct r8152 *tp, struct ethtool_eee *eee)
 {
-   u32 ocp_data, lp, adv, supported = 0;
+   u32 lp, adv, supported = 0;
u16 val;
 
val = ocp_reg_read(tp, OCP_EEE_ABLE);
@@ -4943,13 +4960,10 @@ static int r8153_get_eee(struct r8152 *tp, struct 
ethtool_eee *eee)
val = ocp_reg_read(tp, OCP_EEE_LPABLE);
lp = mmd_eee_adv_to_ethtool_adv_t(val);
 
-   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EEE_CR);
-   ocp_data &= EEE_RX_EN | EEE_TX_EN;
-
-   eee->eee_enabled = !!ocp_data;
+   eee->eee_enabled = tp->eee_en;
eee->eee_active = !!(supported & adv & lp);
eee->supported = supported;
-   eee->advertised = adv;
+   eee->advertised = tp->eee_adv;
eee->lp_advertised = lp;
 
return 0;
@@ -4959,12 +4973,15 @

[PATCH net-next v2] r8152: divide the tx and rx bottom functions

2019-08-18 Thread Hayes Wang
Move the tx bottom function from NAPI to a new tasklet. Then, for
multi-cores, the bottom functions of tx and rx may be run at same
time with different cores. This is used to improve performance.

On x86, Tx/Rx 943/943 Mbits/sec -> 945/944.
For arm platform, Tx/Rx: 917/917 Mbits/sec -> 933/933.

Signed-off-by: Hayes Wang 
---
v2: add the performance number in the commit message.
---
 drivers/net/usb/r8152.c | 39 ++-
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 40d18e866269..3ed9f8e082c9 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -619,7 +619,7 @@ enum rtl8152_flags {
RTL8152_LINK_CHG,
SELECTIVE_SUSPEND,
PHY_RESET,
-   SCHEDULE_NAPI,
+   SCHEDULE_TASKLET,
GREEN_ETHERNET,
DELL_TB_RX_AGG_BUG,
 };
@@ -733,6 +733,7 @@ struct r8152 {
 #ifdef CONFIG_PM_SLEEP
struct notifier_block pm_notifier;
 #endif
+   struct tasklet_struct tx_tl;
 
struct rtl_ops {
void (*init)(struct r8152 *);
@@ -1401,7 +1402,7 @@ static void write_bulk_callback(struct urb *urb)
return;
 
if (!skb_queue_empty(&tp->tx_queue))
-   napi_schedule(&tp->napi);
+   tasklet_schedule(&tp->tx_tl);
 }
 
 static void intr_callback(struct urb *urb)
@@ -2179,8 +2180,12 @@ static void tx_bottom(struct r8152 *tp)
} while (res == 0);
 }
 
-static void bottom_half(struct r8152 *tp)
+static void bottom_half(unsigned long data)
 {
+   struct r8152 *tp;
+
+   tp = (struct r8152 *)data;
+
if (test_bit(RTL8152_UNPLUG, &tp->flags))
return;
 
@@ -2192,7 +2197,7 @@ static void bottom_half(struct r8152 *tp)
if (!netif_carrier_ok(tp->netdev))
return;
 
-   clear_bit(SCHEDULE_NAPI, &tp->flags);
+   clear_bit(SCHEDULE_TASKLET, &tp->flags);
 
tx_bottom(tp);
 }
@@ -2203,16 +2208,12 @@ static int r8152_poll(struct napi_struct *napi, int 
budget)
int work_done;
 
work_done = rx_bottom(tp, budget);
-   bottom_half(tp);
 
if (work_done < budget) {
if (!napi_complete_done(napi, work_done))
goto out;
if (!list_empty(&tp->rx_done))
napi_schedule(napi);
-   else if (!skb_queue_empty(&tp->tx_queue) &&
-!list_empty(&tp->tx_free))
-   napi_schedule(napi);
}
 
 out:
@@ -2366,11 +2367,11 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff 
*skb,
 
if (!list_empty(&tp->tx_free)) {
if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
-   set_bit(SCHEDULE_NAPI, &tp->flags);
+   set_bit(SCHEDULE_TASKLET, &tp->flags);
schedule_delayed_work(&tp->schedule, 0);
} else {
usb_mark_last_busy(tp->udev);
-   napi_schedule(&tp->napi);
+   tasklet_schedule(&tp->tx_tl);
}
} else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen) {
netif_stop_queue(netdev);
@@ -4020,9 +4021,11 @@ static void set_carrier(struct r8152 *tp)
} else {
if (netif_carrier_ok(netdev)) {
netif_carrier_off(netdev);
+   tasklet_disable(&tp->tx_tl);
napi_disable(napi);
tp->rtl_ops.disable(tp);
napi_enable(napi);
+   tasklet_enable(&tp->tx_tl);
netif_info(tp, link, netdev, "carrier off\n");
}
}
@@ -4055,10 +4058,10 @@ static void rtl_work_func_t(struct work_struct *work)
if (test_and_clear_bit(RTL8152_SET_RX_MODE, &tp->flags))
_rtl8152_set_rx_mode(tp->netdev);
 
-   /* don't schedule napi before linking */
-   if (test_and_clear_bit(SCHEDULE_NAPI, &tp->flags) &&
+   /* don't schedule tasket before linking */
+   if (test_and_clear_bit(SCHEDULE_TASKLET, &tp->flags) &&
netif_carrier_ok(tp->netdev))
-   napi_schedule(&tp->napi);
+   tasklet_schedule(&tp->tx_tl);
 
mutex_unlock(&tp->control);
 
@@ -4144,6 +4147,7 @@ static int rtl8152_open(struct net_device *netdev)
goto out_unlock;
}
napi_enable(&tp->napi);
+   tasklet_enable(&tp->tx_tl);
 
mutex_unlock(&tp->control);
 
@@ -4171,6 +4175,7 @@ static int rtl8152_close(struct net_device *netdev)
 #ifdef CONFIG_PM_SLEEP
unregister_pm_notifier(&tp->pm_notifier);
 #endif

[PATCH net-next] r8152: fix accessing skb after napi_gro_receive

2019-08-18 Thread Hayes Wang
Fix accessing skb after napi_gro_receive which is caused by
commit 47922fcde536 ("r8152: support skb_add_rx_frag").

Fixes: 47922fcde536 ("r8152: support skb_add_rx_frag")
Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 40d18e866269..b1db6df6f4ab 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -2094,10 +2094,10 @@ static int rx_bottom(struct r8152 *tp, int budget)
skb->protocol = eth_type_trans(skb, netdev);
rtl_rx_vlan_tag(rx_desc, skb);
if (work_done < budget) {
-   napi_gro_receive(napi, skb);
work_done++;
stats->rx_packets++;
stats->rx_bytes += skb->len;
+   napi_gro_receive(napi, skb);
} else {
__skb_queue_tail(&tp->rx_queue, skb);
}
-- 
2.21.0



RE: [PATCH net-next] r8152: divide the tx and rx bottom functions

2019-08-16 Thread Hayes Wang
Eric Dumazet [mailto:eric.duma...@gmail.com]
> Sent: Friday, August 16, 2019 5:27 PM
[...]
> Maybe you would avoid messing with a tasklet (we really try to get rid
> of tasklets in general) using two NAPI, one for TX, one for RX.
> 
> Some drivers already use two NAPI, it is fine.
> 
> This might avoid the ugly dance in r8152_poll(),
> calling napi_schedule(napi) after napi_complete_done() !

The reason is that the USB device couldn't control
the interrupt of USB controller. That is, I couldn't
disable the interrupt before napi_schedule and
enable it after napi_complete_done. If the callback
function occurs during the following timing, it is
possible no one would schedule the napi again.

static int r8152_poll(struct napi_struct *napi, int budget)
{
struct r8152 *tp = container_of(napi, struct r8152, napi);
int work_done;

work_done = rx_bottom(tp, budget);
bottom_half(tp);

--> callback occurs here and try to call napi_schedule

napi_complete_done(napi, work_done)

That is, no tx or rx could be handled unless
something trigger napi_schedule.


Best Regards,
Hayes





RE: [PATCH net-next] r8152: divide the tx and rx bottom functions

2019-08-16 Thread Hayes Wang
Eric Dumazet [mailto:eric.duma...@gmail.com]
> Sent: Friday, August 16, 2019 4:20 PM
[...]
> Which callback ?

The USB device has two endpoints for Tx and Rx.
If I submit tx or rx URB to the USB host controller,
the relative callback functions would be called, when
they are finished. For rx, it is read_bulk_callback.
For tx, it is write_bulk_callback.

> After an idle period (no activity, no prior packets being tx-completed ...),
> a packet is sent by the upper stack, enters the ndo_start_xmit() of a network
> driver.
> 
> This driver ndo_start_xmit() simply adds an skb to a local list, and returns.

Base on the current method (without tasklet), when
ndo_start_xmit() is called, napi_schedule is called only
if there is at least one free buffer (!list_empty(&tp->tx_free))
to transmit the packet. Then, the flow would be as following.

- Call r8152_poll
 -- Call bottom_half
  --- Call tx_bottom
    Call r8152_tx_agg_fill
- submit tx urb

- Call write_bulk_callback if tx is completed

When the tx transfer is completed, write_bulk_callback would
be called. And it would check if there is any tx packet
in &tp->tx_queue and determine whether it is necessary to
schedule the napi again or not.

> Where/how is scheduled this callback ?

For tx, you could find the following code in r8152_tx_agg_fill().

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);
ret = usb_submit_urb(agg->urb, GFP_ATOMIC);

For rx you could find the following code in r8152_submit_rx().

usb_fill_bulk_urb(agg->urb, tp->udev, usb_rcvbulkpipe(tp->udev, 1),
  agg->buffer, tp->rx_buf_sz,
  (usb_complete_t)read_bulk_callback, agg);

ret = usb_submit_urb(agg->urb, mem_flags);

> Some kind of timer ?
> An (unrelated) incoming packet ?

When the rx or tx is completed, a interrupt of USB
host controller would be triggered. Then, the callback
functions would be called.

Best Regards,
Hayes




RE: [PATCH net-next] r8152: divide the tx and rx bottom functions

2019-08-16 Thread Hayes Wang
Eric Dumazet [mailto:eric.duma...@gmail.com]
> Sent: Friday, August 16, 2019 2:40 PM
[...]
> tasklet and NAPI are scheduled on the same core (the current
> cpu calling napi_schedule() or tasklet_schedule())
> 
> I would rather not add this dubious tasklet, and instead try to understand
> what is wrong in this driver ;)
> 
> The various napi_schedule() calls are suspect IMO.

The original method as following.

static int r8152_poll(struct napi_struct *napi, int budget)
{
struct r8152 *tp = container_of(napi, struct r8152, napi);
int work_done;

work_done = rx_bottom(tp, budget); <-- RX
bottom_half(tp); <-- Tx (tx_bottom)
[...]

The rx_bottom and tx_bottom would only be called in r8152_poll.
That is, tx_bottom wouldn't be run unless rx_bottom is finished.
And, rx_bottom would be called if tx_bottom is running.

If the traffic is busy. rx_bottom or tx_bottom may take a lot
of time to deal with the packets. And the one would increase
the latency time for the other one.

Therefore, when I separate the tx_bottom and rx_bottom to
different tasklet and napi, the callback functions of tx and
rx may schedule the tasklet and napi to different cpu. Then,
the rx_bottom and tx_bottom may be run at the same time.

Take our arm platform for example. There are five cpus to
handle the interrupt of USB host controller. When the rx is
completed, cpu #1 may handle the interrupt and napi would
be scheduled. When the tx is finished, cpu #2 may handle
the interrupt and the tasklet is scheduled. Then, napi is
run on cpu #1, and tasklet is run on cpu #2.

> Also rtl8152_start_xmit() uses skb_queue_tail(&tp->tx_queue, skb);
> 
> But I see nothing really kicking the transmit if tx_free is empty ?

Tx callback function "write_bulk_callback" would deal with it.
The callback function would check if there are packets waiting
to be sent.


Best Regards,
Hayes




RE: [PATCH net-next] r8152: divide the tx and rx bottom functions

2019-08-15 Thread Hayes Wang
David Miller [mailto:da...@davemloft.net]
> Sent: Friday, August 16, 2019 4:59 AM
[...]
> Theoretically, yes.
> 
> But do you have actual performance numbers showing this to be worth
> the change?
> 
> Always provide performance numbers with changes that are supposed to
> improve performance.

On x86, they are almost the same.
Tx/Rx: 943/943 Mbits/sec -> 945/944

For arm platform,
Tx/Rx: 917/917 Mbits/sec -> 933/933
Improve about 1.74%.

Best Regards,
Hayes




[PATCH net-next] r8152: divide the tx and rx bottom functions

2019-08-14 Thread Hayes Wang
Move the tx bottom function from NAPI to a new tasklet. Then, for
multi-cores, the bottom functions of tx and rx may be run at same
time with different cores. This is used to improve performance.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 39 ++-
 1 file changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 40d18e866269..3ed9f8e082c9 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -619,7 +619,7 @@ enum rtl8152_flags {
RTL8152_LINK_CHG,
SELECTIVE_SUSPEND,
PHY_RESET,
-   SCHEDULE_NAPI,
+   SCHEDULE_TASKLET,
GREEN_ETHERNET,
DELL_TB_RX_AGG_BUG,
 };
@@ -733,6 +733,7 @@ struct r8152 {
 #ifdef CONFIG_PM_SLEEP
struct notifier_block pm_notifier;
 #endif
+   struct tasklet_struct tx_tl;
 
struct rtl_ops {
void (*init)(struct r8152 *);
@@ -1401,7 +1402,7 @@ static void write_bulk_callback(struct urb *urb)
return;
 
if (!skb_queue_empty(&tp->tx_queue))
-   napi_schedule(&tp->napi);
+   tasklet_schedule(&tp->tx_tl);
 }
 
 static void intr_callback(struct urb *urb)
@@ -2179,8 +2180,12 @@ static void tx_bottom(struct r8152 *tp)
} while (res == 0);
 }
 
-static void bottom_half(struct r8152 *tp)
+static void bottom_half(unsigned long data)
 {
+   struct r8152 *tp;
+
+   tp = (struct r8152 *)data;
+
if (test_bit(RTL8152_UNPLUG, &tp->flags))
return;
 
@@ -2192,7 +2197,7 @@ static void bottom_half(struct r8152 *tp)
if (!netif_carrier_ok(tp->netdev))
return;
 
-   clear_bit(SCHEDULE_NAPI, &tp->flags);
+   clear_bit(SCHEDULE_TASKLET, &tp->flags);
 
tx_bottom(tp);
 }
@@ -2203,16 +2208,12 @@ static int r8152_poll(struct napi_struct *napi, int 
budget)
int work_done;
 
work_done = rx_bottom(tp, budget);
-   bottom_half(tp);
 
if (work_done < budget) {
if (!napi_complete_done(napi, work_done))
goto out;
if (!list_empty(&tp->rx_done))
napi_schedule(napi);
-   else if (!skb_queue_empty(&tp->tx_queue) &&
-!list_empty(&tp->tx_free))
-   napi_schedule(napi);
}
 
 out:
@@ -2366,11 +2367,11 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff 
*skb,
 
if (!list_empty(&tp->tx_free)) {
if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
-   set_bit(SCHEDULE_NAPI, &tp->flags);
+   set_bit(SCHEDULE_TASKLET, &tp->flags);
schedule_delayed_work(&tp->schedule, 0);
} else {
usb_mark_last_busy(tp->udev);
-   napi_schedule(&tp->napi);
+   tasklet_schedule(&tp->tx_tl);
}
} else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen) {
netif_stop_queue(netdev);
@@ -4020,9 +4021,11 @@ static void set_carrier(struct r8152 *tp)
} else {
if (netif_carrier_ok(netdev)) {
netif_carrier_off(netdev);
+   tasklet_disable(&tp->tx_tl);
napi_disable(napi);
tp->rtl_ops.disable(tp);
napi_enable(napi);
+   tasklet_enable(&tp->tx_tl);
netif_info(tp, link, netdev, "carrier off\n");
}
}
@@ -4055,10 +4058,10 @@ static void rtl_work_func_t(struct work_struct *work)
if (test_and_clear_bit(RTL8152_SET_RX_MODE, &tp->flags))
_rtl8152_set_rx_mode(tp->netdev);
 
-   /* don't schedule napi before linking */
-   if (test_and_clear_bit(SCHEDULE_NAPI, &tp->flags) &&
+   /* don't schedule tasket before linking */
+   if (test_and_clear_bit(SCHEDULE_TASKLET, &tp->flags) &&
netif_carrier_ok(tp->netdev))
-   napi_schedule(&tp->napi);
+   tasklet_schedule(&tp->tx_tl);
 
mutex_unlock(&tp->control);
 
@@ -4144,6 +4147,7 @@ static int rtl8152_open(struct net_device *netdev)
goto out_unlock;
}
napi_enable(&tp->napi);
+   tasklet_enable(&tp->tx_tl);
 
mutex_unlock(&tp->control);
 
@@ -4171,6 +4175,7 @@ static int rtl8152_close(struct net_device *netdev)
 #ifdef CONFIG_PM_SLEEP
unregister_pm_notifier(&tp->pm_notifier);
 #endif
+   tasklet_disable(&tp->tx_tl);
if (!test_bit(RTL8152_UNPLUG, &tp->flags))
napi_disable(&tp->napi);

[PATCH net] r8152: set RTL8152_UNPLUG only for real disconnection

2019-07-04 Thread Hayes Wang
Set the flag of RTL8152_UNPLUG if and only if the device is unplugged.
Some error codes sometimes don't mean the real disconnection of usb device.
For those situations, set the flag of RTL8152_UNPLUG causes the driver skips
some flows of disabling the device, and it let the device stay at incorrect
state.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 27 ---
 1 file changed, 16 insertions(+), 11 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index e887ac86fbef..39e0768d734d 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -28,7 +28,7 @@
 #define NETNEXT_VERSION"09"
 
 /* Information for net */
-#define NET_VERSION"9"
+#define NET_VERSION"10"
 
 #define DRIVER_VERSION "v1." NETNEXT_VERSION "." NET_VERSION
 #define DRIVER_AUTHOR "Realtek linux nic maintainers "
@@ -825,6 +825,14 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, 
u16 size, void *data)
return ret;
 }
 
+static void rtl_set_unplug(struct r8152 *tp)
+{
+   if (tp->udev->state == USB_STATE_NOTATTACHED) {
+   set_bit(RTL8152_UNPLUG, &tp->flags);
+   smp_mb__after_atomic();
+   }
+}
+
 static int generic_ocp_read(struct r8152 *tp, u16 index, u16 size,
void *data, u16 type)
 {
@@ -863,7 +871,7 @@ static int generic_ocp_read(struct r8152 *tp, u16 index, 
u16 size,
}
 
if (ret == -ENODEV)
-   set_bit(RTL8152_UNPLUG, &tp->flags);
+   rtl_set_unplug(tp);
 
return ret;
 }
@@ -933,7 +941,7 @@ static int generic_ocp_write(struct r8152 *tp, u16 index, 
u16 byteen,
 
 error1:
if (ret == -ENODEV)
-   set_bit(RTL8152_UNPLUG, &tp->flags);
+   rtl_set_unplug(tp);
 
return ret;
 }
@@ -1321,7 +1329,7 @@ static void read_bulk_callback(struct urb *urb)
napi_schedule(&tp->napi);
return;
case -ESHUTDOWN:
-   set_bit(RTL8152_UNPLUG, &tp->flags);
+   rtl_set_unplug(tp);
netif_device_detach(tp->netdev);
return;
case -ENOENT:
@@ -1441,7 +1449,7 @@ static void intr_callback(struct urb *urb)
 resubmit:
res = usb_submit_urb(urb, GFP_ATOMIC);
if (res == -ENODEV) {
-   set_bit(RTL8152_UNPLUG, &tp->flags);
+   rtl_set_unplug(tp);
netif_device_detach(tp->netdev);
} else if (res) {
netif_err(tp, intr, tp->netdev,
@@ -2036,7 +2044,7 @@ static void tx_bottom(struct r8152 *tp)
struct net_device *netdev = tp->netdev;
 
if (res == -ENODEV) {
-   set_bit(RTL8152_UNPLUG, &tp->flags);
+   rtl_set_unplug(tp);
netif_device_detach(netdev);
} else {
struct net_device_stats *stats = &netdev->stats;
@@ -2110,7 +2118,7 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, 
gfp_t mem_flags)
 
ret = usb_submit_urb(agg->urb, mem_flags);
if (ret == -ENODEV) {
-   set_bit(RTL8152_UNPLUG, &tp->flags);
+   rtl_set_unplug(tp);
netif_device_detach(tp->netdev);
} else if (ret) {
struct urb *urb = agg->urb;
@@ -5355,10 +5363,7 @@ static void rtl8152_disconnect(struct usb_interface 
*intf)
 
usb_set_intfdata(intf, NULL);
if (tp) {
-   struct usb_device *udev = tp->udev;
-
-   if (udev->state == USB_STATE_NOTATTACHED)
-   set_bit(RTL8152_UNPLUG, &tp->flags);
+   rtl_set_unplug(tp);
 
netif_napi_del(&tp->napi);
unregister_netdev(tp->netdev);
-- 
2.21.0



[PATCH net] r8152: move calling r8153b_rx_agg_chg_indicate()

2019-07-03 Thread Hayes Wang
r8153b_rx_agg_chg_indicate() needs to be called after enabling TX/RX and
before calling rxdy_gated_en(tp, false). Otherwise, the change of the
settings of RX aggregation wouldn't work.

Besides, adjust rtl8152_set_coalesce() for the same reason. If
rx_coalesce_usecs is changed, restart TX/RX to let the setting work.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 36 ++--
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 101d1325f3f1..e887ac86fbef 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -2367,6 +2367,12 @@ static int rtl_stop_rx(struct r8152 *tp)
return 0;
 }
 
+static inline void r8153b_rx_agg_chg_indicate(struct r8152 *tp)
+{
+   ocp_write_byte(tp, MCU_TYPE_USB, USB_UPT_RXDMA_OWN,
+  OWN_UPDATE | OWN_CLEAR);
+}
+
 static int rtl_enable(struct r8152 *tp)
 {
u32 ocp_data;
@@ -2377,6 +2383,15 @@ static int rtl_enable(struct r8152 *tp)
ocp_data |= CR_RE | CR_TE;
ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data);
 
+   switch (tp->version) {
+   case RTL_VER_08:
+   case RTL_VER_09:
+   r8153b_rx_agg_chg_indicate(tp);
+   break;
+   default:
+   break;
+   }
+
rxdy_gated_en(tp, false);
 
return 0;
@@ -2393,12 +2408,6 @@ static int rtl8152_enable(struct r8152 *tp)
return rtl_enable(tp);
 }
 
-static inline void r8153b_rx_agg_chg_indicate(struct r8152 *tp)
-{
-   ocp_write_byte(tp, MCU_TYPE_USB, USB_UPT_RXDMA_OWN,
-  OWN_UPDATE | OWN_CLEAR);
-}
-
 static void r8153_set_rx_early_timeout(struct r8152 *tp)
 {
u32 ocp_data = tp->coalesce / 8;
@@ -2421,7 +2430,6 @@ static void r8153_set_rx_early_timeout(struct r8152 *tp)
   128 / 8);
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EXTRA_AGGR_TMR,
   ocp_data);
-   r8153b_rx_agg_chg_indicate(tp);
break;
 
default:
@@ -2445,7 +2453,6 @@ static void r8153_set_rx_early_size(struct r8152 *tp)
case RTL_VER_09:
ocp_write_word(tp, MCU_TYPE_USB, USB_RX_EARLY_SIZE,
   ocp_data / 8);
-   r8153b_rx_agg_chg_indicate(tp);
break;
default:
WARN_ON_ONCE(1);
@@ -4919,8 +4926,17 @@ static int rtl8152_set_coalesce(struct net_device 
*netdev,
if (tp->coalesce != coalesce->rx_coalesce_usecs) {
tp->coalesce = coalesce->rx_coalesce_usecs;
 
-   if (netif_running(tp->netdev) && netif_carrier_ok(netdev))
-   r8153_set_rx_early_timeout(tp);
+   if (netif_running(netdev) && netif_carrier_ok(netdev)) {
+   netif_stop_queue(netdev);
+   napi_disable(&tp->napi);
+   tp->rtl_ops.disable(tp);
+   tp->rtl_ops.enable(tp);
+   rtl_start_rx(tp);
+   clear_bit(RTL8152_SET_RX_MODE, &tp->flags);
+   _rtl8152_set_rx_mode(netdev);
+   napi_enable(&tp->napi);
+   netif_wake_queue(netdev);
+   }
}
 
mutex_unlock(&tp->control);
-- 
2.21.0



[PATCH net] r8152: fix the setting of detecting the linking change for runtime suspend

2019-07-01 Thread Hayes Wang
1. Rename r8153b_queue_wake() to r8153_queue_wake().

2. Correct the setting. The enable bit should be 0xd38c bit 0. Besides,
   the 0xd38a bit 0 and 0xd398 bit 8 have to be cleared for both enabled
   and disabled.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 38 +++---
 1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index e0dcb681cfe5..101d1325f3f1 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -53,6 +53,9 @@
 #define PAL_BDC_CR 0xd1a0
 #define PLA_TEREDO_TIMER   0xd2cc
 #define PLA_REALWOW_TIMER  0xd2e8
+#define PLA_SUSPEND_FLAG   0xd38a
+#define PLA_INDICATE_FALG  0xd38c
+#define PLA_EXTRA_STATUS   0xd398
 #define PLA_EFUSE_DATA 0xdd00
 #define PLA_EFUSE_CMD  0xdd02
 #define PLA_LEDSEL 0xdd90
@@ -336,6 +339,15 @@
 /* PLA_BOOT_CTRL */
 #define AUTOLOAD_DONE  0x0002
 
+/* PLA_SUSPEND_FLAG */
+#define LINK_CHG_EVENT BIT(0)
+
+/* PLA_INDICATE_FALG */
+#define UPCOMING_RUNTIME_D3BIT(0)
+
+/* PLA_EXTRA_STATUS */
+#define LINK_CHANGE_FLAG   BIT(8)
+
 /* USB_USB2PHY */
 #define USB2PHY_SUSPEND0x0001
 #define USB2PHY_L1 0x0002
@@ -2806,20 +2818,24 @@ static void r8153b_power_cut_en(struct r8152 *tp, bool 
enable)
ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data);
 }
 
-static void r8153b_queue_wake(struct r8152 *tp, bool enable)
+static void r8153_queue_wake(struct r8152 *tp, bool enable)
 {
u32 ocp_data;
 
-   ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xd38a);
+   ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG);
if (enable)
-   ocp_data |= BIT(0);
+   ocp_data |= UPCOMING_RUNTIME_D3;
else
-   ocp_data &= ~BIT(0);
-   ocp_write_byte(tp, MCU_TYPE_PLA, 0xd38a, ocp_data);
+   ocp_data &= ~UPCOMING_RUNTIME_D3;
+   ocp_write_byte(tp, MCU_TYPE_PLA, PLA_INDICATE_FALG, ocp_data);
+
+   ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_SUSPEND_FLAG);
+   ocp_data &= ~LINK_CHG_EVENT;
+   ocp_write_byte(tp, MCU_TYPE_PLA, PLA_SUSPEND_FLAG, ocp_data);
 
-   ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, 0xd38c);
-   ocp_data &= ~BIT(0);
-   ocp_write_byte(tp, MCU_TYPE_PLA, 0xd38c, ocp_data);
+   ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS);
+   ocp_data &= ~LINK_CHANGE_FLAG;
+   ocp_write_word(tp, MCU_TYPE_PLA, PLA_EXTRA_STATUS, ocp_data);
 }
 
 static bool rtl_can_wakeup(struct r8152 *tp)
@@ -2887,14 +2903,14 @@ static void rtl8153_runtime_enable(struct r8152 *tp, 
bool enable)
 static void rtl8153b_runtime_enable(struct r8152 *tp, bool enable)
 {
if (enable) {
-   r8153b_queue_wake(tp, true);
+   r8153_queue_wake(tp, true);
r8153b_u1u2en(tp, false);
r8153_u2p3en(tp, false);
rtl_runtime_suspend_enable(tp, true);
r8153b_ups_en(tp, true);
} else {
r8153b_ups_en(tp, false);
-   r8153b_queue_wake(tp, false);
+   r8153_queue_wake(tp, false);
rtl_runtime_suspend_enable(tp, false);
r8153_u2p3en(tp, true);
r8153b_u1u2en(tp, true);
@@ -4221,7 +4237,7 @@ static void r8153b_init(struct r8152 *tp)
 
r8153b_power_cut_en(tp, false);
r8153b_ups_en(tp, false);
-   r8153b_queue_wake(tp, false);
+   r8153_queue_wake(tp, false);
rtl_runtime_suspend_enable(tp, false);
r8153b_u1u2en(tp, true);
usb_enable_lpm(tp->udev);
-- 
2.21.0



RE: skb_to_sgvec() causes sg_pcopy_to_buffer() wrong

2019-06-21 Thread Hayes Wang
> Use skb_to_sgvec() to set scatter list, and sometime we would get a
> sg->offset which is more than PAGE_SIZE. Call sg_pcopy_to_buffer()
> with this scatter list would get wrong data.
> 
> In sg_miter_get_next_page(), you would get wrong miter->__remaining,
> when the sg->offset is more than PAGE_SIZE.
> 
> static bool sg_miter_get_next_page(struct sg_mapping_iter *miter)
> {
>   if (!miter->__remaining) {
>   struct scatterlist *sg;
>   unsigned long pgoffset;
> 
>   if (!__sg_page_iter_next(&miter->piter))
>   return false;
> 
>   sg = miter->piter.sg;
>   pgoffset = miter->piter.sg_pgoffset;
> 
>   miter->__offset = pgoffset ? 0 : sg->offset;
>   miter->__remaining = sg->offset + sg->length -
>   (pgoffset << PAGE_SHIFT) - miter->__offset;
>   miter->__remaining = min_t(unsigned long, miter->__remaining,
>  PAGE_SIZE - miter->__offset);
>   }
> 
>   return true;
> }

Excuse me. The following patch could solve my problem.

https://patchwork.kernel.org/patch/11000549/

Best Regards,
Hayes



skb_to_sgvec() casuses sg_pcopy_to_buffer() wrong

2019-06-19 Thread Hayes Wang
Use skb_to_sgvec() to set scatter list, and sometime we would get a
sg->offset which is more than PAGE_SIZE. Call sg_pcopy_to_buffer()
with this scatter list would get wrong data.

In sg_miter_get_next_page(), you would get wrong miter->__remaining,
when the sg->offset is more than PAGE_SIZE.

static bool sg_miter_get_next_page(struct sg_mapping_iter *miter)
{
if (!miter->__remaining) {
struct scatterlist *sg;
unsigned long pgoffset;

if (!__sg_page_iter_next(&miter->piter))
return false;

sg = miter->piter.sg;
pgoffset = miter->piter.sg_pgoffset;

miter->__offset = pgoffset ? 0 : sg->offset;
miter->__remaining = sg->offset + sg->length -
(pgoffset << PAGE_SHIFT) - miter->__offset;
miter->__remaining = min_t(unsigned long, miter->__remaining,
   PAGE_SIZE - miter->__offset);
}

return true;
}

Best Regards,
Hayes



RE: r8152: data corruption in various scenarios

2019-01-06 Thread Hayes Wang
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 0/2] r8152: fix rx issues

2018-02-02 Thread Hayes Wang
The two patched are used to fix rx issues.

Hayes Wang (2):
  r8152: fix wrong checksum status for received IPv4 packets
  r8152: set rx mode early when linking on

 drivers/net/usb/r8152.c | 13 ++---
 1 file changed, 6 insertions(+), 7 deletions(-)

-- 
2.13.6



[PATCH net 2/2] r8152: set rx mode early when linking on

2018-02-02 Thread Hayes Wang
Set rx mode before calling netif_wake_queue() when linking on to avoid
the device missing the receiving packets.

The transmission may start after calling netif_wake_queue(), and the
packets of resopnse may reach before calling rtl8152_set_rx_mode()
which let the device could receive packets. Then, the packets of
response would be missed.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 756de9ea8d2e..958b2e8b90f6 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3795,11 +3795,12 @@ static void set_carrier(struct r8152 *tp)
if (speed & LINK_STATUS) {
if (!netif_carrier_ok(netdev)) {
tp->rtl_ops.enable(tp);
-   set_bit(RTL8152_SET_RX_MODE, &tp->flags);
netif_stop_queue(netdev);
napi_disable(napi);
netif_carrier_on(netdev);
rtl_start_rx(tp);
+   clear_bit(RTL8152_SET_RX_MODE, &tp->flags);
+   _rtl8152_set_rx_mode(netdev);
napi_enable(&tp->napi);
netif_wake_queue(netdev);
netif_info(tp, link, netdev, "carrier on\n");
@@ -4259,7 +4260,7 @@ static int rtl8152_post_reset(struct usb_interface *intf)
mutex_lock(&tp->control);
tp->rtl_ops.enable(tp);
rtl_start_rx(tp);
-   rtl8152_set_rx_mode(netdev);
+   _rtl8152_set_rx_mode(netdev);
mutex_unlock(&tp->control);
}
 
-- 
2.13.6



[PATCH net 1/2] r8152: fix wrong checksum status for received IPv4 packets

2018-02-02 Thread Hayes Wang
The device could only check the checksum of TCP and UDP packets. Therefore,
for the IPv4 packets excluding TCP and UDP, the check of checksum is necessary,
even though the IP checksum is correct.

Take ICMP for example, The IP checksum may be correct, but the ICMP checksum
may be wrong.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0657203ffb91..756de9ea8d2e 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1848,11 +1848,9 @@ static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc 
*rx_desc)
if (opts2 & RD_IPV4_CS) {
if (opts3 & IPF)
checksum = CHECKSUM_NONE;
-   else if ((opts2 & RD_UDP_CS) && (opts3 & UDPF))
-   checksum = CHECKSUM_NONE;
-   else if ((opts2 & RD_TCP_CS) && (opts3 & TCPF))
-   checksum = CHECKSUM_NONE;
-   else
+   else if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF))
+   checksum = CHECKSUM_UNNECESSARY;
+   else if ((opts2 & RD_TCP_CS) && !(opts3 & TCPF))
checksum = CHECKSUM_UNNECESSARY;
} else if (opts2 & RD_IPV6_CS) {
if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF))
-- 
2.13.6



RE: [PATCH v2] r8152: disable RX aggregation on Dell TB16 dock

2018-01-17 Thread Hayes Wang
[...]
> > 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




[PATCH net-next] r8152: correct the definition

2017-06-20 Thread Hayes Wang
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



RE: [PATCH net-next v2 0/2] r8152: adjust runtime suspend/resume

2017-06-15 Thread Hayes Wang
David Miller [mailto:da...@davemloft.net]
> Sent: Wednesday, June 14, 2017 1:02 AM
> > v2:
> > For #1, replace GFP_KERNEL with GFP_NOIO for usb_submit_urb().
> >
> > v1:
> > Improve the flow about runtime suspend/resume and make the code
> > easy to read.
> 
> Series applied.

Excuse me. I don't see these patches in net-next repository. Where could I find 
them?

Best Regards,
Hayes



[PATCH net-next 0/3] r8152: support new chips

2017-06-14 Thread Hayes Wang
These patches are used to support new chips.

Hayes Wang (3):
  r8152: support new chip 8050
  r8152: support RTL8153B
  r8152: add byte_enable for ocp_read_word function

 drivers/net/usb/r8152.c | 687 ++--
 1 file changed, 671 insertions(+), 16 deletions(-)

-- 
2.7.4



[PATCH net-next 1/3] r8152: support new chip 8050

2017-06-14 Thread Hayes Wang
The settings of the new chip are the same with RTL8152, except that
its product ID is 0x8050.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 5a02053..2744405 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -659,6 +659,7 @@ enum rtl_version {
RTL_VER_04,
RTL_VER_05,
RTL_VER_06,
+   RTL_VER_07,
RTL_VER_MAX
 };
 
@@ -4183,6 +4184,7 @@ static int rtl8152_get_coalesce(struct net_device *netdev,
switch (tp->version) {
case RTL_VER_01:
case RTL_VER_02:
+   case RTL_VER_07:
return -EOPNOTSUPP;
default:
break;
@@ -4202,6 +4204,7 @@ static int rtl8152_set_coalesce(struct net_device *netdev,
switch (tp->version) {
case RTL_VER_01:
case RTL_VER_02:
+   case RTL_VER_07:
return -EOPNOTSUPP;
default:
break;
@@ -4301,6 +4304,7 @@ static int rtl8152_change_mtu(struct net_device *dev, int 
new_mtu)
switch (tp->version) {
case RTL_VER_01:
case RTL_VER_02:
+   case RTL_VER_07:
dev->mtu = new_mtu;
return 0;
default:
@@ -4370,6 +4374,7 @@ static int rtl_ops_init(struct r8152 *tp)
switch (tp->version) {
case RTL_VER_01:
case RTL_VER_02:
+   case RTL_VER_07:
ops->init   = r8152b_init;
ops->enable = rtl8152_enable;
ops->disable= rtl8152_disable;
@@ -4448,6 +4453,9 @@ static u8 rtl_get_version(struct usb_interface *intf)
case 0x5c30:
version = RTL_VER_06;
break;
+   case 0x4800:
+   version = RTL_VER_07;
+   break;
default:
version = RTL_VER_UNKNOWN;
dev_info(&intf->dev, "Unknown version 0x%04x\n", ocp_data);
@@ -4493,6 +4501,7 @@ static int rtl8152_probe(struct usb_interface *intf,
switch (version) {
case RTL_VER_01:
case RTL_VER_02:
+   case RTL_VER_07:
tp->mii.supports_gmii = 0;
break;
default:
@@ -4627,6 +4636,7 @@ static void rtl8152_disconnect(struct usb_interface *intf)
 
 /* table of devices that work with this driver */
 static struct usb_device_id rtl8152_table[] = {
+   {REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8050)},
{REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8152)},
{REALTEK_USB_DEVICE(VENDOR_ID_REALTEK, 0x8153)},
{REALTEK_USB_DEVICE(VENDOR_ID_MICROSOFT, 0x07ab)},
-- 
2.7.4



[PATCH net-next 3/3] r8152: add byte_enable for ocp_read_word function

2017-06-14 Thread Hayes Wang
Add byte_enable for ocp_read_word() to replace reading 4
bytes data with reading the desired 2 bytes data.

This is used to avoid the issue which is described in
commit b4d99def0938 ("r8152: remove sram_read"). The
original method always reads 4 bytes data, and it may
have problem when reading the PHY registers.

The new method is supported since RTL8153B, but it
doesn't influence the previous chips. The bits of the
byte_enable for the previous chips are the reserved
bits, and the hw would ignore them.

Signed-off-by: Hayes Wang 
---
 drivers/net/usb/r8152.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 4c197da..184b680 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -962,11 +962,13 @@ static u16 ocp_read_word(struct r8152 *tp, u16 type, u16 
index)
 {
u32 data;
__le32 tmp;
+   u16 byen = BYTE_EN_WORD;
u8 shift = index & 2;
 
index &= ~3;
+   byen <<= shift;
 
-   generic_ocp_read(tp, index, sizeof(tmp), &tmp, type);
+   generic_ocp_read(tp, index, sizeof(tmp), &tmp, type | byen);
 
data = __le32_to_cpu(tmp);
data >>= (shift * 8);
-- 
2.7.4



  1   2   3   4   5   6   7   >