All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 00/12] r8152: new features
@ 2014-03-04 12:00 Hayes Wang
  2014-03-04 12:00 ` [PATCH net-next 01/12] r8152: deal with the empty line and space Hayes Wang
                   ` (19 more replies)
  0 siblings, 20 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:00 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Besides the adjustment of the code, support rx checksum,
TCP large send, and IPv6.

Hayes Wang (12):
  r8152: deal with the empty line and space
  r8152: replace tp->netdev with netdev
  r8152: remove rtl8152_get_stats
  r8152: replace spin_lock_irqsave and spin_unlock_irqrestore
  r8152: check tx agg list before spin lock
  r8152: up the priority of the transmission
  r8152: support rx checksum
  r8152: support TSO
  r8152: support IPv6
  r8152: reduce the numbers of the bulks
  r8152: add additional parameter for non x86 platform
  r8152: modify the tx timeout funcfion

 drivers/net/usb/r8152.c | 436 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 343 insertions(+), 93 deletions(-)

-- 
1.8.4.2


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

* [PATCH net-next 01/12] r8152: deal with the empty line and space
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
@ 2014-03-04 12:00 ` Hayes Wang
  2014-03-04 12:00 ` [PATCH net-next 02/12] r8152: replace tp->netdev with netdev Hayes Wang
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:00 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Add or remove some empty lines. Replace the spaces with the tabs.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0654bd3..c8bad62 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -593,6 +593,7 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
 			       value, index, tmp, size, 500);
 
 	kfree(tmp);
+
 	return ret;
 }
 
@@ -1514,6 +1515,7 @@ static void tx_bottom(struct r8152 *tp)
 				netif_warn(tp, tx_err, netdev,
 					   "failed tx_urb %d\n", res);
 				stats->tx_dropped += agg->skb_num;
+
 				spin_lock_irqsave(&tp->tx_lock, flags);
 				list_add_tail(&agg->list, &tp->tx_free);
 				spin_unlock_irqrestore(&tp->tx_lock, flags);
@@ -1833,7 +1835,6 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable)
 	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);
-
 }
 
 #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
@@ -2013,8 +2014,8 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
 
 static void r8152b_exit_oob(struct r8152 *tp)
 {
-	u32	ocp_data;
-	int	i;
+	u32 ocp_data;
+	int i;
 
 	ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
 	ocp_data &= ~RCR_ACPT_ALL;
@@ -2573,6 +2574,7 @@ static int rtl8152_open(struct net_device *netdev)
 	netif_carrier_off(netdev);
 	netif_start_queue(netdev);
 	set_bit(WORK_ENABLE, &tp->flags);
+
 	res = usb_submit_urb(tp->intr_urb, GFP_KERNEL);
 	if (res) {
 		if (res == -ENODEV)
@@ -3101,6 +3103,7 @@ static int rtl8152_probe(struct usb_interface *intf,
 
 	netdev->features |= NETIF_F_IP_CSUM;
 	netdev->hw_features = NETIF_F_IP_CSUM;
+
 	SET_ETHTOOL_OPS(netdev, &ops);
 
 	tp->mii.dev = netdev;
-- 
1.8.4.2


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

* [PATCH net-next 02/12] r8152: replace tp->netdev with netdev
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
  2014-03-04 12:00 ` [PATCH net-next 01/12] r8152: deal with the empty line and space Hayes Wang
@ 2014-03-04 12:00 ` Hayes Wang
  2014-03-04 12:00 ` [PATCH net-next 03/12] r8152: remove rtl8152_get_stats Hayes Wang
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:00 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Replace some tp->netdev with netdev.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c8bad62..151398b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1037,6 +1037,7 @@ static void read_bulk_callback(struct urb *urb)
 static void write_bulk_callback(struct urb *urb)
 {
 	struct net_device_stats *stats;
+	struct net_device *netdev;
 	unsigned long flags;
 	struct tx_agg *agg;
 	struct r8152 *tp;
@@ -1050,10 +1051,11 @@ static void write_bulk_callback(struct urb *urb)
 	if (!tp)
 		return;
 
-	stats = rtl8152_get_stats(tp->netdev);
+	netdev = tp->netdev;
+	stats = rtl8152_get_stats(netdev);
 	if (status) {
 		if (net_ratelimit())
-			netdev_warn(tp->netdev, "Tx status %d\n", status);
+			netdev_warn(netdev, "Tx status %d\n", status);
 		stats->tx_errors += agg->skb_num;
 	} else {
 		stats->tx_packets += agg->skb_num;
@@ -1066,7 +1068,7 @@ static void write_bulk_callback(struct urb *urb)
 
 	usb_autopm_put_interface_async(tp->intf);
 
-	if (!netif_carrier_ok(tp->netdev))
+	if (!netif_carrier_ok(netdev))
 		return;
 
 	if (!test_bit(WORK_ENABLE, &tp->flags))
-- 
1.8.4.2


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

* [PATCH net-next 03/12] r8152: remove rtl8152_get_stats
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
  2014-03-04 12:00 ` [PATCH net-next 01/12] r8152: deal with the empty line and space Hayes Wang
  2014-03-04 12:00 ` [PATCH net-next 02/12] r8152: replace tp->netdev with netdev Hayes Wang
@ 2014-03-04 12:00 ` Hayes Wang
  2014-03-04 12:00 ` [PATCH net-next 04/12] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore Hayes Wang
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:00 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

The rtl8152_get_stats() returns the point address of the struct
net_device_stats. This could be got from struct net_device directly.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 151398b..b8eee36 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -960,11 +960,6 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p)
 	return 0;
 }
 
-static struct net_device_stats *rtl8152_get_stats(struct net_device *dev)
-{
-	return &dev->stats;
-}
-
 static void read_bulk_callback(struct urb *urb)
 {
 	struct net_device *netdev;
@@ -1052,7 +1047,7 @@ static void write_bulk_callback(struct urb *urb)
 		return;
 
 	netdev = tp->netdev;
-	stats = rtl8152_get_stats(netdev);
+	stats = &netdev->stats;
 	if (status) {
 		if (net_ratelimit())
 			netdev_warn(netdev, "Tx status %d\n", status);
@@ -1442,7 +1437,7 @@ static void rx_bottom(struct r8152 *tp)
 
 		while (urb->actual_length > len_used) {
 			struct net_device *netdev = tp->netdev;
-			struct net_device_stats *stats;
+			struct net_device_stats *stats = &netdev->stats;
 			unsigned int pkt_len;
 			struct sk_buff *skb;
 
@@ -1454,8 +1449,6 @@ static void rx_bottom(struct r8152 *tp)
 			if (urb->actual_length < len_used)
 				break;
 
-			stats = rtl8152_get_stats(netdev);
-
 			pkt_len -= CRC_SIZE;
 			rx_data += sizeof(struct rx_desc);
 
@@ -1504,16 +1497,14 @@ static void tx_bottom(struct r8152 *tp)
 
 		res = r8152_tx_agg_fill(tp, agg);
 		if (res) {
-			struct net_device_stats *stats;
-			struct net_device *netdev;
-			unsigned long flags;
-
-			netdev = tp->netdev;
-			stats = rtl8152_get_stats(netdev);
+			struct net_device *netdev = tp->netdev;
 
 			if (res == -ENODEV) {
 				netif_device_detach(netdev);
 			} else {
+				struct net_device_stats *stats = &netdev->stats;
+				unsigned long flags;
+
 				netif_warn(tp, tx_err, netdev,
 					   "failed tx_urb %d\n", res);
 				stats->tx_dropped += agg->skb_num;
-- 
1.8.4.2


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

* [PATCH net-next 04/12] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (2 preceding siblings ...)
  2014-03-04 12:00 ` [PATCH net-next 03/12] r8152: remove rtl8152_get_stats Hayes Wang
@ 2014-03-04 12:00 ` Hayes Wang
  2014-03-04 12:00 ` [PATCH net-next 05/12] r8152: check tx agg list before spin lock Hayes Wang
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:00 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Use spin_lock and spin_unlock in interrupt context.

The ndo_start_xmit would not be called in interrupt context, so
replace the relative spin_lock_irqsave and spin_unlock_irqrestore
with spin_lock_bh and spin_unlock_bh.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b8eee36..8ecb41b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -963,7 +963,6 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p)
 static void read_bulk_callback(struct urb *urb)
 {
 	struct net_device *netdev;
-	unsigned long flags;
 	int status = urb->status;
 	struct rx_agg *agg;
 	struct r8152 *tp;
@@ -997,9 +996,9 @@ static void read_bulk_callback(struct urb *urb)
 		if (urb->actual_length < ETH_ZLEN)
 			break;
 
-		spin_lock_irqsave(&tp->rx_lock, flags);
+		spin_lock(&tp->rx_lock);
 		list_add_tail(&agg->list, &tp->rx_done);
-		spin_unlock_irqrestore(&tp->rx_lock, flags);
+		spin_unlock(&tp->rx_lock);
 		tasklet_schedule(&tp->tl);
 		return;
 	case -ESHUTDOWN:
@@ -1022,9 +1021,9 @@ static void read_bulk_callback(struct urb *urb)
 	if (result == -ENODEV) {
 		netif_device_detach(tp->netdev);
 	} else if (result) {
-		spin_lock_irqsave(&tp->rx_lock, flags);
+		spin_lock(&tp->rx_lock);
 		list_add_tail(&agg->list, &tp->rx_done);
-		spin_unlock_irqrestore(&tp->rx_lock, flags);
+		spin_unlock(&tp->rx_lock);
 		tasklet_schedule(&tp->tl);
 	}
 }
@@ -1033,7 +1032,6 @@ static void write_bulk_callback(struct urb *urb)
 {
 	struct net_device_stats *stats;
 	struct net_device *netdev;
-	unsigned long flags;
 	struct tx_agg *agg;
 	struct r8152 *tp;
 	int status = urb->status;
@@ -1057,9 +1055,9 @@ static void write_bulk_callback(struct urb *urb)
 		stats->tx_bytes += agg->skb_len;
 	}
 
-	spin_lock_irqsave(&tp->tx_lock, flags);
+	spin_lock(&tp->tx_lock);
 	list_add_tail(&agg->list, &tp->tx_free);
-	spin_unlock_irqrestore(&tp->tx_lock, flags);
+	spin_unlock(&tp->tx_lock);
 
 	usb_autopm_put_interface_async(tp->intf);
 
@@ -1330,14 +1328,13 @@ 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, ret;
 	u8 *tx_data;
 
 	__skb_queue_head_init(&skb_head);
-	spin_lock_irqsave(&tx_queue->lock, flags);
+	spin_lock_bh(&tx_queue->lock);
 	skb_queue_splice_init(tx_queue, &skb_head);
-	spin_unlock_irqrestore(&tx_queue->lock, flags);
+	spin_unlock_bh(&tx_queue->lock);
 
 	tx_data = agg->head;
 	agg->skb_num = agg->skb_len = 0;
@@ -1374,9 +1371,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 	}
 
 	if (!skb_queue_empty(&skb_head)) {
-		spin_lock_irqsave(&tx_queue->lock, flags);
+		spin_lock_bh(&tx_queue->lock);
 		skb_queue_splice(&skb_head, tx_queue);
-		spin_unlock_irqrestore(&tx_queue->lock, flags);
+		spin_unlock_bh(&tx_queue->lock);
 	}
 
 	netif_tx_lock_bh(tp->netdev);
@@ -1551,16 +1548,15 @@ 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;
 
 	if (skb_queue_empty(tx_queue))
 		return;
 
 	__skb_queue_head_init(&skb_head);
-	spin_lock_irqsave(&tx_queue->lock, flags);
+	spin_lock_bh(&tx_queue->lock);
 	skb_queue_splice_init(tx_queue, &skb_head);
-	spin_unlock_irqrestore(&tx_queue->lock, flags);
+	spin_unlock_bh(&tx_queue->lock);
 
 	while ((skb = __skb_dequeue(&skb_head))) {
 		dev_kfree_skb(skb);
-- 
1.8.4.2


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

* [PATCH net-next 05/12] r8152: check tx agg list before spin lock
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (3 preceding siblings ...)
  2014-03-04 12:00 ` [PATCH net-next 04/12] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore Hayes Wang
@ 2014-03-04 12:00 ` Hayes Wang
  2014-03-04 12:00 ` [PATCH net-next 06/12] r8152: up the priority of the transmission Hayes Wang
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:00 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Check tx agg list before spin lock to avoid doing spin lock every
times.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 8ecb41b..00b3192 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1266,6 +1266,9 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp)
 	struct tx_agg *agg = NULL;
 	unsigned long flags;
 
+	if (list_empty(&tp->tx_free))
+		return NULL;
+
 	spin_lock_irqsave(&tp->tx_lock, flags);
 	if (!list_empty(&tp->tx_free)) {
 		struct list_head *cursor;
-- 
1.8.4.2


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

* [PATCH net-next 06/12] r8152: up the priority of the transmission
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (4 preceding siblings ...)
  2014-03-04 12:00 ` [PATCH net-next 05/12] r8152: check tx agg list before spin lock Hayes Wang
@ 2014-03-04 12:00 ` Hayes Wang
  2014-03-04 12:00 ` [PATCH net-next 07/12] r8152: support rx checksum Hayes Wang
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:00 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

move the tx_bottom() from delayed_work to tasklet. It makes the rx
and tx balanced. If the device is in runtime suspend when getting
the tx packet, wakeup the device before trasmitting.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 00b3192..f1eaa18 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -447,6 +447,7 @@ enum rtl8152_flags {
 	RTL8152_LINK_CHG,
 	SELECTIVE_SUSPEND,
 	PHY_RESET,
+	SCHEDULE_TASKLET,
 };
 
 /* Define these values to match your device */
@@ -1071,7 +1072,7 @@ static void write_bulk_callback(struct urb *urb)
 		return;
 
 	if (!skb_queue_empty(&tp->tx_queue))
-		schedule_delayed_work(&tp->schedule, 0);
+		tasklet_schedule(&tp->tl);
 }
 
 static void intr_callback(struct urb *urb)
@@ -1335,9 +1336,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 	u8 *tx_data;
 
 	__skb_queue_head_init(&skb_head);
-	spin_lock_bh(&tx_queue->lock);
+	spin_lock(&tx_queue->lock);
 	skb_queue_splice_init(tx_queue, &skb_head);
-	spin_unlock_bh(&tx_queue->lock);
+	spin_unlock(&tx_queue->lock);
 
 	tx_data = agg->head;
 	agg->skb_num = agg->skb_len = 0;
@@ -1374,20 +1375,20 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 	}
 
 	if (!skb_queue_empty(&skb_head)) {
-		spin_lock_bh(&tx_queue->lock);
+		spin_lock(&tx_queue->lock);
 		skb_queue_splice(&skb_head, tx_queue);
-		spin_unlock_bh(&tx_queue->lock);
+		spin_unlock(&tx_queue->lock);
 	}
 
-	netif_tx_lock_bh(tp->netdev);
+	netif_tx_lock(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_bh(tp->netdev);
+	netif_tx_unlock(tp->netdev);
 
-	ret = usb_autopm_get_interface(tp->intf);
+	ret = usb_autopm_get_interface_async(tp->intf);
 	if (ret < 0)
 		goto out_tx_fill;
 
@@ -1395,9 +1396,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 			  agg->head, (int)(tx_data - (u8 *)agg->head),
 			  (usb_complete_t)write_bulk_callback, agg);
 
-	ret = usb_submit_urb(agg->urb, GFP_KERNEL);
+	ret = usb_submit_urb(agg->urb, GFP_ATOMIC);
 	if (ret < 0)
-		usb_autopm_put_interface(tp->intf);
+		usb_autopm_put_interface_async(tp->intf);
 
 out_tx_fill:
 	return ret;
@@ -1535,6 +1536,7 @@ static void bottom_half(unsigned long data)
 		return;
 
 	rx_bottom(tp);
+	tx_bottom(tp);
 }
 
 static
@@ -1630,7 +1632,7 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev)
 }
 
 static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
-					    struct net_device *netdev)
+					struct net_device *netdev)
 {
 	struct r8152 *tp = netdev_priv(netdev);
 
@@ -1638,13 +1640,17 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
 
 	skb_queue_tail(&tp->tx_queue, skb);
 
-	if (list_empty(&tp->tx_free) &&
-	    skb_queue_len(&tp->tx_queue) > tp->tx_qlen)
+	if (!list_empty(&tp->tx_free)) {
+		if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+			set_bit(SCHEDULE_TASKLET, &tp->flags);
+			schedule_delayed_work(&tp->schedule, 0);
+		} else {
+			usb_mark_last_busy(tp->udev);
+			tasklet_schedule(&tp->tl);
+		}
+	} else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen)
 		netif_stop_queue(netdev);
 
-	if (!list_empty(&tp->tx_free))
-		schedule_delayed_work(&tp->schedule, 0);
-
 	return NETDEV_TX_OK;
 }
 
@@ -2523,8 +2529,11 @@ 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(SCHEDULE_TASKLET, &tp->flags) &&
+	    (tp->speed & LINK_STATUS)) {
+		clear_bit(SCHEDULE_TASKLET, &tp->flags);
+		tasklet_schedule(&tp->tl);
+	}
 
 	if (test_bit(PHY_RESET, &tp->flags))
 		rtl_phy_reset(tp);
-- 
1.8.4.2


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

* [PATCH net-next 07/12] r8152: support rx checksum
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (5 preceding siblings ...)
  2014-03-04 12:00 ` [PATCH net-next 06/12] r8152: up the priority of the transmission Hayes Wang
@ 2014-03-04 12:00 ` Hayes Wang
  2014-03-04 21:32   ` David Miller
  2014-03-04 12:01 ` [PATCH net-next 08/12] r8152: support TSO Hayes Wang
                   ` (12 subsequent siblings)
  19 siblings, 1 reply; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:00 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support hw rx checksum for TCP and UDP packets.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index f1eaa18..5fdf0af 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -464,11 +464,23 @@ enum rtl8152_flags {
 #define REALTEK_USB_DEVICE(vend, prod)	\
 	USB_DEVICE_INTERFACE_CLASS(vend, prod, USB_CLASS_VENDOR_SPEC)
 
+#define RTL_CHECKSUM_FAIL		-1
+
 struct rx_desc {
 	__le32 opts1;
+#define RD_CRC				(1 << 15)
 #define RX_LEN_MASK			0x7fff
+
 	__le32 opts2;
+#define RD_UDP_CS			(1 << 23)
+#define RD_TCP_CS			(1 << 22)
+#define RD_IPV4_CS			(1 << 19)
+
 	__le32 opts3;
+#define IPF				(1 << 23) /* IP checksum fail */
+#define UDPF				(1 << 22) /* UDP checksum fail */
+#define TCPF				(1 << 21) /* TCP checksum fail */
+
 	__le32 opts4;
 	__le32 opts5;
 	__le32 opts6;
@@ -1404,6 +1416,31 @@ out_tx_fill:
 	return ret;
 }
 
+static int r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc)
+{
+	int checksum = CHECKSUM_NONE;
+	u32 opts2, opts3;
+
+	if (tp->version == RTL_VER_01)
+		goto return_result;
+
+	opts2 = le32_to_cpu(rx_desc->opts2);
+	opts3 = le32_to_cpu(rx_desc->opts3);
+
+	if (opts2 & RD_IPV4_CS) {
+		if (opts3 & IPF)
+			checksum = RTL_CHECKSUM_FAIL;
+		else if (((opts2 & RD_UDP_CS) && (opts3 & UDPF)) ||
+			 ((opts2 & RD_TCP_CS) && (opts3 & TCPF)))
+			checksum = RTL_CHECKSUM_FAIL;
+		else
+			checksum = CHECKSUM_UNNECESSARY;
+	}
+
+return_result:
+	return checksum;
+}
+
 static void rx_bottom(struct r8152 *tp)
 {
 	unsigned long flags;
@@ -1441,6 +1478,7 @@ static void rx_bottom(struct r8152 *tp)
 			struct net_device_stats *stats = &netdev->stats;
 			unsigned int pkt_len;
 			struct sk_buff *skb;
+			int checksum;
 
 			pkt_len = le32_to_cpu(rx_desc->opts1) & RX_LEN_MASK;
 			if (pkt_len < ETH_ZLEN)
@@ -1453,11 +1491,19 @@ static void rx_bottom(struct r8152 *tp)
 			pkt_len -= CRC_SIZE;
 			rx_data += sizeof(struct rx_desc);
 
+			checksum = r8152_rx_csum(tp, rx_desc);
+			if (checksum == RTL_CHECKSUM_FAIL) {
+				stats->rx_errors++;
+				goto find_next_rx;
+			}
+
 			skb = netdev_alloc_skb_ip_align(netdev, pkt_len);
 			if (!skb) {
 				stats->rx_dropped++;
-				break;
+				goto find_next_rx;
 			}
+
+			skb->ip_summed = checksum;
 			memcpy(skb->data, rx_data, pkt_len);
 			skb_put(skb, pkt_len);
 			skb->protocol = eth_type_trans(skb, netdev);
@@ -1465,6 +1511,7 @@ static void rx_bottom(struct r8152 *tp)
 			stats->rx_packets++;
 			stats->rx_bytes += pkt_len;
 
+find_next_rx:
 			rx_data = rx_agg_align(rx_data + pkt_len + CRC_SIZE);
 			rx_desc = (struct rx_desc *)rx_data;
 			len_used = (int)(rx_data - (u8 *)agg->head);
@@ -3102,8 +3149,8 @@ static int rtl8152_probe(struct usb_interface *intf,
 	netdev->netdev_ops = &rtl8152_netdev_ops;
 	netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
 
-	netdev->features |= NETIF_F_IP_CSUM;
-	netdev->hw_features = NETIF_F_IP_CSUM;
+	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
 
 	SET_ETHTOOL_OPS(netdev, &ops);
 
-- 
1.8.4.2


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

* [PATCH net-next 08/12] r8152: support TSO
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (6 preceding siblings ...)
  2014-03-04 12:00 ` [PATCH net-next 07/12] r8152: support rx checksum Hayes Wang
@ 2014-03-04 12:01 ` Hayes Wang
  2014-03-04 12:11   ` David Laight
                     ` (2 more replies)
  2014-03-04 12:01 ` [PATCH net-next 09/12] r8152: support IPv6 Hayes Wang
                   ` (11 subsequent siblings)
  19 siblings, 3 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:01 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support scatter gather and TSO.

Adjust the tx checksum function and set the max gso size to fix the
size of the tx aggregation buffer.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 5fdf0af..774a19a 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.05.0 (2014/02/18)"
+#define DRIVER_VERSION "v1.06.0 (2014/03/03)"
 #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
 #define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
 #define MODULENAME "r8152"
@@ -490,13 +490,18 @@ struct tx_desc {
 	__le32 opts1;
 #define TX_FS			(1 << 31) /* First segment of a packet */
 #define TX_LS			(1 << 30) /* Final segment of a packet */
-#define TX_LEN_MASK		0x3ffff
+#define GTSENDV4		(1 << 28)
+#define GTTCPHO_SHIFT		18
+#define TX_LEN_MAX		0x3ffffU
 
 	__le32 opts2;
 #define UDP_CS			(1 << 31) /* Calculate UDP/IP checksum */
 #define TCP_CS			(1 << 30) /* Calculate TCP/IP checksum */
 #define IPV4_CS			(1 << 29) /* Calculate IPv4 checksum */
 #define IPV6_CS			(1 << 28) /* Calculate IPv6 checksum */
+#define MSS_SHIFT		17
+#define MSS_MAX			0x7ffU
+#define TCPHO_SHIFT		17
 };
 
 struct r8152;
@@ -563,12 +568,21 @@ enum rtl_version {
 	RTL_VER_MAX
 };
 
+enum tx_csum_stat {
+	TX_CSUM_SUCCESS = 0,
+	TX_CSUM_TSO,
+	TX_CSUM_NONE
+};
+
 /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
  * The RTL chips use a 64 element hash table based on the Ethernet CRC.
  */
 static const int multicast_filter_limit = 32;
 static unsigned int rx_buf_sz = 16384;
 
+#define RTL_LIMITED_TSO_SIZE	(rx_buf_sz - sizeof(struct tx_desc) - \
+				 VLAN_ETH_HLEN - VLAN_HLEN)
+
 static
 int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
 {
@@ -1295,24 +1309,46 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp)
 	return agg;
 }
 
-static void
-r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
+static inline __be16 get_protocol(struct sk_buff *skb)
 {
-	memset(desc, 0, sizeof(*desc));
+	__be16 protocol;
 
-	desc->opts1 = cpu_to_le32((skb->len & TX_LEN_MASK) | TX_FS | TX_LS);
+	if (skb->protocol == htons(ETH_P_8021Q))
+		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+	else
+		protocol = skb->protocol;
 
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		__be16 protocol;
-		u8 ip_protocol;
-		u32 opts2 = 0;
+	return protocol;
+}
 
-		if (skb->protocol == htons(ETH_P_8021Q))
-			protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
-		else
-			protocol = skb->protocol;
+static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
+			 struct sk_buff *skb, u32 len, u32 transport_offset)
+{
+	u32 mss = skb_shinfo(skb)->gso_size;
+	u32 opts1, opts2 = 0;
+	int ret = TX_CSUM_SUCCESS;
+
+	WARN_ON_ONCE(len > TX_LEN_MAX);
+
+	opts1 = len | TX_FS | TX_LS;
+
+	if (mss) {
+		switch (get_protocol(skb)) {
+		case htons(ETH_P_IP):
+			opts1 |= GTSENDV4;
+			break;
 
-		switch (protocol) {
+		default:
+			WARN_ON_ONCE(1);
+			break;
+		}
+
+		opts1 |= transport_offset << GTTCPHO_SHIFT;
+		opts2 |= min(mss, MSS_MAX) << MSS_SHIFT;
+	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		u8 ip_protocol;
+
+		switch (get_protocol(skb)) {
 		case htons(ETH_P_IP):
 			opts2 |= IPV4_CS;
 			ip_protocol = ip_hdr(skb)->protocol;
@@ -1328,17 +1364,44 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
 			break;
 		}
 
-		if (ip_protocol == IPPROTO_TCP) {
+		if (ip_protocol == IPPROTO_TCP)
 			opts2 |= TCP_CS;
-			opts2 |= (skb_transport_offset(skb) & 0x7fff) << 17;
-		} else if (ip_protocol == IPPROTO_UDP) {
+		else if (ip_protocol == IPPROTO_UDP)
 			opts2 |= UDP_CS;
-		} else {
+		else
 			WARN_ON_ONCE(1);
-		}
 
-		desc->opts2 = cpu_to_le32(opts2);
+		opts2 |= transport_offset << TCPHO_SHIFT;
+	}
+
+	desc->opts2 = cpu_to_le32(opts2);
+	desc->opts1 = cpu_to_le32(opts1);
+
+	return ret;
+}
+
+static u32 r8152_xmit_frags(struct r8152 *tp, struct sk_buff *skb, u8 *data)
+{
+	struct skb_shared_info *info = skb_shinfo(skb);
+	unsigned int cur_frag;
+	u32 total = skb_headlen(skb);
+
+	memcpy(data, skb->data, total);
+	data += total;
+
+	for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) {
+		const skb_frag_t *frag = info->frags + cur_frag;
+		void *addr;
+		u32 len;
+
+		len = skb_frag_size(frag);
+		addr = skb_frag_address(frag);
+		memcpy(data, addr, len);
+		data += len;
+		total += len;
 	}
+
+	return total;
 }
 
 static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
@@ -1360,29 +1423,36 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		struct tx_desc *tx_desc;
 		struct sk_buff *skb;
 		unsigned int len;
+		u32 offset;
 
 		skb = __skb_dequeue(&skb_head);
 		if (!skb)
 			break;
 
-		remain -= sizeof(*tx_desc);
-		len = skb->len;
-		if (remain < len) {
+		len = skb->len + sizeof(*tx_desc);
+
+		if (len > remain) {
 			__skb_queue_head(&skb_head, skb);
 			break;
 		}
 
 		tx_data = tx_agg_align(tx_data);
 		tx_desc = (struct tx_desc *)tx_data;
+
+		offset = (u32)skb_transport_offset(skb);
+
+		r8152_tx_csum(tp, tx_desc, skb, skb->len, offset);
+
 		tx_data += sizeof(*tx_desc);
 
-		r8152_tx_csum(tp, tx_desc, skb);
-		memcpy(tx_data, skb->data, len);
-		agg->skb_num++;
+		len = r8152_xmit_frags(tp, skb, tx_data);
+
+		tx_data += len;
 		agg->skb_len += len;
+		agg->skb_num++;
+
 		dev_kfree_skb_any(skb);
 
-		tx_data += len;
 		remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
 	}
 
@@ -3149,10 +3219,13 @@ static int rtl8152_probe(struct usb_interface *intf,
 	netdev->netdev_ops = &rtl8152_netdev_ops;
 	netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
 
-	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
-	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
+			    NETIF_F_TSO;
+	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
+			      NETIF_F_TSO;
 
 	SET_ETHTOOL_OPS(netdev, &ops);
+	netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
 
 	tp->mii.dev = netdev;
 	tp->mii.mdio_read = read_mii_word;
-- 
1.8.4.2


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

* [PATCH net-next 09/12] r8152: support IPv6
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (7 preceding siblings ...)
  2014-03-04 12:01 ` [PATCH net-next 08/12] r8152: support TSO Hayes Wang
@ 2014-03-04 12:01 ` Hayes Wang
  2014-03-04 16:58   ` Eric Dumazet
  2014-03-04 12:01 ` [PATCH net-next 10/12] r8152: reduce the numbers of the bulks Hayes Wang
                   ` (10 subsequent siblings)
  19 siblings, 1 reply; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:01 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support hw IPv6 checksum for TCP and UDP packets.

Note that the hw has the limitation of the range of the transport
offset. Besides, the TCP Pseudo Header of the IPv6 TSO of the hw
bases on the Microsoft document which excludes the packet length.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 774a19a..72cbab1 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -21,6 +21,7 @@
 #include <linux/list.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
+#include <net/ip6_checksum.h>
 
 /* Version Information */
 #define DRIVER_VERSION "v1.06.0 (2014/03/03)"
@@ -474,6 +475,7 @@ struct rx_desc {
 	__le32 opts2;
 #define RD_UDP_CS			(1 << 23)
 #define RD_TCP_CS			(1 << 22)
+#define RD_IPV6_CS			(1 << 20)
 #define RD_IPV4_CS			(1 << 19)
 
 	__le32 opts3;
@@ -491,7 +493,9 @@ struct tx_desc {
 #define TX_FS			(1 << 31) /* First segment of a packet */
 #define TX_LS			(1 << 30) /* Final segment of a packet */
 #define GTSENDV4		(1 << 28)
+#define GTSENDV6		(1 << 27)
 #define GTTCPHO_SHIFT		18
+#define GTTCPHO_MAX		0x7fU
 #define TX_LEN_MAX		0x3ffffU
 
 	__le32 opts2;
@@ -502,6 +506,7 @@ struct tx_desc {
 #define MSS_SHIFT		17
 #define MSS_MAX			0x7ffU
 #define TCPHO_SHIFT		17
+#define TCPHO_MAX		0x7ffU
 };
 
 struct r8152;
@@ -1321,6 +1326,65 @@ static inline __be16 get_protocol(struct sk_buff *skb)
 	return protocol;
 }
 
+/*
+ * r8152_csum_workaround()
+ * The hw limites the value the transport offset. When the offset is out of the
+ * range, calculate the checksum by sw.
+ */
+static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb,
+				  struct sk_buff_head *list)
+{
+	if (skb_shinfo(skb)->gso_size) {
+		netdev_features_t features = tp->netdev->features;
+		struct sk_buff *segs, *nskb;
+
+		features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
+		segs = skb_gso_segment(skb, features);
+		if (IS_ERR(segs) || !segs)
+			goto drop;
+
+		do {
+			nskb = segs;
+			segs = segs->next;
+			nskb->next = NULL;
+			__skb_queue_head(list, nskb);
+		} while (segs);
+
+		dev_kfree_skb(skb);
+	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		if (skb_checksum_help(skb) < 0)
+			goto drop;
+
+		__skb_queue_head(list, skb);
+	} else {
+		struct net_device_stats *stats;
+
+drop:
+		stats = &tp->netdev->stats;
+		stats->tx_dropped++;
+		dev_kfree_skb(skb);
+	}
+}
+
+/*
+ * msdn_giant_send_check()
+ * According to the document of microsoft, the TCP Pseudo Header excludes the
+ * packet length for IPv6 TCP large packets.
+ */
+static int msdn_giant_send_check(struct sk_buff *skb)
+{
+	const struct ipv6hdr *ipv6h;
+	struct tcphdr *th;
+
+	ipv6h = ipv6_hdr(skb);
+	th = tcp_hdr(skb);
+
+	th->check = 0;
+	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
+
+	return 0;
+}
+
 static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 			 struct sk_buff *skb, u32 len, u32 transport_offset)
 {
@@ -1333,11 +1397,24 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 	opts1 = len | TX_FS | TX_LS;
 
 	if (mss) {
+		if (transport_offset > GTTCPHO_MAX) {
+			netif_warn(tp, tx_err, tp->netdev,
+				   "Invalid transport offset 0x%x for TSO\n",
+				   transport_offset);
+			ret = TX_CSUM_TSO;
+			goto unavailable;
+		}
+
 		switch (get_protocol(skb)) {
 		case htons(ETH_P_IP):
 			opts1 |= GTSENDV4;
 			break;
 
+		case htons(ETH_P_IPV6):
+			opts1 |= GTSENDV6;
+			msdn_giant_send_check(skb);
+			break;
+
 		default:
 			WARN_ON_ONCE(1);
 			break;
@@ -1348,6 +1425,14 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		u8 ip_protocol;
 
+		if (transport_offset > TCPHO_MAX) {
+			netif_warn(tp, tx_err, tp->netdev,
+				   "Invalid transport offset 0x%x\n",
+				   transport_offset);
+			ret = TX_CSUM_NONE;
+			goto unavailable;
+		}
+
 		switch (get_protocol(skb)) {
 		case htons(ETH_P_IP):
 			opts2 |= IPV4_CS;
@@ -1377,6 +1462,7 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 	desc->opts2 = cpu_to_le32(opts2);
 	desc->opts1 = cpu_to_le32(opts1);
 
+unavailable:
 	return ret;
 }
 
@@ -1441,7 +1527,10 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 
 		offset = (u32)skb_transport_offset(skb);
 
-		r8152_tx_csum(tp, tx_desc, skb, skb->len, offset);
+		if (r8152_tx_csum(tp, tx_desc, skb, skb->len, offset)) {
+			r8152_csum_workaround(tp, skb, &skb_head);
+			continue;
+		}
 
 		tx_data += sizeof(*tx_desc);
 
@@ -1505,6 +1594,18 @@ static int r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc)
 			checksum = RTL_CHECKSUM_FAIL;
 		else
 			checksum = CHECKSUM_UNNECESSARY;
+	} else if (RD_IPV6_CS) {
+		if (opts2 & RD_UDP_CS) {
+			if (opts3 & UDPF)
+				checksum = RTL_CHECKSUM_FAIL;
+			else
+				checksum = CHECKSUM_UNNECESSARY;
+		} else if (opts2 & RD_TCP_CS) {
+			if (opts3 & TCPF)
+				checksum = RTL_CHECKSUM_FAIL;
+			else
+				checksum = CHECKSUM_UNNECESSARY;
+		}
 	}
 
 return_result:
@@ -3220,9 +3321,9 @@ static int rtl8152_probe(struct usb_interface *intf,
 	netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
 
 	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
-			    NETIF_F_TSO;
+			    NETIF_F_TSO | NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
 	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
-			      NETIF_F_TSO;
+			      NETIF_F_TSO | NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
 
 	SET_ETHTOOL_OPS(netdev, &ops);
 	netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
-- 
1.8.4.2


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

* [PATCH net-next 10/12] r8152: reduce the numbers of the bulks
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (8 preceding siblings ...)
  2014-03-04 12:01 ` [PATCH net-next 09/12] r8152: support IPv6 Hayes Wang
@ 2014-03-04 12:01 ` Hayes Wang
  2014-03-04 12:01 ` [PATCH net-next 11/12] r8152: add additional parameter for non x86 platform Hayes Wang
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:01 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Reduce the numbers of tx and rx aggregation buffers.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 72cbab1..b60b3bc 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -416,8 +416,8 @@ enum rtl_register_content {
 	FULL_DUP	= 0x01,
 };
 
-#define RTL8152_MAX_TX		10
-#define RTL8152_MAX_RX		10
+#define RTL8152_MAX_TX		4
+#define RTL8152_MAX_RX		4
 #define INTBUFSIZE		2
 #define CRC_SIZE		4
 #define TX_ALIGN		4
-- 
1.8.4.2


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

* [PATCH net-next 11/12] r8152: add additional parameter for non x86 platform
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (9 preceding siblings ...)
  2014-03-04 12:01 ` [PATCH net-next 10/12] r8152: reduce the numbers of the bulks Hayes Wang
@ 2014-03-04 12:01 ` Hayes Wang
  2014-03-04 12:01 ` [PATCH net-next 12/12] r8152: modify the tx timeout funcfion Hayes Wang
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:01 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Add additional parameter for non x86 platform for better throughput.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b60b3bc..e04fcbd 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -313,7 +313,11 @@
 #define PCUT_STATUS		0x0001
 
 /* USB_RX_EARLY_AGG */
-#define EARLY_AGG_SUPPER	0x0e832981
+#if defined(__i386__) || defined(__x86_64__)
+	#define EARLY_AGG_SUPPER	0x0e832981
+#else
+	#define EARLY_AGG_SUPPER	0x0e835000
+#endif
 #define EARLY_AGG_HIGH		0x0e837a12
 #define EARLY_AGG_SLOW		0x0e83ffff
 
-- 
1.8.4.2


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

* [PATCH net-next 12/12] r8152: modify the tx timeout funcfion
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (10 preceding siblings ...)
  2014-03-04 12:01 ` [PATCH net-next 11/12] r8152: add additional parameter for non x86 platform Hayes Wang
@ 2014-03-04 12:01 ` Hayes Wang
  2014-03-25 20:12     ` Grant Grundler
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                   ` (7 subsequent siblings)
  19 siblings, 1 reply; 91+ messages in thread
From: Hayes Wang @ 2014-03-04 12:01 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Reset and reinitialize the device when the tx timeout occurs.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index e04fcbd..23e03a6 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1791,16 +1791,6 @@ static void rtl_drop_queued_tx(struct r8152 *tp)
 	}
 }
 
-static void rtl8152_tx_timeout(struct net_device *netdev)
-{
-	struct r8152 *tp = netdev_priv(netdev);
-	int i;
-
-	netif_warn(tp, tx_err, netdev, "Tx timeout\n");
-	for (i = 0; i < RTL8152_MAX_TX; i++)
-		usb_unlink_urb(tp->tx_info[i].urb);
-}
-
 static void rtl8152_set_rx_mode(struct net_device *netdev)
 {
 	struct r8152 *tp = netdev_priv(netdev);
@@ -3177,6 +3167,37 @@ out:
 	return res;
 }
 
+static void rtl8152_tx_timeout(struct net_device *netdev)
+{
+	struct r8152 *tp = netdev_priv(netdev);
+
+	netif_warn(tp, tx_err, netdev, "Tx timeout\n");
+
+	if (usb_autopm_get_interface(tp->intf) < 0)
+		return;
+
+	netif_stop_queue(netdev);
+	clear_bit(WORK_ENABLE, &tp->flags);
+	usb_kill_urb(tp->intr_urb);
+	cancel_delayed_work_sync(&tp->schedule);
+	tp->rtl_ops.down(tp);
+
+	usb_reset_device(tp->udev);
+
+	tp->rtl_ops.init(tp);
+	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(netdev);
+	netif_start_queue(netdev);
+	set_bit(WORK_ENABLE, &tp->flags);
+	usb_submit_urb(tp->intr_urb, GFP_KERNEL);
+
+	usb_autopm_put_interface(tp->intf);
+}
+
 static const struct net_device_ops rtl8152_netdev_ops = {
 	.ndo_open		= rtl8152_open,
 	.ndo_stop		= rtl8152_close,
-- 
1.8.4.2


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

* RE: [PATCH net-next 08/12] r8152: support TSO
  2014-03-04 12:01 ` [PATCH net-next 08/12] r8152: support TSO Hayes Wang
@ 2014-03-04 12:11   ` David Laight
  2014-03-04 13:11     ` hayeswang
  2014-03-04 16:11   ` Eric Dumazet
  2014-03-04 16:52   ` Eric Dumazet
  2 siblings, 1 reply; 91+ messages in thread
From: David Laight @ 2014-03-04 12:11 UTC (permalink / raw)
  To: 'Hayes Wang', netdev; +Cc: nic_swsd, linux-kernel, linux-usb

From: Hayes Wang
> Support scatter gather and TSO.
> 
> Adjust the tx checksum function and set the max gso size to fix the
> size of the tx aggregation buffer.

There is little point supporting TSO unless the usb host controller
supports arbitrary aligned scatter-gather.
All you do is require that a large skb be allocated (that may well
fail), and add it another data copy.

The xhci controller is almost capable of arbitrary scatter-gather,
but it is currently disabled because the data must be aligned at
the end of the transfer ring (the hardware designers have made it
almost impossible to write efficient software).

Note that the various xhci controllers behave subtly differently.

	David




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

* RE: [PATCH net-next 08/12] r8152: support TSO
  2014-03-04 12:11   ` David Laight
@ 2014-03-04 13:11     ` hayeswang
  2014-03-04 14:35         ` David Laight
  0 siblings, 1 reply; 91+ messages in thread
From: hayeswang @ 2014-03-04 13:11 UTC (permalink / raw)
  To: 'David Laight', netdev; +Cc: nic_swsd, linux-kernel, linux-usb

 David Laight [mailto:David.Laight@ACULAB.COM] 
> Sent: Tuesday, March 04, 2014 8:12 PM
> To: 'Hayes Wang'; netdev@vger.kernel.org
> Cc: nic_swsd@realtek.com; linux-kernel@vger.kernel.org; 
> linux-usb@vger.kernel.org
> Subject: RE: [PATCH net-next 08/12] r8152: support TSO
> 
> From: Hayes Wang
> > Support scatter gather and TSO.
> > 
> > Adjust the tx checksum function and set the max gso size to fix the
> > size of the tx aggregation buffer.
> 
> There is little point supporting TSO unless the usb host controller
> supports arbitrary aligned scatter-gather.
> All you do is require that a large skb be allocated (that may well
> fail), and add it another data copy.

I think I have done it. For also working for EHCI usb host controller,
I allocate 16 KB continuous buffer and copy the fragmented packets to
it and bulk out the buffer.
 
Best Regards,
Hayes


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

* RE: [PATCH net-next 08/12] r8152: support TSO
@ 2014-03-04 14:35         ` David Laight
  0 siblings, 0 replies; 91+ messages in thread
From: David Laight @ 2014-03-04 14:35 UTC (permalink / raw)
  To: 'hayeswang', netdev; +Cc: nic_swsd, linux-kernel, linux-usb

From: hayeswang 
>  David Laight [mailto:David.Laight@ACULAB.COM]
> > Sent: Tuesday, March 04, 2014 8:12 PM
> > To: 'Hayes Wang'; netdev@vger.kernel.org
> > Cc: nic_swsd@realtek.com; linux-kernel@vger.kernel.org;
> > linux-usb@vger.kernel.org
> > Subject: RE: [PATCH net-next 08/12] r8152: support TSO
> >
> > From: Hayes Wang
> > > Support scatter gather and TSO.
> > >
> > > Adjust the tx checksum function and set the max gso size to fix the
> > > size of the tx aggregation buffer.
> >
> > There is little point supporting TSO unless the usb host controller
> > supports arbitrary aligned scatter-gather.
> > All you do is require that a large skb be allocated (that may well
> > fail), and add it another data copy.
> 
> I think I have done it. For also working for EHCI usb host controller,
> I allocate 16 KB continuous buffer and copy the fragmented packets to
> it and bulk out the buffer.

Does that mean you are splitting the 64k 'ethernet packet' from TCP
is software? I've looked at the ax88179 where the hardware can do it.

Is there really a gain doing segmentation here if you have to do the
extra data copy?

It might be worth packing multiple short packets into a single USB bulk
data packet, but that might require a CBU (crystal ball unit).

I did measure a maximum transmit ethernet frame rate of (IIRC) 250000
frames/sec for the ax88179 - probably limited by the USB3 frame rate.
Exceeding that would probably require putting multiple tx packets into
a single URB. OTOH that limit probably doesn't matter

What might be more useful is to set the rx side up to receive into
page-aligned 2k (or 4k) buffers and then separate out the ethernet
frames into the required skb - probably as page list fragments
(I'm not entirely sure how such skb can be created).

I don't know what the r8152 does, but the usbnet code encourages it to
allocate long skb, pass them to the usb stack to fill, and then clone
them if they contain multiple frames.

This isn't really good use of memory or cpu cycles.
The ax88179 driver also lies badly about the skb's truesize.

	David




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

* RE: [PATCH net-next 08/12] r8152: support TSO
@ 2014-03-04 14:35         ` David Laight
  0 siblings, 0 replies; 91+ messages in thread
From: David Laight @ 2014-03-04 14:35 UTC (permalink / raw)
  To: 'hayeswang', netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA

From: hayeswang 
>  David Laight [mailto:David.Laight-ZS65k/vG3HxXrIkS9f7CXA@public.gmane.org]
> > Sent: Tuesday, March 04, 2014 8:12 PM
> > To: 'Hayes Wang'; netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Cc: nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org; linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org;
> > linux-usb-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> > Subject: RE: [PATCH net-next 08/12] r8152: support TSO
> >
> > From: Hayes Wang
> > > Support scatter gather and TSO.
> > >
> > > Adjust the tx checksum function and set the max gso size to fix the
> > > size of the tx aggregation buffer.
> >
> > There is little point supporting TSO unless the usb host controller
> > supports arbitrary aligned scatter-gather.
> > All you do is require that a large skb be allocated (that may well
> > fail), and add it another data copy.
> 
> I think I have done it. For also working for EHCI usb host controller,
> I allocate 16 KB continuous buffer and copy the fragmented packets to
> it and bulk out the buffer.

Does that mean you are splitting the 64k 'ethernet packet' from TCP
is software? I've looked at the ax88179 where the hardware can do it.

Is there really a gain doing segmentation here if you have to do the
extra data copy?

It might be worth packing multiple short packets into a single USB bulk
data packet, but that might require a CBU (crystal ball unit).

I did measure a maximum transmit ethernet frame rate of (IIRC) 250000
frames/sec for the ax88179 - probably limited by the USB3 frame rate.
Exceeding that would probably require putting multiple tx packets into
a single URB. OTOH that limit probably doesn't matter

What might be more useful is to set the rx side up to receive into
page-aligned 2k (or 4k) buffers and then separate out the ethernet
frames into the required skb - probably as page list fragments
(I'm not entirely sure how such skb can be created).

I don't know what the r8152 does, but the usbnet code encourages it to
allocate long skb, pass them to the usb stack to fill, and then clone
them if they contain multiple frames.

This isn't really good use of memory or cpu cycles.
The ax88179 driver also lies badly about the skb's truesize.

	David



--
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] 91+ messages in thread

* RE: [PATCH net-next 08/12] r8152: support TSO
  2014-03-04 14:35         ` David Laight
  (?)
@ 2014-03-04 15:02         ` Eric Dumazet
  2014-03-04 15:14             ` David Laight
  -1 siblings, 1 reply; 91+ messages in thread
From: Eric Dumazet @ 2014-03-04 15:02 UTC (permalink / raw)
  To: David Laight
  Cc: 'hayeswang', netdev, nic_swsd, linux-kernel, linux-usb

On Tue, 2014-03-04 at 14:35 +0000, David Laight wrote:

> Does that mean you are splitting the 64k 'ethernet packet' from TCP
> is software? I've looked at the ax88179 where the hardware can do it.
> 
> Is there really a gain doing segmentation here if you have to do the
> extra data copy?

There is no 'extra' copy.

There is _already_ a copy, so what's the deal of doing this copy in a SG
enabled way ?




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

* RE: [PATCH net-next 08/12] r8152: support TSO
  2014-03-04 15:02         ` Eric Dumazet
@ 2014-03-04 15:14             ` David Laight
  0 siblings, 0 replies; 91+ messages in thread
From: David Laight @ 2014-03-04 15:14 UTC (permalink / raw)
  To: 'Eric Dumazet'
  Cc: 'hayeswang', netdev, nic_swsd, linux-kernel, linux-usb

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 798 bytes --]

From: Eric Dumazet 
> On Tue, 2014-03-04 at 14:35 +0000, David Laight wrote:
> 
> > Does that mean you are splitting the 64k 'ethernet packet' from TCP
> > is software? I've looked at the ax88179 where the hardware can do it.
> >
> > Is there really a gain doing segmentation here if you have to do the
> > extra data copy?
> 
> There is no 'extra' copy.
> 
> There is _already_ a copy, so what's the deal of doing this copy in a SG
> enabled way ?

Ok.

But there is one more copy than for a normal ethernet chipset which
can use multiple ring entries to send the MAC+IP+TCP headers from a
different buffer to the TCP userdata.

	David

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

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

* RE: [PATCH net-next 08/12] r8152: support TSO
@ 2014-03-04 15:14             ` David Laight
  0 siblings, 0 replies; 91+ messages in thread
From: David Laight @ 2014-03-04 15:14 UTC (permalink / raw)
  To: 'Eric Dumazet'
  Cc: 'hayeswang', netdev, nic_swsd, linux-kernel, linux-usb

From: Eric Dumazet 
> On Tue, 2014-03-04 at 14:35 +0000, David Laight wrote:
> 
> > Does that mean you are splitting the 64k 'ethernet packet' from TCP
> > is software? I've looked at the ax88179 where the hardware can do it.
> >
> > Is there really a gain doing segmentation here if you have to do the
> > extra data copy?
> 
> There is no 'extra' copy.
> 
> There is _already_ a copy, so what's the deal of doing this copy in a SG
> enabled way ?

Ok.

But there is one more copy than for a normal ethernet chipset which
can use multiple ring entries to send the MAC+IP+TCP headers from a
different buffer to the TCP userdata.

	David


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

* Re: [PATCH net-next 08/12] r8152: support TSO
  2014-03-04 12:01 ` [PATCH net-next 08/12] r8152: support TSO Hayes Wang
  2014-03-04 12:11   ` David Laight
@ 2014-03-04 16:11   ` Eric Dumazet
  2014-03-04 16:52   ` Eric Dumazet
  2 siblings, 0 replies; 91+ messages in thread
From: Eric Dumazet @ 2014-03-04 16:11 UTC (permalink / raw)
  To: Hayes Wang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

On Tue, 2014-03-04 at 20:01 +0800, Hayes Wang wrote:

> +static u32 r8152_xmit_frags(struct r8152 *tp, struct sk_buff *skb, u8 *data)
> +{
> +	struct skb_shared_info *info = skb_shinfo(skb);
> +	unsigned int cur_frag;
> +	u32 total = skb_headlen(skb);
> +
> +	memcpy(data, skb->data, total);
> +	data += total;
> +
> +	for (cur_frag = 0; cur_frag < info->nr_frags; cur_frag++) {
> +		const skb_frag_t *frag = info->frags + cur_frag;
> +		void *addr;
> +		u32 len;
> +
> +		len = skb_frag_size(frag);
> +		addr = skb_frag_address(frag);
> +		memcpy(data, addr, len);
> +		data += len;
> +		total += len;
>  	}
> +
> +	return total;
>  }
>  

I would rather use skb_copy_bits(), because it correctly handles
kmap() case. (If a frag resides in high memory)




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

* Re: [PATCH net-next 08/12] r8152: support TSO
  2014-03-04 12:01 ` [PATCH net-next 08/12] r8152: support TSO Hayes Wang
  2014-03-04 12:11   ` David Laight
  2014-03-04 16:11   ` Eric Dumazet
@ 2014-03-04 16:52   ` Eric Dumazet
  2 siblings, 0 replies; 91+ messages in thread
From: Eric Dumazet @ 2014-03-04 16:52 UTC (permalink / raw)
  To: Hayes Wang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

On Tue, 2014-03-04 at 20:01 +0800, Hayes Wang wrote:
> Support scatter gather and TSO.

>  
> -	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
> -	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
> +	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
> +			    NETIF_F_TSO;
> +	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
> +			      NETIF_F_TSO;
>  

Minor nit :

If you use skb_copy_bits(), then you also can add NETIF_F_FRAGLIST here.




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

* Re: [PATCH net-next 09/12] r8152: support IPv6
  2014-03-04 12:01 ` [PATCH net-next 09/12] r8152: support IPv6 Hayes Wang
@ 2014-03-04 16:58   ` Eric Dumazet
  0 siblings, 0 replies; 91+ messages in thread
From: Eric Dumazet @ 2014-03-04 16:58 UTC (permalink / raw)
  To: Hayes Wang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

On Tue, 2014-03-04 at 20:01 +0800, Hayes Wang wrote:
> Support hw IPv6 checksum for TCP and UDP packets.


> +/*
> + * r8152_csum_workaround()
> + * The hw limites the value the transport offset. When the offset is out of the
> + * range, calculate the checksum by sw.
> + */
> +static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb,
> +				  struct sk_buff_head *list)
> +{
> +	if (skb_shinfo(skb)->gso_size) {
> +		netdev_features_t features = tp->netdev->features;
> +		struct sk_buff *segs, *nskb;
> +
> +		features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
> +		segs = skb_gso_segment(skb, features);
> +		if (IS_ERR(segs) || !segs)
> +			goto drop;
> +
> +		do {
> +			nskb = segs;
> +			segs = segs->next;
> +			nskb->next = NULL;
> +			__skb_queue_head(list, nskb);

This introduces TCP reordering.

You should use some kind of skb_queue_splice()




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

* Re: [PATCH net-next 07/12] r8152: support rx checksum
  2014-03-04 12:00 ` [PATCH net-next 07/12] r8152: support rx checksum Hayes Wang
@ 2014-03-04 21:32   ` David Miller
  0 siblings, 0 replies; 91+ messages in thread
From: David Miller @ 2014-03-04 21:32 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: Hayes Wang <hayeswang@realtek.com>
Date: Tue, 4 Mar 2014 20:00:59 +0800

> @@ -1453,11 +1491,19 @@ static void rx_bottom(struct r8152 *tp)
>  			pkt_len -= CRC_SIZE;
>  			rx_data += sizeof(struct rx_desc);
>  
> +			checksum = r8152_rx_csum(tp, rx_desc);
> +			if (checksum == RTL_CHECKSUM_FAIL) {
> +				stats->rx_errors++;
> +				goto find_next_rx;
> +			}
> +

It is not for the driver to make this policy decision and drop the
packet.  It is not a device RX error event.

In fact you do not know what corrupted the checksum, or even if
the device verified it correctly.  Anything is possible.

You must therefore still pass the packet up into the networking
stack using CHECKSUM_NONE, and let the protocols double-check
the checksum(s) in software and bump the appropriate statistic
counter if the checksum is really bad.

This allows allows network taps to see the packet, so that the
administrator can analyze the situation.

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

* [PATCH net-next v2 00/13] r8152: new features
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (11 preceding siblings ...)
  2014-03-04 12:01 ` [PATCH net-next 12/12] r8152: modify the tx timeout funcfion Hayes Wang
@ 2014-03-05  6:49 ` Hayes Wang
  2014-03-05  6:49     ` Hayes Wang
                     ` (12 more replies)
  2014-03-06  7:07   ` Hayes Wang
                   ` (6 subsequent siblings)
  19 siblings, 13 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Besides the adjustment of the code, support rx checksum,
TCP large send, and IPv6.

v2:
 - Split "support rx checksum" into two patches.
 - Don't drop the packet, even though the rx checksum fail for
   "support rx checksum".
 - Replace r8152_xmit_frags() with skb_copy_bits() for "support TSO".
 - Fix the issue of reording the packets for "support IPv6".

Hayes Wang (13):
  r8152: deal with the empty line and space
  r8152: replace tp->netdev with netdev
  r8152: remove rtl8152_get_stats
  r8152: replace spin_lock_irqsave and spin_unlock_irqrestore
  r8152: check tx agg list before spin lock
  r8152: up the priority of the transmission
  r8152: calculate the dropped packets for rx
  r8152: support rx checksum
  r8152: support TSO
  r8152: support IPv6
  r8152: reduce the numbers of the bulks
  r8152: add additional parameter for non x86 platform
  r8152: modify the tx timeout funcfion

 drivers/net/usb/r8152.c | 411 +++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 318 insertions(+), 93 deletions(-)

--
1.8.4.2


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

* [PATCH net-next v2 01/13] r8152: deal with the empty line and space
@ 2014-03-05  6:49     ` Hayes Wang
  0 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Add or remove some empty lines. Replace the spaces with the tabs.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0654bd3..c8bad62 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -593,6 +593,7 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
 			       value, index, tmp, size, 500);
 
 	kfree(tmp);
+
 	return ret;
 }
 
@@ -1514,6 +1515,7 @@ static void tx_bottom(struct r8152 *tp)
 				netif_warn(tp, tx_err, netdev,
 					   "failed tx_urb %d\n", res);
 				stats->tx_dropped += agg->skb_num;
+
 				spin_lock_irqsave(&tp->tx_lock, flags);
 				list_add_tail(&agg->list, &tp->tx_free);
 				spin_unlock_irqrestore(&tp->tx_lock, flags);
@@ -1833,7 +1835,6 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable)
 	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);
-
 }
 
 #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
@@ -2013,8 +2014,8 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
 
 static void r8152b_exit_oob(struct r8152 *tp)
 {
-	u32	ocp_data;
-	int	i;
+	u32 ocp_data;
+	int i;
 
 	ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
 	ocp_data &= ~RCR_ACPT_ALL;
@@ -2573,6 +2574,7 @@ static int rtl8152_open(struct net_device *netdev)
 	netif_carrier_off(netdev);
 	netif_start_queue(netdev);
 	set_bit(WORK_ENABLE, &tp->flags);
+
 	res = usb_submit_urb(tp->intr_urb, GFP_KERNEL);
 	if (res) {
 		if (res == -ENODEV)
@@ -3101,6 +3103,7 @@ static int rtl8152_probe(struct usb_interface *intf,
 
 	netdev->features |= NETIF_F_IP_CSUM;
 	netdev->hw_features = NETIF_F_IP_CSUM;
+
 	SET_ETHTOOL_OPS(netdev, &ops);
 
 	tp->mii.dev = netdev;
-- 
1.8.4.2


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

* [PATCH net-next v2 01/13] r8152: deal with the empty line and space
@ 2014-03-05  6:49     ` Hayes Wang
  0 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, Hayes Wang

Add or remove some empty lines. Replace the spaces with the tabs.

Signed-off-by: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/usb/r8152.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0654bd3..c8bad62 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -593,6 +593,7 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
 			       value, index, tmp, size, 500);
 
 	kfree(tmp);
+
 	return ret;
 }
 
@@ -1514,6 +1515,7 @@ static void tx_bottom(struct r8152 *tp)
 				netif_warn(tp, tx_err, netdev,
 					   "failed tx_urb %d\n", res);
 				stats->tx_dropped += agg->skb_num;
+
 				spin_lock_irqsave(&tp->tx_lock, flags);
 				list_add_tail(&agg->list, &tp->tx_free);
 				spin_unlock_irqrestore(&tp->tx_lock, flags);
@@ -1833,7 +1835,6 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable)
 	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);
