Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+68 −66
Original line number Diff line number Diff line
@@ -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,69 +1249,27 @@ static void rx_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;

	netdev = tp->netdev;
	do {
		struct tx_agg *agg;

next_agg:
	agg = NULL;
		if (skb_queue_empty(&tp->tx_queue))
		return;
			break;

		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)
			break;

		len = skb->len;
		if (remain < len) {
			skb_queue_head(&tp->tx_queue, skb);
			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;

			netdev = tp->netdev;
			stats = rtl8152_get_stats(netdev);

	if (res) {
		/* Can we get/handle EPIPE here? */
			if (res == -ENODEV) {
				netif_device_detach(netdev);
			} else {
@@ -1277,9 +1280,8 @@ static void tx_bottom(struct r8152 *tp)
				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)