aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2500usb.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/rt2500usb.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/rt2500usb.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c23
1 files changed, 9 insertions, 14 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/*