-
 }
 
 #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
@@ -2013,8 +2014,8 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
 
 static void r8152b_exit_oob(struct r8152 *tp)
 {
-	u32	ocp_data;
-	int	i;
+	u32 ocp_data;
+	int i;
 
 	ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
 	ocp_data &= ~RCR_ACPT_ALL;
@@ -2573,6 +2574,7 @@ static int rtl8152_open(struct net_device *netdev)
 	netif_carrier_off(netdev);
 	netif_start_queue(netdev);
 	set_bit(WORK_ENABLE, &tp->flags);
+
 	res = usb_submit_urb(tp->intr_urb, GFP_KERNEL);
 	if (res) {
 		if (res == -ENODEV)
@@ -3101,6 +3103,7 @@ static int rtl8152_probe(struct usb_interface *intf,
 
 	netdev->features |= NETIF_F_IP_CSUM;
 	netdev->hw_features = NETIF_F_IP_CSUM;
+
 	SET_ETHTOOL_OPS(netdev, &ops);
 
 	tp->mii.dev = netdev;
-- 
1.8.4.2

--
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 related	[flat|nested] 91+ messages in thread

* [PATCH net-next v2 02/13] r8152: replace tp->netdev with netdev
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
  2014-03-05  6:49     ` Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 03/13] r8152: remove rtl8152_get_stats Hayes Wang
                     ` (10 subsequent siblings)
  12 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Replace some tp->netdev with netdev.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c8bad62..151398b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1037,6 +1037,7 @@ static void read_bulk_callback(struct urb *urb)
 static void write_bulk_callback(struct urb *urb)
 {
 	struct net_device_stats *stats;
+	struct net_device *netdev;
 	unsigned long flags;
 	struct tx_agg *agg;
 	struct r8152 *tp;
@@ -1050,10 +1051,11 @@ static void write_bulk_callback(struct urb *urb)
 	if (!tp)
 		return;
 
-	stats = rtl8152_get_stats(tp->netdev);
+	netdev = tp->netdev;
+	stats = rtl8152_get_stats(netdev);
 	if (status) {
 		if (net_ratelimit())
-			netdev_warn(tp->netdev, "Tx status %d\n", status);
+			netdev_warn(netdev, "Tx status %d\n", status);
 		stats->tx_errors += agg->skb_num;
 	} else {
 		stats->tx_packets += agg->skb_num;
@@ -1066,7 +1068,7 @@ static void write_bulk_callback(struct urb *urb)
 
 	usb_autopm_put_interface_async(tp->intf);
 
-	if (!netif_carrier_ok(tp->netdev))
+	if (!netif_carrier_ok(netdev))
 		return;
 
 	if (!test_bit(WORK_ENABLE, &tp->flags))
-- 
1.8.4.2


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

* [PATCH net-next v2 03/13] r8152: remove rtl8152_get_stats
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
  2014-03-05  6:49     ` Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 02/13] r8152: replace tp->netdev with netdev Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 04/13] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore Hayes Wang
                     ` (9 subsequent siblings)
  12 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

The rtl8152_get_stats() returns the point address of the struct
net_device_stats. This could be got from struct net_device directly.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 151398b..b8eee36 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -960,11 +960,6 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p)
 	return 0;
 }
 
-static struct net_device_stats *rtl8152_get_stats(struct net_device *dev)
-{
-	return &dev->stats;
-}
-
 static void read_bulk_callback(struct urb *urb)
 {
 	struct net_device *netdev;
@@ -1052,7 +1047,7 @@ static void write_bulk_callback(struct urb *urb)
 		return;
 
 	netdev = tp->netdev;
-	stats = rtl8152_get_stats(netdev);
+	stats = &netdev->stats;
 	if (status) {
 		if (net_ratelimit())
 			netdev_warn(netdev, "Tx status %d\n", status);
@@ -1442,7 +1437,7 @@ static void rx_bottom(struct r8152 *tp)
 
 		while (urb->actual_length > len_used) {
 			struct net_device *netdev = tp->netdev;
-			struct net_device_stats *stats;
+			struct net_device_stats *stats = &netdev->stats;
 			unsigned int pkt_len;
 			struct sk_buff *skb;
 
@@ -1454,8 +1449,6 @@ static void rx_bottom(struct r8152 *tp)
 			if (urb->actual_length < len_used)
 				break;
 
-			stats = rtl8152_get_stats(netdev);
-
 			pkt_len -= CRC_SIZE;
 			rx_data += sizeof(struct rx_desc);
 
@@ -1504,16 +1497,14 @@ static void tx_bottom(struct r8152 *tp)
 
 		res = r8152_tx_agg_fill(tp, agg);
 		if (res) {
-			struct net_device_stats *stats;
-			struct net_device *netdev;
-			unsigned long flags;
-
-			netdev = tp->netdev;
-			stats = rtl8152_get_stats(netdev);
+			struct net_device *netdev = tp->netdev;
 
 			if (res == -ENODEV) {
 				netif_device_detach(netdev);
 			} else {
+				struct net_device_stats *stats = &netdev->stats;
+				unsigned long flags;
+
 				netif_warn(tp, tx_err, netdev,
 					   "failed tx_urb %d\n", res);
 				stats->tx_dropped += agg->skb_num;
-- 
1.8.4.2


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

* [PATCH net-next v2 04/13] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                     ` (2 preceding siblings ...)
  2014-03-05  6:49   ` [PATCH net-next v2 03/13] r8152: remove rtl8152_get_stats Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 05/13] r8152: check tx agg list before spin lock Hayes Wang
                     ` (8 subsequent siblings)
  12 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Use spin_lock and spin_unlock in interrupt context.

The ndo_start_xmit would not be called in interrupt context, so
replace the relative spin_lock_irqsave and spin_unlock_irqrestore
with spin_lock_bh and spin_unlock_bh.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b8eee36..8ecb41b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -963,7 +963,6 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p)
 static void read_bulk_callback(struct urb *urb)
 {
 	struct net_device *netdev;
-	unsigned long flags;
 	int status = urb->status;
 	struct rx_agg *agg;
 	struct r8152 *tp;
@@ -997,9 +996,9 @@ static void read_bulk_callback(struct urb *urb)
 		if (urb->actual_length < ETH_ZLEN)
 			break;
 
-		spin_lock_irqsave(&tp->rx_lock, flags);
+		spin_lock(&tp->rx_lock);
 		list_add_tail(&agg->list, &tp->rx_done);
-		spin_unlock_irqrestore(&tp->rx_lock, flags);
+		spin_unlock(&tp->rx_lock);
 		tasklet_schedule(&tp->tl);
 		return;
 	case -ESHUTDOWN:
@@ -1022,9 +1021,9 @@ static void read_bulk_callback(struct urb *urb)
 	if (result == -ENODEV) {
 		netif_device_detach(tp->netdev);
 	} else if (result) {
-		spin_lock_irqsave(&tp->rx_lock, flags);
+		spin_lock(&tp->rx_lock);
 		list_add_tail(&agg->list, &tp->rx_done);
-		spin_unlock_irqrestore(&tp->rx_lock, flags);
+		spin_unlock(&tp->rx_lock);
 		tasklet_schedule(&tp->tl);
 	}
 }
@@ -1033,7 +1032,6 @@ static void write_bulk_callback(struct urb *urb)
 {
 	struct net_device_stats *stats;
 	struct net_device *netdev;
-	unsigned long flags;
 	struct tx_agg *agg;
 	struct r8152 *tp;
 	int status = urb->status;
@@ -1057,9 +1055,9 @@ static void write_bulk_callback(struct urb *urb)
 		stats->tx_bytes += agg->skb_len;
 	}
 
-	spin_lock_irqsave(&tp->tx_lock, flags);
+	spin_lock(&tp->tx_lock);
 	list_add_tail(&agg->list, &tp->tx_free);
-	spin_unlock_irqrestore(&tp->tx_lock, flags);
+	spin_unlock(&tp->tx_lock);
 
 	usb_autopm_put_interface_async(tp->intf);
 
@@ -1330,14 +1328,13 @@ 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, ret;
 	u8 *tx_data;
 
 	__skb_queue_head_init(&skb_head);
-	spin_lock_irqsave(&tx_queue->lock, flags);
+	spin_lock_bh(&tx_queue->lock);
 	skb_queue_splice_init(tx_queue, &skb_head);
-	spin_unlock_irqrestore(&tx_queue->lock, flags);
+	spin_unlock_bh(&tx_queue->lock);
 
 	tx_data = agg->head;
 	agg->skb_num = agg->skb_len = 0;
@@ -1374,9 +1371,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 	}
 
 	if (!skb_queue_empty(&skb_head)) {
-		spin_lock_irqsave(&tx_queue->lock, flags);
+		spin_lock_bh(&tx_queue->lock);
 		skb_queue_splice(&skb_head, tx_queue);
-		spin_unlock_irqrestore(&tx_queue->lock, flags);
+		spin_unlock_bh(&tx_queue->lock);
 	}
 
 	netif_tx_lock_bh(tp->netdev);
@@ -1551,16 +1548,15 @@ 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;
 
 	if (skb_queue_empty(tx_queue))
 		return;
 
 	__skb_queue_head_init(&skb_head);
-	spin_lock_irqsave(&tx_queue->lock, flags);
+	spin_lock_bh(&tx_queue->lock);
 	skb_queue_splice_init(tx_queue, &skb_head);
-	spin_unlock_irqrestore(&tx_queue->lock, flags);
+	spin_unlock_bh(&tx_queue->lock);
 
 	while ((skb = __skb_dequeue(&skb_head))) {
 		dev_kfree_skb(skb);
-- 
1.8.4.2


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

* [PATCH net-next v2 05/13] r8152: check tx agg list before spin lock
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                     ` (3 preceding siblings ...)
  2014-03-05  6:49   ` [PATCH net-next v2 04/13] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 06/13] r8152: up the priority of the transmission Hayes Wang
                     ` (7 subsequent siblings)
  12 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Check tx agg list before spin lock to avoid doing spin lock every
times.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 8ecb41b..00b3192 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1266,6 +1266,9 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp)
 	struct tx_agg *agg = NULL;
 	unsigned long flags;
 
+	if (list_empty(&tp->tx_free))
+		return NULL;
+
 	spin_lock_irqsave(&tp->tx_lock, flags);
 	if (!list_empty(&tp->tx_free)) {
 		struct list_head *cursor;
-- 
1.8.4.2


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

* [PATCH net-next v2 06/13] r8152: up the priority of the transmission
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                     ` (4 preceding siblings ...)
  2014-03-05  6:49   ` [PATCH net-next v2 05/13] r8152: check tx agg list before spin lock Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 07/13] r8152: calculate the dropped packets for rx Hayes Wang
                     ` (6 subsequent siblings)
  12 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

move the tx_bottom() from delayed_work to tasklet. It makes the rx
and tx balanced. If the device is in runtime suspend when getting
the tx packet, wakeup the device before trasmitting.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 00b3192..f1eaa18 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -447,6 +447,7 @@ enum rtl8152_flags {
 	RTL8152_LINK_CHG,
 	SELECTIVE_SUSPEND,
 	PHY_RESET,
+	SCHEDULE_TASKLET,
 };
 
 /* Define these values to match your device */
@@ -1071,7 +1072,7 @@ static void write_bulk_callback(struct urb *urb)
 		return;
 
 	if (!skb_queue_empty(&tp->tx_queue))
-		schedule_delayed_work(&tp->schedule, 0);
+		tasklet_schedule(&tp->tl);
 }
 
 static void intr_callback(struct urb *urb)
@@ -1335,9 +1336,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 	u8 *tx_data;
 
 	__skb_queue_head_init(&skb_head);
-	spin_lock_bh(&tx_queue->lock);
+	spin_lock(&tx_queue->lock);
 	skb_queue_splice_init(tx_queue, &skb_head);
-	spin_unlock_bh(&tx_queue->lock);
+	spin_unlock(&tx_queue->lock);
 
 	tx_data = agg->head;
 	agg->skb_num = agg->skb_len = 0;
@@ -1374,20 +1375,20 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 	}
 
 	if (!skb_queue_empty(&skb_head)) {
-		spin_lock_bh(&tx_queue->lock);
+		spin_lock(&tx_queue->lock);
 		skb_queue_splice(&skb_head, tx_queue);
-		spin_unlock_bh(&tx_queue->lock);
+		spin_unlock(&tx_queue->lock);
 	}
 
-	netif_tx_lock_bh(tp->netdev);
+	netif_tx_lock(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_bh(tp->netdev);
+	netif_tx_unlock(tp->netdev);
 
-	ret = usb_autopm_get_interface(tp->intf);
+	ret = usb_autopm_get_interface_async(tp->intf);
 	if (ret < 0)
 		goto out_tx_fill;
 
@@ -1395,9 +1396,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 			  agg->head, (int)(tx_data - (u8 *)agg->head),
 			  (usb_complete_t)write_bulk_callback, agg);
 
-	ret = usb_submit_urb(agg->urb, GFP_KERNEL);
+	ret = usb_submit_urb(agg->urb, GFP_ATOMIC);
 	if (ret < 0)
-		usb_autopm_put_interface(tp->intf);
+		usb_autopm_put_interface_async(tp->intf);
 
 out_tx_fill:
 	return ret;
@@ -1535,6 +1536,7 @@ static void bottom_half(unsigned long data)
 		return;
 
 	rx_bottom(tp);
+	tx_bottom(tp);
 }
 
 static
@@ -1630,7 +1632,7 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev)
 }
 
 static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
-					    struct net_device *netdev)
+					struct net_device *netdev)
 {
 	struct r8152 *tp = netdev_priv(netdev);
 
@@ -1638,13 +1640,17 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
 
 	skb_queue_tail(&tp->tx_queue, skb);
 
-	if (list_empty(&tp->tx_free) &&
-	    skb_queue_len(&tp->tx_queue) > tp->tx_qlen)
+	if (!list_empty(&tp->tx_free)) {
+		if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+			set_bit(SCHEDULE_TASKLET, &tp->flags);
+			schedule_delayed_work(&tp->schedule, 0);
+		} else {
+			usb_mark_last_busy(tp->udev);
+			tasklet_schedule(&tp->tl);
+		}
+	} else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen)
 		netif_stop_queue(netdev);
 
-	if (!list_empty(&tp->tx_free))
-		schedule_delayed_work(&tp->schedule, 0);
-
 	return NETDEV_TX_OK;
 }
 
@@ -2523,8 +2529,11 @@ 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(SCHEDULE_TASKLET, &tp->flags) &&
+	    (tp->speed & LINK_STATUS)) {
+		clear_bit(SCHEDULE_TASKLET, &tp->flags);
+		tasklet_schedule(&tp->tl);
+	}
 
 	if (test_bit(PHY_RESET, &tp->flags))
 		rtl_phy_reset(tp);
-- 
1.8.4.2


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

* [PATCH net-next v2 07/13] r8152: calculate the dropped packets for rx
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                     ` (5 preceding siblings ...)
  2014-03-05  6:49   ` [PATCH net-next v2 06/13] r8152: up the priority of the transmission Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 08/13] r8152: support rx checksum Hayes Wang
                     ` (5 subsequent siblings)
  12 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Continue dealing with the remain rx packets, even though the allocation
of the skb fail. This could calculate the correct dropped packets.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index f1eaa18..08f4e870 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1456,7 +1456,7 @@ static void rx_bottom(struct r8152 *tp)
 			skb = netdev_alloc_skb_ip_align(netdev, pkt_len);
 			if (!skb) {
 				stats->rx_dropped++;
-				break;
+				goto find_next_rx;
 			}
 			memcpy(skb->data, rx_data, pkt_len);
 			skb_put(skb, pkt_len);
@@ -1465,6 +1465,7 @@ static void rx_bottom(struct r8152 *tp)
 			stats->rx_packets++;
 			stats->rx_bytes += pkt_len;
 
+find_next_rx:
 			rx_data = rx_agg_align(rx_data + pkt_len + CRC_SIZE);
 			rx_desc = (struct rx_desc *)rx_data;
 			len_used = (int)(rx_data - (u8 *)agg->head);
-- 
1.8.4.2


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

* [PATCH net-next v2 08/13] r8152: support rx checksum
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                     ` (6 preceding siblings ...)
  2014-03-05  6:49   ` [PATCH net-next v2 07/13] r8152: calculate the dropped packets for rx Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 09/13] r8152: support TSO Hayes Wang
                     ` (4 subsequent siblings)
  12 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support hw rx checksum for TCP and UDP packets.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 08f4e870..c76e018 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -466,9 +466,19 @@ enum rtl8152_flags {
 
 struct rx_desc {
 	__le32 opts1;
+#define RD_CRC				(1 << 15)
 #define RX_LEN_MASK			0x7fff
+
 	__le32 opts2;
+#define RD_UDP_CS			(1 << 23)
+#define RD_TCP_CS			(1 << 22)
+#define RD_IPV4_CS			(1 << 19)
+
 	__le32 opts3;
+#define IPF				(1 << 23) /* IP checksum fail */
+#define UDPF				(1 << 22) /* UDP checksum fail */
+#define TCPF				(1 << 21) /* TCP checksum fail */
+
 	__le32 opts4;
 	__le32 opts5;
 	__le32 opts6;
@@ -1404,6 +1414,31 @@ out_tx_fill:
 	return ret;
 }
 
+static int r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc)
+{
+	int checksum = CHECKSUM_NONE;
+	u32 opts2, opts3;
+
+	if (tp->version == RTL_VER_01)
+		goto return_result;
+
+	opts2 = le32_to_cpu(rx_desc->opts2);
+	opts3 = le32_to_cpu(rx_desc->opts3);
+
+	if (opts2 & RD_IPV4_CS) {
+		if (opts3 & IPF)
+			checksum = CHECKSUM_NONE;
+		else if (((opts2 & RD_UDP_CS) && (opts3 & UDPF)) ||
+			 ((opts2 & RD_TCP_CS) && (opts3 & TCPF)))
+			checksum = CHECKSUM_NONE;
+		else
+			checksum = CHECKSUM_UNNECESSARY;
+	}
+
+return_result:
+	return checksum;
+}
+
 static void rx_bottom(struct r8152 *tp)
 {
 	unsigned long flags;
@@ -1458,6 +1493,8 @@ static void rx_bottom(struct r8152 *tp)
 				stats->rx_dropped++;
 				goto find_next_rx;
 			}
+
+			skb->ip_summed = r8152_rx_csum(tp, rx_desc);
 			memcpy(skb->data, rx_data, pkt_len);
 			skb_put(skb, pkt_len);
 			skb->protocol = eth_type_trans(skb, netdev);
@@ -3103,8 +3140,8 @@ static int rtl8152_probe(struct usb_interface *intf,
 	netdev->netdev_ops = &rtl8152_netdev_ops;
 	netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
 
-	netdev->features |= NETIF_F_IP_CSUM;
-	netdev->hw_features = NETIF_F_IP_CSUM;
+	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
 
 	SET_ETHTOOL_OPS(netdev, &ops);
 
-- 
1.8.4.2


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

* [PATCH net-next v2 09/13] r8152: support TSO
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                     ` (7 preceding siblings ...)
  2014-03-05  6:49   ` [PATCH net-next v2 08/13] r8152: support rx checksum Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 10/13] r8152: support IPv6 Hayes Wang
                     ` (3 subsequent siblings)
  12 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support scatter gather and TSO.

Adjust the tx checksum function and set the max gso size to fix the
size of the tx aggregation buffer.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c76e018..8f6d0f8 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.05.0 (2014/02/18)"
+#define DRIVER_VERSION "v1.06.0 (2014/03/03)"
 #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
 #define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
 #define MODULENAME "r8152"
@@ -488,13 +488,18 @@ struct tx_desc {
 	__le32 opts1;
 #define TX_FS			(1 << 31) /* First segment of a packet */
 #define TX_LS			(1 << 30) /* Final segment of a packet */
-#define TX_LEN_MASK		0x3ffff
+#define GTSENDV4		(1 << 28)
+#define GTTCPHO_SHIFT		18
+#define TX_LEN_MAX		0x3ffffU
 
 	__le32 opts2;
 #define UDP_CS			(1 << 31) /* Calculate UDP/IP checksum */
 #define TCP_CS			(1 << 30) /* Calculate TCP/IP checksum */
 #define IPV4_CS			(1 << 29) /* Calculate IPv4 checksum */
 #define IPV6_CS			(1 << 28) /* Calculate IPv6 checksum */
+#define MSS_SHIFT		17
+#define MSS_MAX			0x7ffU
+#define TCPHO_SHIFT		17
 };
 
 struct r8152;
@@ -561,12 +566,21 @@ enum rtl_version {
 	RTL_VER_MAX
 };
 
+enum tx_csum_stat {
+	TX_CSUM_SUCCESS = 0,
+	TX_CSUM_TSO,
+	TX_CSUM_NONE
+};
+
 /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
  * The RTL chips use a 64 element hash table based on the Ethernet CRC.
  */
 static const int multicast_filter_limit = 32;
 static unsigned int rx_buf_sz = 16384;
 
+#define RTL_LIMITED_TSO_SIZE	(rx_buf_sz - sizeof(struct tx_desc) - \
+				 VLAN_ETH_HLEN - VLAN_HLEN)
+
 static
 int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
 {
@@ -1293,24 +1307,46 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp)
 	return agg;
 }
 
-static void
-r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
+static inline __be16 get_protocol(struct sk_buff *skb)
 {
-	memset(desc, 0, sizeof(*desc));
+	__be16 protocol;
 
-	desc->opts1 = cpu_to_le32((skb->len & TX_LEN_MASK) | TX_FS | TX_LS);
+	if (skb->protocol == htons(ETH_P_8021Q))
+		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+	else
+		protocol = skb->protocol;
 
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		__be16 protocol;
-		u8 ip_protocol;
-		u32 opts2 = 0;
+	return protocol;
+}
 
-		if (skb->protocol == htons(ETH_P_8021Q))
-			protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
-		else
-			protocol = skb->protocol;
+static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
+			 struct sk_buff *skb, u32 len, u32 transport_offset)
+{
+	u32 mss = skb_shinfo(skb)->gso_size;
+	u32 opts1, opts2 = 0;
+	int ret = TX_CSUM_SUCCESS;
+
+	WARN_ON_ONCE(len > TX_LEN_MAX);
+
+	opts1 = len | TX_FS | TX_LS;
+
+	if (mss) {
+		switch (get_protocol(skb)) {
+		case htons(ETH_P_IP):
+			opts1 |= GTSENDV4;
+			break;
+
+		default:
+			WARN_ON_ONCE(1);
+			break;
+		}
+
+		opts1 |= transport_offset << GTTCPHO_SHIFT;
+		opts2 |= min(mss, MSS_MAX) << MSS_SHIFT;
+	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		u8 ip_protocol;
 
-		switch (protocol) {
+		switch (get_protocol(skb)) {
 		case htons(ETH_P_IP):
 			opts2 |= IPV4_CS;
 			ip_protocol = ip_hdr(skb)->protocol;
@@ -1326,17 +1362,20 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
 			break;
 		}
 
-		if (ip_protocol == IPPROTO_TCP) {
+		if (ip_protocol == IPPROTO_TCP)
 			opts2 |= TCP_CS;
-			opts2 |= (skb_transport_offset(skb) & 0x7fff) << 17;
-		} else if (ip_protocol == IPPROTO_UDP) {
+		else if (ip_protocol == IPPROTO_UDP)
 			opts2 |= UDP_CS;
-		} else {
+		else
 			WARN_ON_ONCE(1);
-		}
 
-		desc->opts2 = cpu_to_le32(opts2);
+		opts2 |= transport_offset << TCPHO_SHIFT;
 	}
+
+	desc->opts2 = cpu_to_le32(opts2);
+	desc->opts1 = cpu_to_le32(opts1);
+
+	return ret;
 }
 
 static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
@@ -1358,29 +1397,44 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		struct tx_desc *tx_desc;
 		struct sk_buff *skb;
 		unsigned int len;
+		u32 offset;
 
 		skb = __skb_dequeue(&skb_head);
 		if (!skb)
 			break;
 
-		remain -= sizeof(*tx_desc);
-		len = skb->len;
-		if (remain < len) {
+		len = skb->len + sizeof(*tx_desc);
+
+		if (len > remain) {
 			__skb_queue_head(&skb_head, skb);
 			break;
 		}
 
 		tx_data = tx_agg_align(tx_data);
 		tx_desc = (struct tx_desc *)tx_data;
+
+		offset = (u32)skb_transport_offset(skb);
+
+		r8152_tx_csum(tp, tx_desc, skb, skb->len, offset);
+
 		tx_data += sizeof(*tx_desc);
 
-		r8152_tx_csum(tp, tx_desc, skb);
-		memcpy(tx_data, skb->data, len);
-		agg->skb_num++;
+		len = skb->len;
+		if (skb_copy_bits(skb, 0, tx_data, len) < 0) {
+			struct net_device_stats *stats = &tp->netdev->stats;
+
+			stats->tx_dropped++;
+			dev_kfree_skb_any(skb);
+			tx_data -= sizeof(*tx_desc);
+			continue;
+		}
+
+		tx_data += len;
 		agg->skb_len += len;
+		agg->skb_num++;
+
 		dev_kfree_skb_any(skb);
 
-		tx_data += len;
 		remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
 	}
 
@@ -3140,10 +3194,13 @@ static int rtl8152_probe(struct usb_interface *intf,
 	netdev->netdev_ops = &rtl8152_netdev_ops;
 	netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
 
-	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
-	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
+			    NETIF_F_TSO | NETIF_F_FRAGLIST;
+	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
+			      NETIF_F_TSO | NETIF_F_FRAGLIST;
 
 	SET_ETHTOOL_OPS(netdev, &ops);
+	netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
 
 	tp->mii.dev = netdev;
 	tp->mii.mdio_read = read_mii_word;
-- 
1.8.4.2


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

* [PATCH net-next v2 10/13] r8152: support IPv6
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                     ` (8 preceding siblings ...)
  2014-03-05  6:49   ` [PATCH net-next v2 09/13] r8152: support TSO Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-09 19:47       ` Ben Hutchings
  2014-03-05  6:49   ` [PATCH net-next v2 11/13] r8152: reduce the numbers of the bulks Hayes Wang
                     ` (2 subsequent siblings)
  12 siblings, 1 reply; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support hw IPv6 checksum for TCP and UDP packets.

Note that the hw has the limitation of the range of the transport
offset. Besides, the TCP Pseudo Header of the IPv6 TSO of the hw
bases on the Microsoft document which excludes the packet length.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 8f6d0f8..8e208f30 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -21,6 +21,7 @@
 #include <linux/list.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
+#include <net/ip6_checksum.h>
 
 /* Version Information */
 #define DRIVER_VERSION "v1.06.0 (2014/03/03)"
@@ -472,6 +473,7 @@ struct rx_desc {
 	__le32 opts2;
 #define RD_UDP_CS			(1 << 23)
 #define RD_TCP_CS			(1 << 22)
+#define RD_IPV6_CS			(1 << 20)
 #define RD_IPV4_CS			(1 << 19)
 
 	__le32 opts3;
@@ -489,7 +491,9 @@ struct tx_desc {
 #define TX_FS			(1 << 31) /* First segment of a packet */
 #define TX_LS			(1 << 30) /* Final segment of a packet */
 #define GTSENDV4		(1 << 28)
+#define GTSENDV6		(1 << 27)
 #define GTTCPHO_SHIFT		18
+#define GTTCPHO_MAX		0x7fU
 #define TX_LEN_MAX		0x3ffffU
 
 	__le32 opts2;
@@ -500,6 +504,7 @@ struct tx_desc {
 #define MSS_SHIFT		17
 #define MSS_MAX			0x7ffU
 #define TCPHO_SHIFT		17
+#define TCPHO_MAX		0x7ffU
 };
 
 struct r8152;
@@ -1319,6 +1324,70 @@ static inline __be16 get_protocol(struct sk_buff *skb)
 	return protocol;
 }
 
+/*
+ * r8152_csum_workaround()
+ * The hw limites the value the transport offset. When the offset is out of the
+ * range, calculate the checksum by sw.
+ */
+static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb,
+				  struct sk_buff_head *list)
+{
+	if (skb_shinfo(skb)->gso_size) {
+		netdev_features_t features = tp->netdev->features;
+		struct sk_buff_head seg_list;
+		struct sk_buff *segs, *nskb;
+
+		features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
+		segs = skb_gso_segment(skb, features);
+		if (IS_ERR(segs) || !segs)
+			goto drop;
+
+		__skb_queue_head_init(&seg_list);
+
+		do {
+			nskb = segs;
+			segs = segs->next;
+			nskb->next = NULL;
+			__skb_queue_tail(&seg_list, nskb);
+		} while (segs);
+
+		skb_queue_splice(&seg_list, list);
+
+		dev_kfree_skb(skb);
+	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		if (skb_checksum_help(skb) < 0)
+			goto drop;
+
+		__skb_queue_head(list, skb);
+	} else {
+		struct net_device_stats *stats;
+
+drop:
+		stats = &tp->netdev->stats;
+		stats->tx_dropped++;
+		dev_kfree_skb(skb);
+	}
+}
+
+/*
+ * msdn_giant_send_check()
+ * According to the document of microsoft, the TCP Pseudo Header excludes the
+ * packet length for IPv6 TCP large packets.
+ */
+static int msdn_giant_send_check(struct sk_buff *skb)
+{
+	const struct ipv6hdr *ipv6h;
+	struct tcphdr *th;
+
+	ipv6h = ipv6_hdr(skb);
+	th = tcp_hdr(skb);
+
+	th->check = 0;
+	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
+
+	return 0;
+}
+
 static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 			 struct sk_buff *skb, u32 len, u32 transport_offset)
 {
@@ -1331,11 +1400,24 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 	opts1 = len | TX_FS | TX_LS;
 
 	if (mss) {
+		if (transport_offset > GTTCPHO_MAX) {
+			netif_warn(tp, tx_err, tp->netdev,
+				   "Invalid transport offset 0x%x for TSO\n",
+				   transport_offset);
+			ret = TX_CSUM_TSO;
+			goto unavailable;
+		}
+
 		switch (get_protocol(skb)) {
 		case htons(ETH_P_IP):
 			opts1 |= GTSENDV4;
 			break;
 
+		case htons(ETH_P_IPV6):
+			opts1 |= GTSENDV6;
+			msdn_giant_send_check(skb);
+			break;
+
 		default:
 			WARN_ON_ONCE(1);
 			break;
@@ -1346,6 +1428,14 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		u8 ip_protocol;
 
+		if (transport_offset > TCPHO_MAX) {
+			netif_warn(tp, tx_err, tp->netdev,
+				   "Invalid transport offset 0x%x\n",
+				   transport_offset);
+			ret = TX_CSUM_NONE;
+			goto unavailable;
+		}
+
 		switch (get_protocol(skb)) {
 		case htons(ETH_P_IP):
 			opts2 |= IPV4_CS;
@@ -1375,6 +1465,7 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 	desc->opts2 = cpu_to_le32(opts2);
 	desc->opts1 = cpu_to_le32(opts1);
 
+unavailable:
 	return ret;
 }
 
@@ -1415,7 +1506,10 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 
 		offset = (u32)skb_transport_offset(skb);
 
-		r8152_tx_csum(tp, tx_desc, skb, skb->len, offset);
+		if (r8152_tx_csum(tp, tx_desc, skb, skb->len, offset)) {
+			r8152_csum_workaround(tp, skb, &skb_head);
+			continue;
+		}
 
 		tx_data += sizeof(*tx_desc);
 
@@ -1487,6 +1581,11 @@ static int r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc)
 			checksum = CHECKSUM_NONE;
 		else
 			checksum = CHECKSUM_UNNECESSARY;
+	} else if (RD_IPV6_CS) {
+		if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF))
+			checksum = CHECKSUM_UNNECESSARY;
+		else if ((opts2 & RD_TCP_CS) && !(opts3 & TCPF))
+			checksum = CHECKSUM_UNNECESSARY;
 	}
 
 return_result:
@@ -3195,9 +3294,11 @@ static int rtl8152_probe(struct usb_interface *intf,
 	netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
 
 	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
-			    NETIF_F_TSO | NETIF_F_FRAGLIST;
+			    NETIF_F_TSO | NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM |
+			    NETIF_F_TSO6;
 	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
-			      NETIF_F_TSO | NETIF_F_FRAGLIST;
+			      NETIF_F_TSO | NETIF_F_FRAGLIST |
+			      NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
 
 	SET_ETHTOOL_OPS(netdev, &ops);
 	netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
-- 
1.8.4.2


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

* [PATCH net-next v2 11/13] r8152: reduce the numbers of the bulks
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                     ` (9 preceding siblings ...)
  2014-03-05  6:49   ` [PATCH net-next v2 10/13] r8152: support IPv6 Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 12/13] r8152: add additional parameter for non x86 platform Hayes Wang
  2014-03-05  6:49   ` [PATCH net-next v2 13/13] r8152: modify the tx timeout funcfion Hayes Wang
  12 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Reduce the numbers of tx and rx aggregation buffers.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 8e208f30..ddb5200 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -416,8 +416,8 @@ enum rtl_register_content {
 	FULL_DUP	= 0x01,
 };
 
-#define RTL8152_MAX_TX		10
-#define RTL8152_MAX_RX		10
+#define RTL8152_MAX_TX		4
+#define RTL8152_MAX_RX		4
 #define INTBUFSIZE		2
 #define CRC_SIZE		4
 #define TX_ALIGN		4
-- 
1.8.4.2


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

* [PATCH net-next v2 12/13] r8152: add additional parameter for non x86 platform
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                     ` (10 preceding siblings ...)
  2014-03-05  6:49   ` [PATCH net-next v2 11/13] r8152: reduce the numbers of the bulks Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  2014-03-06  5:05     ` David Miller
  2014-03-05  6:49   ` [PATCH net-next v2 13/13] r8152: modify the tx timeout funcfion Hayes Wang
  12 siblings, 1 reply; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Add additional parameter for non x86 platform for better throughput.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index ddb5200..6c0ec37 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -313,7 +313,11 @@
 #define PCUT_STATUS		0x0001
 
 /* USB_RX_EARLY_AGG */
-#define EARLY_AGG_SUPPER	0x0e832981
+#if defined(__i386__) || defined(__x86_64__)
+	#define EARLY_AGG_SUPPER	0x0e832981
+#else
+	#define EARLY_AGG_SUPPER	0x0e835000
+#endif
 #define EARLY_AGG_HIGH		0x0e837a12
 #define EARLY_AGG_SLOW		0x0e83ffff
 
-- 
1.8.4.2


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

* [PATCH net-next v2 13/13] r8152: modify the tx timeout funcfion
  2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
                     ` (11 preceding siblings ...)
  2014-03-05  6:49   ` [PATCH net-next v2 12/13] r8152: add additional parameter for non x86 platform Hayes Wang
@ 2014-03-05  6:49   ` Hayes Wang
  12 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-05  6:49 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Reset and reinitialize the device when the tx timeout occurs.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 6c0ec37..2de8ce4 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1764,16 +1764,6 @@ static void rtl_drop_queued_tx(struct r8152 *tp)
 	}
 }
 
-static void rtl8152_tx_timeout(struct net_device *netdev)
-{
-	struct r8152 *tp = netdev_priv(netdev);
-	int i;
-
-	netif_warn(tp, tx_err, netdev, "Tx timeout\n");
-	for (i = 0; i < RTL8152_MAX_TX; i++)
-		usb_unlink_urb(tp->tx_info[i].urb);
-}
-
 static void rtl8152_set_rx_mode(struct net_device *netdev)
 {
 	struct r8152 *tp = netdev_priv(netdev);
@@ -3150,6 +3140,37 @@ out:
 	return res;
 }
 
+static void rtl8152_tx_timeout(struct net_device *netdev)
+{
+	struct r8152 *tp = netdev_priv(netdev);
+
+	netif_warn(tp, tx_err, netdev, "Tx timeout\n");
+
+	if (usb_autopm_get_interface(tp->intf) < 0)
+		return;
+
+	netif_stop_queue(netdev);
+	clear_bit(WORK_ENABLE, &tp->flags);
+	usb_kill_urb(tp->intr_urb);
+	cancel_delayed_work_sync(&tp->schedule);
+	tp->rtl_ops.down(tp);
+
+	usb_reset_device(tp->udev);
+
+	tp->rtl_ops.init(tp);
+	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(netdev);
+	netif_start_queue(netdev);
+	set_bit(WORK_ENABLE, &tp->flags);
+	usb_submit_urb(tp->intr_urb, GFP_KERNEL);
+
+	usb_autopm_put_interface(tp->intf);
+}
+
 static const struct net_device_ops rtl8152_netdev_ops = {
 	.ndo_open		= rtl8152_open,
 	.ndo_stop		= rtl8152_close,
-- 
1.8.4.2


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

* Re: [PATCH net-next v2 12/13] r8152: add additional parameter for non x86 platform
  2014-03-05  6:49   ` [PATCH net-next v2 12/13] r8152: add additional parameter for non x86 platform Hayes Wang
@ 2014-03-06  5:05     ` David Miller
  0 siblings, 0 replies; 91+ messages in thread
From: David Miller @ 2014-03-06  5:05 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: Hayes Wang <hayeswang@realtek.com>
Date: Wed, 5 Mar 2014 14:49:27 +0800

> Add additional parameter for non x86 platform for better throughput.
> 
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>

This commit message tells me absolutely nothing.

First of all, it doesn't say what the issue is, why is the chip
slower on non-x86 platforms with the current way it is programmed?

And in particular, which non-x86 platform?  You can't possibly mean
all of them.

I can almost guarentee if you actually explain the issue, I'm going
to tell you to use a more meaningful test for the condition or
property an architecture has which makes the alternative setting
more desirable.

>  /* USB_RX_EARLY_AGG */
> -#define EARLY_AGG_SUPPER	0x0e832981
> +#if defined(__i386__) || defined(__x86_64__)
> +	#define EARLY_AGG_SUPPER	0x0e832981
> +#else
> +	#define EARLY_AGG_SUPPER	0x0e835000
> +#endif

And this value is completely magic, you must document what this
register value means.

I find this patch series extremely frustrating.

You are combining so many things all at once, so if one aspect
requires changes or to be removed, it invalidates the rest of
the series and you have to respin it all over again.

Why don't you re-submit this in pieces?  First the cleanups
(first three patches) would be one series.

Once I apply that, perhaps submit the locking changes and
tso/checksum support.

Then finally, after I apply that, submit the tweaks at the end.

Thank you.

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

* [PATCH net-next 0/3] r8152: cleanups
@ 2014-03-06  7:07   ` Hayes Wang
  0 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-06  7:07 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Deal with some empty lines and spaces, replace some tp->netdev with netdev,
and remove the unnecessary function.

Hayes Wang (3):
  r8152: deal with the empty line and space
  r8152: replace tp->netdev with netdev
  r8152: remove rtl8152_get_stats

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

-- 
1.8.4.2


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

* [PATCH net-next 0/3] r8152: cleanups
@ 2014-03-06  7:07   ` Hayes Wang
  0 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-06  7:07 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, Hayes Wang

Deal with some empty lines and spaces, replace some tp->netdev with netdev,
and remove the unnecessary function.

Hayes Wang (3):
  r8152: deal with the empty line and space
  r8152: replace tp->netdev with netdev
  r8152: remove rtl8152_get_stats

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

-- 
1.8.4.2

--
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] 91+ messages in thread

* [PATCH net-next 1/3] r8152: deal with the empty line and space
  2014-03-06  7:07   ` Hayes Wang
  (?)
@ 2014-03-06  7:07   ` Hayes Wang
  -1 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-06  7:07 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Add or remove some empty lines. Replace the spaces with the tabs.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0654bd3..c8bad62 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -593,6 +593,7 @@ int set_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
 			       value, index, tmp, size, 500);
 
 	kfree(tmp);
+
 	return ret;
 }
 
@@ -1514,6 +1515,7 @@ static void tx_bottom(struct r8152 *tp)
 				netif_warn(tp, tx_err, netdev,
 					   "failed tx_urb %d\n", res);
 				stats->tx_dropped += agg->skb_num;
+
 				spin_lock_irqsave(&tp->tx_lock, flags);
 				list_add_tail(&agg->list, &tp->tx_free);
 				spin_unlock_irqrestore(&tp->tx_lock, flags);
@@ -1833,7 +1835,6 @@ static void r8152_power_cut_en(struct r8152 *tp, bool enable)
 	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);
-
 }
 
 #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST)
@@ -2013,8 +2014,8 @@ static void r8152b_hw_phy_cfg(struct r8152 *tp)
 
 static void r8152b_exit_oob(struct r8152 *tp)
 {
-	u32	ocp_data;
-	int	i;
+	u32 ocp_data;
+	int i;
 
 	ocp_data = ocp_read_dword(tp, MCU_TYPE_PLA, PLA_RCR);
 	ocp_data &= ~RCR_ACPT_ALL;
@@ -2573,6 +2574,7 @@ static int rtl8152_open(struct net_device *netdev)
 	netif_carrier_off(netdev);
 	netif_start_queue(netdev);
 	set_bit(WORK_ENABLE, &tp->flags);
+
 	res = usb_submit_urb(tp->intr_urb, GFP_KERNEL);
 	if (res) {
 		if (res == -ENODEV)
@@ -3101,6 +3103,7 @@ static int rtl8152_probe(struct usb_interface *intf,
 
 	netdev->features |= NETIF_F_IP_CSUM;
 	netdev->hw_features = NETIF_F_IP_CSUM;
+
 	SET_ETHTOOL_OPS(netdev, &ops);
 
 	tp->mii.dev = netdev;
-- 
1.8.4.2


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

* [PATCH net-next 2/3] r8152: replace tp->netdev with netdev
  2014-03-06  7:07   ` Hayes Wang
  (?)
  (?)
@ 2014-03-06  7:07   ` Hayes Wang
  -1 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-06  7:07 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Replace some tp->netdev with netdev.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c8bad62..151398b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1037,6 +1037,7 @@ static void read_bulk_callback(struct urb *urb)
 static void write_bulk_callback(struct urb *urb)
 {
 	struct net_device_stats *stats;
+	struct net_device *netdev;
 	unsigned long flags;
 	struct tx_agg *agg;
 	struct r8152 *tp;
@@ -1050,10 +1051,11 @@ static void write_bulk_callback(struct urb *urb)
 	if (!tp)
 		return;
 
-	stats = rtl8152_get_stats(tp->netdev);
+	netdev = tp->netdev;
+	stats = rtl8152_get_stats(netdev);
 	if (status) {
 		if (net_ratelimit())
-			netdev_warn(tp->netdev, "Tx status %d\n", status);
+			netdev_warn(netdev, "Tx status %d\n", status);
 		stats->tx_errors += agg->skb_num;
 	} else {
 		stats->tx_packets += agg->skb_num;
@@ -1066,7 +1068,7 @@ static void write_bulk_callback(struct urb *urb)
 
 	usb_autopm_put_interface_async(tp->intf);
 
-	if (!netif_carrier_ok(tp->netdev))
+	if (!netif_carrier_ok(netdev))
 		return;
 
 	if (!test_bit(WORK_ENABLE, &tp->flags))
-- 
1.8.4.2


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

* [PATCH net-next 3/3] r8152: remove rtl8152_get_stats
  2014-03-06  7:07   ` Hayes Wang
                     ` (2 preceding siblings ...)
  (?)
@ 2014-03-06  7:07   ` Hayes Wang
  -1 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-06  7:07 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

The rtl8152_get_stats() returns the point address of the struct
net_device_stats. This could be got from struct net_device directly.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 151398b..b8eee36 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -960,11 +960,6 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p)
 	return 0;
 }
 
-static struct net_device_stats *rtl8152_get_stats(struct net_device *dev)
-{
-	return &dev->stats;
-}
-
 static void read_bulk_callback(struct urb *urb)
 {
 	struct net_device *netdev;
@@ -1052,7 +1047,7 @@ static void write_bulk_callback(struct urb *urb)
 		return;
 
 	netdev = tp->netdev;
-	stats = rtl8152_get_stats(netdev);
+	stats = &netdev->stats;
 	if (status) {
 		if (net_ratelimit())
 			netdev_warn(netdev, "Tx status %d\n", status);
@@ -1442,7 +1437,7 @@ static void rx_bottom(struct r8152 *tp)
 
 		while (urb->actual_length > len_used) {
 			struct net_device *netdev = tp->netdev;
-			struct net_device_stats *stats;
+			struct net_device_stats *stats = &netdev->stats;
 			unsigned int pkt_len;
 			struct sk_buff *skb;
 
@@ -1454,8 +1449,6 @@ static void rx_bottom(struct r8152 *tp)
 			if (urb->actual_length < len_used)
 				break;
 
-			stats = rtl8152_get_stats(netdev);
-
 			pkt_len -= CRC_SIZE;
 			rx_data += sizeof(struct rx_desc);
 
@@ -1504,16 +1497,14 @@ static void tx_bottom(struct r8152 *tp)
 
 		res = r8152_tx_agg_fill(tp, agg);
 		if (res) {
-			struct net_device_stats *stats;
-			struct net_device *netdev;
-			unsigned long flags;
-
-			netdev = tp->netdev;
-			stats = rtl8152_get_stats(netdev);
+			struct net_device *netdev = tp->netdev;
 
 			if (res == -ENODEV) {
 				netif_device_detach(netdev);
 			} else {
+				struct net_device_stats *stats = &netdev->stats;
+				unsigned long flags;
+
 				netif_warn(tp, tx_err, netdev,
 					   "failed tx_urb %d\n", res);
 				stats->tx_dropped += agg->skb_num;
-- 
1.8.4.2


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

* Re: [PATCH net-next 0/3] r8152: cleanups
  2014-03-06  7:07   ` Hayes Wang
                     ` (3 preceding siblings ...)
  (?)
@ 2014-03-06 18:17   ` David Miller
  -1 siblings, 0 replies; 91+ messages in thread
From: David Miller @ 2014-03-06 18:17 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: Hayes Wang <hayeswang@realtek.com>
Date: Thu, 6 Mar 2014 15:07:15 +0800

> Deal with some empty lines and spaces, replace some tp->netdev with netdev,
> and remove the unnecessary function.

Series applied, thank you.

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

* [PATCH net-next 0/7] r8152: tx/rx improvement
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (13 preceding siblings ...)
  2014-03-06  7:07   ` Hayes Wang
@ 2014-03-07  3:04 ` Hayes Wang
  2014-03-07  3:04   ` [PATCH net-next 1/7] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore Hayes Wang
                     ` (7 more replies)
  2014-03-10  6:22   ` Hayes Wang
                   ` (4 subsequent siblings)
  19 siblings, 8 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-07  3:04 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

 - Select the suitable spin lock for each function.
 - Add additional check to reduce the spin lock.
 - Up the priority of the tx to avoid interrupted by rx.
 - Support rx checksum, large send, and IPv6 hw checksum.

Hayes Wang (7):
  r8152: replace spin_lock_irqsave and spin_unlock_irqrestore
  r8152: check tx agg list before spin lock
  r8152: up the priority of the transmission
  r8152: calculate the dropped packets for rx
  r8152: support rx checksum
  r8152: support TSO
  r8152: support IPv6

 drivers/net/usb/r8152.c | 323 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 263 insertions(+), 60 deletions(-)

-- 
1.8.4.2


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

* [PATCH net-next 1/7] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore
  2014-03-07  3:04 ` [PATCH net-next 0/7] r8152: tx/rx improvement Hayes Wang
@ 2014-03-07  3:04   ` Hayes Wang
  2014-03-07  3:04     ` Hayes Wang
                     ` (6 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-07  3:04 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Use spin_lock and spin_unlock in interrupt context.

The ndo_start_xmit would not be called in interrupt context, so
replace the relative spin_lock_irqsave and spin_unlock_irqrestore
with spin_lock_bh and spin_unlock_bh.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b8eee36..8ecb41b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -963,7 +963,6 @@ static int rtl8152_set_mac_address(struct net_device *netdev, void *p)
 static void read_bulk_callback(struct urb *urb)
 {
 	struct net_device *netdev;
-	unsigned long flags;
 	int status = urb->status;
 	struct rx_agg *agg;
 	struct r8152 *tp;
@@ -997,9 +996,9 @@ static void read_bulk_callback(struct urb *urb)
 		if (urb->actual_length < ETH_ZLEN)
 			break;
 
-		spin_lock_irqsave(&tp->rx_lock, flags);
+		spin_lock(&tp->rx_lock);
 		list_add_tail(&agg->list, &tp->rx_done);
-		spin_unlock_irqrestore(&tp->rx_lock, flags);
+		spin_unlock(&tp->rx_lock);
 		tasklet_schedule(&tp->tl);
 		return;
 	case -ESHUTDOWN:
@@ -1022,9 +1021,9 @@ static void read_bulk_callback(struct urb *urb)
 	if (result == -ENODEV) {
 		netif_device_detach(tp->netdev);
 	} else if (result) {
-		spin_lock_irqsave(&tp->rx_lock, flags);
+		spin_lock(&tp->rx_lock);
 		list_add_tail(&agg->list, &tp->rx_done);
-		spin_unlock_irqrestore(&tp->rx_lock, flags);
+		spin_unlock(&tp->rx_lock);
 		tasklet_schedule(&tp->tl);
 	}
 }
@@ -1033,7 +1032,6 @@ static void write_bulk_callback(struct urb *urb)
 {
 	struct net_device_stats *stats;
 	struct net_device *netdev;
-	unsigned long flags;
 	struct tx_agg *agg;
 	struct r8152 *tp;
 	int status = urb->status;
@@ -1057,9 +1055,9 @@ static void write_bulk_callback(struct urb *urb)
 		stats->tx_bytes += agg->skb_len;
 	}
 
-	spin_lock_irqsave(&tp->tx_lock, flags);
+	spin_lock(&tp->tx_lock);
 	list_add_tail(&agg->list, &tp->tx_free);
-	spin_unlock_irqrestore(&tp->tx_lock, flags);
+	spin_unlock(&tp->tx_lock);
 
 	usb_autopm_put_interface_async(tp->intf);
 
@@ -1330,14 +1328,13 @@ 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, ret;
 	u8 *tx_data;
 
 	__skb_queue_head_init(&skb_head);
-	spin_lock_irqsave(&tx_queue->lock, flags);
+	spin_lock_bh(&tx_queue->lock);
 	skb_queue_splice_init(tx_queue, &skb_head);
-	spin_unlock_irqrestore(&tx_queue->lock, flags);
+	spin_unlock_bh(&tx_queue->lock);
 
 	tx_data = agg->head;
 	agg->skb_num = agg->skb_len = 0;
@@ -1374,9 +1371,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 	}
 
 	if (!skb_queue_empty(&skb_head)) {
-		spin_lock_irqsave(&tx_queue->lock, flags);
+		spin_lock_bh(&tx_queue->lock);
 		skb_queue_splice(&skb_head, tx_queue);
-		spin_unlock_irqrestore(&tx_queue->lock, flags);
+		spin_unlock_bh(&tx_queue->lock);
 	}
 
 	netif_tx_lock_bh(tp->netdev);
@@ -1551,16 +1548,15 @@ 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;
 
 	if (skb_queue_empty(tx_queue))
 		return;
 
 	__skb_queue_head_init(&skb_head);
-	spin_lock_irqsave(&tx_queue->lock, flags);
+	spin_lock_bh(&tx_queue->lock);
 	skb_queue_splice_init(tx_queue, &skb_head);
-	spin_unlock_irqrestore(&tx_queue->lock, flags);
+	spin_unlock_bh(&tx_queue->lock);
 
 	while ((skb = __skb_dequeue(&skb_head))) {
 		dev_kfree_skb(skb);
-- 
1.8.4.2


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

* [PATCH net-next 2/7] r8152: check tx agg list before spin lock
@ 2014-03-07  3:04     ` Hayes Wang
  0 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-07  3:04 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Check tx agg list before spin lock to avoid doing spin lock every
times.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 8ecb41b..00b3192 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1266,6 +1266,9 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp)
 	struct tx_agg *agg = NULL;
 	unsigned long flags;
 
+	if (list_empty(&tp->tx_free))
+		return NULL;
+
 	spin_lock_irqsave(&tp->tx_lock, flags);
 	if (!list_empty(&tp->tx_free)) {
 		struct list_head *cursor;
-- 
1.8.4.2


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

* [PATCH net-next 2/7] r8152: check tx agg list before spin lock
@ 2014-03-07  3:04     ` Hayes Wang
  0 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-07  3:04 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, Hayes Wang

Check tx agg list before spin lock to avoid doing spin lock every
times.

Signed-off-by: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/usb/r8152.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 8ecb41b..00b3192 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1266,6 +1266,9 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp)
 	struct tx_agg *agg = NULL;
 	unsigned long flags;
 
+	if (list_empty(&tp->tx_free))
+		return NULL;
+
 	spin_lock_irqsave(&tp->tx_lock, flags);
 	if (!list_empty(&tp->tx_free)) {
 		struct list_head *cursor;
-- 
1.8.4.2

--
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 related	[flat|nested] 91+ messages in thread

* [PATCH net-next 3/7] r8152: up the priority of the transmission
  2014-03-07  3:04 ` [PATCH net-next 0/7] r8152: tx/rx improvement Hayes Wang
  2014-03-07  3:04   ` [PATCH net-next 1/7] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore Hayes Wang
  2014-03-07  3:04     ` Hayes Wang
@ 2014-03-07  3:04   ` Hayes Wang
  2014-03-07  3:04   ` [PATCH net-next 4/7] r8152: calculate the dropped packets for rx Hayes Wang
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-07  3:04 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

move the tx_bottom() from delayed_work to tasklet. It makes the rx
and tx balanced. If the device is in runtime suspend when getting
the tx packet, wakeup the device before trasmitting.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 00b3192..f1eaa18 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -447,6 +447,7 @@ enum rtl8152_flags {
 	RTL8152_LINK_CHG,
 	SELECTIVE_SUSPEND,
 	PHY_RESET,
+	SCHEDULE_TASKLET,
 };
 
 /* Define these values to match your device */
@@ -1071,7 +1072,7 @@ static void write_bulk_callback(struct urb *urb)
 		return;
 
 	if (!skb_queue_empty(&tp->tx_queue))
-		schedule_delayed_work(&tp->schedule, 0);
+		tasklet_schedule(&tp->tl);
 }
 
 static void intr_callback(struct urb *urb)
@@ -1335,9 +1336,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 	u8 *tx_data;
 
 	__skb_queue_head_init(&skb_head);
-	spin_lock_bh(&tx_queue->lock);
+	spin_lock(&tx_queue->lock);
 	skb_queue_splice_init(tx_queue, &skb_head);
-	spin_unlock_bh(&tx_queue->lock);
+	spin_unlock(&tx_queue->lock);
 
 	tx_data = agg->head;
 	agg->skb_num = agg->skb_len = 0;
@@ -1374,20 +1375,20 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 	}
 
 	if (!skb_queue_empty(&skb_head)) {
-		spin_lock_bh(&tx_queue->lock);
+		spin_lock(&tx_queue->lock);
 		skb_queue_splice(&skb_head, tx_queue);
-		spin_unlock_bh(&tx_queue->lock);
+		spin_unlock(&tx_queue->lock);
 	}
 
-	netif_tx_lock_bh(tp->netdev);
+	netif_tx_lock(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_bh(tp->netdev);
+	netif_tx_unlock(tp->netdev);
 
-	ret = usb_autopm_get_interface(tp->intf);
+	ret = usb_autopm_get_interface_async(tp->intf);
 	if (ret < 0)
 		goto out_tx_fill;
 
@@ -1395,9 +1396,9 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 			  agg->head, (int)(tx_data - (u8 *)agg->head),
 			  (usb_complete_t)write_bulk_callback, agg);
 
-	ret = usb_submit_urb(agg->urb, GFP_KERNEL);
+	ret = usb_submit_urb(agg->urb, GFP_ATOMIC);
 	if (ret < 0)
-		usb_autopm_put_interface(tp->intf);
+		usb_autopm_put_interface_async(tp->intf);
 
 out_tx_fill:
 	return ret;
@@ -1535,6 +1536,7 @@ static void bottom_half(unsigned long data)
 		return;
 
 	rx_bottom(tp);
+	tx_bottom(tp);
 }
 
 static
@@ -1630,7 +1632,7 @@ static void _rtl8152_set_rx_mode(struct net_device *netdev)
 }
 
 static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
-					    struct net_device *netdev)
+					struct net_device *netdev)
 {
 	struct r8152 *tp = netdev_priv(netdev);
 
@@ -1638,13 +1640,17 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
 
 	skb_queue_tail(&tp->tx_queue, skb);
 
-	if (list_empty(&tp->tx_free) &&
-	    skb_queue_len(&tp->tx_queue) > tp->tx_qlen)
+	if (!list_empty(&tp->tx_free)) {
+		if (test_bit(SELECTIVE_SUSPEND, &tp->flags)) {
+			set_bit(SCHEDULE_TASKLET, &tp->flags);
+			schedule_delayed_work(&tp->schedule, 0);
+		} else {
+			usb_mark_last_busy(tp->udev);
+			tasklet_schedule(&tp->tl);
+		}
+	} else if (skb_queue_len(&tp->tx_queue) > tp->tx_qlen)
 		netif_stop_queue(netdev);
 
-	if (!list_empty(&tp->tx_free))
-		schedule_delayed_work(&tp->schedule, 0);
-
 	return NETDEV_TX_OK;
 }
 
@@ -2523,8 +2529,11 @@ 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(SCHEDULE_TASKLET, &tp->flags) &&
+	    (tp->speed & LINK_STATUS)) {
+		clear_bit(SCHEDULE_TASKLET, &tp->flags);
+		tasklet_schedule(&tp->tl);
+	}
 
 	if (test_bit(PHY_RESET, &tp->flags))
 		rtl_phy_reset(tp);
