ath9k: Setup MFP options for CCMP
authorJouni Malinen <j@w1.fi>
Thu, 8 Jan 2009 11:32:13 +0000 (13:32 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Thu, 29 Jan 2009 21:00:10 +0000 (16:00 -0500)
Configure hardware CCMP for management frame protection and use
software crypto when needed.

Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath9k/ath9k.h
drivers/net/wireless/ath9k/hw.c
drivers/net/wireless/ath9k/main.c
drivers/net/wireless/ath9k/recv.c
drivers/net/wireless/ath9k/reg.h

index f2ad62536bf8212c81a23176a8ef50bbfbcfee8a..3817645b85dca4965608dd4db6a43c4dc075d703 100644 (file)
@@ -809,6 +809,8 @@ struct ath_hal {
 #ifndef ATH_NF_PER_CHAN
        struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
 #endif
+
+       bool sw_mgmt_crypto;
 };
 
 struct chan_centers {
index 3c026e6b245380b26ec1eab0ef5f15cf322ba225..e9a3951996e270efbe87e7a0702fae8cf65c8d77 100644 (file)
@@ -2265,6 +2265,23 @@ int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
        if (r)
                return r;
 
+       /* Setup MFP options for CCMP */
+       if (AR_SREV_9280_20_OR_LATER(ah)) {
+               /* Mask Retry(b11), PwrMgt(b12), MoreData(b13) to 0 in mgmt
+                * frames when constructing CCMP AAD. */
+               REG_RMW_FIELD(ah, AR_AES_MUTE_MASK1, AR_AES_MUTE_MASK1_FC_MGMT,
+                             0xc7ff);
+               ah->sw_mgmt_crypto = false;
+       } else if (AR_SREV_9160_10_OR_LATER(ah)) {
+               /* Disable hardware crypto for management frames */
+               REG_CLR_BIT(ah, AR_PCU_MISC_MODE2,
+                           AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE);
+               REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
+                           AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT);
+               ah->sw_mgmt_crypto = true;
+       } else
+               ah->sw_mgmt_crypto = true;
+
        if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
                ath9k_hw_set_delta_slope(ah, chan);
 
index fc4439f97506b8b3fc2068d1175a96217fb1f101..72f2956c4c54c6559f0f25264070394a10bc36a1 100644 (file)
@@ -1557,6 +1557,9 @@ static int ath_attach(u16 devid, struct ath_softc *sc)
                IEEE80211_HW_SIGNAL_DBM |
                IEEE80211_HW_AMPDU_AGGREGATION;
 
+       if (AR_SREV_9160_10_OR_LATER(sc->sc_ah))
+               hw->flags |= IEEE80211_HW_MFP_CAPABLE;
+
        hw->wiphy->interface_modes =
                BIT(NL80211_IFTYPE_AP) |
                BIT(NL80211_IFTYPE_STATION) |
@@ -2348,6 +2351,8 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
                        key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
                        if (key->alg == ALG_TKIP)
                                key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
+                       if (sc->sc_ah->sw_mgmt_crypto && key->alg == ALG_CCMP)
+                               key->flags |= IEEE80211_KEY_FLAG_SW_MGMT;
                        ret = 0;
                }
                break;
index 462e08c3d09dc4cf18693f4e39c383a7dc34c580..dbf24be23ccbd3cf4c89f57e52841dacbdb6a894 100644 (file)
@@ -593,6 +593,12 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
                        if (test_bit(keyix, sc->sc_keymap))
                                rx_status.flag |= RX_FLAG_DECRYPTED;
                }
+               if (ah->sw_mgmt_crypto &&
+                   (rx_status.flag & RX_FLAG_DECRYPTED) &&
+                   ieee80211_is_mgmt(hdr->frame_control)) {
+                       /* Use software decrypt for management frames. */
+                       rx_status.flag &= ~RX_FLAG_DECRYPTED;
+               }
 
                /* Send the frame to mac80211 */
                __ieee80211_rx(sc->hw, skb, &rx_status);
index 9a615224e4f74c139b2476465ed33cdb86ee6586..2dffe371ffe418f0e119045ec30e0c0897b6ba36 100644 (file)
@@ -1253,6 +1253,8 @@ enum {
 
 #define AR_AES_MUTE_MASK1       0x8060
 #define AR_AES_MUTE_MASK1_SEQ   0x0000FFFF
+#define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
+#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
 
 #define AR_GATED_CLKS       0x8064
 #define AR_GATED_CLKS_TX    0x00000002
@@ -1477,6 +1479,10 @@ enum {
 #define AR_PCU_TXBUF_CTRL_USABLE_SIZE   0x700
 #define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE   0x380
 
+#define AR_PCU_MISC_MODE2               0x8344
+#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE           0x00000002
+#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT   0x00000004
+
 #define AR_KEYTABLE_0           0x8800
 #define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
 #define AR_KEY_CACHE_SIZE       128