aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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}