All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 00/14] r8152: improvement and new features
@ 2014-02-18 13:48 Hayes Wang
  2014-02-18 13:48 ` [PATCH net-next 01/14] r8152: move some functions Hayes Wang
                   ` (14 more replies)
  0 siblings, 15 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:48 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Change some flows or behavior to improve the efficiency or make the
code readable. Besides, support WOL and runtime suspend.

Hayes Wang (14):
  r8152: move some functions
  r8152: add three functions
  r8152: replace some types from int to bool
  r8152: load the default MAC address
  r8152: reduce the frequency of spin_lock
  r8152: clear BMCR_PDOWN
  r8152: combine PHY reset with set_speed
  r8152: move some functions from probe to open
  r8152: support WOL
  r8152: support runtime suspend
  r8152: disable teredo for RTL8152
  r8152: replace netif_rx with netif_receive_skb
  r8152: set disable_hub_initiated_lpm
  r8152: support get_msglevel and set_msglevel

 drivers/net/usb/r8152.c | 711 +++++++++++++++++++++++++++++++++++-------------
 1 file changed, 526 insertions(+), 185 deletions(-)

-- 
1.8.4.2


^ permalink raw reply	[flat|nested] 23+ messages in thread

* [PATCH net-next 01/14] r8152: move some functions
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
@ 2014-02-18 13:48 ` Hayes Wang
  2014-02-18 13:48 ` [PATCH net-next 02/14] r8152: add three functions Hayes Wang
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:48 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Move the following functions which is for the further coding.
 - rtl_clear_bp
 - r8153_clear_bp
 - r8153_teredo_off
 - r8152b_disable_aldps
 - r8152b_enable_aldps
 - r8152b_hw_phy_cfg

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 106 ++++++++++++++++++++++++------------------------
 1 file changed, 53 insertions(+), 53 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index d89dbe3..f042a85 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1721,6 +1721,59 @@ static void rtl8152_disable(struct r8152 *tp)
 	rtl8152_nic_reset(tp);
 }
 
+static void rtl_clear_bp(struct r8152 *tp)
+{
+	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
+	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_2, 0);
+	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_4, 0);
+	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_6, 0);
+	ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_0, 0);
+	ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_2, 0);
+	ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_4, 0);
+	ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_6, 0);
+	mdelay(3);
+	ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0);
+	ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0);
+}
+
+static void r8153_clear_bp(struct r8152 *tp)
+{
+	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0);
+	ocp_write_byte(tp, MCU_TYPE_USB, USB_BP_EN, 0);
+	rtl_clear_bp(tp);
+}
+
+static void r8153_teredo_off(struct r8152 *tp)
+{
+	u32 ocp_data;
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG);
+	ocp_data &= ~(TEREDO_SEL | TEREDO_RS_EVENT_MASK | OOB_TEREDO_EN);
+	ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data);
+
+	ocp_write_word(tp, MCU_TYPE_PLA, PLA_WDT6_CTRL, WDT6_SET_MODE);
+	ocp_write_word(tp, MCU_TYPE_PLA, PLA_REALWOW_TIMER, 0);
+	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TEREDO_TIMER, 0);
+}
+
+static void r8152b_disable_aldps(struct r8152 *tp)
+{
+	ocp_reg_write(tp, OCP_ALDPS_CONFIG, ENPDNPS | LINKENA | DIS_SDSAVE);
+	msleep(20);
+}
+
+static inline void r8152b_enable_aldps(struct r8152 *tp)
+{
+	ocp_reg_write(tp, OCP_ALDPS_CONFIG, ENPWRSAVE | ENPDNPS |
+					    LINKENA | DIS_SDSAVE);
+}
+
+static void r8152b_hw_phy_cfg(struct r8152 *tp)
+{
+	r8152_mdio_write(tp, MII_BMCR, BMCR_ANENABLE);
+	r8152b_disable_aldps(tp);
+}
+
 static void r8152b_exit_oob(struct r8152 *tp)
 {
 	u32	ocp_data;
@@ -1865,18 +1918,6 @@ static void r8152b_enter_oob(struct r8152 *tp)
 	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
 }
 
-static void r8152b_disable_aldps(struct r8152 *tp)
-{
-	ocp_reg_write(tp, OCP_ALDPS_CONFIG, ENPDNPS | LINKENA | DIS_SDSAVE);
-	msleep(20);
-}
-
-static inline void r8152b_enable_aldps(struct r8152 *tp)
-{
-	ocp_reg_write(tp, OCP_ALDPS_CONFIG, ENPWRSAVE | ENPDNPS |
-					    LINKENA | DIS_SDSAVE);
-}
-
 static void r8153_hw_phy_cfg(struct r8152 *tp)
 {
 	u32 ocp_data;
@@ -1961,19 +2002,6 @@ static void r8153_power_cut_en(struct r8152 *tp, int enable)
 	ocp_write_word(tp, MCU_TYPE_USB, USB_MISC_0, ocp_data);
 }
 
-static void r8153_teredo_off(struct r8152 *tp)
-{
-	u32 ocp_data;
-
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG);
-	ocp_data &= ~(TEREDO_SEL | TEREDO_RS_EVENT_MASK | OOB_TEREDO_EN);
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data);
-
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_WDT6_CTRL, WDT6_SET_MODE);
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_REALWOW_TIMER, 0);
-	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_TEREDO_TIMER, 0);
-}
-
 static void r8153_first_init(struct r8152 *tp)
 {
 	u32 ocp_data;
@@ -2308,28 +2336,6 @@ static int rtl8152_close(struct net_device *netdev)
 	return res;
 }
 
-static void rtl_clear_bp(struct r8152 *tp)
-{
-	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
-	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_2, 0);
-	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_4, 0);
-	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_6, 0);
-	ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_0, 0);
-	ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_2, 0);
-	ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_4, 0);
-	ocp_write_dword(tp, MCU_TYPE_USB, USB_BP_6, 0);
-	mdelay(3);
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_BP_BA, 0);
-	ocp_write_word(tp, MCU_TYPE_USB, USB_BP_BA, 0);
-}
-
-static void r8153_clear_bp(struct r8152 *tp)
-{
-	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_BP_EN, 0);
-	ocp_write_byte(tp, MCU_TYPE_USB, USB_BP_EN, 0);
-	rtl_clear_bp(tp);
-}
-
 static void r8152b_enable_eee(struct r8152 *tp)
 {
 	u32 ocp_data;
@@ -2378,12 +2384,6 @@ static void r8152b_enable_fc(struct r8152 *tp)
 	r8152_mdio_write(tp, MII_ADVERTISE, anar);
 }
 
