diff options
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00queue.c')
-rw-r--r-- | drivers/net/wireless/rt2x00/rt2x00queue.c | 50 |
1 files changed, 12 insertions, 38 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 8e68f87ab13c..66ff36447b94 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -158,55 +158,29 @@ void rt2x00queue_align_frame(struct sk_buff *skb) | |||
158 | skb_trim(skb, frame_length); | 158 | skb_trim(skb, frame_length); |
159 | } | 159 | } |
160 | 160 | ||
161 | void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) | 161 | /* |
162 | * H/W needs L2 padding between the header and the paylod if header size | ||
163 | * is not 4 bytes aligned. | ||
164 | */ | ||
165 | void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int hdr_len) | ||
162 | { | 166 | { |
163 | unsigned int payload_length = skb->len - header_length; | 167 | unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0; |
164 | unsigned int header_align = ALIGN_SIZE(skb, 0); | ||
165 | unsigned int payload_align = ALIGN_SIZE(skb, header_length); | ||
166 | unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0; | ||
167 | 168 | ||
168 | /* | 169 | if (!l2pad) |
169 | * Adjust the header alignment if the payload needs to be moved more | ||
170 | * than the header. | ||
171 | */ | ||
172 | if (payload_align > header_align) | ||
173 | header_align += 4; | ||
174 | |||
175 | /* There is nothing to do if no alignment is needed */ | ||
176 | if (!header_align) | ||
177 | return; | 170 | return; |
178 | 171 | ||
179 | /* Reserve the amount of space needed in front of the frame */ | 172 | skb_push(skb, l2pad); |
180 | skb_push(skb, header_align); | 173 | memmove(skb->data, skb->data + l2pad, hdr_len); |
181 | |||
182 | /* | ||
183 | * Move the header. | ||
184 | */ | ||
185 | memmove(skb->data, skb->data + header_align, header_length); | ||
186 | |||
187 | /* Move the payload, if present and if required */ | ||
188 | if (payload_length && payload_align) | ||
189 | memmove(skb->data + header_length + l2pad, | ||
190 | skb->data + header_length + l2pad + payload_align, | ||
191 | payload_length); | ||
192 | |||
193 | /* Trim the skb to the correct size */ | ||
194 | skb_trim(skb, header_length + l2pad + payload_length); | ||
195 | } | 174 | } |
196 | 175 | ||
197 | void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) | 176 | void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int hdr_len) |
198 | { | 177 | { |
199 | /* | 178 | unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0; |
200 | * L2 padding is only present if the skb contains more than just the | ||
201 | * IEEE 802.11 header. | ||
202 | */ | ||
203 | unsigned int l2pad = (skb->len > header_length) ? | ||
204 | L2PAD_SIZE(header_length) : 0; | ||
205 | 179 | ||
206 | if (!l2pad) | 180 | if (!l2pad) |
207 | return; | 181 | return; |
208 | 182 | ||
209 | memmove(skb->data + l2pad, skb->data, header_length); | 183 | memmove(skb->data + l2pad, skb->data, hdr_len); |
210 | skb_pull(skb, l2pad); | 184 | skb_pull(skb, l2pad); |
211 | } | 185 | } |
212 | 186 | ||