Skip to contentSkip to conversation

ath5k: Update PCU code

PATCH In review Nick Kossifidis 3 participants 8 messages Oct 29, 2008 – Oct 30, 2008 Networking drivers (wireless)

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ath5k: Update PCU code

* In set_opmode don't handle antenna settings and preserve other STA_ID1 settings (shouldn't matter because we call it during reset but it makes things cleaner) Also set properly AP/ADHOC indicator flag on CFG while setting AP/ADHOC modes and always enable key search mode.

* Properly set BSSID Mask during reset (cache it and reuse it durring set_associd)

* Update beacon_init to flush pending BMISS interrupts and handle setting of adhoc beacon ATIM policy flag for ad-hoc mode. Also set TSF to 0 to start TSF increment on AP mode. We need to handle sleep timers for AR5212 there + add support for PCF.

* Properly clean MIC key from keytable when TKIP is used (Bob is working on set_key function etc so i leave it for now).

Tested on AR5212 (Hainan) and AR5413 and works fine

Changes-Licensed-under: ISC

---

drivers/net/wireless/ath5k/ath5k.h +2 -1
index b117920..a725bb9 100644
@@ -1093,10 +1093,11 @@ struct ath5k_hw {
 
 	u8			ah_sta_id[ETH_ALEN];
 
-	/* Current BSSID we are trying to assoc to / creating.
+	/* Current BSSID we are trying to assoc to / create.
 	 * This is passed by mac80211 on config_interface() and cached here for
 	 * use in resets */
 	u8			ah_bssid[ETH_ALEN];
+	u8			ah_bssid_mask[ETH_ALEN];
 
 	u32			ah_gpio[AR5K_MAX_GPIO];
 	int			ah_gpio_npins;
drivers/net/wireless/ath5k/pcu.c +88 -20

203 lines not on this page · raw message

drivers/net/wireless/ath5k/reg.h +9 -3
index 0dae54d..69755fc 100644
@@ -1114,14 +1114,16 @@
 #define AR5K_PCU_MAX	0x8fff
 
 /*
- * First station id register (MAC address in lower 32 bits)
+ * First station id register (Lower 32 bits of MAC address)
  */
-#define AR5K_STA_ID0	0x8000
+#define AR5K_STA_ID0		0x8000
+#define	AR5K_STA_ID0_ARRD_L32	0xffffffff
 
 /*
- * Second station id register (MAC address in upper 16 bits)
+ * Second station id register (Upper 16 bits of MAC address + PCU settings)
  */
 #define AR5K_STA_ID1			0x8004			/* Register Address */
+#define	AR5K_STA_ID1_ADDR_U16		0x0000ffff	/* Upper 16 bits of MAC addres */
 #define AR5K_STA_ID1_AP			0x00010000	/* Set AP mode */
 #define AR5K_STA_ID1_ADHOC		0x00020000	/* Set Ad-Hoc mode */
 #define AR5K_STA_ID1_PWR_SV		0x00040000	/* Power save reporting */
@@ -1811,6 +1813,10 @@
 #define AR5K_KEYTABLE_MAC1(_n)		AR5K_KEYTABLE_OFF(_n, 7)
 #define AR5K_KEYTABLE_VALID		0x00008000
 
+/* If key type is TKIP and MIC is enabled
+ * MIC key goes in offset entry + 64 */
+#define	AR5K_KEYTABLE_MIC_OFFSET	64
+
 /* 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
#1 lore raw

* In set_opmode don't handle antenna settings and preserve other STA_ID1 settings (shouldn't matter because we call it during reset but it makes things cleaner) Also set properly AP/ADHOC indicator flag on CFG while setting AP/ADHOC modes and always enable key search mode.

* Properly set BSSID Mask during reset (cache it and reuse it durring set_associd)

* Update beacon_init to flush pending BMISS interrupts and handle setting of adhoc beacon ATIM policy flag for ad-hoc mode. Also set TSF to 0 to start TSF increment on AP mode. We need to handle sleep timers for AR5212 there + add support for PCF.

* Properly clean MIC key from keytable when TKIP is used (Bob is working on set_key function etc so i leave it for now).

Tested on AR5212 (Hainan) and AR5413 and works fine

v2 Set PISR on AR5211+ and ISR on AR5210, got to sleep more ;-)

Changes-Licensed-under: ISC

---

drivers/net/wireless/ath5k/ath5k.h +2 -1
index b117920..a725bb9 100644
@@ -1093,10 +1093,11 @@ struct ath5k_hw {
 
 	u8			ah_sta_id[ETH_ALEN];
 
-	/* Current BSSID we are trying to assoc to / creating.
+	/* Current BSSID we are trying to assoc to / create.
 	 * This is passed by mac80211 on config_interface() and cached here for
 	 * use in resets */
 	u8			ah_bssid[ETH_ALEN];
+	u8			ah_bssid_mask[ETH_ALEN];
 
 	u32			ah_gpio[AR5K_MAX_GPIO];
 	int			ah_gpio_npins;
drivers/net/wireless/ath5k/pcu.c +91 -20

206 lines not on this page · raw message

drivers/net/wireless/ath5k/reg.h +9 -3
index 0dae54d..69755fc 100644
@@ -1114,14 +1114,16 @@
 #define AR5K_PCU_MAX	0x8fff
 
 /*
- * First station id register (MAC address in lower 32 bits)
+ * First station id register (Lower 32 bits of MAC address)
  */
-#define AR5K_STA_ID0	0x8000
+#define AR5K_STA_ID0		0x8000
+#define	AR5K_STA_ID0_ARRD_L32	0xffffffff
 
 /*
- * Second station id register (MAC address in upper 16 bits)
+ * Second station id register (Upper 16 bits of MAC address + PCU settings)
  */
 #define AR5K_STA_ID1			0x8004			/* Register Address */
+#define	AR5K_STA_ID1_ADDR_U16		0x0000ffff	/* Upper 16 bits of MAC addres */
 #define AR5K_STA_ID1_AP			0x00010000	/* Set AP mode */
 #define AR5K_STA_ID1_ADHOC		0x00020000	/* Set Ad-Hoc mode */
 #define AR5K_STA_ID1_PWR_SV		0x00040000	/* Power save reporting */
@@ -1811,6 +1813,10 @@
 #define AR5K_KEYTABLE_MAC1(_n)		AR5K_KEYTABLE_OFF(_n, 7)
 #define AR5K_KEYTABLE_VALID		0x00008000
 
+/* If key type is TKIP and MIC is enabled
+ * MIC key goes in offset entry + 64 */
+#define	AR5K_KEYTABLE_MIC_OFFSET	64
+
 /* 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
#2 lore raw
In reply to Nick Kossifidis
Quoted 2 lines · Nick Kossifidis

* Properly clean MIC key from keytable when TKIP is used (Bob is working on set_key function etc so i leave it for now).

Heh, I was just prepping patches to send out. I had basically the same thing for _reset_key too so I'll just rebase mine on top of this.

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

2008/10/29 Bob Copeland <[email protected]>:

Quoted 7 lines · Nick Kossifidis
Quoted 2 lines

* Properly clean MIC key from keytable when TKIP is used (Bob is working on set_key function etc so i leave it for now).

Heh, I was just prepping patches to send out. I had basically the same thing for _reset_key too so I'll just rebase mine on top of this.

ACK, sorry for the bad coordination ;-(

Signature · 3 lines
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick
#4 lore raw
Quoted 10 lines · Nick Kossifidis

2008/10/29 Bob Copeland <[email protected]>:

Quoted 7 lines · Nick Kossifidis
Quoted 2 lines

* Properly clean MIC key from keytable when TKIP is used (Bob is working on set_key function etc so i leave it for now).

Heh, I was just prepping patches to send out. I had basically the same thing for _reset_key too so I'll just rebase mine on top of this.

ACK, sorry for the bad coordination ;-(

No worries, it was easy enough to drop that hunk. But I do think this:

drivers/net/wireless/ath5k/pcu.c int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr) · line 977

Quoted 9 lines
drivers/net/wireless/ath5k/pcu.c +9 -0
+       /* Reset associated MIC entry if TKIP
+        * is enabled located at offset (entry + 64) */
+       if (type == AR5K_KEYTABLE_TYPE_TKIP) {
+               entry = entry + AR5K_KEYTABLE_MIC_OFFSET;
+               AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+               for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++)
+                       ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
+       }
+

