git: 31ded414b128 - main - LinuxKPI: 802.11: force update of net80211 crypto key flags

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Sun, 14 Jun 2026 22:32:27 UTC
The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=31ded414b1282abdebcb24c18cc6dbebf84210f2

commit 31ded414b1282abdebcb24c18cc6dbebf84210f2
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2026-06-13 11:25:42 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2026-06-14 22:31:38 +0000

    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
---
 sys/compat/linuxkpi/common/src/linux_80211.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index b9ac7056f868..23b5009c0384 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -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);