Commit 77e73d18 authored by Gertjan van Wingerde's avatar Gertjan van Wingerde Committed by John W. Linville

rt2x00: Further L2 padding fixes.

Fix a couple of more bugs in the L2 padding code:
1. Compute the amount of L2 padding correctly (in 3 places).
2. Trim the skb correctly when the L2 padding has been applied.

Also introduce a central macro the compute the L2 padding size.
Signed-off-by: default avatarGertjan van Wingerde <gwingerde@gmail.com>
Acked-by: default avatarIvo van Doorn <ivdoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 1398d458
...@@ -103,6 +103,12 @@ ...@@ -103,6 +103,12 @@
#define GET_DURATION(__size, __rate) (((__size) * 8 * 10) / (__rate)) #define GET_DURATION(__size, __rate) (((__size) * 8 * 10) / (__rate))
#define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate)) #define GET_DURATION_RES(__size, __rate)(((__size) * 8 * 10) % (__rate))
/*
* Determine the number of L2 padding bytes required between the header and
* the payload.
*/
#define L2PAD_SIZE(__hdrlen) (-(__hdrlen) & 3)
/* /*
* Determine the alignment requirement, * Determine the alignment requirement,
* to make sure the 802.11 payload is padded to a 4-byte boundrary * to make sure the 802.11 payload is padded to a 4-byte boundrary
......
...@@ -181,7 +181,7 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) ...@@ -181,7 +181,7 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
unsigned int frame_length = skb->len; unsigned int frame_length = skb->len;
unsigned int header_align = ALIGN_SIZE(skb, 0); unsigned int header_align = ALIGN_SIZE(skb, 0);
unsigned int payload_align = ALIGN_SIZE(skb, header_length); unsigned int payload_align = ALIGN_SIZE(skb, header_length);
unsigned int l2pad = 4 - (payload_align - header_align); unsigned int l2pad = L2PAD_SIZE(header_length);
if (header_align == payload_align) { if (header_align == payload_align) {
/* /*
...@@ -216,6 +216,7 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) ...@@ -216,6 +216,7 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
memmove(skb->data + header_length + l2pad, memmove(skb->data + header_length + l2pad,
skb->data + header_length + l2pad + payload_align, skb->data + header_length + l2pad + payload_align,
frame_length - header_length); frame_length - header_length);
skb_trim(skb, frame_length + l2pad);
skbdesc->flags |= SKBDESC_L2_PADDED; skbdesc->flags |= SKBDESC_L2_PADDED;
} }
} }
...@@ -223,7 +224,7 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length) ...@@ -223,7 +224,7 @@ void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length) void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
{ {
struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb);
unsigned int l2pad = 4 - (header_length & 3); unsigned int l2pad = L2PAD_SIZE(header_length);
if (!l2pad || (skbdesc->flags & SKBDESC_L2_PADDED)) if (!l2pad || (skbdesc->flags & SKBDESC_L2_PADDED))
return; return;
...@@ -346,7 +347,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, ...@@ -346,7 +347,8 @@ static void rt2x00queue_create_tx_descriptor(struct queue_entry *entry,
* Header and alignment information. * Header and alignment information.
*/ */
txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb); txdesc->header_length = ieee80211_get_hdrlen_from_skb(entry->skb);
txdesc->l2pad = ALIGN_SIZE(entry->skb, txdesc->header_length); if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
txdesc->l2pad = L2PAD_SIZE(txdesc->header_length);
/* /*
* Check whether this frame is to be acked. * Check whether this frame is to be acked.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment