aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c23
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.c60
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c26
3 files changed, 62 insertions, 47 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 661cf3d7212a..3be4c7ea8dd1 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1129,20 +1129,22 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
1129 __le32 *rxd = 1129 __le32 *rxd =
1130 (__le32 *)(entry->skb->data + 1130 (__le32 *)(entry->skb->data +
1131 (priv_rx->urb->actual_length - entry->queue->desc_size)); 1131 (priv_rx->urb->actual_length - entry->queue->desc_size));
1132 unsigned int offset = entry->queue->desc_size + 2;
1133 u32 word0; 1132 u32 word0;
1134 u32 word1; 1133 u32 word1;
1135 1134
1136 /* 1135 /*
1137 * Copy descriptor to the available headroom inside the skbuffer. 1136 * Copy descriptor to the skb->cb array, this has 2 benefits:
1137 * 1) Each descriptor word is 4 byte aligned.
1138 * 2) Descriptor is safe from moving of frame data in rt2x00usb.
1138 */ 1139 */
1139 skb_push(entry->skb, offset); 1140 skbdesc->desc_len =
1140 memcpy(entry->skb->data, rxd, entry->queue->desc_size); 1141 min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb));
1141 rxd = (__le32 *)entry->skb->data; 1142 memcpy(entry->skb->cb, rxd, skbdesc->desc_len);
1143 skbdesc->desc = entry->skb->cb;
1144 rxd = (__le32 *)skbdesc->desc;
1142 1145
1143 /* 1146 /*
1144 * The descriptor is now aligned to 4 bytes and thus it is 1147 * It is now safe to read the descriptor on all architectures.
1145 * now safe to read it on all architectures.
1146 */ 1148 */
1147 rt2x00_desc_read(rxd, 0, &word0); 1149 rt2x00_desc_read(rxd, 0, &word0);
1148 rt2x00_desc_read(rxd, 1, &word1); 1150 rt2x00_desc_read(rxd, 1, &word1);
@@ -1173,16 +1175,9 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry,
1173 /* 1175 /*
1174 * Adjust the skb memory window to the frame boundaries. 1176 * Adjust the skb memory window to the frame boundaries.
1175 */ 1177 */
1176 skb_pull(entry->skb, offset);
1177 skb_trim(entry->skb, rxdesc->size); 1178 skb_trim(entry->skb, rxdesc->size);
1178
1179 /*
1180 * Set descriptor and data pointer.
1181 */
1182 skbdesc->data = entry->skb->data; 1179 skbdesc->data = entry->skb->data;
1183 skbdesc->data_len = rxdesc->size; 1180 skbdesc->data_len = rxdesc->size;
1184 skbdesc->desc = rxd;
1185 skbdesc->desc_len = entry->queue->desc_size;
1186} 1181}
1187 1182
1188/* 1183/*
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c
index caee65e82198..f72b3d07a42d 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.c
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.c
@@ -246,22 +246,35 @@ static struct sk_buff* rt2x00usb_alloc_rxskb(struct data_queue *queue)
246{ 246{
247 struct sk_buff *skb; 247 struct sk_buff *skb;
248 unsigned int frame_size; 248 unsigned int frame_size;
249 unsigned int reserved_size;
249 250
250 /* 251 /*
251 * As alignment we use 2 and not NET_IP_ALIGN because we need 252 * The frame size includes descriptor size, because the
252 * to be sure we have 2 bytes room in the head. (NET_IP_ALIGN 253 * hardware directly receive the frame into the skbuffer.
253 * can be 0 on some hardware). We use these 2 bytes for frame
254 * alignment later, we assume that the chance that
255 * header_size % 4 == 2 is bigger then header_size % 2 == 0
256 * and thus optimize alignment by reserving the 2 bytes in
257 * advance.
258 */ 254 */
259 frame_size = queue->data_size + queue->desc_size; 255 frame_size = queue->data_size + queue->desc_size;
260 skb = dev_alloc_skb(queue->desc_size + frame_size + 2); 256
257 /*
258 * For the allocation we should keep a few things in mind:
259 * 1) 4byte alignment of 802.11 payload
260 *
261 * For (1) we need at most 4 bytes to guarentee the correct
262 * alignment. We are going to optimize the fact that the chance
263 * that the 802.11 header_size % 4 == 2 is much bigger then
264 * anything else. However since we need to move the frame up
265 * to 3 bytes to the front, which means we need to preallocate
266 * 6 bytes.
267 */
268 reserved_size = 6;
269
270 /*
271 * Allocate skbuffer.
272 */
273 skb = dev_alloc_skb(frame_size + reserved_size);
261 if (!skb) 274 if (!skb)
262 return NULL; 275 return NULL;
263 276
264 skb_reserve(skb, queue->desc_size + 2); 277 skb_reserve(skb, reserved_size);
265 skb_put(skb, frame_size); 278 skb_put(skb, frame_size);
266 279
267 return skb; 280 return skb;
@@ -274,7 +287,8 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
274 struct sk_buff *skb; 287 struct sk_buff *skb;
275 struct skb_frame_desc *skbdesc; 288 struct skb_frame_desc *skbdesc;
276 struct rxdone_entry_desc rxdesc; 289 struct rxdone_entry_desc rxdesc;
277 int header_size; 290 unsigned int header_size;
291 unsigned int align;
278 292
279 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || 293 if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) ||
280 !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) 294 !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags))
@@ -298,19 +312,29 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb)
298 memset(&rxdesc, 0, sizeof(rxdesc)); 312 memset(&rxdesc, 0, sizeof(rxdesc));
299 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); 313 rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc);
300 314
315 header_size = ieee80211_get_hdrlen_from_skb(entry->skb);
316
301 /* 317 /*
302 * The data behind the ieee80211 header must be 318 * The data behind the ieee80211 header must be
303 * aligned on a 4 byte boundary. 319 * aligned on a 4 byte boundary. We already reserved
320 * 2 bytes for header_size % 4 == 2 optimization.
321 * To determine the number of bytes which the data
322 * should be moved to the left, we must add these
323 * 2 bytes to the header_size.
304 */ 324 */
305 header_size = ieee80211_get_hdrlen_from_skb(entry->skb); 325 align = (header_size + 2) % 4;
306 if (header_size % 4 == 0) { 326
307 skb_push(entry->skb, 2); 327 if (align) {
308 memmove(entry->skb->data, entry->skb->data + 2, 328 skb_push(entry->skb, align);
309 entry->skb->len - 2); 329 /* Move entire frame in 1 command */
310 skbdesc->data = entry->skb->data; 330 memmove(entry->skb->data, entry->skb->data + align,
311 skb_trim(entry->skb,entry->skb->len - 2); 331 rxdesc.size);
312 } 332 }
313 333
334 /* Update data pointers, trim buffer to correct size */
335 skbdesc->data = entry->skb->data;
336 skb_trim(entry->skb, rxdesc.size);
337
314 /* 338 /*
315 * Allocate a new sk buffer to replace the current one. 339 * Allocate a new sk buffer to replace the current one.
316 * If allocation fails, we should drop the current frame 340 * If allocation fails, we should drop the current frame
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 2191d8b94a89..1bcf8c132cdc 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -1403,20 +1403,22 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
1403{ 1403{
1404 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); 1404 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);
1405 __le32 *rxd = (__le32 *)entry->skb->data; 1405 __le32 *rxd = (__le32 *)entry->skb->data;
1406 unsigned int offset = entry->queue->desc_size + 2;
1407 u32 word0; 1406 u32 word0;
1408 u32 word1; 1407 u32 word1;
1409 1408
1410 /* 1409 /*
1411 * Copy descriptor to the available headroom inside the skbuffer. 1410 * Copy descriptor to the skb->cb array, this has 2 benefits:
1411 * 1) Each descriptor word is 4 byte aligned.
1412 * 2) Descriptor is safe from moving of frame data in rt2x00usb.
1412 */ 1413 */
1413 skb_push(entry->skb, offset); 1414 skbdesc->desc_len =
1414 memcpy(entry->skb->data, rxd, entry->queue->desc_size); 1415 min_t(u16, entry->queue->desc_size, sizeof(entry->skb->cb));
1415 rxd = (__le32 *)entry->skb->data; 1416 memcpy(entry->skb->cb, rxd, skbdesc->desc_len);
1417 skbdesc->desc = entry->skb->cb;
1418 rxd = (__le32 *)skbdesc->desc;
1416 1419
1417 /* 1420 /*
1418 * The descriptor is now aligned to 4 bytes and thus it is 1421 * It is now safe to read the descriptor on all architectures.
1419 * now safe to read it on all architectures.
1420 */ 1422 */
1421 rt2x00_desc_read(rxd, 0, &word0); 1423 rt2x00_desc_read(rxd, 0, &word0);
1422 rt2x00_desc_read(rxd, 1, &word1); 1424 rt2x00_desc_read(rxd, 1, &word1);
@@ -1442,18 +1444,12 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry,
1442 rxdesc->dev_flags |= RXDONE_MY_BSS; 1444 rxdesc->dev_flags |= RXDONE_MY_BSS;
1443 1445
1444 /* 1446 /*
1445 * Adjust the skb memory window to the frame boundaries. 1447 * Set skb pointers, and update frame information.
1446 */ 1448 */
1447 skb_pull(entry->skb, offset + entry->queue->desc_size); 1449 skb_pull(entry->skb, entry->queue->desc_size);
1448 skb_trim(entry->skb, rxdesc->size); 1450 skb_trim(entry->skb, rxdesc->size);
1449
1450 /*
1451 * Set descriptor and data pointer.
1452 */
1453 skbdesc->data = entry->skb->data; 1451 skbdesc->data = entry->skb->data;
1454 skbdesc->data_len = rxdesc->size; 1452 skbdesc->data_len = rxdesc->size;
1455 skbdesc->desc = rxd;
1456 skbdesc->desc_len = entry->queue->desc_size;
1457} 1453}
1458 1454
1459/* 1455/*