diff options
author | hayeswang <hayeswang@realtek.com> | 2013-08-16 04:09:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-20 03:08:22 -0400 |
commit | b1379d9a20167c41b682e96841b34aab32ec50a5 (patch) | |
tree | e8e6f0cb11f84fbdfd916456b84b684173ba98f1 | |
parent | 43a4478d65ffaa1c2def8ffceafbc3a3f1e99b82 (diff) |
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>
-rw-r--r-- | drivers/net/usb/r8152.c | 134 |
1 files changed, 68 insertions, 66 deletions
diff --git a/drivers/net/usb/r8152.c b/drivers/net/usb/r8152.c index 0a88f647f075..825edfe8c088 100644 --- a/drivers/net/usb/r8152.c +++ b/drivers/net/usb/r8152.c | |||
@@ -1131,6 +1131,51 @@ r8152_tx_csum(struct r8152 *tp, struct tx_desc *desc, struct sk_buff *skb) | |||
1131 | } | 1131 | } |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | static int r8152_tx_agg_fill(struct r8152 *tp, struct tx_agg *agg) | ||
1135 | { | ||
1136 | u32 remain; | ||
1137 | u8 *tx_data; | ||
1138 | |||
1139 | tx_data = agg->head; | ||
1140 | agg->skb_num = agg->skb_len = 0; | ||
1141 | remain = rx_buf_sz - sizeof(struct tx_desc); | ||
1142 | |||
1143 | while (remain >= ETH_ZLEN) { | ||
1144 | struct tx_desc *tx_desc; | ||
1145 | struct sk_buff *skb; | ||
1146 | unsigned int len; | ||
1147 | |||
1148 | skb = skb_dequeue(&tp->tx_queue); | ||
1149 | if (!skb) | ||
1150 | break; | ||
1151 | |||
1152 | len = skb->len; | ||
1153 | if (remain < len) { | ||
1154 | skb_queue_head(&tp->tx_queue, skb); | ||
1155 | break; | ||
1156 | } | ||
1157 | |||
1158 | tx_desc = (struct tx_desc *)tx_data; | ||
1159 | tx_data += sizeof(*tx_desc); | ||
1160 | |||
1161 | r8152_tx_csum(tp, tx_desc, skb); | ||
1162 | memcpy(tx_data, skb->data, len); | ||
1163 | agg->skb_num++; | ||
1164 | agg->skb_len += len; | ||
1165 | dev_kfree_skb_any(skb); | ||
1166 | |||
1167 | tx_data = tx_agg_align(tx_data + len); | ||
1168 | remain = rx_buf_sz - sizeof(*tx_desc) - | ||
1169 | (u32)((void *)tx_data - agg->head); | ||
1170 | } | ||
1171 | |||
1172 | usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), | ||
1173 | agg->head, (int)(tx_data - (u8 *)agg->head), | ||
1174 | (usb_complete_t)write_bulk_callback, agg); | ||
1175 | |||
1176 | return usb_submit_urb(agg->urb, GFP_ATOMIC); | ||
1177 | } | ||
1178 | |||
1134 | static void rx_bottom(struct r8152 *tp) | 1179 | static void rx_bottom(struct r8152 *tp) |
1135 | { | 1180 | { |
1136 | unsigned long flags; | 1181 | unsigned long flags; |
@@ -1204,82 +1249,39 @@ submit: | |||
1204 | 1249 | ||
1205 | static void tx_bottom(struct r8152 *tp) | 1250 | static void tx_bottom(struct r8152 *tp) |
1206 | { | 1251 | { |
1207 | struct net_device_stats *stats; | ||
1208 | struct net_device *netdev; | ||
1209 | struct tx_agg *agg; | ||
1210 | unsigned long flags; | ||
1211 | u32 remain, total; | ||
1212 | u8 *tx_data; | ||
1213 | int res; | 1252 | int res; |
1214 | 1253 | ||
1215 | netdev = tp->netdev; | 1254 | do { |
1216 | 1255 | struct tx_agg *agg; | |
1217 | next_agg: | ||
1218 | agg = NULL; | ||
1219 | if (skb_queue_empty(&tp->tx_queue)) | ||
1220 | return; | ||
1221 | 1256 | ||
1222 | agg = r8152_get_tx_agg(tp); | 1257 | if (skb_queue_empty(&tp->tx_queue)) |
1223 | if (!agg) | ||
1224 | return; | ||
1225 | |||
1226 | tx_data = agg->head; | ||
1227 | agg->skb_num = agg->skb_len = 0; | ||
1228 | remain = rx_buf_sz - sizeof(struct tx_desc); | ||
1229 | total = 0; | ||
1230 | |||
1231 | while (remain >= ETH_ZLEN) { | ||
1232 | struct tx_desc *tx_desc; | ||
1233 | struct sk_buff *skb; | ||
1234 | unsigned int len; | ||
1235 | |||
1236 | skb = skb_dequeue(&tp->tx_queue); | ||
1237 | if (!skb) | ||
1238 | break; | 1258 | break; |
1239 | 1259 | ||
1240 | len = skb->len; | 1260 | agg = r8152_get_tx_agg(tp); |
1241 | if (remain < len) { | 1261 | if (!agg) |
1242 | skb_queue_head(&tp->tx_queue, skb); | ||
1243 | break; | 1262 | break; |
1244 | } | ||
1245 | |||
1246 | tx_data = tx_agg_align(tx_data); | ||
1247 | tx_desc = (struct tx_desc *)tx_data; | ||
1248 | tx_data += sizeof(*tx_desc); | ||
1249 | 1263 | ||
1250 | r8152_tx_csum(tp, tx_desc, skb); | 1264 | res = r8152_tx_agg_fill(tp, agg); |
1251 | memcpy(tx_data, skb->data, len); | 1265 | if (res) { |
1252 | agg->skb_num++; | 1266 | struct net_device_stats *stats; |
1253 | agg->skb_len += len; | 1267 | struct net_device *netdev; |
1254 | dev_kfree_skb_any(skb); | 1268 | unsigned long flags; |
1255 | |||
1256 | tx_data += len; | ||
1257 | remain = rx_buf_sz - sizeof(*tx_desc) - | ||
1258 | (u32)(tx_agg_align(tx_data) - agg->head); | ||
1259 | } | ||
1260 | |||
1261 | usb_fill_bulk_urb(agg->urb, tp->udev, usb_sndbulkpipe(tp->udev, 2), | ||
1262 | agg->head, (int)(tx_data - (u8 *)agg->head), | ||
1263 | (usb_complete_t)write_bulk_callback, agg); | ||
1264 | res = usb_submit_urb(agg->urb, GFP_ATOMIC); | ||
1265 | 1269 | ||
1266 | stats = rtl8152_get_stats(netdev); | 1270 | netdev = tp->netdev; |
1271 | stats = rtl8152_get_stats(netdev); | ||
1267 | 1272 | ||
1268 | if (res) { | 1273 | if (res == -ENODEV) { |
1269 | /* Can we get/handle EPIPE here? */ | 1274 | netif_device_detach(netdev); |
1270 | if (res == -ENODEV) { | 1275 | } else { |
1271 | netif_device_detach(netdev); | 1276 | netif_warn(tp, tx_err, netdev, |
1272 | } else { | 1277 | "failed tx_urb %d\n", res); |
1273 | netif_warn(tp, tx_err, netdev, | 1278 | stats->tx_dropped += agg->skb_num; |
1274 | "failed tx_urb %d\n", res); | 1279 | spin_lock_irqsave(&tp->tx_lock, flags); |
1275 | stats->tx_dropped += agg->skb_num; | 1280 | list_add_tail(&agg->list, &tp->tx_free); |
1276 | spin_lock_irqsave(&tp->tx_lock, flags); | 1281 | spin_unlock_irqrestore(&tp->tx_lock, flags); |
1277 | list_add_tail(&agg->list, &tp->tx_free); | 1282 | } |
1278 | spin_unlock_irqrestore(&tp->tx_lock, flags); | ||
1279 | } | 1283 | } |
1280 | return; | 1284 | } while (res == 0); |
1281 | } | ||
1282 | goto next_agg; | ||
1283 | } | 1285 | } |
1284 | 1286 | ||
1285 | static void bottom_half(unsigned long data) | 1287 | static void bottom_half(unsigned long data) |