LinuxKPI: 802.11: force update of net80211 crypto key flags
Several drivers (rtw8x, mt76) do not announce the supported ciphers suites in the wiphy instance. This means we never populate net80211 ic_cryptocaps on device creation and thus not announcing any supported hw crypto offload forcing a fallback to software crypto. However when the mac80211 (*set_key) succeeds we know we can offload crypto. At that point the net80211 key flags have IEEE80211_KEY_SWCRYPT set which we want to clear. Historically the net80211 API does not allow this though there should be no ill side effects (base on a quick code inspection). We thus have to DECONST the key argument for now. It is expected that with MFP support this will need to become a common operation and the API will need to change as we will only get the information of some details from the driver on a per-cipher case when the (*set_key) downcall returns. Sponsored by: The FreeBSD Foundation MFC after: 3 days
This commit is contained in:
@@ -1570,6 +1570,7 @@ lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
|
||||
struct ieee80211_sta *sta;
|
||||
struct ieee80211_node *ni;
|
||||
struct ieee80211_key_conf *kc;
|
||||
struct ieee80211_key *wk;
|
||||
uint32_t lcipher;
|
||||
uint16_t exp_flags;
|
||||
uint8_t keylen;
|
||||
@@ -1705,6 +1706,16 @@ lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
|
||||
kc, kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Getting here means we support HW crypto offload.
|
||||
* Some drivers do not set the wiphy [n_]cipher_suites and thus we
|
||||
* never populate ic_cryptocaps. which means SWCRYPT will be set and we
|
||||
* should disable this now (before possibly setting other SW flags
|
||||
* again for when we need partial SW support).
|
||||
*/
|
||||
wk = __DECONST(struct ieee80211_key *, k);
|
||||
wk->wk_flags &= ~IEEE80211_KEY_SWCRYPT;
|
||||
|
||||
exp_flags = 0;
|
||||
switch (kc->cipher) {
|
||||
case WLAN_CIPHER_SUITE_TKIP:
|
||||
@@ -1724,8 +1735,8 @@ lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
|
||||
#ifdef __notyet__
|
||||
/* Do flags surgery; special see linuxkpi_ieee80211_ifattach(). */
|
||||
if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) != 0) {
|
||||
k->wk_flags &= ~(IEEE80211_KEY_NOMICMGT|IEEE80211_KEY_NOMIC);
|
||||
k->wk_flags |= IEEE80211_KEY_SWMIC;
|
||||
wk->wk_flags &= ~(IEEE80211_KEY_NOMICMGT|IEEE80211_KEY_NOMIC);
|
||||
wk->wk_flags |= IEEE80211_KEY_SWMIC;
|
||||
ic->ic_cryptocaps &= ~IEEE80211_CRYPTO_TKIPMIC
|
||||
}
|
||||
#endif
|
||||
@@ -1748,9 +1759,9 @@ lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
|
||||
#ifdef __notyet__
|
||||
/* Do flags surgery. */
|
||||
if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV_MGMT) == 0)
|
||||
k->wk_flags |= IEEE80211_KEY_NOIVMGT;
|
||||
wk->wk_flags |= IEEE80211_KEY_NOIVMGT;
|
||||
if ((kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV) == 0)
|
||||
k->wk_flags |= IEEE80211_KEY_NOIV;
|
||||
wk->wk_flags |= IEEE80211_KEY_NOIV;
|
||||
#endif
|
||||
|
||||
ieee80211_free_node(ni);
|
||||
|
||||
Reference in New Issue
Block a user