Skip to contentSkip to conversation

ath9k: Do not remove header padding on RX from short frames

PATCH New Jouni Malinen 4 participants 5 messages Dec 11, 2008 – Dec 13, 2008 Networking drivers (wireless)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ath9k: Do not remove header padding on RX from short frames

The 802.11 header is only padded to 32-bit boundary when the frame has a non-zero length payload. In other words, control frames (e.g., ACK) do not have a padding and we should not try to remove it. This fixes monitor mode for short control frames. In addition, the hdrlen&3 use is described in more detail to make it easier to understand how the padding length is calculated.

---
 drivers/net/wireless/ath9k/recv.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/net/wireless/ath9k/recv.c +10 -2
@@ -571,8 +571,16 @@ int ath_rx_tasklet(struct ath_softc *sc,
 		hdr = (struct ieee80211_hdr *)skb->data;
 		hdrlen = ieee80211_get_hdrlen_from_skb(skb);
 
-		if (hdrlen & 3) {
-			padsize = hdrlen % 4;
+		/* The MAC header is padded to have 32-bit boundary if the
+		 * packet payload is non-zero. The general calculation for
+		 * padsize would take into account odd header lengths:
+		 * padsize = (4 - hdrlen % 4) % 4; However, since only
+		 * even-length headers are used, padding can only be 0 or 2
+		 * bytes and we can optimize this a bit. In addition, we must
+		 * not try to remove padding from short control frames that do
+		 * not have payload. */
+		padsize = hdrlen & 3;
+		if (padsize && hdrlen >= 24) {
 			memmove(skb->data + padsize, skb->data, hdrlen);
 			skb_pull(skb, padsize);
 		}
Signature · 1 line
Jouni Malinen                                            PGP id EFC895FA
#1 lore raw

PATCH 1/1 ath9k: Do not remove header padding on RX from short frames

Quoted 4 lines · Jouni Malinen

The 802.11 header is only padded to 32-bit boundary when the frame has a non-zero length payload. In other words, control frames (e.g., ACK) do not have a padding and we should not try to remove it. This fixes monitor mode for short control frames.

Thanks Jouni, that clears up the question of the same code in ath5k
(http://marc.info/?l=linux-wireless&m=122888546315200&w=2).

Signature · 1 line
Bob Copeland %% www.bobcopeland.com
#2 lore raw

PATCH 1/1 ath9k: Do not remove header padding on RX from short frames

Quoted 7 lines · Bob Copeland
Quoted 2 lines · Jouni Malinen

The 802.11 header is only padded to 32-bit boundary when the frame has a non-zero length payload.

Thanks Jouni, that clears up the question of the same code in ath5k
(http://marc.info/?l=linux-wireless&m=122888546315200&w=2).

Yes, the same rules on 802.11 header padding applies to ath5k.

- Jouni

#3 lore raw

[ath9k-devel] 2.6.28-rc8-wl Connection status bug?

Hi,
I have been having this 'problem' since rc7
Just installed the above kernel as the change log indicate some changes in this area for ath9k.
The problem is that my router displays

	IP Address	Mode	Rate (Mbps)	Signal (%)
	0.0.0.0		802.11g	130		76

Now it should not be possible to get 130 out of 11g.

My router is set up to do both 11g/n, see below.
Prior to rc7 it used to show 11n and 300Mbps.

Not sure if it is relevant but I think the only thing I have changed in the router is turning on the Wi-Fi Protected Setup.

How can I provide more detail/tests

By the way, looking through the change log I cannot believe how much effort is going into this. Thanks one and all.

Brian

Wireless LAN
Wireless Radio : Enabled
802.11 Mode : Mixed 802.11n and 802.11g
Channel Width : 40MHz
Channel : 4
Secondary Channel : 8
WISH : Active
Wi-Fi Protected Setup : Enabled/Configured

#4 lore raw

PATCH 1/1 ath9k: Do not remove header padding on RX from short frames

In reply to Jouni Malinen
Quoted 21 lines · Jouni Malinen

The 802.11 header is only padded to 32-bit boundary when the frame has a non-zero length payload. In other words, control frames (e.g., ACK) do not have a padding and we should not try to remove it. This fixes monitor mode for short control frames. In addition, the hdrlen&3 use is described in more detail to make it easier to understand how the padding length is calculated.

---
 drivers/net/wireless/ath9k/recv.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/net/wireless/ath9k/recv.c 2008-12-11 12:18:02.000000000 +0200 renamed from drivers/net/wireless/ath9k/recv.c 2008-12-11 11:35:56.000000000 +0200 +0 -2
@@ -571,8 +571,16 @@ int ath_rx_tasklet(struct ath_softc *sc,
                hdr = (struct ieee80211_hdr *)skb->data;
                hdrlen = ieee80211_get_hdrlen_from_skb(skb);
 
-               if (hdrlen & 3) {
-                       padsize = hdrlen % 4;

drivers/net/wireless/ath9k/recv.c 2008-12-11 12:18:02.000000000 +0200 int ath_rx_tasklet(struct ath_softc *sc, · line 583

Quoted 10 lines
drivers/net/wireless/ath9k/recv.c 2008-12-11 12:18:02.000000000 +0200 renamed from drivers/net/wireless/ath9k/recv.c 2008-12-11 11:35:56.000000000 +0200 +10 -0
+               /* The MAC header is padded to have 32-bit boundary if the
+                * packet payload is non-zero. The general calculation for
+                * padsize would take into account odd header lengths:
+                * padsize = (4 - hdrlen % 4) % 4; However, since only
+                * even-length headers are used, padding can only be 0 or 2
+                * bytes and we can optimize this a bit. In addition, we must
+                * not try to remove padding from short control frames that do
+                * not have payload. */
+               padsize = hdrlen & 3;
+               if (padsize && hdrlen >= 24) {

I think "if(padsize && hdrlen > 24)" should be sufficient here as padsize is anyway zero for hdlen==24.

Quoted 10 lines
drivers/net/wireless/ath9k/recv.c 2008-12-11 12:18:02.000000000 +0200 renamed from drivers/net/wireless/ath9k/recv.c 2008-12-11 11:35:56.000000000 +0200 +0 -1
                        memmove(skb->data + padsize, skb->data, hdrlen);
                        skb_pull(skb, padsize);
                }
 
--

Jouni Malinen PGP id EFC895FA
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html