aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt73usb.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-03-09 17:38:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-03-13 16:02:33 -0400
commitf855c10b6e7b0c448c35b88266f788dd3738375e (patch)
tree0144787573334e3b87b957347d01453196dc870b /drivers/net/wireless/rt2x00/rt73usb.c
parent40e024de932cca8b54fbcd0e5faf8f364cc84ec0 (diff)
rt2x00: Align RX descriptor to 4 bytes
Some architectures give problems when reading RX frame descriptor words when the descriptor is not aligned on a 4 byte boundrary. Due to optimalizations for the ieee80211 payload 4 byte alignment, it is no longer guarenteed that the descriptor is placed on the 4 byte boundrary (In fact, for rt73usb it is absolutely never aligned to 4 bytes, for rt2500usb it depends on the length of the payload). This will copy the descriptor to a 4 byte aligned location before it is read for the first time. This will also move the payload data alignment in rt2x00usb (instead of inside the driver) where it has always belonged. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt73usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c39
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/*