git: 98e55905ab8a - main - LinuxKPI: 802.11: lkpi_hw_crypto_prepare and lkpi_hw_crypto_tailroom
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 23 Apr 2025 16:25:19 UTC
The branch main has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=98e55905ab8ac34a0b88a1863c1b88e6fe3a8c13
commit 98e55905ab8ac34a0b88a1863c1b88e6fe3a8c13
Author: Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-04-15 20:59:45 +0000
Commit: Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-04-23 16:24:20 +0000
LinuxKPI: 802.11: lkpi_hw_crypto_prepare and lkpi_hw_crypto_tailroom
Split lkpi_hw_crypto_prepare() up per cipher suite and in addition to
the CCMP implementation start drafting the TKIP implementation.
Also add lkpi_hw_crypto_tailroom() dealing with any possible tailroom
we need to prepare for the driver to fill in details later.
Add support for that to lkpi_80211_txq_tx_one().
Sponsored by: The FreeBSD Foundation
MFC after: 3 days
---
sys/compat/linuxkpi/common/src/linux_80211.c | 130 ++++++++++++++++++++++-----
1 file changed, 110 insertions(+), 20 deletions(-)
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index 28c04c9b7a99..6fe41ddb1bb2 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -4609,34 +4609,56 @@ lkpi_ic_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
#ifdef LKPI_80211_HW_CRYPTO
static int
-lkpi_hw_crypto_prepare(struct lkpi_sta *lsta, struct ieee80211_key *k,
- struct sk_buff *skb)
+lkpi_hw_crypto_prepare_tkip(struct ieee80211_key *k,
+ struct ieee80211_key_conf *kc, struct sk_buff *skb)
{
- struct ieee80211_tx_info *info;
- struct ieee80211_key_conf *kc;
struct ieee80211_hdr *hdr;
uint32_t hlen, hdrlen;
- uint8_t *p;
+ uint8_t *p, *m;
- KASSERT(lsta != NULL, ("%s: lsta is NULL", __func__));
- KASSERT(k != NULL, ("%s: key is NULL", __func__));
- KASSERT(skb != NULL, ("%s: skb is NULL", __func__));
+ /*
+ * Check if we have anythig to do as requested by driver
+ * or if we are done?
+ */
+ if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) == 0 &&
+ (kc->flags & IEEE80211_KEY_FLAG_GENERATE_IV) == 0)
+ return (0);
- kc = lsta->kc[k->wk_keyix];
+ hlen = k->wk_cipher->ic_header;
+ if (skb_headroom(skb) < hlen)
+ return (ENOSPC);
- info = IEEE80211_SKB_CB(skb);
- info->control.hw_key = kc;
+ hdr = (void *)skb->data;
+ hdrlen = ieee80211_hdrlen(hdr->frame_control);
+ p = skb_push(skb, hlen);
+ memmove(p, p + hlen, hdrlen);
- /* MUST NOT happen. KASSERT? */
- if (kc == NULL) {
- ic_printf(lsta->ni->ni_ic, "%s: lsta %p k %p skb %p, "
- "kc is NULL on hw crypto offload\n", __func__, lsta, k, skb);
- return (ENXIO);
+ /*
+ * Put in zeroed space for the MMIC if requested.
+ * XXX-BZ in theory this is not the right place but given we
+ * are here we know we do hw_crypto so not much missing.
+ */
+ if ((kc->flags & IEEE80211_KEY_FLAG_PUT_MIC_SPACE) != 0) {
+ m = skb_put(skb, 8);
+ memset(m, 0, 8);
}
+ /* If driver request space only we are done. */
+ if ((kc->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) != 0)
+ return (0);
+
+ p += hdrlen;
+ k->wk_cipher->ic_setiv(k, p);
- IMPROVE("the following should be WLAN_CIPHER_SUITE specific");
- /* We currently only support CCMP so we hardcode things here. */
+ return (ENXIO);
+}
+static int
+lkpi_hw_crypto_prepare_ccmp(struct ieee80211_key *k,
+ struct ieee80211_key_conf *kc, struct sk_buff *skb)
+{
+ struct ieee80211_hdr *hdr;
+ uint32_t hlen, hdrlen;
+ uint8_t *p;
hdr = (void *)skb->data;
@@ -4668,6 +4690,67 @@ lkpi_hw_crypto_prepare(struct lkpi_sta *lsta, struct ieee80211_key *k,
return (0);
}
+
+static int
+lkpi_hw_crypto_prepare(struct lkpi_sta *lsta, struct ieee80211_key *k,
+ struct sk_buff *skb)
+{
+ struct ieee80211_tx_info *info;
+ struct ieee80211_key_conf *kc;
+
+ KASSERT(lsta != NULL, ("%s: lsta is NULL", __func__));
+ KASSERT(k != NULL, ("%s: key is NULL", __func__));
+ KASSERT(skb != NULL, ("%s: skb is NULL", __func__));
+
+ kc = lsta->kc[k->wk_keyix];
+
+ info = IEEE80211_SKB_CB(skb);
+ info->control.hw_key = kc;
+
+ /* MUST NOT happen. KASSERT? */
+ if (kc == NULL) {
+ ic_printf(lsta->ni->ni_ic, "%s: lsta %p k %p skb %p, "
+ "kc is NULL on hw crypto offload\n", __func__, lsta, k, skb);
+ return (ENXIO);
+ }
+
+ switch (kc->cipher) {
+ case WLAN_CIPHER_SUITE_TKIP:
+ return (lkpi_hw_crypto_prepare_tkip(k, kc, skb));
+ case WLAN_CIPHER_SUITE_CCMP:
+ return (lkpi_hw_crypto_prepare_ccmp(k, kc, skb));
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_CCMP_256:
+ case WLAN_CIPHER_SUITE_GCMP:
+ case WLAN_CIPHER_SUITE_GCMP_256:
+ case WLAN_CIPHER_SUITE_AES_CMAC:
+ case WLAN_CIPHER_SUITE_BIP_CMAC_256:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_128:
+ case WLAN_CIPHER_SUITE_BIP_GMAC_256:
+ default:
+ ic_printf(lsta->ni->ni_ic, "%s: lsta %p k %p kc %p skb %p, "
+ "unsupported cipher suite %u (%s)\n", __func__, lsta, k, kc,
+ skb, kc->cipher, lkpi_cipher_suite_to_name(kc->cipher));
+ return (EOPNOTSUPP);
+ }
+}
+
+static uint8_t
+lkpi_hw_crypto_tailroom(struct lkpi_sta *lsta, struct ieee80211_key *k)
+{
+ struct ieee80211_key_conf *kc;
+
+ kc = lsta->kc[k->wk_keyix];
+ if (kc == NULL)
+ return (0);
+
+ IMPROVE("which other flags need tailroom?");
+ if (kc->flags & (IEEE80211_KEY_FLAG_PUT_MIC_SPACE))
+ return (32); /* Large enough to hold everything and pow2. */
+
+ return (0);
+}
#endif
static void
@@ -4690,7 +4773,7 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
struct lkpi_txq *ltxq;
void *buf;
ieee80211_keyix keyix;
- uint8_t ac, tid;
+ uint8_t ac, tid, tailroom;
M_ASSERTPKTHDR(m);
#ifdef LINUXKPI_DEBUG_80211
@@ -4748,13 +4831,20 @@ lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
ieee80211_radiotap_tx(ni->ni_vap, m);
}
+#ifdef LKPI_80211_HW_CRYPTO
+ if (lkpi_hwcrypto && keyix != IEEE80211_KEYIX_NONE)
+ tailroom = lkpi_hw_crypto_tailroom(lsta, k);
+ else
+#endif
+ tailroom = 0;
+
/*
* net80211 should handle hw->extra_tx_headroom.
* Though for as long as we are copying we don't mind.
* XXX-BZ rtw88 asks for too much headroom for ipv6+tcp:
* https://lists.freebsd.org/archives/freebsd-transport/2022-February/000012.html
*/
- skb = dev_alloc_skb(hw->extra_tx_headroom + m->m_pkthdr.len);
+ skb = dev_alloc_skb(hw->extra_tx_headroom + tailroom + m->m_pkthdr.len);
if (skb == NULL) {
static uint8_t skb_alloc_failures = 0;