-static void r8152b_hw_phy_cfg(struct r8152 *tp)
-{
-	r8152_mdio_write(tp, MII_BMCR, BMCR_ANENABLE);
-	r8152b_disable_aldps(tp);
-}
-
 static void r8152b_init(struct r8152 *tp)
 {
 	u32 ocp_data;
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 02/14] r8152: add three functions
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
  2014-02-18 13:48 ` [PATCH net-next 01/14] r8152: move some functions Hayes Wang
@ 2014-02-18 13:48 ` Hayes Wang
  2014-02-18 13:49 ` [PATCH net-next 03/14] r8152: replace some types from int to bool Hayes Wang
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:48 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Replace some codes with the following three functions.
 - rtl_drop_queued_tx
 - rxdy_gated_en
 - r8152_power_cut_en

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 99 +++++++++++++++++++++++++------------------------
 1 file changed, 51 insertions(+), 48 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index f042a85..2d5e761 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1478,6 +1478,17 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags)
 	return usb_submit_urb(agg->urb, mem_flags);
 }
 
+static void rtl_drop_queued_tx(struct r8152 *tp)
+{
+	struct net_device_stats *stats = &tp->netdev->stats;
+	struct sk_buff *skb;
+
+	while ((skb = skb_dequeue(&tp->tx_queue))) {
+		dev_kfree_skb(skb);
+		stats->tx_dropped++;
+	}
+}
+
 static void rtl8152_tx_timeout(struct net_device *netdev)
 {
 	struct r8152 *tp = netdev_priv(netdev);
@@ -1613,6 +1624,18 @@ static void rtl_set_eee_plus(struct r8152 *tp)
 	}
 }
 
+static void rxdy_gated_en(struct r8152 *tp, bool enable)
+{
+	u32 ocp_data;
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1);
+	if (enable)
+		ocp_data |= RXDY_GATED_EN;
+	else
+		ocp_data &= ~RXDY_GATED_EN;
+	ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
+}
+
 static int rtl_enable(struct r8152 *tp)
 {
 	u32 ocp_data;
@@ -1624,9 +1647,7 @@ static int rtl_enable(struct r8152 *tp)
 	ocp_data |= CR_RE | CR_TE;
 	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, ocp_data);
 
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1);
-	ocp_data &= ~RXDY_GATED_EN;
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
+	rxdy_gated_en(tp, false);
 
 	INIT_LIST_HEAD(&tp->rx_done);
 	ret = 0;
@@ -1681,8 +1702,6 @@ static int rtl8153_enable(struct r8152 *tp)
 
 static void rtl8152_disable(struct r8152 *tp)
 {
-	struct net_device_stats *stats = rtl8152_get_stats(tp->netdev);
-	struct sk_buff *skb;
 	u32 ocp_data;
 	int i;
 
@@ -1690,17 +1709,12 @@ static void rtl8152_disable(struct r8152 *tp)
 	ocp_data &= ~RCR_ACPT_ALL;
 	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
 
-	while ((skb = skb_dequeue(&tp->tx_queue))) {
-		dev_kfree_skb(skb);
-		stats->tx_dropped++;
-	}
+	rtl_drop_queued_tx(tp);
 
 	for (i = 0; i < RTL8152_MAX_TX; i++)
 		usb_kill_urb(tp->tx_info[i].urb);
 
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1);
-	ocp_data |= RXDY_GATED_EN;
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
+	rxdy_gated_en(tp, true);
 
 	for (i = 0; i < 1000; i++) {
 		ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL);
@@ -1721,6 +1735,23 @@ static void rtl8152_disable(struct r8152 *tp)
 	rtl8152_nic_reset(tp);
 }
 
+static void r8152_power_cut_en(struct r8152 *tp, bool enable)
+{
+	u32 ocp_data;
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CTRL);
+	if (enable)
+		ocp_data |= POWER_CUT;
+	else
+		ocp_data &= ~POWER_CUT;
+	ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CTRL, ocp_data);
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS);
+	ocp_data &= ~RESUME_INDICATE;
+	ocp_write_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ocp_data);
+
+}
+
 static void rtl_clear_bp(struct r8152 *tp)
 {
 	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
@@ -1783,9 +1814,7 @@ static void r8152b_exit_oob(struct r8152 *tp)
 	ocp_data &= ~RCR_ACPT_ALL;
 	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
 
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1);
-	ocp_data |= RXDY_GATED_EN;
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
+	rxdy_gated_en(tp, true);
 
 	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
 	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, 0x00);
@@ -1909,9 +1938,7 @@ static void r8152b_enter_oob(struct r8152 *tp)
 
 	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5, LAN_WAKE_EN);
 
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1);
-	ocp_data &= ~RXDY_GATED_EN;
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
+	rxdy_gated_en(tp, false);
 
 	ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
 	ocp_data |= RCR_APM | RCR_AM | RCR_AB;
@@ -2007,10 +2034,7 @@ static void r8153_first_init(struct r8152 *tp)
 	u32 ocp_data;
 	int i;
 
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1);
-	ocp_data |= RXDY_GATED_EN;
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
-
+	rxdy_gated_en(tp, true);
 	r8153_teredo_off(tp);
 
 	ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
@@ -2125,9 +2149,7 @@ static void r8153_enter_oob(struct r8152 *tp)
 
 	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5, LAN_WAKE_EN);
 
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_MISC_1);
-	ocp_data &= ~RXDY_GATED_EN;
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_MISC_1, ocp_data);
+	rxdy_gated_en(tp, false);
 
 	ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
 	ocp_data |= RCR_APM | RCR_AM | RCR_AB;
@@ -2231,12 +2253,7 @@ out:
 
 static void rtl8152_down(struct r8152 *tp)
 {
-	u32	ocp_data;
-
-	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CTRL);
-	ocp_data &= ~POWER_CUT;
-	ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CTRL, ocp_data);
-
+	r8152_power_cut_en(tp, false);
 	r8152b_disable_aldps(tp);
 	r8152b_enter_oob(tp);
 	r8152b_enable_aldps(tp);
@@ -2399,13 +2416,8 @@ static void r8152b_init(struct r8152 *tp)
 
 	r8152b_hw_phy_cfg(tp);
 
-	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CTRL);
-	ocp_data &= ~POWER_CUT;
-	ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CTRL, ocp_data);
+	r8152_power_cut_en(tp, false);
 
-	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS);
-	ocp_data &= ~RESUME_INDICATE;
-	ocp_write_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ocp_data);
 
 	r8152b_exit_oob(tp);
 
@@ -2659,17 +2671,8 @@ static void r8152b_get_version(struct r8152 *tp)
 
 static void rtl8152_unload(struct r8152 *tp)
 {
-	u32	ocp_data;
-
-	if (tp->version != RTL_VER_01) {
-		ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_UPS_CTRL);
-		ocp_data |= POWER_CUT;
-		ocp_write_word(tp, MCU_TYPE_USB, USB_UPS_CTRL, ocp_data);
-	}
-
-	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS);
-	ocp_data &= ~RESUME_INDICATE;
-	ocp_write_word(tp, MCU_TYPE_USB, USB_PM_CTRL_STATUS, ocp_data);
+	if (tp->version != RTL_VER_01)
+		r8152_power_cut_en(tp, true);
 }
 
 static void rtl8153_unload(struct r8152 *tp)
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 03/14] r8152: replace some types from int to bool
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
  2014-02-18 13:48 ` [PATCH net-next 01/14] r8152: move some functions Hayes Wang
  2014-02-18 13:48 ` [PATCH net-next 02/14] r8152: add three functions Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 13:49 ` [PATCH net-next 04/14] r8152: load the default MAC address Hayes Wang
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Modify the following functions.
 - r8153_u1u2en
 - r8153_u2p3en
 - r8153_power_cut_en

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 2d5e761..4888e4f 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1989,7 +1989,7 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
 	sram_write(tp, SRAM_10M_AMP2, data);
 }
 
-static void r8153_u1u2en(struct r8152 *tp, int enable)
+static void r8153_u1u2en(struct r8152 *tp, bool enable)
 {
 	u8 u1u2[8];
 
@@ -2001,7 +2001,7 @@ static void r8153_u1u2en(struct r8152 *tp, int enable)
 	usb_ocp_write(tp, USB_TOLERANCE, BYTE_EN_SIX_BYTES, sizeof(u1u2), u1u2);
 }
 
-static void r8153_u2p3en(struct r8152 *tp, int enable)
+static void r8153_u2p3en(struct r8152 *tp, bool enable)
 {
 	u32 ocp_data;
 
@@ -2013,7 +2013,7 @@ static void r8153_u2p3en(struct r8152 *tp, int enable)
 	ocp_write_word(tp, MCU_TYPE_USB, USB_U2P3_CTRL, ocp_data);
 }
 
-static void r8153_power_cut_en(struct r8152 *tp, int enable)
+static void r8153_power_cut_en(struct r8152 *tp, bool enable)
 {
 	u32 ocp_data;
 
@@ -2261,8 +2261,8 @@ static void rtl8152_down(struct r8152 *tp)
 
 static void rtl8153_down(struct r8152 *tp)
 {
-	r8153_u1u2en(tp, 0);
-	r8153_power_cut_en(tp, 0);
+	r8153_u1u2en(tp, false);
+	r8153_power_cut_en(tp, false);
 	r8153_disable_aldps(tp);
 	r8153_enter_oob(tp);
 	r8153_enable_aldps(tp);
@@ -2455,7 +2455,7 @@ static void r8153_init(struct r8152 *tp)
 	u32 ocp_data;
 	int i;
 
-	r8153_u1u2en(tp, 0);
+	r8153_u1u2en(tp, false);
 
 	for (i = 0; i < 500; i++) {
 		if (ocp_read_word(tp, MCU_TYPE_PLA, PLA_BOOT_CTRL) &
@@ -2471,7 +2471,7 @@ static void r8153_init(struct r8152 *tp)
 		msleep(20);
 	}
 
-	r8153_u2p3en(tp, 0);
+	r8153_u2p3en(tp, false);
 
 	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL);
 	ocp_data &= ~TIMER11_EN;
@@ -2496,8 +2496,8 @@ static void r8153_init(struct r8152 *tp)
 	ocp_data |= SEN_VAL_NORMAL | SEL_RXIDLE;
 	ocp_write_word(tp, MCU_TYPE_USB, USB_AFE_CTRL2, ocp_data);
 
-	r8153_power_cut_en(tp, 0);
-	r8153_u1u2en(tp, 1);
+	r8153_power_cut_en(tp, false);
+	r8153_u1u2en(tp, true);
 
 	r8153_first_init(tp);
 
@@ -2677,7 +2677,7 @@ static void rtl8152_unload(struct r8152 *tp)
 
 static void rtl8153_unload(struct r8152 *tp)
 {
-	r8153_power_cut_en(tp, 1);
+	r8153_power_cut_en(tp, true);
 }
 
 static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 04/14] r8152: load the default MAC address
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (2 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 03/14] r8152: replace some types from int to bool Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 13:49 ` [PATCH net-next 05/14] r8152: reduce the frequency of spin_lock Hayes Wang
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Except for RTL_VER_01, replace loading the MAC address from PLA_IDR
with from PLA_BACKUP. The default MAC address may be modified by
the other OS, so the PLA_IDR may be not the default MAC address.

The data in the PLA_BACKUP address of the RTL_VER_01 may be destoryed,
so load MAC address from PLA_IDR for RTL_VER_01.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 4888e4f..3847c35 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -889,11 +889,26 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags);
 static inline void set_ethernet_addr(struct r8152 *tp)
 {
 	struct net_device *dev = tp->netdev;
+	int ret;
 	u8 node_id[8] = {0};
 
-	if (pla_ocp_read(tp, PLA_IDR, sizeof(node_id), node_id) < 0)
+	if (tp->version == RTL_VER_01)
+		ret = pla_ocp_read(tp, PLA_IDR, sizeof(node_id), node_id);
+	else
+		ret = pla_ocp_read(tp, PLA_BACKUP, sizeof(node_id), node_id);
+
+	if (ret < 0) {
 		netif_notice(tp, probe, dev, "inet addr fail\n");
-	else {
+	} else {
+		if (tp->version != RTL_VER_01) {
+			ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR,
+				       CRWECR_CONFIG);
+			pla_ocp_write(tp, PLA_IDR, BYTE_EN_SIX_BYTES,
+				      sizeof(node_id), node_id);
+			ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR,
+				       CRWECR_NORAML);
+		}
+
 		memcpy(dev->dev_addr, node_id, dev->addr_len);
 		memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 	}
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 05/14] r8152: reduce the frequency of spin_lock
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (3 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 04/14] r8152: load the default MAC address Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 13:49 ` [PATCH net-next 06/14] r8152: clear BMCR_PDOWN Hayes Wang
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Replace getting one item from a list with getting the whole list one time.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 47 ++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 38 insertions(+), 9 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 3847c35..2a778fa 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1299,9 +1299,16 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
 
 static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 {
+	struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue;
+	unsigned long flags;
 	int remain;
 	u8 *tx_data;
 
+	__skb_queue_head_init(&skb_head);
+	spin_lock_irqsave(&tx_queue->lock, flags);
+	skb_queue_splice_init(tx_queue, &skb_head);
+	spin_unlock_irqrestore(&tx_queue->lock, flags);
+
 	tx_data = agg->head;
 	agg->skb_num = agg->skb_len = 0;
 	remain = rx_buf_sz;
@@ -1311,14 +1318,14 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		struct sk_buff *skb;
 		unsigned int len;
 
-		skb = skb_dequeue(&tp->tx_queue);
+		skb = __skb_dequeue(&skb_head);
 		if (!skb)
 			break;
 
 		remain -= sizeof(*tx_desc);
 		len = skb->len;
 		if (remain < len) {
-			skb_queue_head(&tp->tx_queue, skb);
+			__skb_queue_head(&skb_head, skb);
 			break;
 		}
 
@@ -1336,6 +1343,12 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
 	}
 
+	if (!skb_queue_empty(&skb_head)) {
+		spin_lock_irqsave(&tx_queue->lock, flags);
+		skb_queue_splice(&skb_head, tx_queue);
+		spin_unlock_irqrestore(&tx_queue->lock, flags);
+	}
+
 	netif_tx_lock(tp->netdev);
 
 	if (netif_queue_stopped(tp->netdev) &&
@@ -1354,10 +1367,17 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 static void rx_bottom(struct r8152 *tp)
 {
 	unsigned long flags;
-	struct list_head *cursor, *next;
+	struct list_head *cursor, *next, rx_queue;
 
+	if (list_empty(&tp->rx_done))
+		return;
+
+	INIT_LIST_HEAD(&rx_queue);
 	spin_lock_irqsave(&tp->rx_lock, flags);
-	list_for_each_safe(cursor, next, &tp->rx_done) {
+	list_splice_init(&tp->rx_done, &rx_queue);
+	spin_unlock_irqrestore(&tp->rx_lock, flags);
+
+	list_for_each_safe(cursor, next, &rx_queue) {
 		struct rx_desc *rx_desc;
 		struct rx_agg *agg;
 		int len_used = 0;
@@ -1366,7 +1386,6 @@ static void rx_bottom(struct r8152 *tp)
 		int ret;
 
 		list_del_init(cursor);
-		spin_unlock_irqrestore(&tp->rx_lock, flags);
 
 		agg = list_entry(cursor, struct rx_agg, list);
 		urb = agg->urb;
@@ -1416,13 +1435,13 @@ static void rx_bottom(struct r8152 *tp)
 
 submit:
 		ret = r8152_submit_rx(tp, agg, GFP_ATOMIC);
-		spin_lock_irqsave(&tp->rx_lock, flags);
 		if (ret && ret != -ENODEV) {
-			list_add_tail(&agg->list, next);
+			spin_lock_irqsave(&tp->rx_lock, flags);
+			list_add_tail(&agg->list, &tp->rx_done);
+			spin_unlock_irqrestore(&tp->rx_lock, flags);
 			tasklet_schedule(&tp->tl);
 		}
 	}
-	spin_unlock_irqrestore(&tp->rx_lock, flags);
 }
 
 static void tx_bottom(struct r8152 *tp)
@@ -1496,9 +1515,19 @@ int r8152_submit_rx(struct r8152 *tp, struct rx_agg *agg, gfp_t mem_flags)
 static void rtl_drop_queued_tx(struct r8152 *tp)
 {
 	struct net_device_stats *stats = &tp->netdev->stats;
+	struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue;
+	unsigned long flags;
 	struct sk_buff *skb;
 
-	while ((skb = skb_dequeue(&tp->tx_queue))) {
+	if (skb_queue_empty(tx_queue))
+		return;
+
+	__skb_queue_head_init(&skb_head);
+	spin_lock_irqsave(&tx_queue->lock, flags);
+	skb_queue_splice_init(tx_queue, &skb_head);
+	spin_unlock_irqrestore(&tx_queue->lock, flags);
+
+	while ((skb = __skb_dequeue(&skb_head))) {
 		dev_kfree_skb(skb);
 		stats->tx_dropped++;
 	}
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 06/14] r8152: clear BMCR_PDOWN
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (4 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 05/14] r8152: reduce the frequency of spin_lock Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 13:49 ` [PATCH net-next 07/14] r8152: combine PHY reset with set_speed Hayes Wang
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Modify the method of enabling the PHY to clear BMCR_PDOWN only.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 2a778fa..c7bae39 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1845,7 +1845,14 @@ static inline void r8152b_enable_aldps(struct r8152 *tp)
 
 static void r8152b_hw_phy_cfg(struct r8152 *tp)
 {
-	r8152_mdio_write(tp, MII_BMCR, BMCR_ANENABLE);
+	u16 data;
+
+	data = r8152_mdio_read(tp, MII_BMCR);
+	if (data & BMCR_PDOWN) {
+		data &= ~BMCR_PDOWN;
+		r8152_mdio_write(tp, MII_BMCR, data);
+	}
+
 	r8152b_disable_aldps(tp);
 }
 
@@ -1995,7 +2002,11 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
 	u16 data;
 
 	ocp_reg_write(tp, OCP_ADC_CFG, CKADSEL_L | ADC_EN | EN_EMI_L);
-	r8152_mdio_write(tp, MII_BMCR, BMCR_ANENABLE);
+	data = r8152_mdio_read(tp, MII_BMCR);
+	if (data & BMCR_PDOWN) {
+		data &= ~BMCR_PDOWN;
+		r8152_mdio_write(tp, MII_BMCR, data);
+	}
 
 	if (tp->version == RTL_VER_03) {
 		data = ocp_reg_read(tp, OCP_EEE_CFG);
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 07/14] r8152: combine PHY reset with set_speed
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (5 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 06/14] r8152: clear BMCR_PDOWN Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 17:19     ` Florian Fainelli
       [not found]   ` <201402190209.s1J29EVG032292@rtits1.realtek.com>
  2014-02-18 13:49 ` [PATCH net-next 08/14] r8152: move some functions from probe to open Hayes Wang
                   ` (7 subsequent siblings)
  14 siblings, 2 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

PHY reset is necessary after some hw settings. However, it would
cause the linking down, and so does the set_speed function. Combine
the PHY reset with set_speed function. That could reduce the frequency
of linking down and accessing the PHY register.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 57 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 45 insertions(+), 12 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c7bae39..b3155da 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -436,6 +436,7 @@ enum rtl8152_flags {
 	RTL8152_SET_RX_MODE,
 	WORK_ENABLE,
 	RTL8152_LINK_CHG,
+	PHY_RESET,
 };
 
 /* Define these values to match your device */
@@ -1796,6 +1797,29 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable)
 
 }
 
+static void rtl_phy_reset(struct r8152 *tp)
+{
+	u16 data;
+	int i;
+
+	clear_bit(PHY_RESET, &tp->flags);
+
+	data = r8152_mdio_read(tp, MII_BMCR);
+
+	/* don't reset again before the previous one complete */
+	if (data & BMCR_RESET)
+		return;
+
+	data |= BMCR_RESET;
+	r8152_mdio_write(tp, MII_BMCR, data);
+
+	for (i = 0; i < 50; i++) {
+		msleep(20);
+		if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0)
+			break;
+	}
+}
+
 static void rtl_clear_bp(struct r8152 *tp)
 {
 	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
@@ -1854,6 +1878,7 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
 	}
 
 	r8152b_disable_aldps(tp);
+	set_bit(PHY_RESET, &tp->flags);
 }
 
 static void r8152b_exit_oob(struct r8152 *tp)
@@ -2042,6 +2067,8 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
 	data = sram_read(tp, SRAM_10M_AMP2);
 	data |= AMP_DN;
 	sram_write(tp, SRAM_10M_AMP2, data);
+
+	set_bit(PHY_RESET, &tp->flags);
 }
 
 static void r8153_u1u2en(struct r8152 *tp, bool enable)
@@ -2295,12 +2322,26 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex)
 		bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
 	}
 
+	if (test_bit(PHY_RESET, &tp->flags))
+		bmcr |= BMCR_RESET;
+
 	if (tp->mii.supports_gmii)
 		r8152_mdio_write(tp, MII_CTRL1000, gbcr);
 
 	r8152_mdio_write(tp, MII_ADVERTISE, anar);
 	r8152_mdio_write(tp, MII_BMCR, bmcr);
 
+	if (test_bit(PHY_RESET, &tp->flags)) {
+		int i;
+
+		clear_bit(PHY_RESET, &tp->flags);
+		for (i = 0; i < 50; i++) {
+			msleep(20);
+			if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0)
+				break;
+		}
+	}
+
 out:
 
 	return ret;
@@ -2364,6 +2405,10 @@ static void rtl_work_func_t(struct work_struct *work)
 	if (test_bit(RTL8152_SET_RX_MODE, &tp->flags))
 		_rtl8152_set_rx_mode(tp->netdev);
 
+
+	if (test_bit(PHY_RESET, &tp->flags))
+		rtl_phy_reset(tp);
+
 out1:
 	return;
 }
@@ -2459,7 +2504,6 @@ static void r8152b_enable_fc(struct r8152 *tp)
 static void r8152b_init(struct r8152 *tp)
 {
 	u32 ocp_data;
-	int i;
 
 	rtl_clear_bp(tp);
 
@@ -2491,14 +2535,6 @@ static void r8152b_init(struct r8152 *tp)
 	r8152b_enable_aldps(tp);
 	r8152b_enable_fc(tp);
 
-	r8152_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE |
-				       BMCR_ANRESTART);
-	for (i = 0; i < 100; i++) {
-		udelay(100);
-		if (!(r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET))
-			break;
-	}
-
 	/* enable rx aggregation */
 	ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
 	ocp_data &= ~RX_AGG_DISABLE;
@@ -2569,9 +2605,6 @@ static void r8153_init(struct r8152 *tp)
 	r8153_enable_eee(tp);
 	r8153_enable_aldps(tp);
 	r8152b_enable_fc(tp);
-
-	r8152_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE |
-				       BMCR_ANRESTART);
 }
 
 static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 08/14] r8152: move some functions from probe to open
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (6 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 07/14] r8152: combine PHY reset with set_speed Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 13:49 ` [PATCH net-next 09/14] r8152: support WOL Hayes Wang
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Add up method for rtl_ops and asign relative functions. Move
clear_bp() and hw_phy_cfg() from init method to up method of rtl_ops.
Call rtl_ops.up() for ndo_open() and rtl_ops.down for ndo_stop().

Replace allocating the memory in probe() with in ndo_open().

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 45 +++++++++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 20 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b3155da..828572a 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -515,6 +515,7 @@ struct r8152 {
 		void (*init)(struct r8152 *);
 		int (*enable)(struct r8152 *);
 		void (*disable)(struct r8152 *);
+		void (*up)(struct r8152 *);
 		void (*down)(struct r8152 *);
 		void (*unload)(struct r8152 *);
 	} rtl_ops;
@@ -1878,6 +1879,10 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
 	}
 
 	r8152b_disable_aldps(tp);
+
+	rtl_clear_bp(tp);
+
+	r8152b_enable_aldps(tp);
 	set_bit(PHY_RESET, &tp->flags);
 }
 
@@ -1891,6 +1896,7 @@ static void r8152b_exit_oob(struct r8152 *tp)
 	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
 
 	rxdy_gated_en(tp, true);
+	r8152b_hw_phy_cfg(tp);
 
 	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
 	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CR, 0x00);
@@ -2033,6 +2039,8 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
 		r8152_mdio_write(tp, MII_BMCR, data);
 	}
 
