Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0ced0e17 authored by Jouni Malinen's avatar Jouni Malinen Committed by John W. Linville
Browse files

ath9k: Setup MFP options for CCMP



Configure hardware CCMP for management frame protection and use
software crypto when needed.

Signed-off-by: default avatarJouni Malinen <jouni.malinen@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent ca470b29
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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 {
+17 −0
Original line number Diff line number Diff line
@@ -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);

+5 −0
Original line number Diff line number Diff line
@@ -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;
+6 −0
Original line number Diff line number Diff line
@@ -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);
+6 −0
Original line number Diff line number Diff line
@@ -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