r8152: adjust tx_bottom function
authorhayeswang <hayeswang@realtek.com>
Fri, 16 Aug 2013 08:09:37 +0000 (16:09 +0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 20 Aug 2013 07:08:22 +0000 (00:08 -0700)
Split some parts of code into another function to simplify
tx_bottom(). Use while loop to replace the goto loop.

Signed-off-by: Hayes Wang <hayeswang@realtek.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/r8152.c

index 0a88f647f075957c6558fab90d8aa61a858a5fe4..825edfe8c088cf2bfa9f63f65786611d66e122a3 100644 (file)
@@ -1131,6 +1131,51 @@ 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)
+{
+       u32 remain;
+       u8 *tx_data;
+
+       tx_data = agg->head;
+       agg->skb_num = agg->skb_len = 0;
+       remain = rx_buf_sz - sizeof(struct tx_desc);
+
+       while (remain >= ETH_ZLEN) {
+               struct tx_desc *tx_desc;
+               struct sk_buff *skb;
+               unsigned int len;
+
+               skb = skb_dequeue(&tp->tx_queue);
+               if (!skb)
+                       break;
+
+               len = skb->len;
+               if (remain < len) {
+                       skb_queue_head(&tp->tx_queue, skb);
+                       break;
+               }
+
+               tx_desc = (struct tx_desc *)tx_data;
+               tx_data += sizeof(*tx_desc);
+
+               r8152_tx_csum(tp, tx_desc, skb);
+               memcpy(tx_data, skb->data, len);
+               agg->skb_num++;
+               agg->skb_len += len;
+               dev_kfree_skb_any(skb);
+
+               tx_data = tx_agg_align(tx_data + len);
+               remain = rx_buf_sz - sizeof(*tx_desc) -
+                        (u32)((void *)tx_data - agg->head);
+       }
+
+       usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
+                         agg->head, (int)(tx_data - (u8 *)agg->head),
+                         (usb_complete_t)write_bulk_callback, agg);
+
+       return usb_submit_urb(agg->urb, GFP_ATOMIC);
+}
+
 static void rx_bottom(struct r8152 *tp)
 {
        unsigned long flags;
@@ -1204,82 +1249,39 @@ submit:
 
 static void tx_bottom(struct r8152 *tp)
 {
-       struct net_device_stats *stats;
-       struct net_device *netdev;
-       struct tx_agg *agg;
-       unsigned long flags;
-       u32 remain, total;
-       u8 *tx_data;
        int res;
 
-       netdev = tp->netdev;
-
-next_agg:
-       agg = NULL;
-       if (skb_queue_empty(&tp->tx_queue))
-               return;
+       do {
+               struct tx_agg *agg;
 
-       agg = r8152_get_tx_agg(tp);
-       if (!agg)
-               return;
-
-       tx_data = agg->head;
-       agg->skb_num = agg->skb_len = 0;
-       remain = rx_buf_sz - sizeof(struct tx_desc);
-       total = 0;
-
-       while (remain >= ETH_ZLEN) {
-               struct tx_desc *tx_desc;
-               struct sk_buff *skb;
-               unsigned int len;
-
-               skb = skb_dequeue(&tp->tx_queue);
-               if (!skb)
+               if (skb_queue_empty(&tp->tx_queue))
                        break;
 
-               len = skb->len;
-               if (remain < len) {
-                       skb_queue_head(&tp->tx_queue, skb);
+               agg = r8152_get_tx_agg(tp);
+               if (!agg)
                        break;
-               }
-
-               tx_data = tx_agg_align(tx_data);
-               tx_desc = (struct tx_desc *)tx_data;
-               tx_data += sizeof(*tx_desc);
 
-               r8152_tx_csum(tp, tx_desc, skb);
-               memcpy(tx_data, skb->data, len);
-               agg->skb_num++;
-               agg->skb_len += len;
-               dev_kfree_skb_any(skb);
-
-               tx_data += len;
-               remain = rx_buf_sz - sizeof(*tx_desc) -
-                        (u32)(tx_agg_align(tx_data) - agg->head);
-       }
-
-       usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2),
-                         agg->head, (int)(tx_data - (u8 *)agg->head),
-                         (usb_complete_t)write_bulk_callback, agg);
-       res = usb_submit_urb(agg->urb, GFP_ATOMIC);
+               res = r8152_tx_agg_fill(tp, agg);
+               if (res) {
+                       struct net_device_stats *stats;
+                       struct net_device *netdev;
+                       unsigned long flags;
 
-       stats = rtl8152_get_stats(netdev);
+                       netdev = tp->netdev;
+                       stats = rtl8152_get_stats(netdev);
 
-       if (res) {
-               /* Can we get/handle EPIPE here? */
-               if (res == -ENODEV) {
-                       netif_device_detach(netdev);
-               } else {
-                       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);
+                       if (res == -ENODEV) {
+                               netif_device_detach(netdev);
+                       } else {
+                               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);
+                       }
                }
-               return;
-       }
-       goto next_agg;
+       } while (res == 0);
 }
 
 static void bottom_half(unsigned long data)