aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/usb
diff options
context:
space:
mode:
authorhayeswang <hayeswang@realtek.com>2013-11-20 04:30:55 -0500
committerDavid S. Miller <davem@davemloft.net>2013-11-20 15:09:41 -0500
commit61598788582cafad52816d5d1db879334d8bd561 (patch)
tree241c6444ab2a86e87d6c483266d7a627c30fcf18 /drivers/net/usb
parent7937f9e5141c9d4864d399d91325605a35cd5831 (diff)
r8152: modify the tx flow
Remove the code for sending the packet in the rtl8152_start_xmit(). Let rtl8152_start_xmit() to queue the packet only, and schedule a tasklet to send the queued packets. This simplify the code and make sure all the packet would be sent by the original order. Signed-off-by: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/usb')
-rw-r--r--drivers/net/usb/r8152.c46
1 files changed, 3 insertions, 43 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c
index 428600d5c056..8a786b65d883 100644
--- a/drivers/net/usb/r8152.c
+++ b/drivers/net/usb/r8152.c
@@ -1388,53 +1388,13 @@ static netdev_tx_t rtl8152_start_xmit(struct sk_buff *skb,
1388 struct net_device *netdev) 1388 struct net_device *netdev)
1389{ 1389{
1390 struct r8152 *tp = netdev_priv(netdev); 1390 struct r8152 *tp = netdev_priv(netdev);
1391 struct net_device_stats *stats = rtl8152_get_stats(netdev);
1392 unsigned long flags;
1393 struct tx_agg *agg = NULL;
1394 struct tx_desc *tx_desc;
1395 unsigned int len;
1396 u8 *tx_data;
1397 int res;
1398 1391
1399 skb_tx_timestamp(skb); 1392 skb_tx_timestamp(skb);
1400 1393
1401 /* If tx_queue is not empty, it means at least one previous packt */ 1394 skb_queue_tail(&tp->tx_queue, skb);
1402 /* is waiting for sending. Don't send current one before it. */
1403 if (skb_queue_empty(&tp->tx_queue))
1404 agg = r8152_get_tx_agg(tp);
1405
1406 if (!agg) {
1407 skb_queue_tail(&tp->tx_queue, skb);
1408 return NETDEV_TX_OK;
1409 }
1410
1411 tx_desc = (struct tx_desc *)agg->head;
1412 tx_data = agg->head + sizeof(*tx_desc);
1413 agg->skb_num = agg->skb_len = 0;
1414 1395
1415 len = skb->len; 1396 if (!list_empty(&tp->tx_free))
1416 r8152_tx_csum(tp, tx_desc, skb); 1397 tasklet_schedule(&tp->tl);
1417 memcpy(tx_data, skb->data, len);
1418 dev_kfree_skb_any(skb);
1419 agg->skb_num++;
1420 agg->skb_len += len;
1421 usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
1422 agg->head, len + sizeof(*tx_desc),
1423 (usb_complete_t)write_bulk_callback, agg);
1424 res = usb_submit_urb(agg->urb, GFP_ATOMIC);
1425 if (res) {
1426 /* Can we get/handle EPIPE here? */
1427 if (res == -ENODEV) {
1428 netif_device_detach(tp->netdev);
1429 } else {
1430 netif_warn(tp, tx_err, netdev,
1431 "failed tx_urb %d\n", res);
1432 stats->tx_dropped++;
1433 spin_lock_irqsave(&tp->tx_lock, flags);
1434 list_add_tail(&agg->list, &tp->tx_free);
1435 spin_unlock_irqrestore(&tp->tx_lock, flags);
1436 }
1437 }
1438 1398
1439 return NETDEV_TX_OK; 1399 return NETDEV_TX_OK;
1440} 1400}