-- 
1.8.4.2


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

* [PATCH net-next 4/7] r8152: calculate the dropped packets for rx
  2014-03-07  3:04 ` [PATCH net-next 0/7] r8152: tx/rx improvement Hayes Wang
                     ` (2 preceding siblings ...)
  2014-03-07  3:04   ` [PATCH net-next 3/7] r8152: up the priority of the transmission Hayes Wang
@ 2014-03-07  3:04   ` Hayes Wang
  2014-03-07  3:04   ` [PATCH net-next 5/7] r8152: support rx checksum Hayes Wang
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-07  3:04 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Continue dealing with the remain rx packets, even though the allocation
of the skb fail. This could calculate the correct dropped packets.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index f1eaa18..08f4e870 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1456,7 +1456,7 @@ static void rx_bottom(struct r8152 *tp)
 			skb = netdev_alloc_skb_ip_align(netdev, pkt_len);
 			if (!skb) {
 				stats->rx_dropped++;
-				break;
+				goto find_next_rx;
 			}
 			memcpy(skb->data, rx_data, pkt_len);
 			skb_put(skb, pkt_len);
@@ -1465,6 +1465,7 @@ static void rx_bottom(struct r8152 *tp)
 			stats->rx_packets++;
 			stats->rx_bytes += pkt_len;
 
+find_next_rx:
 			rx_data = rx_agg_align(rx_data + pkt_len + CRC_SIZE);
 			rx_desc = (struct rx_desc *)rx_data;
 			len_used = (int)(rx_data - (u8 *)agg->head);
-- 
1.8.4.2


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

* [PATCH net-next 5/7] r8152: support rx checksum
  2014-03-07  3:04 ` [PATCH net-next 0/7] r8152: tx/rx improvement Hayes Wang
                     ` (3 preceding siblings ...)
  2014-03-07  3:04   ` [PATCH net-next 4/7] r8152: calculate the dropped packets for rx Hayes Wang
