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: Hayes Wang <hayeswang@realtek.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									43a4478d65
								
							
						
					
					
						commit
						b1379d9a20
					
				| @ -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; | ||||
| 	do { | ||||
| 		struct tx_agg *agg; | ||||
| 
 | ||||
| next_agg: | ||||
| 	agg = NULL; | ||||
| 	if (skb_queue_empty(&tp->tx_queue)) | ||||
| 		return; | ||||
| 
 | ||||
| 	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; | ||||
| 
 | ||||
| 		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 == -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); | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		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); | ||||
| 
 | ||||
| 	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); | ||||
| 		} | ||||
| 		return; | ||||
| 	} | ||||
| 	goto next_agg; | ||||
| 	} while (res == 0); | ||||
| } | ||||
| 
 | ||||
| static void bottom_half(unsigned long data) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user