Commit b1379d9a authored by hayeswang's avatar hayeswang Committed by David S. Miller

r8152: adjust tx_bottom function

Split some parts of code into another function to simplify
tx_bottom(). Use while loop to replace the goto loop.
Signed-off-by: default avatarHayes Wang <hayeswang@realtek.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 43a4478d
...@@ -1131,6 +1131,51 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb) ...@@ -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) static void rx_bottom(struct r8152 *tp)
{ {
unsigned long flags; unsigned long flags;
...@@ -1204,82 +1249,39 @@ static void rx_bottom(struct r8152 *tp) ...@@ -1204,82 +1249,39 @@ static void rx_bottom(struct r8152 *tp)
static void tx_bottom(struct r8152 *tp) 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; int res;
netdev = tp->netdev; do {
struct tx_agg *agg;
next_agg:
agg = NULL;
if (skb_queue_empty(&tp->tx_queue))
return;
agg = r8152_get_tx_agg(tp); if (skb_queue_empty(&tp->tx_queue))
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)
break; break;
len = skb->len; agg = r8152_get_tx_agg(tp);
if (remain < len) { if (!agg)
skb_queue_head(&tp->tx_queue, skb);
break; 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); res = r8152_tx_agg_fill(tp, agg);
memcpy(tx_data, skb->data, len); if (res) {
agg->skb_num++; struct net_device_stats *stats;
agg->skb_len += len; struct net_device *netdev;
dev_kfree_skb_any(skb); unsigned long flags;
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);
stats = rtl8152_get_stats(netdev); netdev = tp->netdev;
stats = rtl8152_get_stats(netdev);
if (res) { if (res == -ENODEV) {
/* Can we get/handle EPIPE here? */ netif_device_detach(netdev);
if (res == -ENODEV) { } else {
netif_device_detach(netdev); netif_warn(tp, tx_err, netdev,
} else { "failed tx_urb %d\n", res);
netif_warn(tp, tx_err, netdev, stats->tx_dropped += agg->skb_num;
"failed tx_urb %d\n", res); spin_lock_irqsave(&tp->tx_lock, flags);
stats->tx_dropped += agg->skb_num; list_add_tail(&agg->list, &tp->tx_free);
spin_lock_irqsave(&tp->tx_lock, flags); spin_unlock_irqrestore(&tp->tx_lock, flags);
list_add_tail(&agg->list, &tp->tx_free); }
spin_unlock_irqrestore(&tp->tx_lock, flags);
} }
return; } while (res == 0);
}
goto next_agg;
} }
static void bottom_half(unsigned long data) static void bottom_half(unsigned long data)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment