netdev.vger.kernel.org archive mirror
 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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
       [not found]   ` <1392731351-25502-8-git-send-email-hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
       [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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ messages in thread

* Re: [PATCH net-next 07/14] r8152: combine PHY reset with set_speed
       [not found]   ` <1392731351-25502-8-git-send-email-hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
@ 2014-02-18 17:19     ` Florian Fainelli
  0 siblings, 0 replies; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ 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; 22+ 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] 22+ messages in thread

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

Thread overview: 22+ 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
     [not found]   ` <1392731351-25502-8-git-send-email-hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).