I was not get getting DHCP replies back with ath5k on a AR5212. Turns out out of all filter flags if I enable AR5K_RX_FILTER_PROM I get my replies back. I've tested enabling AR5K_RX_FILTER_BCAST and AR5K_RX_FILTER_MCAST but AR5K_RX_FILTER_PROM only does the trick. This may fix this for other cards if you are not getting DHCP replies please let us know. For now we can enable AR5K_RX_FILTER_PROM on STA and Ad-hoc only for AR5212 until we sort out the filter flags properly. This patch also takes into account new changes to mac80211 for ieee80211_ops's set_key(). Filter API changes to come soon. In summary this patch has these changes: * AR5212 now receives broadcasts (DHCP works now) * ath5k_hw_set_key() was checking against key table size against key->keyid -- this can only be 0, 1, 2 or 3. Check against key->keylen and divide the table size by 8. * return proper values for WEP setting as per mac80211 documenation This patch applies to the ath5k branch of wireless-dev. Changes to ath5k_base.c Changes-licensed-under: BSD Changes to ath5k_hw.c, ath5k_reg.h Changes-licensed-under: ISC Signed-off-by: Luis R. Rodriguez <mcgrof@xxxxxxxxx> --- drivers/net/wireless/ath5k_base.c | 26 ++++++++++++++++++-------- 1 files changed, 18 insertions(+), 8 deletions(- drivers/net/wireless/ath5k_hw.c | 12 +++++++++--- drivers/net/wireless/ath5k_reg.h | 12 ++++++++++++ 2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/ath5k_base.c b/drivers/net/wireless/ath5k_base.c index fead9a7..c49a744 100644 --- a/drivers/net/wireless/ath5k_base.c +++ b/drivers/net/wireless/ath5k_base.c @@ -734,7 +734,7 @@ static u32 ath_calcrxfilter(struct ath_softc *sc) AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST | AR5K_RX_FILTER_MCAST | AR5K_RX_FILTER_RADARERR; - if (sc->opmode == IEEE80211_IF_TYPE_MNTR) + if (opmode == IEEE80211_IF_TYPE_MNTR) rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM; if (opmode != IEEE80211_IF_TYPE_STA) @@ -742,8 +742,14 @@ static u32 ath_calcrxfilter(struct ath_softc *sc) if (opmode != IEEE80211_IF_TYPE_AP && test_bit(ATH_STAT_PROMISC, sc->status)) rfilt |= AR5K_RX_FILTER_PROM; - if (opmode == IEEE80211_IF_TYPE_STA || opmode == IEEE80211_IF_TYPE_IBSS) + if (opmode == IEEE80211_IF_TYPE_STA || opmode == IEEE80211_IF_TYPE_IBSS) { rfilt |= AR5K_RX_FILTER_BEACON; + /* Note: AR5212 requires AR5K_RX_FILTER_PROM to receive broadcasts, + * perhaps the flags are off, for now to be safe we'll enable it for + * STA and ADHOC until we have this properly mapped */ + if (ah->ah_version == AR5K_AR5212) + rfilt |= AR5K_RX_FILTER_PROM; + } return rfilt; } @@ -1437,21 +1443,28 @@ static int ath_set_key(struct ieee80211_hw *hw, set_key_cmd cmd, struct ath_softc *sc = hw->priv; int ret = 0; + switch(key->alg) { + case ALG_WEP: + break; + case ALG_TKIP: + case ALG_CCMP: + return -EOPNOTSUPP; + case ALG_NONE: + break; + default: + WARN_ON(1); + return -EINVAL; + } + mutex_lock(&sc->lock); switch (cmd) { case SET_KEY: - if (key->alg != ALG_WEP && key->alg != ALG_NONE) { - ret = -EINVAL; - goto unlock; - } - ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, addr); if (ret) { printk(KERN_ERR "ath: can't set the key\n"); goto unlock; } - __set_bit(key->keyidx, sc->keymap); key->hw_key_idx = key->keyidx; break; diff --git a/drivers/net/wireless/ath5k_hw.c b/drivers/net/wireless/ath5k_hw.c index e4cc307..24b717b 100644 --- a/drivers/net/wireless/ath5k_hw.c +++ b/drivers/net/wireless/ath5k_hw.c @@ -3181,21 +3181,27 @@ int ath5k_hw_set_key(struct ath_hw *hal, u16 entry, u32 keytype; AR5K_TRACE; - AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); + + /* key->keylen comes in from mac80211 in bytes */ + + if (key->keylen > AR5K_KEYTABLE_SIZE / 8) + return -EOPNOTSUPP; switch (key->keylen) { + /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */ case 40 / 8: memcpy(&key_v[0], key->key, 5); keytype = AR5K_KEYTABLE_TYPE_40; break; + /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */ case 104 / 8: memcpy(&key_v[0], &key->key[0], 6); memcpy(&key_v[2], &key->key[6], 6); memcpy(&key_v[4], &key->key[12], 1); keytype = AR5K_KEYTABLE_TYPE_104; break; - + /* WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */ case 128 / 8: memcpy(&key_v[0], &key->key[0], 6); memcpy(&key_v[2], &key->key[6], 6); @@ -3204,7 +3210,7 @@ int ath5k_hw_set_key(struct ath_hw *hal, u16 entry, break; default: - return -EINVAL; + return -EINVAL; /* shouldn't happen */ } for (i = 0; i < ARRAY_SIZE(key_v); i++) diff --git a/drivers/net/wireless/ath5k_reg.h b/drivers/net/wireless/ath5k_reg.h index 1d53a9e..e5ce840 100644 --- a/drivers/net/wireless/ath5k_reg.h +++ b/drivers/net/wireless/ath5k_reg.h @@ -1588,6 +1588,18 @@ #define AR5K_KEYTABLE_MAC1(_n) AR5K_KEYTABLE_OFF(_n, 7) #define AR5K_KEYTABLE_VALID 0x00008000 +/* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit + * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit + * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit + * + * Some vendors have introduced bigger WEP keys to address + * security vulnerabilities in WEP. This includes: + * + * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit + * + * We can expand this if we find ar5k Atheros cards with a larger + * key table size. + */ #define AR5K_KEYTABLE_SIZE_5210 64 #define AR5K_KEYTABLE_SIZE_5211 128 #define AR5K_KEYTABLE_SIZE (hal->ah_version == AR5K_AR5210 ? \