...should move a couple of lines down or use a temporary for the micentry slot; otherwise we are setting keytype to NULL in the mic entry and not the original key slot.

The only other difference in mine was I went ahead and reset the whole line instead of just the first 4 words... since nothing goes in that half of the cache line that's probably wasted effort, and the HAL does the above so it should be fine. I just wasn't sure if power-up state clears the keytype properly.

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

2008/10/29 Bob Copeland <[email protected]>:

Quoted 24 lines · Nick Kossifidis
Quoted 10 lines

2008/10/29 Bob Copeland <[email protected]>:

Quoted 7 lines · Nick Kossifidis
Quoted 2 lines

* Properly clean MIC key from keytable when TKIP is used (Bob is working on set_key function etc so i leave it for now).

Heh, I was just prepping patches to send out. I had basically the same thing for _reset_key too so I'll just rebase mine on top of this.

ACK, sorry for the bad coordination ;-(

No worries, it was easy enough to drop that hunk. But I do think this:

drivers/net/wireless/ath5k/pcu.c int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr) · line 977

Quoted 9 lines
drivers/net/wireless/ath5k/pcu.c +9 -0
+       /* Reset associated MIC entry if TKIP
+        * is enabled located at offset (entry + 64) */
+       if (type == AR5K_KEYTABLE_TYPE_TKIP) {
+               entry = entry + AR5K_KEYTABLE_MIC_OFFSET;
+               AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+               for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++)
+                       ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
+       }
+
Quoted 4 lines

...should move a couple of lines down or use a temporary for the micentry slot; otherwise we are setting keytype to NULL in the mic entry and not the original key slot.

Yup you are right, we should set both to NULL so a temp micentry var would do the trick.

Should i resend this one or you 'll resend yours ?

Signature · 3 lines
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick
#6 lore raw
Quoted 5 lines · Nick Kossifidis

2008/10/29 Bob Copeland <[email protected]>:
Yup you are right, we should set both to NULL so a temp micentry var would do the trick.

Should i resend this one or you 'll resend yours ?

Well I just decided to put this in a different patch. Then I saw the 5211 check.. we already read the type without such a check and the other tkip stuff may well all blow up on such hardware. So not sure what to do about that case.

Anyway feel free to just roll this up into your original patch, or to write it differently given the above.

From: Bob Copeland <[email protected]>
Subject: [PATCH] ath5k: fix keytable type buglet in ath5k_hw_reset_key

Be sure we clear out both the mic (if applicable) and the encryption key type.

---
 drivers/net/wireless/ath5k/pcu.c |   15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)
drivers/net/wireless/ath5k/pcu.c +11 -4
index 9b46d64..d7f0c10 100644
@@ -960,6 +960,7 @@ int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
 int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
 {
 	unsigned int i, type;
+	u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
 
 	ATH5K_TRACE(ah->ah_sc);
 	AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
@@ -972,10 +973,10 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
 	/* Reset associated MIC entry if TKIP
 	 * is enabled located at offset (entry + 64) */
 	if (type == AR5K_KEYTABLE_TYPE_TKIP) {
-		entry = entry + AR5K_KEYTABLE_MIC_OFFSET;
-		AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+		AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE);
 		for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++)