+	r8153_clear_bp(tp);
+
 	if (tp->version == RTL_VER_03) {
 		data = ocp_reg_read(tp, OCP_EEE_CFG);
 		data &= ~CTAP_SHORT_EN;
@@ -2418,6 +2426,12 @@ static int rtl8152_open(struct net_device *netdev)
 	struct r8152 *tp = netdev_priv(netdev);
 	int res = 0;
 
+	res = alloc_all_mem(tp);
+	if (res)
+		goto out;
+
+	tp->rtl_ops.up(tp);
+
 	rtl8152_set_speed(tp, AUTONEG_ENABLE,
 			  tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
 			  DUPLEX_FULL);
@@ -2431,9 +2445,11 @@ static int rtl8152_open(struct net_device *netdev)
 			netif_device_detach(tp->netdev);
 		netif_warn(tp, ifup, netdev, "intr_urb submit failed: %d\n",
 			   res);
+		free_all_mem(tp);
 	}
 
 
+out:
 	return res;
 }
 
@@ -2447,9 +2463,11 @@ static int rtl8152_close(struct net_device *netdev)
 	cancel_delayed_work_sync(&tp->schedule);
 	netif_stop_queue(netdev);
 	tasklet_disable(&tp->tl);
-	tp->rtl_ops.disable(tp);
+	tp->rtl_ops.down(tp);
 	tasklet_enable(&tp->tl);
 
+	free_all_mem(tp);
+
 	return res;
 }
 
@@ -2505,21 +2523,14 @@ static void r8152b_init(struct r8152 *tp)
 {
 	u32 ocp_data;
 
-	rtl_clear_bp(tp);
-
 	if (tp->version == RTL_VER_01) {
 		ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE);
 		ocp_data &= ~LED_MODE_MASK;
 		ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data);
 	}
 
-	r8152b_hw_phy_cfg(tp);
-
 	r8152_power_cut_en(tp, false);
 
-
-	r8152b_exit_oob(tp);
-
 	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR);
 	ocp_data |= TX_10M_IDLE_EN | PFM_PWM_SWITCH;
 	ocp_write_word(tp, MCU_TYPE_PLA, PLA_PHY_PWR, ocp_data);
@@ -2568,8 +2579,6 @@ static void r8153_init(struct r8152 *tp)
 	ocp_data &= ~TIMER11_EN;
 	ocp_write_word(tp, MCU_TYPE_USB, USB_WDT11_CTRL, ocp_data);
 
-	r8153_clear_bp(tp);
-
 	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE);
 	ocp_data &= ~LED_MODE_MASK;
 	ocp_write_word(tp, MCU_TYPE_PLA, PLA_LED_FEATURE, ocp_data);
@@ -2590,8 +2599,6 @@ static void r8153_init(struct r8152 *tp)
 	r8153_power_cut_en(tp, false);
 	r8153_u1u2en(tp, true);
 
-	r8153_first_init(tp);
-
 	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,
@@ -2618,10 +2625,10 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
 		usb_kill_urb(tp->intr_urb);
 		cancel_delayed_work_sync(&tp->schedule);
 		tasklet_disable(&tp->tl);
+		tp->rtl_ops.down(tp);
+		tasklet_enable(&tp->tl);
 	}
 
-	tp->rtl_ops.down(tp);
-
 	return 0;
 }
 
@@ -2632,6 +2639,7 @@ static int rtl8152_resume(struct usb_interface *intf)
 	tp->rtl_ops.init(tp);
 	netif_device_attach(tp->netdev);
 	if (netif_running(tp->netdev)) {
+		tp->rtl_ops.up(tp);
 		rtl8152_set_speed(tp, AUTONEG_ENABLE,
 				tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
 				DUPLEX_FULL);
@@ -2639,7 +2647,6 @@ static int rtl8152_resume(struct usb_interface *intf)
 		netif_carrier_off(tp->netdev);
 		set_bit(WORK_ENABLE, &tp->flags);
 		usb_submit_urb(tp->intr_urb, GFP_KERNEL);
-		tasklet_enable(&tp->tl);
 	}
 
 	return 0;
@@ -2780,6 +2787,7 @@ static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
 			ops->init		= r8152b_init;
 			ops->enable		= rtl8152_enable;
 			ops->disable		= rtl8152_disable;
+			ops->up			= r8152b_exit_oob;
 			ops->down		= rtl8152_down;
 			ops->unload		= rtl8152_unload;
 			ret = 0;
@@ -2788,6 +2796,7 @@ static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
 			ops->init		= r8153_init;
 			ops->enable		= rtl8153_enable;
 			ops->disable		= rtl8152_disable;
+			ops->up			= r8153_first_init;
 			ops->down		= rtl8153_down;
 			ops->unload		= rtl8153_unload;
 			ret = 0;
@@ -2803,6 +2812,7 @@ static int rtl_ops_init(struct r8152 *tp, const struct usb_device_id *id)
 			ops->init		= r8153_init;
 			ops->enable		= rtl8153_enable;
 			ops->disable		= rtl8152_disable;
+			ops->up			= r8153_first_init;
 			ops->down		= rtl8153_down;
 			ops->unload		= rtl8153_unload;
 			ret = 0;
@@ -2870,10 +2880,6 @@ static int rtl8152_probe(struct usb_interface *intf,
 	tp->rtl_ops.init(tp);
 	set_ethernet_addr(tp);
 
-	ret = alloc_all_mem(tp);
-	if (ret)
-		goto out;
-
 	usb_set_intfdata(intf, tp);
 
 	ret = register_netdev(netdev);
@@ -2903,7 +2909,6 @@ static void rtl8152_disconnect(struct usb_interface *intf)
 		tasklet_kill(&tp->tl);
 		unregister_netdev(tp->netdev);
 		tp->rtl_ops.unload(tp);
-		free_all_mem(tp);
 		free_netdev(tp->netdev);
 	}
 }
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 09/14] r8152: support WOL
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (7 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 08/14] r8152: move some functions from probe to open Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 13:49 ` [PATCH net-next 10/14] r8152: support runtime suspend Hayes Wang
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support WOL for RTL8152 and RTL8153.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 118 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 105 insertions(+), 13 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 828572a..5d520be 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -23,7 +23,7 @@
 #include <linux/ipv6.h>
 
 /* Version Information */
-#define DRIVER_VERSION "v1.04.0 (2014/01/15)"
+#define DRIVER_VERSION "v1.05.0 (2014/02/18)"
 #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
 #define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
 #define MODULENAME "r8152"
@@ -62,6 +62,8 @@
 #define PLA_RSTTELLY		0xe800
 #define PLA_CR			0xe813
 #define PLA_CRWECR		0xe81c
+#define PLA_CONFIG12		0xe81e	/* CONFIG1, CONFIG2 */
+#define PLA_CONFIG34		0xe820	/* CONFIG3, CONFIG4 */
 #define PLA_CONFIG5		0xe822
 #define PLA_PHY_PWR		0xe84c
 #define PLA_OOB_CTRL		0xe84f
@@ -216,7 +218,14 @@
 /* PAL_BDC_CR */
 #define ALDPS_PROXY_MODE	0x0001
 
+/* PLA_CONFIG34 */
+#define LINK_ON_WAKE_EN		0x0010
+#define LINK_OFF_WAKE_EN	0x0008
+
 /* PLA_CONFIG5 */
+#define BWF_EN			0x0040
+#define MWF_EN			0x0020
+#define UWF_EN			0x0010
 #define LAN_WAKE_EN		0x0002
 
 /* PLA_LED_FEATURE */
@@ -521,6 +530,7 @@ struct r8152 {
 	} rtl_ops;
 
 	int intr_interval;
+	u32 saved_wolopts;
 	u32 msg_enable;
 	u32 tx_qlen;
 	u16 ocp_base;
@@ -1798,6 +1808,74 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable)
 
 }
 
+#define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
+
+static u32 __rtl_get_wol(struct r8152 *tp)
+{
+	u32 ocp_data;
+	u32 wolopts = 0;
+
+	ocp_data = ocp_read_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5);
+	if (!(ocp_data & LAN_WAKE_EN))
+		return 0;
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34);
+	if (ocp_data & LINK_ON_WAKE_EN)
+		wolopts |= WAKE_PHY;
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5);
+	if (ocp_data & UWF_EN)
+		wolopts |= WAKE_UCAST;
+	if (ocp_data & BWF_EN)
+		wolopts |= WAKE_BCAST;
+	if (ocp_data & MWF_EN)
+		wolopts |= WAKE_MCAST;
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL);
+	if (ocp_data & MAGIC_EN)
+		wolopts |= WAKE_MAGIC;
+
+	return wolopts;
+}
+
+static void __rtl_set_wol(struct r8152 *tp, u32 wolopts)
+{
+	u32 ocp_data;
+
+	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG);
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34);
+	ocp_data &= ~LINK_ON_WAKE_EN;
+	if (wolopts & WAKE_PHY)
+		ocp_data |= LINK_ON_WAKE_EN;
+	ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data);
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG5);
+	ocp_data &= ~(UWF_EN | BWF_EN | MWF_EN | LAN_WAKE_EN);
+	if (wolopts & WAKE_UCAST)
+		ocp_data |= UWF_EN;
+	if (wolopts & WAKE_BCAST)
+		ocp_data |= BWF_EN;
+	if (wolopts & WAKE_MCAST)
+		ocp_data |= MWF_EN;
+	if (wolopts & WAKE_ANY)
+		ocp_data |= LAN_WAKE_EN;
+	ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG5, ocp_data);
+
+	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
+
+	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL);
+	ocp_data &= ~MAGIC_EN;
+	if (wolopts & WAKE_MAGIC)
+		ocp_data |= MAGIC_EN;
+	ocp_write_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL, ocp_data);
+
+	if (wolopts & WAKE_ANY)
+		device_set_wakeup_enable(&tp->udev->dev, true);
+	else
+		device_set_wakeup_enable(&tp->udev->dev, false);
+}
+
 static void rtl_phy_reset(struct r8152 *tp)
 {
 	u16 data;
@@ -2002,10 +2080,6 @@ static void r8152b_enter_oob(struct r8152 *tp)
 
 	ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS);
 
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL);
-	ocp_data |= MAGIC_EN;
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL, ocp_data);
-
 	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CPCR);
 	ocp_data |= CPCR_RX_VLAN;
 	ocp_write_word(tp, MCU_TYPE_PLA, PLA_CPCR, ocp_data);
@@ -2018,8 +2092,6 @@ static void r8152b_enter_oob(struct r8152 *tp)
 	ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB;
 	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
 
-	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5, LAN_WAKE_EN);
-
 	rxdy_gated_en(tp, false);
 
 	ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
@@ -2217,10 +2289,6 @@ static void r8153_enter_oob(struct r8152 *tp)
 
 	ocp_write_word(tp, MCU_TYPE_PLA, PLA_RMS, RTL8152_RMS);
 
-	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL);
-	ocp_data |= MAGIC_EN;
-	ocp_write_word(tp, MCU_TYPE_PLA, PLA_CFG_WOL, ocp_data);
-
 	ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG);
 	ocp_data &= ~TEREDO_WAKE_MASK;
 	ocp_write_word(tp, MCU_TYPE_PLA, PLA_TEREDO_CFG, ocp_data);
@@ -2237,8 +2305,6 @@ static void r8153_enter_oob(struct r8152 *tp)
 	ocp_data |= NOW_IS_OOB | DIS_MCU_CLROOB;
 	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_OOB_CTRL, ocp_data);
 
-	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CONFIG5, LAN_WAKE_EN);
-
 	rxdy_gated_en(tp, false);
 
 	ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
@@ -2652,6 +2718,24 @@ static int rtl8152_resume(struct usb_interface *intf)
 	return 0;
 }
 
+static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct r8152 *tp = netdev_priv(dev);
+
+	wol->supported = WAKE_ANY;
+	wol->wolopts = __rtl_get_wol(tp);
+}
+
+static int rtl8152_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+{
+	struct r8152 *tp = netdev_priv(dev);
+
+	__rtl_set_wol(tp, wol->wolopts);
+	tp->saved_wolopts = wol->wolopts & WAKE_ANY;
+
+	return 0;
+}
+
 static void rtl8152_get_drvinfo(struct net_device *netdev,
 				struct ethtool_drvinfo *info)
 {
@@ -2685,6 +2769,8 @@ static struct ethtool_ops ops = {
 	.get_settings = rtl8152_get_settings,
 	.set_settings = rtl8152_set_settings,
 	.get_link = ethtool_op_get_link,
+	.get_wol = rtl8152_get_wol,
+	.set_wol = rtl8152_set_wol,
 };
 
 static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
@@ -2888,6 +2974,12 @@ static int rtl8152_probe(struct usb_interface *intf,
 		goto out1;
 	}
 
+	tp->saved_wolopts = __rtl_get_wol(tp);
+	if (tp->saved_wolopts)
+		device_set_wakeup_enable(&udev->dev, true);
+	else
+		device_set_wakeup_enable(&udev->dev, false);
+
 	netif_info(tp, probe, netdev, "%s\n", DRIVER_VERSION);
 
 	return 0;
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 10/14] r8152: support runtime suspend
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (8 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 09/14] r8152: support WOL Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 13:49 ` [PATCH net-next 11/14] r8152: disable teredo for RTL8152 Hayes Wang
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support runtime suspend for RTL8152 and RTL8153.

Move tx_bottom() from tasklet to delayed_work. That avoids to
transmit tx packets after calling autosuspend.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 181 ++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 158 insertions(+), 23 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 5d520be..f303549 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -445,6 +445,7 @@ enum rtl8152_flags {
 	RTL8152_SET_RX_MODE,
 	WORK_ENABLE,
 	RTL8152_LINK_CHG,
+	SELECTIVE_SUSPEND,
 	PHY_RESET,
 };
 
@@ -877,11 +878,21 @@ static u16 sram_read(struct r8152 *tp, u16 addr)
 static int read_mii_word(struct net_device *netdev, int phy_id, int reg)
 {
 	struct r8152 *tp = netdev_priv(netdev);
+	int ret;
 
 	if (phy_id != R8152_PHY_ID)
 		return -EINVAL;
 
-	return r8152_mdio_read(tp, reg);
+	ret = usb_autopm_get_interface(tp->intf);
+	if (ret < 0)
+		goto out;
+
+	ret = r8152_mdio_read(tp, reg);
+
+	usb_autopm_put_interface(tp->intf);
+
+out:
+	return ret;
 }
 
 static
@@ -892,7 +903,12 @@ void write_mii_word(struct net_device *netdev, int phy_id, int reg, int val)
 	if (phy_id != R8152_PHY_ID)
 		return;
 
+	if (usb_autopm_get_interface(tp->intf) < 0)
+		return;
+
 	r8152_mdio_write(tp, reg, val);
+
+	usb_autopm_put_interface(tp->intf);
 }
 
 static
@@ -978,6 +994,8 @@ static void read_bulk_callback(struct urb *urb)
 	if (!netif_carrier_ok(netdev))
 		return;
 
+	usb_mark_last_busy(tp->udev);
+
 	switch (status) {
 	case 0:
 		if (urb->actual_length < ETH_ZLEN)
@@ -1045,6 +1063,8 @@ static void write_bulk_callback(struct urb *urb)
 	list_add_tail(&agg->list, &tp->tx_free);
 	spin_unlock_irqrestore(&tp->tx_lock, flags);
 
+	usb_autopm_put_interface_async(tp->intf);
+
 	if (!netif_carrier_ok(tp->netdev))
 		return;
 
@@ -1055,7 +1075,7 @@ static void write_bulk_callback(struct urb *urb)
 		return;
 
 	if (!skb_queue_empty(&tp->tx_queue))
-		tasklet_schedule(&tp->tl);
+		schedule_delayed_work(&tp->schedule, 0);
 }
 
 static void intr_callback(struct urb *urb)
@@ -1313,7 +1333,7 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 {
 	struct sk_buff_head skb_head, *tx_queue = &tp->tx_queue;
 	unsigned long flags;
-	int remain;
+	int remain, ret;
 	u8 *tx_data;
 
 	__skb_queue_head_init(&skb_head);
@@ -1361,19 +1381,28 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		spin_unlock_irqrestore(&tx_queue->lock, flags);
 	}
 
-	netif_tx_lock(tp->netdev);
+	netif_tx_lock_bh(tp->netdev);
 
 	if (netif_queue_stopped(tp->netdev) &&
 	    skb_queue_len(&tp->tx_queue) < tp->tx_qlen)
 		netif_wake_queue(tp->netdev);
 
-	netif_tx_unlock(tp->netdev);
+	netif_tx_unlock_bh(tp->netdev);
+
+	ret = usb_autopm_get_interface(tp->intf);
+	if (ret < 0)
+		goto out_tx_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);
 
-	return usb_submit_urb(agg->urb, GFP_ATOMIC);
+	ret = usb_submit_urb(agg->urb, GFP_KERNEL);
+	if (ret < 0)
+		usb_autopm_put_interface(tp->intf);
+
+out_tx_fill:
+	return ret;
 }
 
 static void rx_bottom(struct r8152 *tp)
@@ -1511,7 +1540,6 @@ static void bottom_half(unsigned long data)
 		return;
 
 	rx_bottom(tp);
-	tx_bottom(tp);
 }
 
 static
@@ -1621,7 +1649,7 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
 		netif_stop_queue(netdev);
 
 	if (!list_empty(&tp->tx_free))
-		tasklet_schedule(&tp->tl);
+		schedule_delayed_work(&tp->schedule, 0);
 
 	return NETDEV_TX_OK;
 }
@@ -1876,6 +1904,25 @@ static void __rtl_set_wol(struct r8152 *tp, u32 wolopts)
 		device_set_wakeup_enable(&tp->udev->dev, false);
 }
 
+static void rtl_runtime_suspend_enable(struct r8152 *tp, bool enable)
+{
+	if (enable) {
+		u32 ocp_data;
+
+		__rtl_set_wol(tp, WAKE_ANY);
+
+		ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_CONFIG);
+
+		ocp_data = ocp_read_word(tp, MCU_TYPE_PLA, PLA_CONFIG34);
+		ocp_data |= LINK_OFF_WAKE_EN;
+		ocp_write_word(tp, MCU_TYPE_PLA, PLA_CONFIG34, ocp_data);
+
+		ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
+	} else {
+		__rtl_set_wol(tp, tp->saved_wolopts);
+	}
+}
+
 static void rtl_phy_reset(struct r8152 *tp)
 {
 	u16 data;
@@ -2467,6 +2514,9 @@ static void rtl_work_func_t(struct work_struct *work)
 {
 	struct r8152 *tp = container_of(work, struct r8152, schedule.work);
 
+	if (usb_autopm_get_interface(tp->intf) < 0)
+		return;
+
 	if (!test_bit(WORK_ENABLE, &tp->flags))
 		goto out1;
 
@@ -2479,12 +2529,14 @@ static void rtl_work_func_t(struct work_struct *work)
 	if (test_bit(RTL8152_SET_RX_MODE, &tp->flags))
 		_rtl8152_set_rx_mode(tp->netdev);
 
+	if (tp->speed & LINK_STATUS)
+		tx_bottom(tp);
 
 	if (test_bit(PHY_RESET, &tp->flags))
 		rtl_phy_reset(tp);
 
 out1:
-	return;
+	usb_autopm_put_interface(tp->intf);
 }
 
 static int rtl8152_open(struct net_device *netdev)
@@ -2496,6 +2548,21 @@ static int rtl8152_open(struct net_device *netdev)
 	if (res)
 		goto out;
 
+	res = usb_autopm_get_interface(tp->intf);
+	if (res < 0) {
+		free_all_mem(tp);
+		goto out;
+	}
+
+	/* The WORK_ENABLE may be set when autoresume occurs */
+	if (test_bit(WORK_ENABLE, &tp->flags)) {
+		clear_bit(WORK_ENABLE, &tp->flags);
+		usb_kill_urb(tp->intr_urb);
+		cancel_delayed_work_sync(&tp->schedule);
+		if (tp->speed & LINK_STATUS)
+			tp->rtl_ops.disable(tp);
+	}
+
 	tp->rtl_ops.up(tp);
 
 	rtl8152_set_speed(tp, AUTONEG_ENABLE,
@@ -2514,6 +2581,7 @@ static int rtl8152_open(struct net_device *netdev)
 		free_all_mem(tp);
 	}
 
+	usb_autopm_put_interface(tp->intf);
 
 out:
 	return res;
@@ -2528,9 +2596,26 @@ static int rtl8152_close(struct net_device *netdev)
 	usb_kill_urb(tp->intr_urb);
 	cancel_delayed_work_sync(&tp->schedule);
 	netif_stop_queue(netdev);
-	tasklet_disable(&tp->tl);
-	tp->rtl_ops.down(tp);
-	tasklet_enable(&tp->tl);
+
+	res = usb_autopm_get_interface(tp->intf);
+	if (res < 0) {
+		rtl_drop_queued_tx(tp);
+	} else {
+		/*
+		 * The autosuspend may have been enabled and wouldn't
+		 * be disable when autoresume occurs, because the
+		 * netif_running() would be false.
+		 */
+		if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+			rtl_runtime_suspend_enable(tp, false);
+			clear_bit(SELECTIVE_SUSPEND, &tp->flags);
+		}
+
+		tasklet_disable(&tp->tl);
+		tp->rtl_ops.down(tp);
+		tasklet_enable(&tp->tl);
+		usb_autopm_put_interface(tp->intf);
+	}
 
 	free_all_mem(tp);
 