@ 2014-03-07  3:04   ` Hayes Wang
  2014-03-07  3:04   ` [PATCH net-next 6/7] r8152: support TSO Hayes Wang
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-07  3:04 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support hw rx checksum for TCP and UDP packets.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 08f4e870..8bb8782 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -467,8 +467,17 @@ enum rtl8152_flags {
 struct rx_desc {
 	__le32 opts1;
 #define RX_LEN_MASK			0x7fff
+
 	__le32 opts2;
+#define RD_UDP_CS			(1 << 23)
+#define RD_TCP_CS			(1 << 22)
+#define RD_IPV4_CS			(1 << 19)
+
 	__le32 opts3;
+#define IPF				(1 << 23) /* IP checksum fail */
+#define UDPF				(1 << 22) /* UDP checksum fail */
+#define TCPF				(1 << 21) /* TCP checksum fail */
+
 	__le32 opts4;
 	__le32 opts5;
 	__le32 opts6;
@@ -1404,6 +1413,32 @@ out_tx_fill:
 	return ret;
 }
 
+static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc)
+{
+	u8 checksum = CHECKSUM_NONE;
+	u32 opts2, opts3;
+
+	if (tp->version == RTL_VER_01)
+		goto return_result;
+
+	opts2 = le32_to_cpu(rx_desc->opts2);
+	opts3 = le32_to_cpu(rx_desc->opts3);
+
+	if (opts2 & RD_IPV4_CS) {
+		if (opts3 & IPF)
+			checksum = CHECKSUM_NONE;
+		else if ((opts2 & RD_UDP_CS) && (opts3 & UDPF))
+			checksum = CHECKSUM_NONE;
+		else if ((opts2 & RD_TCP_CS) && (opts3 & TCPF))
+			checksum = CHECKSUM_NONE;
+		else
+			checksum = CHECKSUM_UNNECESSARY;
+	}
+
+return_result:
+	return checksum;
+}
+
 static void rx_bottom(struct r8152 *tp)
 {
 	unsigned long flags;
@@ -1458,6 +1493,8 @@ static void rx_bottom(struct r8152 *tp)
 				stats->rx_dropped++;
 				goto find_next_rx;
 			}
+
+			skb->ip_summed = r8152_rx_csum(tp, rx_desc);
 			memcpy(skb->data, rx_data, pkt_len);
 			skb_put(skb, pkt_len);
 			skb->protocol = eth_type_trans(skb, netdev);
@@ -3103,8 +3140,8 @@ static int rtl8152_probe(struct usb_interface *intf,
 	netdev->netdev_ops = &rtl8152_netdev_ops;
 	netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
 
-	netdev->features |= NETIF_F_IP_CSUM;
-	netdev->hw_features = NETIF_F_IP_CSUM;
+	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
 
 	SET_ETHTOOL_OPS(netdev, &ops);
 
-- 
1.8.4.2


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

* [PATCH net-next 6/7] r8152: support TSO
  2014-03-07  3:04 ` [PATCH net-next 0/7] r8152: tx/rx improvement Hayes Wang
                     ` (4 preceding siblings ...)
  2014-03-07  3:04   ` [PATCH net-next 5/7] r8152: support rx checksum Hayes Wang
@ 2014-03-07  3:04   ` Hayes Wang
  2014-03-07  3:04   ` [PATCH net-next 7/7] r8152: support IPv6 Hayes Wang
  2014-03-07 21:27   ` [PATCH net-next 0/7] r8152: tx/rx improvement David Miller
  7 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-07  3:04 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support scatter gather and TSO.

Adjust the tx checksum function and set the max gso size to fix the
size of the tx aggregation buffer.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 8bb8782..b23b2ae 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.05.0 (2014/02/18)"
+#define DRIVER_VERSION "v1.06.0 (2014/03/03)"
 #define DRIVER_AUTHOR "Realtek linux nic maintainers <nic_swsd@realtek.com>"
 #define DRIVER_DESC "Realtek RTL8152/RTL8153 Based USB Ethernet Adapters"
 #define MODULENAME "r8152"
@@ -487,13 +487,18 @@ struct tx_desc {
 	__le32 opts1;
 #define TX_FS			(1 << 31) /* First segment of a packet */
 #define TX_LS			(1 << 30) /* Final segment of a packet */
-#define TX_LEN_MASK		0x3ffff
+#define GTSENDV4		(1 << 28)
+#define GTTCPHO_SHIFT		18
+#define TX_LEN_MAX		0x3ffffU
 
 	__le32 opts2;
 #define UDP_CS			(1 << 31) /* Calculate UDP/IP checksum */
 #define TCP_CS			(1 << 30) /* Calculate TCP/IP checksum */
 #define IPV4_CS			(1 << 29) /* Calculate IPv4 checksum */
 #define IPV6_CS			(1 << 28) /* Calculate IPv6 checksum */
+#define MSS_SHIFT		17
+#define MSS_MAX			0x7ffU
+#define TCPHO_SHIFT		17
 };
 
 struct r8152;
@@ -560,12 +565,21 @@ enum rtl_version {
 	RTL_VER_MAX
 };
 
+enum tx_csum_stat {
+	TX_CSUM_SUCCESS = 0,
+	TX_CSUM_TSO,
+	TX_CSUM_NONE
+};
+
 /* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
  * The RTL chips use a 64 element hash table based on the Ethernet CRC.
  */
 static const int multicast_filter_limit = 32;
 static unsigned int rx_buf_sz = 16384;
 
+#define RTL_LIMITED_TSO_SIZE	(rx_buf_sz - sizeof(struct tx_desc) - \
+				 VLAN_ETH_HLEN - VLAN_HLEN)
+
 static
 int get_registers(struct r8152 *tp, u16 value, u16 index, u16 size, void *data)
 {
@@ -1292,24 +1306,46 @@ static struct tx_agg *r8152_get_tx_agg(struct r8152 *tp)
 	return agg;
 }
 
