diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt73usb.c | 39 |
1 files changed, 17 insertions, 22 deletions
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 6546b0d607b9..b4b70850edfc 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1370,12 +1370,24 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1370 | { | 1370 | { |
1371 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | 1371 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
1372 | __le32 *rxd = (__le32 *)entry->skb->data; | 1372 | __le32 *rxd = (__le32 *)entry->skb->data; |
1373 | struct ieee80211_hdr *hdr = | 1373 | unsigned int offset = entry->queue->desc_size + 2; |
1374 | (struct ieee80211_hdr *)entry->skb->data + entry->queue->desc_size; | ||
1375 | int header_size = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
1376 | u32 word0; | 1374 | u32 word0; |
1377 | u32 word1; | 1375 | u32 word1; |
1378 | 1376 | ||
1377 | /* | ||
1378 | * Copy descriptor to the available headroom inside the skbuffer. | ||
1379 | * Remove the original copy by pulling the skbuffer. | ||
1380 | */ | ||
1381 | skb_push(entry->skb, offset); | ||
1382 | memcpy(entry->skb->data, rxd, entry->queue->desc_size); | ||
1383 | rxd = (__le32 *)entry->skb->data; | ||
1384 | skb_pull(entry->skb, offset + skbdesc->desc_len); | ||
1385 | skb_trim(entry->skb, rxdesc->size); | ||
1386 | |||
1387 | /* | ||
1388 | * The descriptor is now aligned to 4 bytes and thus it is | ||
1389 | * now safe to read it on all architectures. | ||
1390 | */ | ||
1379 | rt2x00_desc_read(rxd, 0, &word0); | 1391 | rt2x00_desc_read(rxd, 0, &word0); |
1380 | rt2x00_desc_read(rxd, 1, &word1); | 1392 | rt2x00_desc_read(rxd, 1, &word1); |
1381 | 1393 | ||
@@ -1393,29 +1405,12 @@ static void rt73usb_fill_rxdone(struct queue_entry *entry, | |||
1393 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1405 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1394 | 1406 | ||
1395 | /* | 1407 | /* |
1396 | * The data behind the ieee80211 header must be | ||
1397 | * aligned on a 4 byte boundary. | ||
1398 | */ | ||
1399 | if (header_size % 4 == 0) { | ||
1400 | skb_push(entry->skb, 2); | ||
1401 | memmove(entry->skb->data, entry->skb->data + 2, | ||
1402 | entry->skb->len - 2); | ||
1403 | } | ||
1404 | |||
1405 | /* | ||
1406 | * Set descriptor and data pointer. | 1408 | * Set descriptor and data pointer. |
1407 | */ | 1409 | */ |
1408 | skbdesc->data = entry->skb->data + entry->queue->desc_size; | 1410 | skbdesc->data = entry->skb->data; |
1409 | skbdesc->data_len = rxdesc->size; | 1411 | skbdesc->data_len = rxdesc->size; |
1410 | skbdesc->desc = entry->skb->data; | 1412 | skbdesc->desc = entry->skb->data - offset; |
1411 | skbdesc->desc_len = entry->queue->desc_size; | 1413 | skbdesc->desc_len = entry->queue->desc_size; |
1412 | |||
1413 | /* | ||
1414 | * Remove descriptor from skb buffer and trim the whole thing | ||
1415 | * down to only contain data. | ||
1416 | */ | ||
1417 | skb_pull(entry->skb, skbdesc->desc_len); | ||
1418 | skb_trim(entry->skb, rxdesc->size); | ||
1419 | } | 1414 | } |
1420 | 1415 | ||
1421 | /* | 1416 | /* |