Latest working kernel version: n/a Earliest failing kernel version: 2.6.28-rc6-wl Distribution: Ubuntu / Debian Hardware Environment: CM9 Atheros 802.11abg card Software Environment: Problem Description: missing 2 FCS bytes Steps to reproduce: 1. Load ath5k and mac80211 2. Create a monitor interface (iw phy phy0 interface add mon0 type monitor) 3. Run wireshark on it (wireshark -i mon0 -k) 4. Check for 802.11 ACK frames The FCS field (last bytes of the frame) is only 2 bytes instead of 4 bytes.
I'm seeing the same on 2.6.28-rc5 with this hardware: 00:0c.0 Ethernet controller: Atheros Communications Inc. AR5212/AR5213 Multiprotocol MAC/baseband processor (rev 01) Subsystem: Accton Technology Corporation Device ee23 Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV+ VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 168 (2500ns min, 7000ns max), Cache Line Size: 64 bytes Interrupt: pin A routed to IRQ 16 Region 0: Memory at ff610000 (32-bit, non-prefetchable) [size=64K] Capabilities: <access denied> Kernel driver in use: ath5k_pci Kernel modules: ath5k The radiotap header contains "00000000" as FCS value, the real frame is two bytes short. Not sure if this is the reason, but hostapd never adds associated stations to the kernel because it doesn't receive the final ACK.
I've found the reason for the missing two bytes: /* * the hardware adds a padding to 4 byte boundaries between * the header and the payload data if the header length is * not multiples of 4 - remove it */ hdrlen = ieee80211_get_hdrlen_from_skb(skb); if (hdrlen & 3) { pad = hdrlen % 4; memmove(skb->data + pad, skb->data, hdrlen); skb_pull(skb, pad); } For ACKs with an headerlen of ten, it strips the first two byte of the FCS. Since I don't have documentation, I don't know which frames exactly should be skipped above, simply skipping all frames with hdrlen == 10 fixed the ACKs for me.
Nice find. Interesting, hdrlen == 10 would be control frames - ACK/CTS. I don't know the history of the pad removal but I wonder if it's valid. IIRC madwifi did that too.
For other frames it also triggers, but does no (apparent) harm. Perhaps it simply needs to check whether there actually is a payload: if (hdrlen & 3 && hdrlen != rs.rs_datalen - FCS_LEN) or something like that. But I'm just guessing around :)
Benoit, since John committed the patch for this can you close the bug?