-static void
-r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
+static inline __be16 get_protocol(struct sk_buff *skb)
 {
-	memset(desc, 0, sizeof(*desc));
+	__be16 protocol;
 
-	desc->opts1 = cpu_to_le32((skb->len & TX_LEN_MASK) | TX_FS | TX_LS);
+	if (skb->protocol == htons(ETH_P_8021Q))
+		protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
+	else
+		protocol = skb->protocol;
 
-	if (skb->ip_summed == CHECKSUM_PARTIAL) {
-		__be16 protocol;
-		u8 ip_protocol;
-		u32 opts2 = 0;
+	return protocol;
+}
 
-		if (skb->protocol == htons(ETH_P_8021Q))
-			protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
-		else
-			protocol = skb->protocol;
+static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
+			 struct sk_buff *skb, u32 len, u32 transport_offset)
+{
+	u32 mss = skb_shinfo(skb)->gso_size;
+	u32 opts1, opts2 = 0;
+	int ret = TX_CSUM_SUCCESS;
+
+	WARN_ON_ONCE(len > TX_LEN_MAX);
+
+	opts1 = len | TX_FS | TX_LS;
+
+	if (mss) {
+		switch (get_protocol(skb)) {
+		case htons(ETH_P_IP):
+			opts1 |= GTSENDV4;
+			break;
+
+		default:
+			WARN_ON_ONCE(1);
+			break;
+		}
+
+		opts1 |= transport_offset << GTTCPHO_SHIFT;
+		opts2 |= min(mss, MSS_MAX) << MSS_SHIFT;
+	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		u8 ip_protocol;
 
-		switch (protocol) {
+		switch (get_protocol(skb)) {
 		case htons(ETH_P_IP):
 			opts2 |= IPV4_CS;
 			ip_protocol = ip_hdr(skb)->protocol;
@@ -1325,17 +1361,20 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb)
 			break;
 		}
 
-		if (ip_protocol == IPPROTO_TCP) {
+		if (ip_protocol == IPPROTO_TCP)
 			opts2 |= TCP_CS;
-			opts2 |= (skb_transport_offset(skb) & 0x7fff) << 17;
-		} else if (ip_protocol == IPPROTO_UDP) {
+		else if (ip_protocol == IPPROTO_UDP)
 			opts2 |= UDP_CS;
-		} else {
+		else
 			WARN_ON_ONCE(1);
-		}
 
-		desc->opts2 = cpu_to_le32(opts2);
+		opts2 |= transport_offset << TCPHO_SHIFT;
 	}
+
+	desc->opts2 = cpu_to_le32(opts2);
+	desc->opts1 = cpu_to_le32(opts1);
+
+	return ret;
 }
 
 static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
@@ -1357,29 +1396,44 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 		struct tx_desc *tx_desc;
 		struct sk_buff *skb;
 		unsigned int len;
+		u32 offset;
 
 		skb = __skb_dequeue(&skb_head);
 		if (!skb)
 			break;
 
-		remain -= sizeof(*tx_desc);
-		len = skb->len;
-		if (remain < len) {
+		len = skb->len + sizeof(*tx_desc);
+
+		if (len > remain) {
 			__skb_queue_head(&skb_head, skb);
 			break;
 		}
 
 		tx_data = tx_agg_align(tx_data);
 		tx_desc = (struct tx_desc *)tx_data;
+
+		offset = (u32)skb_transport_offset(skb);
+
+		r8152_tx_csum(tp, tx_desc, skb, skb->len, offset);
+
 		tx_data += sizeof(*tx_desc);
 
-		r8152_tx_csum(tp, tx_desc, skb);
-		memcpy(tx_data, skb->data, len);
-		agg->skb_num++;
+		len = skb->len;
+		if (skb_copy_bits(skb, 0, tx_data, len) < 0) {
+			struct net_device_stats *stats = &tp->netdev->stats;
+
+			stats->tx_dropped++;
+			dev_kfree_skb_any(skb);
+			tx_data -= sizeof(*tx_desc);
+			continue;
+		}
+
+		tx_data += len;
 		agg->skb_len += len;
+		agg->skb_num++;
+
 		dev_kfree_skb_any(skb);
 
-		tx_data += len;
 		remain = rx_buf_sz - (int)(tx_agg_align(tx_data) - agg->head);
 	}
 
@@ -3140,10 +3194,13 @@ static int rtl8152_probe(struct usb_interface *intf,
 	netdev->netdev_ops = &rtl8152_netdev_ops;
 	netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
 
-	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
-	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM;
+	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
+			    NETIF_F_TSO | NETIF_F_FRAGLIST;
+	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
+			      NETIF_F_TSO | NETIF_F_FRAGLIST;
 
 	SET_ETHTOOL_OPS(netdev, &ops);
+	netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
 
 	tp->mii.dev = netdev;
 	tp->mii.mdio_read = read_mii_word;
-- 
1.8.4.2


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

* [PATCH net-next 7/7] r8152: support IPv6
  2014-03-07  3:04 ` [PATCH net-next 0/7] r8152: tx/rx improvement Hayes Wang
                     ` (5 preceding siblings ...)
  2014-03-07  3:04   ` [PATCH net-next 6/7] r8152: support TSO Hayes Wang
@ 2014-03-07  3:04   ` Hayes Wang
  2014-03-07 21:27   ` [PATCH net-next 0/7] r8152: tx/rx improvement David Miller
  7 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-07  3:04 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Support hw IPv6 checksum for TCP and UDP packets.

Note that the hw has the limitation of the range of the transport
offset. Besides, the TCP Pseudo Header of the IPv6 TSO of the hw
bases on the Microsoft document which excludes the packet length.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index b23b2ae..c7ef30d 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -21,6 +21,7 @@
 #include <linux/list.h>
 #include <linux/ip.h>
 #include <linux/ipv6.h>
+#include <net/ip6_checksum.h>
 
 /* Version Information */
 #define DRIVER_VERSION "v1.06.0 (2014/03/03)"
@@ -471,6 +472,7 @@ struct rx_desc {
 	__le32 opts2;
 #define RD_UDP_CS			(1 << 23)
 #define RD_TCP_CS			(1 << 22)
+#define RD_IPV6_CS			(1 << 20)
 #define RD_IPV4_CS			(1 << 19)
 
 	__le32 opts3;
@@ -488,7 +490,9 @@ struct tx_desc {
 #define TX_FS			(1 << 31) /* First segment of a packet */
 #define TX_LS			(1 << 30) /* Final segment of a packet */
 #define GTSENDV4		(1 << 28)
+#define GTSENDV6		(1 << 27)
 #define GTTCPHO_SHIFT		18
+#define GTTCPHO_MAX		0x7fU
 #define TX_LEN_MAX		0x3ffffU
 
 	__le32 opts2;
@@ -499,6 +503,7 @@ struct tx_desc {
 #define MSS_SHIFT		17
 #define MSS_MAX			0x7ffU
 #define TCPHO_SHIFT		17
+#define TCPHO_MAX		0x7ffU
 };
 
 struct r8152;
@@ -1318,6 +1323,69 @@ static inline __be16 get_protocol(struct sk_buff *skb)
 	return protocol;
 }
 
+/*
+ * r8152_csum_workaround()
+ * The hw limites the value the transport offset. When the offset is out of the
+ * range, calculate the checksum by sw.
+ */
+static void r8152_csum_workaround(struct r8152 *tp, struct sk_buff *skb,
+				  struct sk_buff_head *list)
+{
+	if (skb_shinfo(skb)->gso_size) {
+		netdev_features_t features = tp->netdev->features;
+		struct sk_buff_head seg_list;
+		struct sk_buff *segs, *nskb;
+
+		features &= ~(NETIF_F_IP_CSUM | NETIF_F_SG | NETIF_F_TSO);
+		segs = skb_gso_segment(skb, features);
+		if (IS_ERR(segs) || !segs)
+			goto drop;
+
+		__skb_queue_head_init(&seg_list);
+
+		do {
+			nskb = segs;
+			segs = segs->next;
+			nskb->next = NULL;
+			__skb_queue_tail(&seg_list, nskb);
+		} while (segs);
+
+		skb_queue_splice(&seg_list, list);
+		dev_kfree_skb(skb);
+	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
+		if (skb_checksum_help(skb) < 0)
+			goto drop;
+
+		__skb_queue_head(list, skb);
+	} else {
+		struct net_device_stats *stats;
+
+drop:
+		stats = &tp->netdev->stats;
+		stats->tx_dropped++;
+		dev_kfree_skb(skb);
+	}
+}
+
+/*
+ * msdn_giant_send_check()
+ * According to the document of microsoft, the TCP Pseudo Header excludes the
+ * packet length for IPv6 TCP large packets.
+ */
+static int msdn_giant_send_check(struct sk_buff *skb)
+{
+	const struct ipv6hdr *ipv6h;
+	struct tcphdr *th;
+
+	ipv6h = ipv6_hdr(skb);
+	th = tcp_hdr(skb);
+
+	th->check = 0;
+	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
+
+	return 0;
+}
+
 static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 			 struct sk_buff *skb, u32 len, u32 transport_offset)
 {
@@ -1330,11 +1398,24 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 	opts1 = len | TX_FS | TX_LS;
 
 	if (mss) {
+		if (transport_offset > GTTCPHO_MAX) {
+			netif_warn(tp, tx_err, tp->netdev,
+				   "Invalid transport offset 0x%x for TSO\n",
+				   transport_offset);
+			ret = TX_CSUM_TSO;
+			goto unavailable;
+		}
+
 		switch (get_protocol(skb)) {
 		case htons(ETH_P_IP):
 			opts1 |= GTSENDV4;
 			break;
 
+		case htons(ETH_P_IPV6):
+			opts1 |= GTSENDV6;
+			msdn_giant_send_check(skb);
+			break;
+
 		default:
 			WARN_ON_ONCE(1);
 			break;
@@ -1345,6 +1426,14 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 	} else if (skb->ip_summed == CHECKSUM_PARTIAL) {
 		u8 ip_protocol;
 
+		if (transport_offset > TCPHO_MAX) {
+			netif_warn(tp, tx_err, tp->netdev,
+				   "Invalid transport offset 0x%x\n",
+				   transport_offset);
+			ret = TX_CSUM_NONE;
+			goto unavailable;
+		}
+
 		switch (get_protocol(skb)) {
 		case htons(ETH_P_IP):
 			opts2 |= IPV4_CS;
@@ -1374,6 +1463,7 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 	desc->opts2 = cpu_to_le32(opts2);
 	desc->opts1 = cpu_to_le32(opts1);
 
+unavailable:
 	return ret;
 }
 
@@ -1414,7 +1504,10 @@ static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg)
 
 		offset = (u32)skb_transport_offset(skb);
 
-		r8152_tx_csum(tp, tx_desc, skb, skb->len, offset);
+		if (r8152_tx_csum(tp, tx_desc, skb, skb->len, offset)) {
+			r8152_csum_workaround(tp, skb, &skb_head);
+			continue;
+		}
 
 		tx_data += sizeof(*tx_desc);
 
@@ -1487,6 +1580,11 @@ static u8 r8152_rx_csum(struct r8152 *tp, struct rx_desc *rx_desc)
 			checksum = CHECKSUM_NONE;
 		else
 			checksum = CHECKSUM_UNNECESSARY;
+	} else if (RD_IPV6_CS) {
+		if ((opts2 & RD_UDP_CS) && !(opts3 & UDPF))
+			checksum = CHECKSUM_UNNECESSARY;
+		else if ((opts2 & RD_TCP_CS) && !(opts3 & TCPF))
+			checksum = CHECKSUM_UNNECESSARY;
 	}
 
 return_result:
@@ -3195,9 +3293,11 @@ static int rtl8152_probe(struct usb_interface *intf,
 	netdev->watchdog_timeo = RTL8152_TX_TIMEOUT;
 
 	netdev->features |= NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
-			    NETIF_F_TSO | NETIF_F_FRAGLIST;
+			    NETIF_F_TSO | NETIF_F_FRAGLIST | NETIF_F_IPV6_CSUM |
+			    NETIF_F_TSO6;
 	netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_SG |
-			      NETIF_F_TSO | NETIF_F_FRAGLIST;
+			      NETIF_F_TSO | NETIF_F_FRAGLIST |
+			      NETIF_F_IPV6_CSUM | NETIF_F_TSO6;
 
 	SET_ETHTOOL_OPS(netdev, &ops);
 	netif_set_gso_max_size(netdev, RTL_LIMITED_TSO_SIZE);
-- 
1.8.4.2


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

* Re: [PATCH net-next 0/7] r8152: tx/rx improvement
  2014-03-07  3:04 ` [PATCH net-next 0/7] r8152: tx/rx improvement Hayes Wang
                     ` (6 preceding siblings ...)
  2014-03-07  3:04   ` [PATCH net-next 7/7] r8152: support IPv6 Hayes Wang
@ 2014-03-07 21:27   ` David Miller
  2014-03-10  3:45     ` hayeswang
  7 siblings, 1 reply; 91+ messages in thread
From: David Miller @ 2014-03-07 21:27 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: Hayes Wang <hayeswang@realtek.com>
Date: Fri, 7 Mar 2014 11:04:33 +0800

>  - Select the suitable spin lock for each function.
>  - Add additional check to reduce the spin lock.
>  - Up the priority of the tx to avoid interrupted by rx.
>  - Support rx checksum, large send, and IPv6 hw checksum.

Series applied, thanks.

Note that if you ever add ->ndo_poll_controller support to this driver,
you will have to revert your spin_lock_irq{save,restore}() changes to
your ->ndo_start_xmit.

Because the transmit function can indeed be invoked from hard IRQ
context once you support netpoll.

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

* Re: [PATCH net-next v2 10/13] r8152: support IPv6
@ 2014-03-09 19:47       ` Ben Hutchings
  0 siblings, 0 replies; 91+ messages in thread
From: Ben Hutchings @ 2014-03-09 19:47 UTC (permalink / raw)
  To: Hayes Wang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

[-- Attachment #1: Type: text/plain, Size: 1156 bytes --]

On Wed, 2014-03-05 at 14:49 +0800, Hayes Wang wrote:
> Support hw IPv6 checksum for TCP and UDP packets.
> 
> Note that the hw has the limitation of the range of the transport
> offset. Besides, the TCP Pseudo Header of the IPv6 TSO of the hw
> bases on the Microsoft document which excludes the packet length.
> 
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
> ---
>  drivers/net/usb/r8152.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 104 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index 8f6d0f8..8e208f30 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
[...]
> +static int msdn_giant_send_check(struct sk_buff *skb)
> +{
> +	const struct ipv6hdr *ipv6h;
> +	struct tcphdr *th;
> +
> +	ipv6h = ipv6_hdr(skb);
> +	th = tcp_hdr(skb);
> +
> +	th->check = 0;
> +	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
[...]

I think you need to call skb_cow_head() before editing the header here.

Ben.

-- 
Ben Hutchings
I say we take off; nuke the site from orbit.  It's the only way to be sure.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]

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

* Re: [PATCH net-next v2 10/13] r8152: support IPv6
@ 2014-03-09 19:47       ` Ben Hutchings
  0 siblings, 0 replies; 91+ messages in thread
From: Ben Hutchings @ 2014-03-09 19:47 UTC (permalink / raw)
  To: Hayes Wang
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA

[-- Attachment #1: Type: text/plain, Size: 1184 bytes --]

On Wed, 2014-03-05 at 14:49 +0800, Hayes Wang wrote:
> Support hw IPv6 checksum for TCP and UDP packets.
> 
> Note that the hw has the limitation of the range of the transport
> offset. Besides, the TCP Pseudo Header of the IPv6 TSO of the hw
> bases on the Microsoft document which excludes the packet length.
> 
> Signed-off-by: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/net/usb/r8152.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 104 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index 8f6d0f8..8e208f30 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
[...]
> +static int msdn_giant_send_check(struct sk_buff *skb)
> +{
> +	const struct ipv6hdr *ipv6h;
> +	struct tcphdr *th;
> +
> +	ipv6h = ipv6_hdr(skb);
> +	th = tcp_hdr(skb);
> +
> +	th->check = 0;
> +	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
[...]

I think you need to call skb_cow_head() before editing the header here.

Ben.

-- 
Ben Hutchings
I say we take off; nuke the site from orbit.  It's the only way to be sure.

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 811 bytes --]

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

* Re: [PATCH net-next v2 10/13] r8152: support IPv6
@ 2014-03-09 22:56         ` David Miller
  0 siblings, 0 replies; 91+ messages in thread
From: David Miller @ 2014-03-09 22:56 UTC (permalink / raw)
  To: ben; +Cc: hayeswang, netdev, nic_swsd, linux-kernel, linux-usb

From: Ben Hutchings <ben@decadent.org.uk>
Date: Sun, 09 Mar 2014 19:47:55 +0000

> On Wed, 2014-03-05 at 14:49 +0800, Hayes Wang wrote:
>> Support hw IPv6 checksum for TCP and UDP packets.
>> 
>> Note that the hw has the limitation of the range of the transport
>> offset. Besides, the TCP Pseudo Header of the IPv6 TSO of the hw
>> bases on the Microsoft document which excludes the packet length.
>> 
>> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
>> ---
>>  drivers/net/usb/r8152.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++--
>>  1 file changed, 104 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
>> index 8f6d0f8..8e208f30 100644
>> --- a/drivers/net/usb/r8152.c
>> +++ b/drivers/net/usb/r8152.c
> [...]
>> +static int msdn_giant_send_check(struct sk_buff *skb)
>> +{
>> +	const struct ipv6hdr *ipv6h;
>> +	struct tcphdr *th;
>> +
>> +	ipv6h = ipv6_hdr(skb);
>> +	th = tcp_hdr(skb);
>> +
>> +	th->check = 0;
>> +	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
> [...]
> 
> I think you need to call skb_cow_head() before editing the header here.

This made me notice that several drivers open-code this:

		if (skb_header_cloned(skb) &&
		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
			goto drop;

If someone is looking for a quick cleanup, transforming these
to use skb_cow_head() would be nice.  That way other driver
authors will be less likely to copy the expanded code.

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

* Re: [PATCH net-next v2 10/13] r8152: support IPv6
@ 2014-03-09 22:56         ` David Miller
  0 siblings, 0 replies; 91+ messages in thread
From: David Miller @ 2014-03-09 22:56 UTC (permalink / raw)
  To: ben-/+tVBieCtBitmTQ+vhA3Yw
  Cc: hayeswang-Rasf1IRRPZFBDgjK7y7TUQ, netdev-u79uwXL29TY76Z2rM5mHXA,
	nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA

From: Ben Hutchings <ben-/+tVBieCtBitmTQ+vhA3Yw@public.gmane.org>
Date: Sun, 09 Mar 2014 19:47:55 +0000

> On Wed, 2014-03-05 at 14:49 +0800, Hayes Wang wrote:
>> Support hw IPv6 checksum for TCP and UDP packets.
>> 
>> Note that the hw has the limitation of the range of the transport
>> offset. Besides, the TCP Pseudo Header of the IPv6 TSO of the hw
>> bases on the Microsoft document which excludes the packet length.
>> 
>> Signed-off-by: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
>> ---
>>  drivers/net/usb/r8152.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++--
>>  1 file changed, 104 insertions(+), 3 deletions(-)
>> 
>> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
>> index 8f6d0f8..8e208f30 100644
>> --- a/drivers/net/usb/r8152.c
>> +++ b/drivers/net/usb/r8152.c
> [...]
>> +static int msdn_giant_send_check(struct sk_buff *skb)
>> +{
>> +	const struct ipv6hdr *ipv6h;
>> +	struct tcphdr *th;
>> +
>> +	ipv6h = ipv6_hdr(skb);
>> +	th = tcp_hdr(skb);
>> +
>> +	th->check = 0;
>> +	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
> [...]
> 
> I think you need to call skb_cow_head() before editing the header here.

This made me notice that several drivers open-code this:

		if (skb_header_cloned(skb) &&
		    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
			goto drop;

If someone is looking for a quick cleanup, transforming these
to use skb_cow_head() would be nice.  That way other driver
authors will be less likely to copy the expanded code.
--
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] 91+ messages in thread

* RE: [PATCH net-next 0/7] r8152: tx/rx improvement
  2014-03-07 21:27   ` [PATCH net-next 0/7] r8152: tx/rx improvement David Miller
@ 2014-03-10  3:45     ` hayeswang
  0 siblings, 0 replies; 91+ messages in thread
From: hayeswang @ 2014-03-10  3:45 UTC (permalink / raw)
  To: 'David Miller'; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

 David Miller [mailto:davem@davemloft.net] 
> Sent: Saturday, March 08, 2014 5:28 AM
> To: hayeswang@realtek.com
> Cc: netdev@vger.kernel.org; nic_swsd@realtek.com; 
> linux-kernel@vger.kernel.org; linux-usb@vger.kernel.org
> Subject: Re: [PATCH net-next 0/7] r8152: tx/rx improvement
[...]
> Note that if you ever add ->ndo_poll_controller support to 
> this driver,
> you will have to revert your spin_lock_irq{save,restore}() changes to
> your ->ndo_start_xmit.
> 
> Because the transmit function can indeed be invoked from hard IRQ
> context once you support netpoll.

Thank you for your reminder. I would notice that.


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

* [PATCH net-next] r8152: add skb_cow_head
@ 2014-03-10  6:22   ` Hayes Wang
  0 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-10  6:22 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Call skb_cow_head() before editing the tx packet header. The header
would be reallocated if it is shared.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c7ef30d..faad39b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1376,6 +1376,11 @@ static int msdn_giant_send_check(struct sk_buff *skb)
 {
 	const struct ipv6hdr *ipv6h;
 	struct tcphdr *th;
+	int ret;
+
+	ret = skb_cow_head(skb, 0);
+	if (ret)
+		goto out1;
 
 	ipv6h = ipv6_hdr(skb);
 	th = tcp_hdr(skb);
@@ -1383,7 +1388,8 @@ static int msdn_giant_send_check(struct sk_buff *skb)
 	th->check = 0;
 	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
 
-	return 0;
+out1:
+	return ret;
 }
 
 static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
@@ -1412,8 +1418,11 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 			break;
 
 		case htons(ETH_P_IPV6):
+			if (msdn_giant_send_check(skb)) {
+				ret = TX_CSUM_TSO;
+				goto unavailable;
+			}
 			opts1 |= GTSENDV6;
-			msdn_giant_send_check(skb);
 			break;
 
 		default:
-- 
1.8.4.2


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

* [PATCH net-next] r8152: add skb_cow_head
@ 2014-03-10  6:22   ` Hayes Wang
  0 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-10  6:22 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, Hayes Wang

Call skb_cow_head() before editing the tx packet header. The header
would be reallocated if it is shared.

Signed-off-by: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/usb/r8152.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c7ef30d..faad39b 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1376,6 +1376,11 @@ static int msdn_giant_send_check(struct sk_buff *skb)
 {
 	const struct ipv6hdr *ipv6h;
 	struct tcphdr *th;
+	int ret;
+
+	ret = skb_cow_head(skb, 0);
+	if (ret)
+		goto out1;
 
 	ipv6h = ipv6_hdr(skb);
 	th = tcp_hdr(skb);
@@ -1383,7 +1388,8 @@ static int msdn_giant_send_check(struct sk_buff *skb)
 	th->check = 0;
 	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
 
-	return 0;
+out1:
+	return ret;
 }
 
 static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
@@ -1412,8 +1418,11 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 			break;
 
 		case htons(ETH_P_IPV6):
+			if (msdn_giant_send_check(skb)) {
+				ret = TX_CSUM_TSO;
+				goto unavailable;
+			}
 			opts1 |= GTSENDV6;
-			msdn_giant_send_check(skb);
 			break;
 
 		default:
-- 
1.8.4.2

--
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 related	[flat|nested] 91+ messages in thread

* Re: [PATCH net-next] r8152: add skb_cow_head
  2014-03-10  6:22   ` Hayes Wang
  (?)
@ 2014-03-10 20:31   ` David Miller
  -1 siblings, 0 replies; 91+ messages in thread
From: David Miller @ 2014-03-10 20:31 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: Hayes Wang <hayeswang@realtek.com>
Date: Mon, 10 Mar 2014 14:22:31 +0800

> Call skb_cow_head() before editing the tx packet header. The header
> would be reallocated if it is shared.
> 
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
> ---
>  drivers/net/usb/r8152.c | 13 +++++++++++--
>  1 file changed, 11 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index c7ef30d..faad39b 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
> @@ -1376,6 +1376,11 @@ static int msdn_giant_send_check(struct sk_buff *skb)
>  {
>  	const struct ipv6hdr *ipv6h;
>  	struct tcphdr *th;
> +	int ret;
> +
> +	ret = skb_cow_head(skb, 0);
> +	if (ret)
> +		goto out1;
>  
>  	ipv6h = ipv6_hdr(skb);
>  	th = tcp_hdr(skb);
> @@ -1383,7 +1388,8 @@ static int msdn_giant_send_check(struct sk_buff *skb)
>  	th->check = 0;
>  	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
>  
> -	return 0;
> +out1:
> +	return ret;
>  }
>  
>  static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,

Please just return directly instead of "goto out1".  There are no other
operations or pieces of state to undo if you fail at the beginning of
the function, and the label furthermore will have only one user, so
it seems completely unnecessary.  A simple "return ret" will work just
fine.

Thanks.

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

* [PATCH net-next v2] r8152: add skb_cow_head
@ 2014-03-11  2:20   ` Hayes Wang
  0 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-11  2:20 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb, Hayes Wang

Call skb_cow_head() before editing the tx packet header. The header
would be reallocated if it is shared.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c7ef30d..a90a7eb9 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1376,6 +1376,11 @@ static int msdn_giant_send_check(struct sk_buff *skb)
 {
 	const struct ipv6hdr *ipv6h;
 	struct tcphdr *th;
+	int ret;
+
+	ret = skb_cow_head(skb, 0);
+	if (ret)
+		return ret;
 
 	ipv6h = ipv6_hdr(skb);
 	th = tcp_hdr(skb);
@@ -1383,7 +1388,7 @@ static int msdn_giant_send_check(struct sk_buff *skb)
 	th->check = 0;
 	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
 
-	return 0;
+	return ret;
 }
 
 static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
@@ -1412,8 +1417,11 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 			break;
 
 		case htons(ETH_P_IPV6):
+			if (msdn_giant_send_check(skb)) {
+				ret = TX_CSUM_TSO;
+				goto unavailable;
+			}
 			opts1 |= GTSENDV6;
-			msdn_giant_send_check(skb);
 			break;
 
 		default:
-- 
1.8.4.2


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

* [PATCH net-next v2] r8152: add skb_cow_head
@ 2014-03-11  2:20   ` Hayes Wang
  0 siblings, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-11  2:20 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA
  Cc: nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA, Hayes Wang

Call skb_cow_head() before editing the tx packet header. The header
would be reallocated if it is shared.

Signed-off-by: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
---
 drivers/net/usb/r8152.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index c7ef30d..a90a7eb9 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1376,6 +1376,11 @@ static int msdn_giant_send_check(struct sk_buff *skb)
 {
 	const struct ipv6hdr *ipv6h;
 	struct tcphdr *th;
+	int ret;
+
+	ret = skb_cow_head(skb, 0);
+	if (ret)
+		return ret;
 
 	ipv6h = ipv6_hdr(skb);
 	th = tcp_hdr(skb);
@@ -1383,7 +1388,7 @@ static int msdn_giant_send_check(struct sk_buff *skb)
 	th->check = 0;
 	th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
 
-	return 0;
+	return ret;
 }
 
 static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
@@ -1412,8 +1417,11 @@ static int r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc,
 			break;
 
 		case htons(ETH_P_IPV6):
+			if (msdn_giant_send_check(skb)) {
+				ret = TX_CSUM_TSO;
+				goto unavailable;
+			}
 			opts1 |= GTSENDV6;
-			msdn_giant_send_check(skb);
 			break;
 
 		default:
-- 
1.8.4.2

--
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 related	[flat|nested] 91+ messages in thread

* Re: [PATCH net-next v2] r8152: add skb_cow_head
  2014-03-11  2:20   ` Hayes Wang
  (?)
@ 2014-03-11  2:25   ` David Miller
  -1 siblings, 0 replies; 91+ messages in thread
From: David Miller @ 2014-03-11  2:25 UTC (permalink / raw)
  To: hayeswang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

From: Hayes Wang <hayeswang@realtek.com>
Date: Tue, 11 Mar 2014 10:20:32 +0800

> Call skb_cow_head() before editing the tx packet header. The header
> would be reallocated if it is shared.
> 
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>

Applied, thanks.

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

* [PATCH net-next 0/2] parameter modification
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (16 preceding siblings ...)
  2014-03-11  2:20   ` Hayes Wang
@ 2014-03-12 12:39 ` Hayes Wang
  2014-03-12 12:39   ` [PATCH net-next 1/2] r8152: add CONFIG_RTL8152_EARLY_AGG_SUPER Hayes Wang
  2014-03-12 12:39   ` [PATCH net-next 2/2] r8152: reduce the numbers of the bulks Hayes Wang
  2014-03-13  3:34 ` [PATCH net-next v2 0/2] parameter modification Hayes Wang
  2014-03-13 12:05 ` [PATCH net-next v3 0/2] parameter modification Hayes Wang
  19 siblings, 2 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-12 12:39 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb

Add opportunity to change the default setting and reduce the tx/rx
buffers.

Hayes Wang (2):
  r8152: add CONFIG_RTL8152_EARLY_AGG_SUPER
  r8152: reduce the numbers of the bulks

 drivers/net/usb/Kconfig | 11 +++++++++++
 drivers/net/usb/r8152.c |  8 ++++----
 2 files changed, 15 insertions(+), 4 deletions(-)

-- 
1.8.4.2


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

* [PATCH net-next 1/2] r8152: add CONFIG_RTL8152_EARLY_AGG_SUPER
  2014-03-12 12:39 ` [PATCH net-next 0/2] parameter modification Hayes Wang
@ 2014-03-12 12:39   ` Hayes Wang
  2014-03-12 13:40     ` Bjørn Mork
  2014-03-12 12:39   ` [PATCH net-next 2/2] r8152: reduce the numbers of the bulks Hayes Wang
  1 sibling, 1 reply; 91+ messages in thread
From: Hayes Wang @ 2014-03-12 12:39 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb

For slow CPU, the frequent bulk transfer would cause poor throughput.
One solution is to increase the timeout of the aggregation. It let
the hw could complete the bulk transfer later and fill more packets
into the buffer. Besides, it could reduce the frequency of the bulk
transfer efficiently and improve the performance.

However, the optimization value of the timeout depends on the
capability of the hardware, especially the CPU. For example, according
to the experiment, the value 0x0e835000 is better than the default
value for the chromebook with the ARM CPU.

Now add CONFIG_RTL8152_EARLY_AGG_SUPER to let someone could choose
desired timeout value if he wants to get the best performance.

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

diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 7e7269f..be6e21d 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -102,6 +102,17 @@ config USB_RTL8152
 	  To compile this driver as a module, choose M here: the
 	  module will be called r8152.
 
+	menu "Aggregation Settings"
+		depends on USB_RTL8152
+
+	config RTL8152_EARLY_AGG_SUPER
+		hex "rx early agg parameter for super speed"
+		default 0x0e832981
+		help
+		  This is the rx early agg parameter for USB super speed.
+
+	endmenu
+
 config USB_USBNET
 	tristate "Multi-purpose USB Networking Framework"
 	select MII
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index aa1d5b2..0c43b28 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -316,7 +316,7 @@
 #define PCUT_STATUS		0x0001
 
 /* USB_RX_EARLY_AGG */
-#define EARLY_AGG_SUPPER	0x0e832981
+/* CONFIG_RTL8152_EARLY_AGG_SUPER default is 0x0e832981 */
 #define EARLY_AGG_HIGH		0x0e837a12
 #define EARLY_AGG_SLOW		0x0e83ffff
 
@@ -1978,7 +1978,7 @@ static void r8153_set_rx_agg(struct r8152 *tp)
 			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
 					RX_THR_SUPPER);
 			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
-					EARLY_AGG_SUPPER);
+					CONFIG_RTL8152_EARLY_AGG_SUPER);
 		} else {
 			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
 					RX_THR_HIGH);
-- 
1.8.4.2


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

* [PATCH net-next 2/2] r8152: reduce the numbers of the bulks
  2014-03-12 12:39 ` [PATCH net-next 0/2] parameter modification Hayes Wang
  2014-03-12 12:39   ` [PATCH net-next 1/2] r8152: add CONFIG_RTL8152_EARLY_AGG_SUPER Hayes Wang
@ 2014-03-12 12:39   ` Hayes Wang
  1 sibling, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-12 12:39 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb

It is not necessary to have many transfer buffers. Reduce the number
from 10 to 4.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 0c43b28..9ff7501 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -419,8 +419,8 @@ enum rtl_register_content {
 	FULL_DUP	= 0x01,
 };
 
-#define RTL8152_MAX_TX		10
-#define RTL8152_MAX_RX		10
+#define RTL8152_MAX_TX		4
+#define RTL8152_MAX_RX		4
 #define INTBUFSIZE		2
 #define CRC_SIZE		4
 #define TX_ALIGN		4
-- 
1.8.4.2


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

* Re: [PATCH net-next 1/2] r8152: add CONFIG_RTL8152_EARLY_AGG_SUPER
  2014-03-12 12:39   ` [PATCH net-next 1/2] r8152: add CONFIG_RTL8152_EARLY_AGG_SUPER Hayes Wang
@ 2014-03-12 13:40     ` Bjørn Mork
  0 siblings, 0 replies; 91+ messages in thread
From: Bjørn Mork @ 2014-03-12 13:40 UTC (permalink / raw)
  To: Hayes Wang; +Cc: netdev, nic_swsd, linux-kernel, linux-usb

Hayes Wang <hayeswang@realtek.com> writes:

> +	config RTL8152_EARLY_AGG_SUPER
> +		hex "rx early agg parameter for super speed"
> +		default 0x0e832981
> +		help
> +		  This is the rx early agg parameter for USB super speed.
> +
> +	endmenu

How do I as an end user know how to adjust this magic(?) value?  Having
a config setting like this without further documentation seems
completely pointless. Anyone with enough knowledge about the driver and
devices will be perfectly capable of editing the driver source anyway.



Bjørn

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

* [PATCH net-next v2 0/2] parameter modification
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (17 preceding siblings ...)
  2014-03-12 12:39 ` [PATCH net-next 0/2] parameter modification Hayes Wang
@ 2014-03-13  3:34 ` Hayes Wang
  2014-03-13  3:34   ` [PATCH net-next v2 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER Hayes Wang
  2014-03-13  3:34   ` [PATCH net-next v2 2/2] r8152: reduce the numbers of the bulks Hayes Wang
  2014-03-13 12:05 ` [PATCH net-next v3 0/2] parameter modification Hayes Wang
  19 siblings, 2 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-13  3:34 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb

Add opportunity to change the default setting and reduce the tx/rx
buffers.

v2: modify the patch #1 to let the value readable.

Hayes Wang (2):
  r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER
  r8152: reduce the numbers of the bulks

 drivers/net/usb/Kconfig | 11 +++++++++++
 drivers/net/usb/r8152.c | 10 ++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

-- 
1.8.4.2


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

* [PATCH net-next v2 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-13  3:34 ` [PATCH net-next v2 0/2] parameter modification Hayes Wang
@ 2014-03-13  3:34   ` Hayes Wang
  2014-03-13  9:28     ` David Laight
  2014-03-13  3:34   ` [PATCH net-next v2 2/2] r8152: reduce the numbers of the bulks Hayes Wang
  1 sibling, 1 reply; 91+ messages in thread
From: Hayes Wang @ 2014-03-13  3:34 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb

For slow CPU, the frequent bulk transfer would cause poor throughput.
One solution is to increase the timeout of the aggregation. It let
the hw could complete the bulk transfer later and fill more packets
into the buffer. Besides, it could reduce the frequency of the bulk
transfer efficiently and improve the performance.

However, the optimization value of the timeout depends on the
capability of the hardware, especially the CPU. For example, according
to the experiment, the timeout 164 us is better than the default
value for the chromebook with the ARM CPU.

Now add RTL8152_EARLY_AGG_TIMEOUT_SUPER to let someone could choose
desired timeout value if he wants to get the best performance.

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

diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 7e7269f..a8639b8 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -102,6 +102,18 @@ config USB_RTL8152
 	  To compile this driver as a module, choose M here: the
 	  module will be called r8152.
 
+	menu "Aggregation Settings"
+		depends on USB_RTL8152
+
+	config RTL8152_EARLY_AGG_TIMEOUT_SUPER
+		int "rx early agg timeout for super speed (unit: us)"
+		default 85
+		help
+		  This is the rx early agg timeout for USB super speed.
+		  The vaild value is 1 ~ 525 us.
+
+	endmenu
+
 config USB_USBNET
 	tristate "Multi-purpose USB Networking Framework"
 	select MII
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index aa1d5b2..293b4d8 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -316,7 +316,10 @@
 #define PCUT_STATUS		0x0001
 
 /* USB_RX_EARLY_AGG */
-#define EARLY_AGG_SUPPER	0x0e832981
+#define EARLY_AGG_SUPER	((((rx_buf_sz - 1522) / 4) << 16) | \
+	(u32)(CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER <= 0 ? 0x2981 : \
+	((CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER * 125) < 0xffff ? \
+	CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER * 125 : 0xffff)))
 #define EARLY_AGG_HIGH		0x0e837a12
 #define EARLY_AGG_SLOW		0x0e83ffff
 
@@ -1978,7 +1981,7 @@ static void r8153_set_rx_agg(struct r8152 *tp)
 			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
 					RX_THR_SUPPER);
 			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
-					EARLY_AGG_SUPPER);
+					EARLY_AGG_SUPER);
 		} else {
 			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
 					RX_THR_HIGH);
-- 
1.8.4.2


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

* [PATCH net-next v2 2/2] r8152: reduce the numbers of the bulks
  2014-03-13  3:34 ` [PATCH net-next v2 0/2] parameter modification Hayes Wang
  2014-03-13  3:34   ` [PATCH net-next v2 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER Hayes Wang
@ 2014-03-13  3:34   ` Hayes Wang
  1 sibling, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-13  3:34 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb

It is not necessary to have many transfer buffers. Reduce the number
from 10 to 4.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 293b4d8..1826fcf 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -422,8 +422,8 @@ enum rtl_register_content {
 	FULL_DUP	= 0x01,
 };
 
-#define RTL8152_MAX_TX		10
-#define RTL8152_MAX_RX		10
+#define RTL8152_MAX_TX		4
+#define RTL8152_MAX_RX		4
 #define INTBUFSIZE		2
 #define CRC_SIZE		4
 #define TX_ALIGN		4
-- 
1.8.4.2


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

* RE: [PATCH net-next v2 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-13  3:34   ` [PATCH net-next v2 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER Hayes Wang
@ 2014-03-13  9:28     ` David Laight
  0 siblings, 0 replies; 91+ messages in thread
From: David Laight @ 2014-03-13  9:28 UTC (permalink / raw)
  To: 'Hayes Wang', netdev; +Cc: nic_swsd, linux-kernel, linux-usb

From: Hayes Wang
> For slow CPU, the frequent bulk transfer would cause poor throughput.
> One solution is to increase the timeout of the aggregation. It let
> the hw could complete the bulk transfer later and fill more packets
> into the buffer. Besides, it could reduce the frequency of the bulk
> transfer efficiently and improve the performance.
> 
> However, the optimization value of the timeout depends on the
> capability of the hardware, especially the CPU. For example, according
> to the experiment, the timeout 164 us is better than the default
> value for the chromebook with the ARM CPU.

The best value probably depends on the workload as well as the
cpu speed.
I wonder if a sane algorithm for dynamically setting this value exists.
It really needs a CBU (crystal ball unit), but working ones are
difficult to come by.

Passing the buck to the 'user' is rather a cop-out (but we all do it).

> Now add RTL8152_EARLY_AGG_TIMEOUT_SUPER to let someone could choose
> desired timeout value if he wants to get the best performance.
...
>  /* USB_RX_EARLY_AGG */
> -#define EARLY_AGG_SUPPER	0x0e832981
> +#define EARLY_AGG_SUPER	((((rx_buf_sz - 1522) / 4) << 16) | \
> +	(u32)(CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER <= 0 ? 0x2981 : \
> +	((CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER * 125) < 0xffff ? \
> +	CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER * 125 : 0xffff)))

The 0x2981 would be better written as (85 * 125).
But maybe replace with something like:
	min((CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER <= 0 ? 85 :
		CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER) * 125u, 0xffffu)

	David




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

* [PATCH net-next v3 0/2] parameter modification
  2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
                   ` (18 preceding siblings ...)
  2014-03-13  3:34 ` [PATCH net-next v2 0/2] parameter modification Hayes Wang
@ 2014-03-13 12:05 ` Hayes Wang
  2014-03-13 12:05   ` [PATCH net-next v3 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER Hayes Wang
  2014-03-13 12:05   ` [PATCH net-next v3 2/2] r8152: reduce the numbers of the bulks Hayes Wang
  19 siblings, 2 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-13 12:05 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb

Add opportunity to change the default setting and reduce the tx/rx
buffers.

v2: modify the patch #1 to let the value readable.

v3: modify the definition of the EARLY_AGG_SUPER for patch #1.

Hayes Wang (2):
  r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER
  r8152: reduce the numbers of the bulks

 drivers/net/usb/Kconfig | 11 +++++++++++
 drivers/net/usb/r8152.c | 10 ++++++----
 2 files changed, 17 insertions(+), 4 deletions(-)

-- 
1.8.4.2


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

* [PATCH net-next v3 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-13 12:05 ` [PATCH net-next v3 0/2] parameter modification Hayes Wang
@ 2014-03-13 12:05   ` Hayes Wang
  2014-03-13 13:12     ` David Laight
  2014-03-13 12:05   ` [PATCH net-next v3 2/2] r8152: reduce the numbers of the bulks Hayes Wang
  1 sibling, 1 reply; 91+ messages in thread
From: Hayes Wang @ 2014-03-13 12:05 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb

For slow CPU, the frequent bulk transfer would cause poor throughput.
One solution is to increase the timeout of the aggregation. It let
the hw could complete the bulk transfer later and fill more packets
into the buffer. Besides, it could reduce the frequency of the bulk
transfer efficiently and improve the performance.

However, the optimization value of the timeout depends on the
capability of the hardware, especially the CPU. For example, according
to the experiment, the timeout 164 us is better than the default
value for the chromebook with the ARM CPU.

Now add RTL8152_EARLY_AGG_TIMEOUT_SUPER to let someone could choose
desired timeout value if he wants to get the best performance.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
 drivers/net/usb/Kconfig | 12 ++++++++++++
 drivers/net/usb/r8152.c |  6 ++++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index 7e7269f..a8639b8 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -102,6 +102,18 @@ config USB_RTL8152
 	  To compile this driver as a module, choose M here: the
 	  module will be called r8152.
 
+	menu "Aggregation Settings"
+		depends on USB_RTL8152
+
+	config RTL8152_EARLY_AGG_TIMEOUT_SUPER
+		int "rx early agg timeout for super speed (unit: us)"
+		default 85
+		help
+		  This is the rx early agg timeout for USB super speed.
+		  The vaild value is 1 ~ 525 us.
+
+	endmenu
+
 config USB_USBNET
 	tristate "Multi-purpose USB Networking Framework"
 	select MII
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index aa1d5b2..756c0a6 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -316,7 +316,9 @@
 #define PCUT_STATUS		0x0001
 
 /* USB_RX_EARLY_AGG */
-#define EARLY_AGG_SUPPER	0x0e832981
+#define EARLY_AGG_SUPER	((((rx_buf_sz - 1522) / 4) << 16) | \
+	(u32)(CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER <= 0 ? 85 * 125 : \
+	min(CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER * 125, 0xffff)))
 #define EARLY_AGG_HIGH		0x0e837a12
 #define EARLY_AGG_SLOW		0x0e83ffff
 
@@ -1978,7 +1980,7 @@ static void r8153_set_rx_agg(struct r8152 *tp)
 			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
 					RX_THR_SUPPER);
 			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
-					EARLY_AGG_SUPPER);
+					EARLY_AGG_SUPER);
 		} else {
 			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
 					RX_THR_HIGH);
-- 
1.8.4.2


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

* [PATCH net-next v3 2/2] r8152: reduce the numbers of the bulks
  2014-03-13 12:05 ` [PATCH net-next v3 0/2] parameter modification Hayes Wang
  2014-03-13 12:05   ` [PATCH net-next v3 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER Hayes Wang
@ 2014-03-13 12:05   ` Hayes Wang
  1 sibling, 0 replies; 91+ messages in thread
From: Hayes Wang @ 2014-03-13 12:05 UTC (permalink / raw)
  To: netdev; +Cc: nic_swsd, linux-kernel, linux-usb

It is not necessary to have many transfer buffers. Reduce the number
from 10 to 4.

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

diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 756c0a6..b6bde59 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -421,8 +421,8 @@ enum rtl_register_content {
 	FULL_DUP	= 0x01,
 };
 
-#define RTL8152_MAX_TX		10
-#define RTL8152_MAX_RX		10
+#define RTL8152_MAX_TX		4
+#define RTL8152_MAX_RX		4
 #define INTBUFSIZE		2
 #define CRC_SIZE		4
 #define TX_ALIGN		4
-- 
1.8.4.2


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

* RE: [PATCH net-next v3 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-13 12:05   ` [PATCH net-next v3 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER Hayes Wang
@ 2014-03-13 13:12     ` David Laight
  2014-03-13 17:22       ` David Miller
  0 siblings, 1 reply; 91+ messages in thread
From: David Laight @ 2014-03-13 13:12 UTC (permalink / raw)
  To: 'Hayes Wang', netdev; +Cc: nic_swsd, linux-kernel, linux-usb

From: Hayes Wang
...

I should have spotted this before.

>  /* USB_RX_EARLY_AGG */
> -#define EARLY_AGG_SUPPER	0x0e832981
> +#define EARLY_AGG_SUPER	((((rx_buf_sz - 1522) / 4) << 16) | \
> +	(u32)(CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER <= 0 ? 85 * 125 : \
> +	min(CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER * 125, 0xffff)))
>  #define EARLY_AGG_HIGH		0x0e837a12
>  #define EARLY_AGG_SLOW		0x0e83ffff
> 
> @@ -1978,7 +1980,7 @@ static void r8153_set_rx_agg(struct r8152 *tp)
>  			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
>  					RX_THR_SUPPER);
>  			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
> -					EARLY_AGG_SUPPER);
> +					EARLY_AGG_SUPER);
>  		} else {
>  			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
>  					RX_THR_HIGH);

It looks as though rx_buf_sz should be a parameter to EARLY_AGG_SUPER.

	David




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