-			ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
+			ath5k_hw_reg_write(ah, 0,
+				AR5K_KEYTABLE_OFF(micentry, i));
 	}
 
 	/*
@@ -987,10 +988,16 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
 	 * Note2: Windows driver (ndiswrapper) sets this to
 	 *        0x00000714 instead of 0x00000007
 	 */
-	if (ah->ah_version > AR5K_AR5211)
+	if (ah->ah_version > AR5K_AR5211) {
 		ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
 				AR5K_KEYTABLE_TYPE(entry));
 
+		if (type == AR5K_KEYTABLE_TYPE_TKIP) {
+			ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+				AR5K_KEYTABLE_TYPE(micentry));
+		}
+	}
+
 	return 0;
 }
 
Signature · 6 lines
1.5.4.2.182.gb3092



-- 
Bob Copeland %% www.bobcopeland.com
#7 lore raw

2008/10/30 Bob Copeland <[email protected]>:

Quoted 60 lines · Nick Kossifidis
Quoted 5 lines

2008/10/29 Bob Copeland <[email protected]>:
Yup you are right, we should set both to NULL so a temp micentry var would do the trick.

Should i resend this one or you 'll resend yours ?

Well I just decided to put this in a different patch. Then I saw the 5211 check.. we already read the type without such a check and the other tkip stuff may well all blow up on such hardware. So not sure what to do about that case.

Anyway feel free to just roll this up into your original patch, or to write it differently given the above.

From: Bob Copeland <[email protected]>
Subject: [PATCH] ath5k: fix keytable type buglet in ath5k_hw_reset_key

Be sure we clear out both the mic (if applicable) and the encryption key type.

---
 drivers/net/wireless/ath5k/pcu.c |   15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)
drivers/net/wireless/ath5k/pcu.c +5 -4
index 9b46d64..d7f0c10 100644
@@ -960,6 +960,7 @@ int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
 int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
 {
       unsigned int i, type;
+       u16 micentry = entry + AR5K_KEYTABLE_MIC_OFFSET;
 
       ATH5K_TRACE(ah->ah_sc);
       AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
@@ -972,10 +973,10 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
       /* Reset associated MIC entry if TKIP
        * is enabled located at offset (entry + 64) */
       if (type == AR5K_KEYTABLE_TYPE_TKIP) {
-               entry = entry + AR5K_KEYTABLE_MIC_OFFSET;
-               AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
+               AR5K_ASSERT_ENTRY(micentry, AR5K_KEYTABLE_SIZE);
               for (i = 0; i < AR5K_KEYCACHE_SIZE / 2 ; i++)
-                       ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
+                       ath5k_hw_reg_write(ah, 0,
+                               AR5K_KEYTABLE_OFF(micentry, i));
       }
 
       /*
@@ -987,10 +988,16 @@ int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
        * Note2: Windows driver (ndiswrapper) sets this to
        *        0x00000714 instead of 0x00000007
        */
-       if (ah->ah_version > AR5K_AR5211)
+       if (ah->ah_version > AR5K_AR5211) {
               ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
                               AR5K_KEYTABLE_TYPE(entry));

drivers/net/wireless/ath5k/pcu.c int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) · line 1003

Quoted 10 lines
drivers/net/wireless/ath5k/pcu.c +6 -0
 
+               if (type == AR5K_KEYTABLE_TYPE_TKIP) {
+                       ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
+                               AR5K_KEYTABLE_TYPE(micentry));
+               }
+       }
+
       return 0;
 }
 

Let's apply this for now and i'll take a look on what's going on for AR5211 (i don't know if TKIP/MIC is supported or not right now, i'll have to test this). Let's finish with AR5212 first (i also have a patch for QCU updates pending) since many people want AR5212 hw encryption support ;-)

Signature · 3 lines
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick