aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt73usb.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2008-05-10 07:43:38 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-05-21 21:47:32 -0400
commit70a96109439cba0af0780ee1dc25ec7ed15f0bae (patch)
tree1e6feb2b77486a90012f117201c13b35ab2020d7 /drivers/net/wireless/rt2x00/rt73usb.c
parent61448f88078e813bbaaa58eb775d650c85e7d407 (diff)
rt2x00: Preserve descriptor information after memmove()
Due to usage of memmove() in rt2x00usb the descriptor can become corrupted because it is being overwritten by the data part. Overall having the descriptor in front of the frame is a bad idea, we can however use the skb->cb array for this task, since that contains more then enough room to hold the entire descriptor and preserve the information long enough. After this we can also cleanup the alignment code a bit to make it work a bit more flexible to allow for all kinds of odd header lengths. 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.c26
1 files changed, 11 insertions, 15 deletions
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/*