* Re: [PATCH net-next v3 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-13 13:12     ` David Laight
@ 2014-03-13 17:22       ` David Miller
  2014-03-14  2:37         ` [PATCH net-next v3 1/2] r8152: addRTL8152_EARLY_AGG_TIMEOUT_SUPER hayeswang
  0 siblings, 1 reply; 91+ messages in thread
From: David Miller @ 2014-03-13 17:22 UTC (permalink / raw)
  To: David.Laight; +Cc: hayeswang, netdev, nic_swsd, linux-kernel, linux-usb

From: David Laight <David.Laight@ACULAB.COM>
Date: Thu, 13 Mar 2014 13:12:35 +0000

> From: Hayes Wang
> ...
> 
> I should have spotted this before.
> 
>>  /* USB_RX_EARLY_AGG */
>> -#define EARLY_AGG_SUPPER	0x0e832981
>> +#define EARLY_AGG_SUPER	((((rx_buf_sz - 1522) / 4) << 16) | \
>> +	(u32)(CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER <= 0 ? 85 * 125 : \
>> +	min(CONFIG_RTL8152_EARLY_AGG_TIMEOUT_SUPER * 125, 0xffff)))
>>  #define EARLY_AGG_HIGH		0x0e837a12
>>  #define EARLY_AGG_SLOW		0x0e83ffff
>> 
>> @@ -1978,7 +1980,7 @@ static void r8153_set_rx_agg(struct r8152 *tp)
>>  			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
>>  					RX_THR_SUPPER);
>>  			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_EARLY_AGG,
>> -					EARLY_AGG_SUPPER);
>> +					EARLY_AGG_SUPER);
>>  		} else {
>>  			ocp_write_dword(tp, MCU_TYPE_USB, USB_RX_BUF_TH,
>>  					RX_THR_HIGH);
> 
> It looks as though rx_buf_sz should be a parameter to EARLY_AGG_SUPER.

And I fundamentally disagree with this being a Kconfig parameter.

Make it run-time calculated _or_ settable via ethtool.

Thanks.

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

* RE: [PATCH net-next v3 1/2] r8152: addRTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-13 17:22       ` David Miller
@ 2014-03-14  2:37         ` hayeswang
  2014-03-14  4:07           ` David Miller
  0 siblings, 1 reply; 91+ messages in thread
From: hayeswang @ 2014-03-14  2:37 UTC (permalink / raw)
  To: 'David Miller', David.Laight
  Cc: netdev, nic_swsd, linux-kernel, linux-usb

 From: David Miller [mailto:davem@davemloft.net] 
 Sent: Friday, March 14, 2014 1:22 AM
[...]
> And I fundamentally disagree with this being a Kconfig parameter.
> 
> Make it run-time calculated _or_ settable via ethtool.

Excuse me. How should I make it run-time calculated without a
Kconfig parameter? Should I use module_param? 

Best Regards,
Hayes


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

* Re: [PATCH net-next v3 1/2] r8152: addRTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-14  2:37         ` [PATCH net-next v3 1/2] r8152: addRTL8152_EARLY_AGG_TIMEOUT_SUPER hayeswang
@ 2014-03-14  4:07           ` David Miller
  2014-03-14  7:24               ` hayeswang
  0 siblings, 1 reply; 91+ messages in thread
From: David Miller @ 2014-03-14  4:07 UTC (permalink / raw)
  To: hayeswang; +Cc: David.Laight, netdev, nic_swsd, linux-kernel, linux-usb

From: hayeswang <hayeswang@realtek.com>
Date: Fri, 14 Mar 2014 10:37:21 +0800

>  From: David Miller [mailto:davem@davemloft.net] 
>  Sent: Friday, March 14, 2014 1:22 AM
> [...]
>> And I fundamentally disagree with this being a Kconfig parameter.
>> 
>> Make it run-time calculated _or_ settable via ethtool.
> 
> Excuse me. How should I make it run-time calculated without a
> Kconfig parameter? Should I use module_param? 

You run-time determine the setting based upon the negotiated link
speed and traffic patterns.

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

* RE: [PATCH net-next v3 1/2] r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER
@ 2014-03-14  7:24               ` hayeswang
  0 siblings, 0 replies; 91+ messages in thread
From: hayeswang @ 2014-03-14  7:24 UTC (permalink / raw)
  To: 'David Miller'
  Cc: David.Laight, netdev, nic_swsd, linux-kernel, linux-usb

 From: David Miller [mailto:davem@davemloft.net] 
 Sent: Friday, March 14, 2014 12:08 PM
[...]
> >> And I fundamentally disagree with this being a Kconfig parameter.
> >> 
> >> Make it run-time calculated _or_ settable via ethtool.
> > 
> > Excuse me. How should I make it run-time calculated without a
> > Kconfig parameter? Should I use module_param? 
> 
> You run-time determine the setting based upon the negotiated link
> speed and traffic patterns.

It is difficult to design a algorithm which considers the hardware
of the platform, network traffic, and even the USB behavior to
dynamically modify the setting. I don't think I have the capability
to do it.

Besides, I don't wish to modify the setting by ethtool when re-loading
the driver or rebooting every time.

Excuse me. Why is it not accepted for being a Kconfig parameter.
It let the manufactuers of some platforms, especially the embedded
system, could tune their performance. Should I give up this patch?


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

* RE: [PATCH net-next v3 1/2] r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER
@ 2014-03-14  7:24               ` hayeswang
  0 siblings, 0 replies; 91+ messages in thread
From: hayeswang @ 2014-03-14  7:24 UTC (permalink / raw)
  To: 'David Miller'
  Cc: David.Laight-ZS65k/vG3HxXrIkS9f7CXA,
	netdev-u79uwXL29TY76Z2rM5mHXA, nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-usb-u79uwXL29TY76Z2rM5mHXA

 From: David Miller [mailto:davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org] 
 Sent: Friday, March 14, 2014 12:08 PM
[...]
> >> And I fundamentally disagree with this being a Kconfig parameter.
> >> 
> >> Make it run-time calculated _or_ settable via ethtool.
> > 
> > Excuse me. How should I make it run-time calculated without a
> > Kconfig parameter? Should I use module_param? 
> 
> You run-time determine the setting based upon the negotiated link
> speed and traffic patterns.

It is difficult to design a algorithm which considers the hardware
of the platform, network traffic, and even the USB behavior to
dynamically modify the setting. I don't think I have the capability
to do it.

Besides, I don't wish to modify the setting by ethtool when re-loading
the driver or rebooting every time.

Excuse me. Why is it not accepted for being a Kconfig parameter.
It let the manufactuers of some platforms, especially the embedded
system, could tune their performance. Should I give up this patch?

--
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] 91+ messages in thread

* Re: [PATCH net-next v3 1/2] r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-14  7:24               ` hayeswang
  (?)
@ 2014-03-14 18:43               ` David Miller
  2014-03-17  6:01                 ` [PATCH net-next v3 1/2]r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER hayeswang
  -1 siblings, 1 reply; 91+ messages in thread
From: David Miller @ 2014-03-14 18:43 UTC (permalink / raw)
  To: hayeswang; +Cc: David.Laight, netdev, nic_swsd, linux-kernel, linux-usb

From: hayeswang <hayeswang@realtek.com>
Date: Fri, 14 Mar 2014 15:24:50 +0800

> Besides, I don't wish to modify the setting by ethtool when re-loading
> the driver or rebooting every time.

You have code to reset the driver, you can do it when the user asks
for the setting to be changed via ethtool.  I do not see this as
a problem.

The ethtool change can occur while the driver is already up, you'll
just need to reset the chip and make the new configuration, this is
not a problem.

> Excuse me. Why is it not accepted for being a Kconfig parameter.
> It let the manufactuers of some platforms, especially the embedded
> system, could tune their performance. Should I give up this patch?

We want to discourage such hard-coding, not encourage it.

I think you are limiting yourself unnecessarily by refusing to
consider that there may be ways other than Kconfig to adjust this
setting.

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

* Re: [PATCH net-next v3 1/2] r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-14  7:24               ` hayeswang
  (?)
  (?)
@ 2014-03-14 23:42               ` Francois Romieu
  2014-03-17  6:03                 ` hayeswang
  -1 siblings, 1 reply; 91+ messages in thread
From: Francois Romieu @ 2014-03-14 23:42 UTC (permalink / raw)
  To: hayeswang
  Cc: 'David Miller',
	David.Laight, netdev, nic_swsd, linux-kernel, linux-usb

hayeswang <hayeswang@realtek.com> :
[...]
> Besides, I don't wish to modify the setting by ethtool when re-loading
> the driver or rebooting every time.

Why ?

The recipe is different but there isn't much setup difference between a
module param and an ethtool command that is run through udev. The latter
is more versatile though.

> Excuse me. Why is it not accepted for being a Kconfig parameter.

You have stated that the optimal value is not easy to figure.

It's thus hard to give much credit to an hardcoded solution.

-- 
Ueimor

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

* RE: [PATCH net-next v3 1/2]r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-14 18:43               ` David Miller
@ 2014-03-17  6:01                 ` hayeswang
  0 siblings, 0 replies; 91+ messages in thread
From: hayeswang @ 2014-03-17  6:01 UTC (permalink / raw)
  To: 'David Miller'
  Cc: David.Laight, netdev, nic_swsd, linux-kernel, linux-usb

 From: David Miller [mailto:davem@davemloft.net] 
> Sent: Saturday, March 15, 2014 2:43 AM
[...]
> > Besides, I don't wish to modify the setting by ethtool when re-loading
> > the driver or rebooting every time.
> 
> You have code to reset the driver, you can do it when the user asks
> for the setting to be changed via ethtool.  I do not see this as
> a problem.
> 
> The ethtool change can occur while the driver is already up, you'll
> just need to reset the chip and make the new configuration, this is
> not a problem.

Thanks for your answer. I would study how to set it by ethtool. 

Best Regards,
Hayes


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

* RE: [PATCH net-next v3 1/2] r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER
  2014-03-14 23:42               ` [PATCH net-next v3 1/2] r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER Francois Romieu
@ 2014-03-17  6:03                 ` hayeswang
  0 siblings, 0 replies; 91+ messages in thread
From: hayeswang @ 2014-03-17  6:03 UTC (permalink / raw)
  To: 'Francois Romieu'
  Cc: 'David Miller',
	David.Laight, netdev, nic_swsd, linux-kernel, linux-usb

 From: Francois Romieu [mailto:romieu@fr.zoreil.com] 
> Sent: Saturday, March 15, 2014 7:43 AM
[...]
> > Besides, I don't wish to modify the setting by ethtool when re-loading
> > the driver or rebooting every time.
> 
> Why ?
> 
> The recipe is different but there isn't much setup difference 
> between a module param and an ethtool command that is run through udev.
> The latter is more versatile though.

Thanks for your suggestion. I think I have to understand how to use them first.
 
Best Regards,
Hayes


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

* Re: [PATCH net-next 12/12] r8152: modify the tx timeout funcfion
@ 2014-03-25 20:12     ` Grant Grundler
  0 siblings, 0 replies; 91+ messages in thread
From: Grant Grundler @ 2014-03-25 20:12 UTC (permalink / raw)
  To: Hayes Wang; +Cc: netdev, nic_swsd, LKML, linux-usb

On Tue, Mar 4, 2014 at 4:01 AM, Hayes Wang <hayeswang@realtek.com> wrote:
> Reset and reinitialize the device when the tx timeout occurs.

Hayes,
I believe this patch was dropped after the series was split.
Can you please repost this patch by itself?

(and fix the "function" typo in the patch header)

>
> Signed-off-by: Hayes Wang <hayeswang@realtek.com>
> ---
>  drivers/net/usb/r8152.c | 41 +++++++++++++++++++++++++++++++----------
>  1 file changed, 31 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index e04fcbd..23e03a6 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
> @@ -1791,16 +1791,6 @@ static void rtl_drop_queued_tx(struct r8152 *tp)
>         }
>  }
>
> -static void rtl8152_tx_timeout(struct net_device *netdev)
> -{
> -       struct r8152 *tp = netdev_priv(netdev);
> -       int i;
> -
> -       netif_warn(tp, tx_err, netdev, "Tx timeout\n");
> -       for (i = 0; i < RTL8152_MAX_TX; i++)
> -               usb_unlink_urb(tp->tx_info[i].urb);
> -}
> -
>  static void rtl8152_set_rx_mode(struct net_device *netdev)
>  {
>         struct r8152 *tp = netdev_priv(netdev);
> @@ -3177,6 +3167,37 @@ out:
>         return res;
>  }
>
> +static void rtl8152_tx_timeout(struct net_device *netdev)
> +{
> +       struct r8152 *tp = netdev_priv(netdev);
> +
> +       netif_warn(tp, tx_err, netdev, "Tx timeout\n");
> +
> +       if (usb_autopm_get_interface(tp->intf) < 0)
> +               return;
> +
> +       netif_stop_queue(netdev);
> +       clear_bit(WORK_ENABLE, &tp->flags);
> +       usb_kill_urb(tp->intr_urb);
> +       cancel_delayed_work_sync(&tp->schedule);
> +       tp->rtl_ops.down(tp);
> +
> +       usb_reset_device(tp->udev);
> +
> +       tp->rtl_ops.init(tp);
> +       tp->rtl_ops.up(tp);
> +       rtl8152_set_speed(tp, AUTONEG_ENABLE,
> +                         tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
> +                         DUPLEX_FULL);
> +       tp->speed = 0;

Nit: Could rtl_ops.up() set speed since it appears to be changing the
state of the link?

rtl8152_open() uses a remarkably similar code sequence. Is there an
opportunity to refactor and  make sure this sequence is consistent?
(different patch, not this one)

cheers,
grant

> +       netif_carrier_off(netdev);
> +       netif_start_queue(netdev);
> +       set_bit(WORK_ENABLE, &tp->flags);
> +       usb_submit_urb(tp->intr_urb, GFP_KERNEL);
> +
> +       usb_autopm_put_interface(tp->intf);
> +}
> +
>  static const struct net_device_ops rtl8152_netdev_ops = {
>         .ndo_open               = rtl8152_open,
>         .ndo_stop               = rtl8152_close,
> --
> 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/
>
>

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

* Re: [PATCH net-next 12/12] r8152: modify the tx timeout funcfion
@ 2014-03-25 20:12     ` Grant Grundler
  0 siblings, 0 replies; 91+ messages in thread
From: Grant Grundler @ 2014-03-25 20:12 UTC (permalink / raw)
  To: Hayes Wang
  Cc: netdev, nic_swsd-Rasf1IRRPZFBDgjK7y7TUQ, LKML,
	linux-usb-u79uwXL29TY76Z2rM5mHXA

On Tue, Mar 4, 2014 at 4:01 AM, Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org> wrote:
> Reset and reinitialize the device when the tx timeout occurs.

Hayes,
I believe this patch was dropped after the series was split.
Can you please repost this patch by itself?

(and fix the "function" typo in the patch header)

>
> Signed-off-by: Hayes Wang <hayeswang-Rasf1IRRPZFBDgjK7y7TUQ@public.gmane.org>
> ---
>  drivers/net/usb/r8152.c | 41 +++++++++++++++++++++++++++++++----------
>  1 file changed, 31 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
> index e04fcbd..23e03a6 100644
> --- a/drivers/net/usb/r8152.c
> +++ b/drivers/net/usb/r8152.c
> @@ -1791,16 +1791,6 @@ static void rtl_drop_queued_tx(struct r8152 *tp)
>         }
>  }
>
> -static void rtl8152_tx_timeout(struct net_device *netdev)
> -{
> -       struct r8152 *tp = netdev_priv(netdev);
> -       int i;
> -
> -       netif_warn(tp, tx_err, netdev, "Tx timeout\n");
> -       for (i = 0; i < RTL8152_MAX_TX; i++)
> -               usb_unlink_urb(tp->tx_info[i].urb);
> -}
> -
>  static void rtl8152_set_rx_mode(struct net_device *netdev)
>  {
>         struct r8152 *tp = netdev_priv(netdev);
> @@ -3177,6 +3167,37 @@ out:
>         return res;
>  }
>
> +static void rtl8152_tx_timeout(struct net_device *netdev)
> +{
> +       struct r8152 *tp = netdev_priv(netdev);
> +
> +       netif_warn(tp, tx_err, netdev, "Tx timeout\n");
> +
> +       if (usb_autopm_get_interface(tp->intf) < 0)
> +               return;
> +
> +       netif_stop_queue(netdev);
> +       clear_bit(WORK_ENABLE, &tp->flags);
> +       usb_kill_urb(tp->intr_urb);
> +       cancel_delayed_work_sync(&tp->schedule);
> +       tp->rtl_ops.down(tp);
> +
> +       usb_reset_device(tp->udev);
> +
> +       tp->rtl_ops.init(tp);
> +       tp->rtl_ops.up(tp);
> +       rtl8152_set_speed(tp, AUTONEG_ENABLE,
> +                         tp->mii.supports_gmii ? SPEED_1000 : SPEED_100,
> +                         DUPLEX_FULL);
> +       tp->speed = 0;

Nit: Could rtl_ops.up() set speed since it appears to be changing the
state of the link?

rtl8152_open() uses a remarkably similar code sequence. Is there an
opportunity to refactor and  make sure this sequence is consistent?
(different patch, not this one)

cheers,
grant

> +       netif_carrier_off(netdev);
> +       netif_start_queue(netdev);
> +       set_bit(WORK_ENABLE, &tp->flags);
> +       usb_submit_urb(tp->intr_urb, GFP_KERNEL);
> +
> +       usb_autopm_put_interface(tp->intf);
> +}
> +
>  static const struct net_device_ops rtl8152_netdev_ops = {
>         .ndo_open               = rtl8152_open,
>         .ndo_stop               = rtl8152_close,
> --
> 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/
>
>
--
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] 91+ messages in thread

* RE: [PATCH net-next 12/12] r8152: modify the tx timeout funcfion
  2014-03-25 20:12     ` Grant Grundler
  (?)
@ 2014-03-26  9:54     ` hayeswang
  -1 siblings, 0 replies; 91+ messages in thread
From: hayeswang @ 2014-03-26  9:54 UTC (permalink / raw)
  To: 'Grant Grundler'
  Cc: 'netdev', nic_swsd, 'LKML', linux-usb

 Grant Grundler [mailto:grundler@google.com] 
> Sent: Wednesday, March 26, 2014 4:12 AM
[...]
> Hayes,
> I believe this patch was dropped after the series was split.
> Can you please repost this patch by itself?

There is no problem for current behavior, and I don't get the
issue of tx timeout, yet. I think the other patches are prior
to this one, so I plan to deal with this one after the others.
Besides, maybe I would have different idea for this one then.
Although reinitialization is more safe, I don't sure if it is
necessary.

> (and fix the "function" typo in the patch header)

oops.

[...]
> Nit: Could rtl_ops.up() set speed since it appears to be changing the
> state of the link?

I don't plan to do it. I don't think it is a part of rtl_ops.up().
Although it alwayes follows rtl_ops.up() now, I think they should
be separeted because they are for different purposes. The set_speed
is used to make sure the speed is correct, because you don't know
what speed it is before the driver is loaded. The other OS may
change the speed, so the device should have opportunity to change
the speed to the default when the driver is loaded. Normally, the
set_speed is not necessary.

> rtl8152_open() uses a remarkably similar code sequence. Is there an
> opportunity to refactor and  make sure this sequence is consistent?
> (different patch, not this one)

It is a good question. I would think about it.
 
Best Regards,
Hayes


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

end of thread, other threads:[~2014-03-26  9:54 UTC | newest]

Thread overview: 91+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-03-04 12:00 [PATCH net-next 00/12] r8152: new features Hayes Wang
2014-03-04 12:00 ` [PATCH net-next 01/12] r8152: deal with the empty line and space Hayes Wang
2014-03-04 12:00 ` [PATCH net-next 02/12] r8152: replace tp->netdev with netdev Hayes Wang
2014-03-04 12:00 ` [PATCH net-next 03/12] r8152: remove rtl8152_get_stats Hayes Wang
2014-03-04 12:00 ` [PATCH net-next 04/12] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore Hayes Wang
2014-03-04 12:00 ` [PATCH net-next 05/12] r8152: check tx agg list before spin lock Hayes Wang
2014-03-04 12:00 ` [PATCH net-next 06/12] r8152: up the priority of the transmission Hayes Wang
2014-03-04 12:00 ` [PATCH net-next 07/12] r8152: support rx checksum Hayes Wang
2014-03-04 21:32   ` David Miller
2014-03-04 12:01 ` [PATCH net-next 08/12] r8152: support TSO Hayes Wang
2014-03-04 12:11   ` David Laight
2014-03-04 13:11     ` hayeswang
2014-03-04 14:35       ` David Laight
2014-03-04 14:35         ` David Laight
2014-03-04 15:02         ` Eric Dumazet
2014-03-04 15:14           ` David Laight
2014-03-04 15:14             ` David Laight
2014-03-04 16:11   ` Eric Dumazet
2014-03-04 16:52   ` Eric Dumazet
2014-03-04 12:01 ` [PATCH net-next 09/12] r8152: support IPv6 Hayes Wang
2014-03-04 16:58   ` Eric Dumazet
2014-03-04 12:01 ` [PATCH net-next 10/12] r8152: reduce the numbers of the bulks Hayes Wang
2014-03-04 12:01 ` [PATCH net-next 11/12] r8152: add additional parameter for non x86 platform Hayes Wang
2014-03-04 12:01 ` [PATCH net-next 12/12] r8152: modify the tx timeout funcfion Hayes Wang
2014-03-25 20:12   ` Grant Grundler
2014-03-25 20:12     ` Grant Grundler
2014-03-26  9:54     ` hayeswang
2014-03-05  6:49 ` [PATCH net-next v2 00/13] r8152: new features Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 01/13] r8152: deal with the empty line and space Hayes Wang
2014-03-05  6:49     ` Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 02/13] r8152: replace tp->netdev with netdev Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 03/13] r8152: remove rtl8152_get_stats Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 04/13] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 05/13] r8152: check tx agg list before spin lock Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 06/13] r8152: up the priority of the transmission Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 07/13] r8152: calculate the dropped packets for rx Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 08/13] r8152: support rx checksum Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 09/13] r8152: support TSO Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 10/13] r8152: support IPv6 Hayes Wang
2014-03-09 19:47     ` Ben Hutchings
2014-03-09 19:47       ` Ben Hutchings
2014-03-09 22:56       ` David Miller
2014-03-09 22:56         ` David Miller
2014-03-05  6:49   ` [PATCH net-next v2 11/13] r8152: reduce the numbers of the bulks Hayes Wang
2014-03-05  6:49   ` [PATCH net-next v2 12/13] r8152: add additional parameter for non x86 platform Hayes Wang
2014-03-06  5:05     ` David Miller
2014-03-05  6:49   ` [PATCH net-next v2 13/13] r8152: modify the tx timeout funcfion Hayes Wang
2014-03-06  7:07 ` [PATCH net-next 0/3] r8152: cleanups Hayes Wang
2014-03-06  7:07   ` Hayes Wang
2014-03-06  7:07   ` [PATCH net-next 1/3] r8152: deal with the empty line and space Hayes Wang
2014-03-06  7:07   ` [PATCH net-next 2/3] r8152: replace tp->netdev with netdev Hayes Wang
2014-03-06  7:07   ` [PATCH net-next 3/3] r8152: remove rtl8152_get_stats Hayes Wang
2014-03-06 18:17   ` [PATCH net-next 0/3] r8152: cleanups David Miller
2014-03-07  3:04 ` [PATCH net-next 0/7] r8152: tx/rx improvement Hayes Wang
2014-03-07  3:04   ` [PATCH net-next 1/7] r8152: replace spin_lock_irqsave and spin_unlock_irqrestore Hayes Wang
2014-03-07  3:04   ` [PATCH net-next 2/7] r8152: check tx agg list before spin lock Hayes Wang
2014-03-07  3:04     ` Hayes Wang
2014-03-07  3:04   ` [PATCH net-next 3/7] r8152: up the priority of the transmission Hayes Wang
2014-03-07  3:04   ` [PATCH net-next 4/7] r8152: calculate the dropped packets for rx Hayes Wang
2014-03-07  3:04   ` [PATCH net-next 5/7] r8152: support rx checksum Hayes Wang
2014-03-07  3:04   ` [PATCH net-next 6/7] r8152: support TSO Hayes Wang
2014-03-07  3:04   ` [PATCH net-next 7/7] r8152: support IPv6 Hayes Wang
2014-03-07 21:27   ` [PATCH net-next 0/7] r8152: tx/rx improvement David Miller
2014-03-10  3:45     ` hayeswang
2014-03-10  6:22 ` [PATCH net-next] r8152: add skb_cow_head Hayes Wang
2014-03-10  6:22   ` Hayes Wang
2014-03-10 20:31   ` David Miller
2014-03-11  2:20 ` [PATCH net-next v2] " Hayes Wang
2014-03-11  2:20   ` Hayes Wang
2014-03-11  2:25   ` David Miller
2014-03-12 12:39 ` [PATCH net-next 0/2] parameter modification Hayes Wang
2014-03-12 12:39   ` [PATCH net-next 1/2] r8152: add CONFIG_RTL8152_EARLY_AGG_SUPER Hayes Wang
2014-03-12 13:40     ` Bjørn Mork
2014-03-12 12:39   ` [PATCH net-next 2/2] r8152: reduce the numbers of the bulks Hayes Wang
2014-03-13  3:34 ` [PATCH net-next v2 0/2] parameter modification Hayes Wang
2014-03-13  3:34   ` [PATCH net-next v2 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER Hayes Wang
2014-03-13  9:28     ` David Laight
2014-03-13  3:34   ` [PATCH net-next v2 2/2] r8152: reduce the numbers of the bulks Hayes Wang
2014-03-13 12:05 ` [PATCH net-next v3 0/2] parameter modification Hayes Wang
2014-03-13 12:05   ` [PATCH net-next v3 1/2] r8152: add RTL8152_EARLY_AGG_TIMEOUT_SUPER Hayes Wang
2014-03-13 13:12     ` David Laight
2014-03-13 17:22       ` David Miller
2014-03-14  2:37         ` [PATCH net-next v3 1/2] r8152: addRTL8152_EARLY_AGG_TIMEOUT_SUPER hayeswang
2014-03-14  4:07           ` David Miller
2014-03-14  7:24             ` [PATCH net-next v3 1/2] r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER hayeswang
2014-03-14  7:24               ` hayeswang
2014-03-14 18:43               ` David Miller
2014-03-17  6:01                 ` [PATCH net-next v3 1/2]r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER hayeswang
2014-03-14 23:42               ` [PATCH net-next v3 1/2] r8152:addRTL8152_EARLY_AGG_TIMEOUT_SUPER Francois Romieu
2014-03-17  6:03                 ` hayeswang
2014-03-13 12:05   ` [PATCH net-next v3 2/2] r8152: reduce the numbers of the bulks Hayes Wang

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.