@@ -2684,15 +2769,22 @@ static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
 {
 	struct r8152 *tp = usb_get_intfdata(intf);
 
-	netif_device_detach(tp->netdev);
+	if (PMSG_IS_AUTO(message))
+		set_bit(SELECTIVE_SUSPEND, &tp->flags);
+	else
+		netif_device_detach(tp->netdev);
 
 	if (netif_running(tp->netdev)) {
 		clear_bit(WORK_ENABLE, &tp->flags);
 		usb_kill_urb(tp->intr_urb);
 		cancel_delayed_work_sync(&tp->schedule);
-		tasklet_disable(&tp->tl);
-		tp->rtl_ops.down(tp);
-		tasklet_enable(&tp->tl);
+		if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+			rtl_runtime_suspend_enable(tp, true);
+		} else {
+			tasklet_disable(&tp->tl);
+			tp->rtl_ops.down(tp);
+			tasklet_enable(&tp->tl);
+		}
 	}
 
 	return 0;
@@ -2702,13 +2794,23 @@ static int rtl8152_resume(struct usb_interface *intf)
 {
 	struct r8152 *tp = usb_get_intfdata(intf);
 
-	tp->rtl_ops.init(tp);
-	netif_device_attach(tp->netdev);
+	if (!test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+		tp->rtl_ops.init(tp);
+		netif_device_attach(tp->netdev);
+	}
+
 	if (netif_running(tp->netdev)) {
-		tp->rtl_ops.up(tp);
-		rtl8152_set_speed(tp, AUTONEG_ENABLE,
+		if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+			rtl_runtime_suspend_enable(tp, false);
+			clear_bit(SELECTIVE_SUSPEND, &tp->flags);
+			if (tp->speed & LINK_STATUS)
+				tp->rtl_ops.disable(tp);
+		} else {
+			tp->rtl_ops.up(tp);
+			rtl8152_set_speed(tp, AUTONEG_ENABLE,
 				tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
 				DUPLEX_FULL);
+		}
 		tp->speed = 0;
 		netif_carrier_off(tp->netdev);
 		set_bit(WORK_ENABLE, &tp->flags);
@@ -2722,18 +2824,31 @@ static void rtl8152_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct r8152 *tp = netdev_priv(dev);
 
+	if (usb_autopm_get_interface(tp->intf) < 0)
+		return;
+
 	wol->supported = WAKE_ANY;
 	wol->wolopts = __rtl_get_wol(tp);
+
+	usb_autopm_put_interface(tp->intf);
 }
 
 static int rtl8152_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
 {
 	struct r8152 *tp = netdev_priv(dev);
+	int ret;
+
+	ret = usb_autopm_get_interface(tp->intf);
+	if (ret < 0)
+		goto out_set_wol;
 
 	__rtl_set_wol(tp, wol->wolopts);
 	tp->saved_wolopts = wol->wolopts & WAKE_ANY;
 
-	return 0;
+	usb_autopm_put_interface(tp->intf);
+
+out_set_wol:
+	return ret;
 }
 
 static void rtl8152_get_drvinfo(struct net_device *netdev,
@@ -2760,8 +2875,18 @@ int rtl8152_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd)
 static int rtl8152_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct r8152 *tp = netdev_priv(dev);
+	int ret;
+
+	ret = usb_autopm_get_interface(tp->intf);
+	if (ret < 0)
+		goto out;
 
-	return rtl8152_set_speed(tp, cmd->autoneg, cmd->speed, cmd->duplex);
+	ret = rtl8152_set_speed(tp, cmd->autoneg, cmd->speed, cmd->duplex);
+
+	usb_autopm_put_interface(tp->intf);
+
+out:
+	return ret;
 }
 
 static struct ethtool_ops ops = {
@@ -2777,7 +2902,11 @@ static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
 {
 	struct r8152 *tp = netdev_priv(netdev);
 	struct mii_ioctl_data *data = if_mii(rq);
-	int res = 0;
+	int res;
+
+	res = usb_autopm_get_interface(tp->intf);
+	if (res < 0)
+		goto out;
 
 	switch (cmd) {
 	case SIOCGMIIPHY:
@@ -2800,6 +2929,9 @@ static int rtl8152_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
 		res = -EOPNOTSUPP;
 	}
 
+	usb_autopm_put_interface(tp->intf);
+
+out:
 	return res;
 }
 
@@ -2962,6 +3094,8 @@ static int rtl8152_probe(struct usb_interface *intf,
 	tp->mii.phy_id = R8152_PHY_ID;
 	tp->mii.supports_gmii = 0;
 
+	intf->needs_remote_wakeup = 1;
+
 	r8152b_get_version(tp);
 	tp->rtl_ops.init(tp);
 	set_ethernet_addr(tp);
@@ -3023,6 +3157,7 @@ static struct usb_driver rtl8152_driver = {
 	.suspend =	rtl8152_suspend,
 	.resume =	rtl8152_resume,
 	.reset_resume =	rtl8152_resume,
+	.supports_autosuspend = 1,
 };
 
 module_usb_driver(rtl8152_driver);
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 11/14] r8152: disable teredo for RTL8152
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (9 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 10/14] r8152: support runtime suspend Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 13:49 ` [PATCH net-next 12/14] r8152: replace netif_rx with netif_receive_skb Hayes Wang
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Disable teredo for RTL8152 by default.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index f303549..3ff11ed 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -2021,6 +2021,7 @@ static void r8152b_exit_oob(struct r8152 *tp)
 	ocp_write_dword(tp, MCU_TYPE_PLA, PLA_RCR, ocp_data);
 
 	rxdy_gated_en(tp, true);
+	r8153_teredo_off(tp);
 	r8152b_hw_phy_cfg(tp);
 
 	ocp_write_byte(tp, MCU_TYPE_PLA, PLA_CRWECR, CRWECR_NORAML);
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 12/14] r8152: replace netif_rx with netif_receive_skb
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (10 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 11/14] r8152: disable teredo for RTL8152 Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 23:28   ` Francois Romieu
  2014-02-18 13:49 ` [PATCH net-next 13/14] r8152: set disable_hub_initiated_lpm Hayes Wang
                   ` (2 subsequent siblings)
  14 siblings, 1 reply; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Replace netif_rx with netif_receive_skb to avoid disabling irq frequently
for increasing the efficiency.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 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 3ff11ed..ff02d5d 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1464,7 +1464,7 @@ static void rx_bottom(struct r8152 *tp)
 			memcpy(skb->data, rx_data, pkt_len);
 			skb_put(skb, pkt_len);
 			skb->protocol = eth_type_trans(skb, netdev);
-			netif_rx(skb);
+			netif_receive_skb(skb);
 			stats->rx_packets++;
 			stats->rx_bytes += pkt_len;
 
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 13/14] r8152: set disable_hub_initiated_lpm
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (11 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 12/14] r8152: replace netif_rx with netif_receive_skb Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 13:49 ` [PATCH net-next 14/14] r8152: support get_msglevel and set_msglevel Hayes Wang
  2014-02-18 21:41 ` [PATCH net-next 00/14] r8152: improvement and new features David Miller
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Set disable_hub_initiated_lpm = 1.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ff02d5d..db98842 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -3159,6 +3159,7 @@ static struct usb_driver rtl8152_driver = {
 	.resume =	rtl8152_resume,
 	.reset_resume =	rtl8152_resume,
 	.supports_autosuspend = 1,
+	.disable_hub_initiated_lpm = 1,
 };
 
 module_usb_driver(rtl8152_driver);
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* [PATCH net-next 14/14] r8152: support get_msglevel and set_msglevel
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (12 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 13/14] r8152: set disable_hub_initiated_lpm Hayes Wang
@ 2014-02-18 13:49 ` Hayes Wang
  2014-02-18 21:41 ` [PATCH net-next 00/14] r8152: improvement and new features David Miller
  14 siblings, 0 replies; 23+ messages in thread
From: Hayes Wang @ 2014-02-18 13:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support get_msglevel and set_msglevel.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/r8152.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index db98842..0654bd3 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -2852,6 +2852,20 @@ out_set_wol:
 	return ret;
 }
 
+static u32 rtl8152_get_msglevel(struct net_device *dev)
+{
+	struct r8152 *tp = netdev_priv(dev);
+
+	return tp->msg_enable;
+}
+
+static void rtl8152_set_msglevel(struct net_device *dev, u32 value)
+{
+	struct r8152 *tp = netdev_priv(dev);
+
+	tp->msg_enable = value;
+}
+
 static void rtl8152_get_drvinfo(struct net_device *netdev,
 				struct ethtool_drvinfo *info)
 {
@@ -2895,6 +2909,8 @@ static struct ethtool_ops ops = {
 	.get_settings = rtl8152_get_settings,
 	.set_settings = rtl8152_set_settings,
 	.get_link = ethtool_op_get_link,
+	.get_msglevel = rtl8152_get_msglevel,
+	.set_msglevel = rtl8152_set_msglevel,
 	.get_wol = rtl8152_get_wol,
 	.set_wol = rtl8152_set_wol,
 };
-- 
1.8.4.2


^ permalink raw reply related	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 07/14] r8152: combine PHY reset with set_speed
@ 2014-02-18 17:19     ` Florian Fainelli
  0 siblings, 0 replies; 23+ messages in thread
From: Florian Fainelli @ 2014-02-18 17:19 UTC (permalink / raw)
  To: Hayes Wang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

Hi Hayes,

2014-02-18 5:49 GMT-08:00 Hayes Wang <hayeswang@realtek.com>:
> PHY reset is necessary after some hw settings. However, it would
> cause the linking down, and so does the set_speed function. Combine
> the PHY reset with set_speed function. That could reduce the frequency
> of linking down and accessing the PHY register.
>
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
> ---
>  drivers/net/usb/r8152.c | 57 ++++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 45 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index c7bae39..b3155da 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
> @@ -436,6 +436,7 @@ enum rtl8152_flags {
>         RTL8152_SET_RX_MODE,
>         WORK_ENABLE,
>         RTL8152_LINK_CHG,
> +       PHY_RESET,
>  };
>
>  /* Define these values to match your device */
> @@ -1796,6 +1797,29 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable)
>
>  }
>
> +static void rtl_phy_reset(struct r8152 *tp)
> +{
> +       u16 data;
> +       int i;
> +
> +       clear_bit(PHY_RESET, &tp->flags);
> +
> +       data = r8152_mdio_read(tp, MII_BMCR);
> +
> +       /* don't reset again before the previous one complete */
> +       if (data & BMCR_RESET)
> +               return;
> +
> +       data |= BMCR_RESET;
> +       r8152_mdio_write(tp, MII_BMCR, data);
> +
> +       for (i = 0; i < 50; i++) {
> +               msleep(20);
> +               if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0)
> +                       break;
> +       }
> +}

If you implemented libphy in the driver you would not have to
duplicate that and you could use "phy_init_hw()" or
genphy_soft_reset() to perform the BMCR-based software reset.

> +
>  static void rtl_clear_bp(struct r8152 *tp)
>  {
>         ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
> @@ -1854,6 +1878,7 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
>         }
>
>         r8152b_disable_aldps(tp);
> +       set_bit(PHY_RESET, &tp->flags);
>  }
>
>  static void r8152b_exit_oob(struct r8152 *tp)
> @@ -2042,6 +2067,8 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
>         data = sram_read(tp, SRAM_10M_AMP2);
>         data |= AMP_DN;
>         sram_write(tp, SRAM_10M_AMP2, data);
> +
> +       set_bit(PHY_RESET, &tp->flags);
>  }
>
>  static void r8153_u1u2en(struct r8152 *tp, bool enable)
> @@ -2295,12 +2322,26 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex)
>                 bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
>         }
>
> +       if (test_bit(PHY_RESET, &tp->flags))
> +               bmcr |= BMCR_RESET;
> +
>         if (tp->mii.supports_gmii)
>                 r8152_mdio_write(tp, MII_CTRL1000, gbcr);
>
>         r8152_mdio_write(tp, MII_ADVERTISE, anar);
>         r8152_mdio_write(tp, MII_BMCR, bmcr);
>
> +       if (test_bit(PHY_RESET, &tp->flags)) {
> +               int i;
> +
> +               clear_bit(PHY_RESET, &tp->flags);
> +               for (i = 0; i < 50; i++) {
> +                       msleep(20);
> +                       if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0)
> +                               break;
> +               }
> +       }
> +
>  out:
>
>         return ret;
> @@ -2364,6 +2405,10 @@ static void rtl_work_func_t(struct work_struct *work)
>         if (test_bit(RTL8152_SET_RX_MODE, &tp->flags))
>                 _rtl8152_set_rx_mode(tp->netdev);
>
> +
> +       if (test_bit(PHY_RESET, &tp->flags))
> +               rtl_phy_reset(tp);
> +
>  out1:
>         return;
>  }
> @@ -2459,7 +2504,6 @@ static void r8152b_enable_fc(struct r8152 *tp)
>  static void r8152b_init(struct r8152 *tp)
>  {
>         u32 ocp_data;
> -       int i;
>
>         rtl_clear_bp(tp);
>
> @@ -2491,14 +2535,6 @@ static void r8152b_init(struct r8152 *tp)
>         r8152b_enable_aldps(tp);
>         r8152b_enable_fc(tp);
>
> -       r8152_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE |
> -                                      BMCR_ANRESTART);
> -       for (i = 0; i < 100; i++) {
> -               udelay(100);
> -               if (!(r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET))
> -                       break;
> -       }
> -
>         /* enable rx aggregation */
>         ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
>         ocp_data &= ~RX_AGG_DISABLE;
> @@ -2569,9 +2605,6 @@ static void r8153_init(struct r8152 *tp)
>         r8153_enable_eee(tp);
>         r8153_enable_aldps(tp);
>         r8152b_enable_fc(tp);
> -
> -       r8152_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE |
> -                                      BMCR_ANRESTART);
>  }
>
>  static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
> --
> 1.8.4.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Florian

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 07/14] r8152: combine PHY reset with set_speed
@ 2014-02-18 17:19     ` Florian Fainelli
  0 siblings, 0 replies; 23+ messages in thread
From: Florian Fainelli @ 2014-02-18 17:19 UTC (permalink / raw)
  To: Hayes Wang
  Cc: netdev, nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA, linux-usb

Hi Hayes,

2014-02-18 5:49 GMT-08:00 Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>:
> PHY reset is necessary after some hw settings. However, it would
> cause the linking down, and so does the set_speed function. Combine
> the PHY reset with set_speed function. That could reduce the frequency
> of linking down and accessing the PHY register.
>
> Signed-off-by: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/net/usb/r8152.c | 57 ++++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 45 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index c7bae39..b3155da 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
> @@ -436,6 +436,7 @@ enum rtl8152_flags {
>         RTL8152_SET_RX_MODE,
>         WORK_ENABLE,
>         RTL8152_LINK_CHG,
> +       PHY_RESET,
>  };
>
>  /* Define these values to match your device */
> @@ -1796,6 +1797,29 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable)
>
>  }
>
> +static void rtl_phy_reset(struct r8152 *tp)
> +{
> +       u16 data;
> +       int i;
> +
> +       clear_bit(PHY_RESET, &tp->flags);
> +
> +       data = r8152_mdio_read(tp, MII_BMCR);
> +
> +       /* don't reset again before the previous one complete */
> +       if (data & BMCR_RESET)
> +               return;
> +
> +       data |= BMCR_RESET;
> +       r8152_mdio_write(tp, MII_BMCR, data);
> +
> +       for (i = 0; i < 50; i++) {
> +               msleep(20);
> +               if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0)
> +                       break;
> +       }
> +}

If you implemented libphy in the driver you would not have to
duplicate that and you could use "phy_init_hw()" or
genphy_soft_reset() to perform the BMCR-based software reset.

> +
>  static void rtl_clear_bp(struct r8152 *tp)
>  {
>         ocp_write_dword(tp, MCU_TYPE_PLA, PLA_BP_0, 0);
> @@ -1854,6 +1878,7 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
>         }
>
>         r8152b_disable_aldps(tp);
> +       set_bit(PHY_RESET, &tp->flags);
>  }
>
>  static void r8152b_exit_oob(struct r8152 *tp)
> @@ -2042,6 +2067,8 @@ static void r8153_hw_phy_cfg(struct r8152 *tp)
>         data = sram_read(tp, SRAM_10M_AMP2);
>         data |= AMP_DN;
>         sram_write(tp, SRAM_10M_AMP2, data);
> +
> +       set_bit(PHY_RESET, &tp->flags);
>  }
>
>  static void r8153_u1u2en(struct r8152 *tp, bool enable)
> @@ -2295,12 +2322,26 @@ static int rtl8152_set_speed(struct r8152 *tp, u8 autoneg, u16 speed, u8 duplex)
>                 bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
>         }
>
> +       if (test_bit(PHY_RESET, &tp->flags))
> +               bmcr |= BMCR_RESET;
> +
>         if (tp->mii.supports_gmii)
>                 r8152_mdio_write(tp, MII_CTRL1000, gbcr);
>
>         r8152_mdio_write(tp, MII_ADVERTISE, anar);
>         r8152_mdio_write(tp, MII_BMCR, bmcr);
>
> +       if (test_bit(PHY_RESET, &tp->flags)) {
> +               int i;
> +
> +               clear_bit(PHY_RESET, &tp->flags);
> +               for (i = 0; i < 50; i++) {
> +                       msleep(20);
> +                       if ((r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET) == 0)
> +                               break;
> +               }
> +       }
> +
>  out:
>
>         return ret;
> @@ -2364,6 +2405,10 @@ static void rtl_work_func_t(struct work_struct *work)
>         if (test_bit(RTL8152_SET_RX_MODE, &tp->flags))
>                 _rtl8152_set_rx_mode(tp->netdev);
>
> +
> +       if (test_bit(PHY_RESET, &tp->flags))
> +               rtl_phy_reset(tp);
> +
>  out1:
>         return;
>  }
> @@ -2459,7 +2504,6 @@ static void r8152b_enable_fc(struct r8152 *tp)
>  static void r8152b_init(struct r8152 *tp)
>  {
>         u32 ocp_data;
> -       int i;
>
>         rtl_clear_bp(tp);
>
> @@ -2491,14 +2535,6 @@ static void r8152b_init(struct r8152 *tp)
>         r8152b_enable_aldps(tp);
>         r8152b_enable_fc(tp);
>
> -       r8152_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE |
> -                                      BMCR_ANRESTART);
> -       for (i = 0; i < 100; i++) {
> -               udelay(100);
> -               if (!(r8152_mdio_read(tp, MII_BMCR) & BMCR_RESET))
> -                       break;
> -       }
> -
>         /* enable rx aggregation */
>         ocp_data = ocp_read_word(tp, MCU_TYPE_USB, USB_USB_CTRL);
>         ocp_data &= ~RX_AGG_DISABLE;
> @@ -2569,9 +2605,6 @@ static void r8153_init(struct r8152 *tp)
>         r8153_enable_eee(tp);
>         r8153_enable_aldps(tp);
>         r8152b_enable_fc(tp);
> -
> -       r8152_mdio_write(tp, MII_BMCR, BMCR_RESET | BMCR_ANENABLE |
> -                                      BMCR_ANRESTART);
>  }
>
>  static int rtl8152_suspend(struct usb_interface *intf, pm_message_t message)
> --
> 1.8.4.2
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/



-- 
Florian
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 00/14] r8152: improvement and new features
  2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
                   ` (13 preceding siblings ...)
  2014-02-18 13:49 ` [PATCH net-next 14/14] r8152: support get_msglevel and set_msglevel Hayes Wang
@ 2014-02-18 21:41 ` David Miller
  14 siblings, 0 replies; 23+ messages in thread
From: David Miller @ 2014-02-18 21:41 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: Hayes Wang <hayeswang@realtek.com>
Date: Tue, 18 Feb 2014 21:48:57 +0800

> Change some flows or behavior to improve the efficiency or make the
> code readable. Besides, support WOL and runtime suspend.

Series applied, but as Florian mentioned you should seriously consider
converting this driver to use phylib.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 12/14] r8152: replace netif_rx with netif_receive_skb
  2014-02-18 13:49 ` [PATCH net-next 12/14] r8152: replace netif_rx with netif_receive_skb Hayes Wang
@ 2014-02-18 23:28   ` Francois Romieu
  2014-02-19  3:01     ` [PATCH net-next 12/14] r8152: replace netif_rx withnetif_receive_skb hayeswang
  0 siblings, 1 reply; 23+ messages in thread
From: Francois Romieu @ 2014-02-18 23:28 UTC (permalink / raw)
  To: Hayes Wang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

Hayes Wang <hayeswang@realtek.com> :
> Replace netif_rx with netif_receive_skb to avoid disabling irq frequently
> for increasing the efficiency.

read_bulk_callback is issued in irq context. It could thus use plain
spin_lock / spin_unlock instead of the irq disabling version.

-- 
Ueimor

^ permalink raw reply	[flat|nested] 23+ messages in thread

* RE: [PATCH net-next 07/14] r8152: combine PHY reset with set_speed
       [not found]   ` <201402190209.s1J29EVG032292@rtits1.realtek.com>
@ 2014-02-19  2:41     ` hayeswang
  0 siblings, 0 replies; 23+ messages in thread
From: hayeswang @ 2014-02-19  2:41 UTC (permalink / raw)
  To: 'Florian Fainelli'
  Cc: 'netdev', nic_swsd, linux-kernel, 'linux-usb'

 Florian Fainelli [mailto:f.fainelli@gmail.com] 
> Sent: Wednesday, February 19, 2014 1:19 AM
> To: Hayes Wang
> Cc: netdev; nic_swsd@realtek.com; 
> linux-kernel@vger.kernel.org; linux-usb
> Subject: Re: [PATCH net-next 07/14] r8152: combine PHY reset 
> with set_speed
[...]
> > +static void rtl_phy_reset(struct r8152 *tp)
> > +{
> > +       u16 data;
> > +       int i;
> > +
> > +       clear_bit(PHY_RESET, &tp->flags);
> > +
> > +       data = r8152_mdio_read(tp, MII_BMCR);
> > +
> > +       /* don't reset again before the previous one complete */
> > +       if (data & BMCR_RESET)
> > +               return;
> > +
> > +       data |= BMCR_RESET;
> > +       r8152_mdio_write(tp, MII_BMCR, data);
> > +
> > +       for (i = 0; i < 50; i++) {
> > +               msleep(20);
> > +               if ((r8152_mdio_read(tp, MII_BMCR) & 
> BMCR_RESET) == 0)
> > +                       break;
> > +       }
> > +}
> 
> If you implemented libphy in the driver you would not have to
> duplicate that and you could use "phy_init_hw()" or
> genphy_soft_reset() to perform the BMCR-based software reset.

Thanks for you suggestion. I would study about those.
 
Best Regards,
Hayes



^ permalink raw reply	[flat|nested] 23+ messages in thread

* RE: [PATCH net-next 12/14] r8152: replace netif_rx withnetif_receive_skb
  2014-02-18 23:28   ` Francois Romieu
@ 2014-02-19  3:01     ` hayeswang
  2014-02-19  7:46       ` Francois Romieu
  0 siblings, 1 reply; 23+ messages in thread
From: hayeswang @ 2014-02-19  3:01 UTC (permalink / raw)
  To: 'Francois Romieu'; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

 Francois Romieu [mailto:romieu@fr.zoreil.com] 
> Sent: Wednesday, February 19, 2014 7:29 AM
> To: Hayes Wang
> Cc: netdev@vger.kernel.org; nic_swsd@realtek.com; 
> linux-kernel@vger.kernel.org; linux-usb@vger.kernel.org
> Subject: Re: [PATCH net-next 12/14] r8152: replace netif_rx 
> withnetif_receive_skb
> 
> Hayes Wang <hayeswang@realtek.com> :
> > Replace netif_rx with netif_receive_skb to avoid disabling irq frequently
> > for increasing the efficiency.
> 
> read_bulk_callback is issued in irq context. It could thus use plain
> spin_lock / spin_unlock instead of the irq disabling version.

The rx_bottom() is called in tasklet, so I just think I could use
netif_receive_skb directly. The netif_rx seems to queue the packet,
and local_irq_disable() would be called before dequeuing the skb.
 
Best Regards,
Hayes


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: [PATCH net-next 12/14] r8152: replace netif_rx withnetif_receive_skb
  2014-02-19  3:01     ` [PATCH net-next 12/14] r8152: replace netif_rx withnetif_receive_skb hayeswang
@ 2014-02-19  7:46       ` Francois Romieu
  2014-02-19 12:45         ` [PATCH net-next 12/14] r8152: replace netif_rxwithnetif_receive_skb hayeswang
  0 siblings, 1 reply; 23+ messages in thread
From: Francois Romieu @ 2014-02-19  7:46 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

hayeswang <hayeswang@realtek.com> :
>  Francois Romieu [mailto:romieu@fr.zoreil.com] 
> > Hayes Wang <hayeswang@realtek.com> :
> > > Replace netif_rx with netif_receive_skb to avoid disabling irq frequently
> > > for increasing the efficiency.
> > 
> > read_bulk_callback is issued in irq context. It could thus use plain
> > spin_lock / spin_unlock instead of the irq disabling version.
> 
> The rx_bottom() is called in tasklet, so I just think I could use
> netif_receive_skb directly. The netif_rx seems to queue the packet,
> and local_irq_disable() would be called before dequeuing the skb.

The change in rx_bottom is fine. My point is about read_bulk_callback.

rx_bottom races with read_bulk_callback. rx_bottom is issued in
tasklet (softirq) context. read_bulk_callback is issued in irq
context, with irq disabled. read_bulk_callback does not need to
disable irq itself and could go with spin_lock in place of
spin_lock_irqsave (rx_bottom can't, of course).

-- 
Ueimor

^ permalink raw reply	[flat|nested] 23+ messages in thread

* RE: [PATCH net-next 12/14] r8152: replace netif_rxwithnetif_receive_skb
  2014-02-19  7:46       ` Francois Romieu
@ 2014-02-19 12:45         ` hayeswang
  0 siblings, 0 replies; 23+ messages in thread
From: hayeswang @ 2014-02-19 12:45 UTC (permalink / raw)
  To: 'Francois Romieu'; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

 Francois Romieu [mailto:romieu@fr.zoreil.com] 
> Sent: Wednesday, February 19, 2014 3:47 PM
> To: hayeswang
> Cc: netdev@vger.kernel.org; nic_swsd@realtek.com; 
> linux-kernel@vger.kernel.org; linux-usb@vger.kernel.org
> Subject: Re: [PATCH net-next 12/14] r8152: replace 
> netif_rxwithnetif_receive_skb
> 
[...]
> The change in rx_bottom is fine. My point is about read_bulk_callback.
> 
> rx_bottom races with read_bulk_callback. rx_bottom is issued in
> tasklet (softirq) context. read_bulk_callback is issued in irq
> context, with irq disabled. read_bulk_callback does not need to
> disable irq itself and could go with spin_lock in place of
> spin_lock_irqsave (rx_bottom can't, of course).

I think I misunderstand your meaning.
I would modify them. Thanks.
 
Best Regards,
Hayes


^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2014-02-19 12:45 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-18 13:48 [PATCH net-next 00/14] r8152: improvement and new features Hayes Wang
2014-02-18 13:48 ` [PATCH net-next 01/14] r8152: move some functions Hayes Wang
2014-02-18 13:48 ` [PATCH net-next 02/14] r8152: add three functions Hayes Wang
2014-02-18 13:49 ` [PATCH net-next 03/14] r8152: replace some types from int to bool Hayes Wang
2014-02-18 13:49 ` [PATCH net-next 04/14] r8152: load the default MAC address Hayes Wang
2014-02-18 13:49 ` [PATCH net-next 05/14] r8152: reduce the frequency of spin_lock Hayes Wang
2014-02-18 13:49 ` [PATCH net-next 06/14] r8152: clear BMCR_PDOWN Hayes Wang
2014-02-18 13:49 ` [PATCH net-next 07/14] r8152: combine PHY reset with set_speed Hayes Wang
2014-02-18 17:19   ` Florian Fainelli
2014-02-18 17:19     ` Florian Fainelli
     [not found]   ` <201402190209.s1J29EVG032292@rtits1.realtek.com>
2014-02-19  2:41     ` hayeswang
2014-02-18 13:49 ` [PATCH net-next 08/14] r8152: move some functions from probe to open Hayes Wang
2014-02-18 13:49 ` [PATCH net-next 09/14] r8152: support WOL Hayes Wang
2014-02-18 13:49 ` [PATCH net-next 10/14] r8152: support runtime suspend Hayes Wang
2014-02-18 13:49 ` [PATCH net-next 11/14] r8152: disable teredo for RTL8152 Hayes Wang
2014-02-18 13:49 ` [PATCH net-next 12/14] r8152: replace netif_rx with netif_receive_skb Hayes Wang
2014-02-18 23:28   ` Francois Romieu
2014-02-19  3:01     ` [PATCH net-next 12/14] r8152: replace netif_rx withnetif_receive_skb hayeswang
2014-02-19  7:46       ` Francois Romieu
2014-02-19 12:45         ` [PATCH net-next 12/14] r8152: replace netif_rxwithnetif_receive_skb hayeswang
2014-02-18 13:49 ` [PATCH net-next 13/14] r8152: set disable_hub_initiated_lpm Hayes Wang
2014-02-18 13:49 ` [PATCH net-next 14/14] r8152: support get_msglevel and set_msglevel Hayes Wang
2014-02-18 21:41 ` [PATCH net-next 00/14] r8152: improvement and new features David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.