Search Linux Wireless

[PATCH] ath5k - Fix filters for AR5212, correct return values for WEP

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 ? \

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux