diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2500usb.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2500usb.c | 37 |
1 files changed, 17 insertions, 20 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 9f59db91cfc2..86cd9a5eee2b 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1117,11 +1117,24 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1117 | __le32 *rxd = | 1117 | __le32 *rxd = |
1118 | (__le32 *)(entry->skb->data + | 1118 | (__le32 *)(entry->skb->data + |
1119 | (priv_rx->urb->actual_length - entry->queue->desc_size)); | 1119 | (priv_rx->urb->actual_length - entry->queue->desc_size)); |
1120 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data; | 1120 | unsigned int offset = entry->queue->desc_size + 2; |
1121 | int header_size = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_control)); | ||
1122 | u32 word0; | 1121 | u32 word0; |
1123 | u32 word1; | 1122 | u32 word1; |
1124 | 1123 | ||
1124 | /* | ||
1125 | * Copy descriptor to the available headroom inside the skbuffer. | ||
1126 | * Remove the original copy by trimming the skbuffer. | ||
1127 | */ | ||
1128 | skb_push(entry->skb, offset); | ||
1129 | memcpy(entry->skb->data, rxd, entry->queue->desc_size); | ||
1130 | rxd = (__le32 *)entry->skb->data; | ||
1131 | skb_pull(entry->skb, offset); | ||
1132 | skb_trim(entry->skb, rxdesc->size); | ||
1133 | |||
1134 | /* | ||
1135 | * The descriptor is now aligned to 4 bytes and thus it is | ||
1136 | * now safe to read it on all architectures. | ||
1137 | */ | ||
1125 | rt2x00_desc_read(rxd, 0, &word0); | 1138 | rt2x00_desc_read(rxd, 0, &word0); |
1126 | rt2x00_desc_read(rxd, 1, &word1); | 1139 | rt2x00_desc_read(rxd, 1, &word1); |
1127 | 1140 | ||
@@ -1142,28 +1155,12 @@ static void rt2500usb_fill_rxdone(struct queue_entry *entry, | |||
1142 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); | 1155 | rxdesc->my_bss = !!rt2x00_get_field32(word0, RXD_W0_MY_BSS); |
1143 | 1156 | ||
1144 | /* | 1157 | /* |
1145 | * The data behind the ieee80211 header must be | 1158 | * Set descriptor and data pointer. |
1146 | * aligned on a 4 byte boundary. | ||
1147 | */ | ||
1148 | if (header_size % 4 == 0) { | ||
1149 | skb_push(entry->skb, 2); | ||
1150 | memmove(entry->skb->data, entry->skb->data + 2, | ||
1151 | entry->skb->len - 2); | ||
1152 | } | ||
1153 | |||
1154 | /* | ||
1155 | * Set descriptor pointer. | ||
1156 | */ | 1159 | */ |
1157 | skbdesc->data = entry->skb->data; | 1160 | skbdesc->data = entry->skb->data; |
1158 | skbdesc->data_len = rxdesc->size; | 1161 | skbdesc->data_len = rxdesc->size; |
1159 | skbdesc->desc = entry->skb->data + rxdesc->size; | 1162 | skbdesc->desc = entry->skb->data - offset; |
1160 | skbdesc->desc_len = entry->queue->desc_size; | 1163 | skbdesc->desc_len = entry->queue->desc_size; |
1161 | |||
1162 | /* | ||
1163 | * Remove descriptor from skb buffer and trim the whole thing | ||
1164 | * down to only contain data. | ||
1165 | */ | ||
1166 | skb_trim(entry->skb, rxdesc->size); | ||
1167 | } | 1164 | } |
1168 | 1165 | ||
1169 | /* | 1166 | /* |