diff options
author | Gertjan van Wingerde <gwingerde@gmail.com> | 2009-12-04 17:47:03 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-12-21 18:56:34 -0500 |
commit | 2e331462fcb3d897921d8a0af4fca1b08c1b7269 (patch) | |
tree | 4560331e21591dba952bdbdb249a6cd72ff30de4 | |
parent | 354e39dbb19f29ef28a9c2db9e55ff2a7435b35a (diff) |
rt2x00: Reorganize L2 padding inserting function.
Simplify the rt2x00queue_insert_l2pad function by handling the alignment
operations one by one. Do not special case special circumstances.
Basically first perform header alignment, and then perform payload alignment
(if any payload does exist). This results in a properly aligned skb.
The end result is better readable code, with better results, as now L2 padding
is inserted only when a payload is actually present in the frame.
Signed-off-by: Gertjan van Wingerde <gwingerde@gmail.com>
Acked-by: Ivo van Doorn <ivdoorn@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 60 |
1 files changed, 27 insertions, 33 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 719f4aebcaf6..7452fa850a0f 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -177,45 +177,38 @@ void rt2x00queue_align_payload(struct sk_buff *skb, unsigned int header_length) | |||
177 | 177 | ||
178 | void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) | 178 | void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) |
179 | { | 179 | { |
180 | unsigned int frame_length = skb->len; | 180 | unsigned int payload_length = skb->len - header_length; |
181 | unsigned int header_align = ALIGN_SIZE(skb, 0); | 181 | unsigned int header_align = ALIGN_SIZE(skb, 0); |
182 | unsigned int payload_align = ALIGN_SIZE(skb, header_length); | 182 | unsigned int payload_align = ALIGN_SIZE(skb, header_length); |
183 | unsigned int l2pad = L2PAD_SIZE(header_length); | 183 | unsigned int l2pad = L2PAD_SIZE(header_length); |
184 | 184 | ||
185 | if (header_align == payload_align) { | 185 | /* |
186 | /* | 186 | * Adjust the header alignment if the payload needs to be moved more |
187 | * Both header and payload must be moved the same | 187 | * than the header. |
188 | * amount of bytes to align them properly. This means | 188 | */ |
189 | * we don't use the L2 padding but just move the entire | 189 | if (payload_align > header_align) |
190 | * frame. | 190 | header_align += 4; |
191 | */ | 191 | |
192 | rt2x00queue_align_frame(skb); | 192 | /* There is nothing to do if no alignment is needed */ |
193 | } else if (!payload_align) { | 193 | if (!header_align) |
194 | /* | 194 | return; |
195 | * Simple L2 padding, only the header needs to be moved, | ||
196 | * the payload is already properly aligned. | ||
197 | */ | ||
198 | skb_push(skb, header_align); | ||
199 | memmove(skb->data, skb->data + header_align, header_length); | ||
200 | } else { | ||
201 | /* | ||
202 | * | ||
203 | * Complicated L2 padding, both header and payload need | ||
204 | * to be moved. By default we only move to the start | ||
205 | * of the buffer, so our header alignment needs to be | ||
206 | * increased if there is not enough room for the header | ||
207 | * to be moved. | ||
208 | */ | ||
209 | if (payload_align > header_align) | ||
210 | header_align += 4; | ||
211 | 195 | ||
212 | skb_push(skb, header_align); | 196 | /* Reserve the amount of space needed in front of the frame */ |
213 | memmove(skb->data, skb->data + header_align, header_length); | 197 | skb_push(skb, header_align); |
198 | |||
199 | /* | ||
200 | * Move the header. | ||
201 | */ | ||
202 | memmove(skb->data, skb->data + header_align, header_length); | ||
203 | |||
204 | /* Move the payload, if present and if required */ | ||
205 | if (payload_length && payload_align) | ||
214 | memmove(skb->data + header_length + l2pad, | 206 | memmove(skb->data + header_length + l2pad, |
215 | skb->data + header_length + l2pad + payload_align, | 207 | skb->data + header_length + l2pad + payload_align, |
216 | frame_length - header_length); | 208 | payload_length); |
217 | skb_trim(skb, frame_length + l2pad); | 209 | |
218 | } | 210 | /* Trim the skb to the correct size */ |
211 | skb_trim(skb, header_length + l2pad + payload_length); | ||
219 | } | 212 | } |
220 | 213 | ||
221 | void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) | 214 | void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) |
@@ -343,7 +336,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
343 | * Header and alignment information. | 336 | * Header and alignment information. |
344 | */ | 337 | */ |
345 | txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); | 338 | txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); |
346 | if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags)) | 339 | if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags) && |
340 | (entry->skb->len > txdesc->header_length)) | ||
347 | txdesc->l2pad = L2PAD_SIZE(txdesc->header_length); | 341 | txdesc->l2pad = L2PAD_SIZE(txdesc->header_length); |
348 | 342 | ||
349 | /* | 343 | /* |