Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Feb 2011 15:23:17 +0000 (UTC)
From:      Adrian Chadd <adrian@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r218483 - in head/sys/dev/ath: . ath_hal/ar5212
Message-ID:  <201102091523.p19FNHa1088397@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: adrian
Date: Wed Feb  9 15:23:16 2011
New Revision: 218483
URL: http://svn.freebsd.org/changeset/base/218483

Log:
  Fix the keycache behaviour for multicast keycache search.
  
  The correct bit to set is 0x1 in the high MAC address byte, not 0x80.
  The hardware isn't programmed with that bit (which is the multicast
  adress bit.)
  
  The linux ath9k keycache code uses that bit in the MAC as a "this is
  a multicast key!" and doesn't set the AR_KEYTABLE_VALID bit.
  This tells the hardware the MAC isn't to be used for unicast destination
  matching but it can be used for multicast bssid traffic.
  
  This fixes some encryption problems in station mode.
  
  PR: kern/154598

Modified:
  head/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c
  head/sys/dev/ath/if_ath.c

Modified: head/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c
==============================================================================
--- head/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c	Wed Feb  9 14:37:33 2011	(r218482)
+++ head/sys/dev/ath/ath_hal/ar5212/ar5212_keycache.c	Wed Feb  9 15:23:16 2011	(r218483)
@@ -99,11 +99,18 @@ ar5212ResetKeyCacheEntry(struct ath_hal 
 /*
  * Sets the mac part of the specified key cache entry (and any
  * associated MIC entry) and mark them valid.
+ *
+ * Since mac[0] is shifted off and not presented to the hardware,
+ * it does double duty as a "don't use for unicast, use for multicast
+ * matching" flag. This interface should later be extended to
+ * explicitly do that rather than overloading a bit in the MAC
+ * address.
  */
 HAL_BOOL
 ar5212SetKeyCacheEntryMac(struct ath_hal *ah, uint16_t entry, const uint8_t *mac)
 {
 	uint32_t macHi, macLo;
+	uint32_t unicast_flag = AR_KEYTABLE_VALID;
 
 	if (entry >= AH_PRIVATE(ah)->ah_caps.halKeyCacheSize) {
 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: entry %u out of range\n",
@@ -115,6 +122,16 @@ ar5212SetKeyCacheEntryMac(struct ath_hal
 	 * the 4 MSBs, and MacHi is the 2 LSBs.
 	 */
 	if (mac != AH_NULL) {
+		/*
+		 * AR_KEYTABLE_VALID indicates that the address is a unicast
+		 * address, which must match the transmitter address for
+		 * decrypting frames.
+		 * Not setting this bit allows the hardware to use the key
+		 * for multicast frame decryption.
+		 */
+		if (mac[0] & 0x01)
+			unicast_flag = 0;
+
 		macHi = (mac[5] << 8) | mac[4];
 		macLo = (mac[3] << 24)| (mac[2] << 16)
 		      | (mac[1] << 8) | mac[0];
@@ -125,7 +142,7 @@ ar5212SetKeyCacheEntryMac(struct ath_hal
 		macLo = macHi = 0;
 	}
 	OS_REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
-	OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
+	OS_REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | unicast_flag);
 	return AH_TRUE;
 }
 

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Wed Feb  9 14:37:33 2011	(r218482)
+++ head/sys/dev/ath/if_ath.c	Wed Feb  9 15:23:16 2011	(r218483)
@@ -1938,10 +1938,10 @@ ath_keyset(struct ath_softc *sc, const s
 		/*
 		 * Group keys on hardware that supports multicast frame
 		 * key search use a MAC that is the sender's address with
-		 * the high bit set instead of the app-specified address.
+		 * the multicast bit set instead of the app-specified address.
 		 */
 		IEEE80211_ADDR_COPY(gmac, bss->ni_macaddr);
-		gmac[0] |= 0x80;
+		gmac[0] |= 0x01;
 		mac = gmac;
 	} else
 		mac = k->wk_macaddr;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102091523.p19FNHa1088397>