From: Gokul Sivakumar <gokulkumar.sivakumar@infineon.com>
To: <linux-wireless@vger.kernel.org>
Cc: Johannes Berg <johannes@sipsolutions.net>,
Arend van Spriel <arend.vanspriel@broadcom.com>,
<marex@nabladev.com>, <wlan-kernel-dev-list@infineon.com>,
<gokulkumar.sivakumar@infineon.com>
Subject: [PATCH wireless-next v2 03/34] wifi: inffmac: add he.c/h
Date: Wed, 14 Jan 2026 02:03:16 +0530 [thread overview]
Message-ID: <20260113203350.16734-4-gokulkumar.sivakumar@infineon.com> (raw)
In-Reply-To: <20260113203350.16734-1-gokulkumar.sivakumar@infineon.com>
Collect the 802.11ax HE capabilities of the Device and register it as part
of the wiphy capabilities in the cfg80211 driver.
Signed-off-by: Gokul Sivakumar <gokulkumar.sivakumar@infineon.com>
---
drivers/net/wireless/infineon/inffmac/he.c | 234 +++++++++++++++++++++
drivers/net/wireless/infineon/inffmac/he.h | 67 ++++++
2 files changed, 301 insertions(+)
create mode 100644 drivers/net/wireless/infineon/inffmac/he.c
create mode 100644 drivers/net/wireless/infineon/inffmac/he.h
diff --git a/drivers/net/wireless/infineon/inffmac/he.c b/drivers/net/wireless/infineon/inffmac/he.c
new file mode 100644
index 000000000000..3e2a7e6c17a7
--- /dev/null
+++ b/drivers/net/wireless/infineon/inffmac/he.c
@@ -0,0 +1,234 @@
+// SPDX-License-Identifier: ISC
+/*
+ * Copyright (c) 2025-2026, Infineon Technologies AG, or an affiliate of Infineon Technologies AG.
+ * All rights reserved.
+ */
+
+#include <linux/bitfield.h>
+#include "he.h"
+#include "feature.h"
+#include "dev_cmd.h"
+#include "cfg80211.h"
+#include "debug.h"
+
+static struct ieee80211_sband_iftype_data sdata[NUM_NL80211_BANDS];
+
+int
+inff_he_get_enable(struct inff_if *ifp, u8 *param, int param_len)
+{
+ s32 ret = 0;
+
+ ret = inff_fwcmd_xtlv_data_get(ifp, "he", INFF_HE_CMD_ENAB, param, param_len);
+ if (unlikely(ret))
+ iphy_err(ifp->drvr, "failed to check if HE is enabled");
+
+ return ret;
+}
+
+int
+inff_he_get_bss_color(struct inff_if *ifp, u8 *param, int param_len)
+{
+ struct inff_pub *drvr = ifp->drvr;
+ struct inff_xtlv *he_tlv;
+ int err = 0;
+
+ he_tlv = (struct inff_xtlv *)param;
+ he_tlv->id = cpu_to_le16(INFF_HE_CMD_BSSCOLOR);
+
+ err = inff_fwcmd_iovar_data_get(ifp, "he", param, param_len);
+ if (err)
+ iphy_err(drvr, "get he bss_color error:%d\n", err);
+
+ return err;
+}
+
+int
+inff_he_set_bss_color(struct inff_if *ifp, u8 color)
+{
+ struct inff_pub *drvr = ifp->drvr;
+ struct inff_xtlv *he_tlv;
+ u8 param[8] = {0};
+ int err = 0;
+
+ he_tlv = (struct inff_xtlv *)param;
+ he_tlv->id = cpu_to_le16(INFF_HE_CMD_BSSCOLOR);
+ he_tlv->len = cpu_to_le16(1);
+ memcpy(he_tlv->data, &color, sizeof(u8));
+
+ err = inff_fwcmd_iovar_data_set(ifp, "he", param, sizeof(param));
+ if (err)
+ iphy_err(drvr, "set he bss_color error:%d\n", err);
+
+ return err;
+}
+
+int
+inff_he_get_muedca_opt(struct inff_if *ifp, u8 *param, int param_len)
+{
+ struct inff_pub *drvr = ifp->drvr;
+ struct inff_xtlv *he_tlv;
+ int err = 0;
+
+ he_tlv = (struct inff_xtlv *)param;
+ he_tlv->id = cpu_to_le16(INFF_HE_CMD_MUEDCA_OPT);
+
+ err = inff_fwcmd_iovar_data_get(ifp, "he", param, param_len);
+ if (err)
+ iphy_err(drvr, "get he muedca_opt_enable error:%d\n", err);
+
+ return err;
+}
+
+int
+inff_he_set_muedca_opt(struct inff_if *ifp, u8 val)
+{
+ struct inff_pub *drvr = ifp->drvr;
+ struct inff_xtlv *he_tlv;
+ u8 param[8] = {0};
+ int err = 0;
+
+ he_tlv = (struct inff_xtlv *)param;
+ he_tlv->id = cpu_to_le16(INFF_HE_CMD_BSSCOLOR);
+ he_tlv->len = cpu_to_le16(1);
+ he_tlv->data[0] = val;
+
+ err = inff_fwcmd_iovar_data_set(ifp, "he", param, sizeof(param));
+ if (err)
+ iphy_err(drvr, "set he muedca_opt_enable error:%d\n", err);
+
+ return err;
+}
+
+int
+inff_he_set_bitrate(struct inff_if *ifp, const struct cfg80211_bitrate_mask *mask, u8 band)
+{
+ struct inff_pub *drvr = ifp->drvr;
+ uint hegi;
+ u16 mcs_mask;
+ u32 rspec = 0;
+ s32 ret = 0;
+ u8 mcs = 0;
+
+ mcs_mask = mask->control[band].he_mcs[0];
+ mcs_mask = (mcs_mask ^ ((mcs_mask - 1) & mcs_mask));
+ if (mcs_mask != mask->control[band].he_mcs[0])
+ return ret;
+
+ while (mcs_mask) {
+ mcs++;
+ mcs_mask >>= 1;
+ }
+
+ rspec = WL_RSPEC_ENCODE_HE; /* 11ax HE */
+ rspec |= (WL_RSPEC_HE_NSS_UNSPECIFIED << WL_RSPEC_HE_NSS_SHIFT) | (mcs - 1);
+ /* set the other rspec fields */
+ hegi = mask->control[band].he_gi + 1;
+ rspec |= ((hegi != 0xFF) ? HE_GI_TO_RSPEC(hegi) : 0);
+
+ switch (band) {
+ case NL80211_BAND_2GHZ:
+ ret = inff_fwcmd_iovar_data_set(ifp, "2g_rate", (char *)&rspec, 4);
+ break;
+ case NL80211_BAND_5GHZ:
+ ret = inff_fwcmd_iovar_data_set(ifp, "5g_rate", (char *)&rspec, 4);
+ break;
+ case NL80211_BAND_6GHZ:
+ ret = inff_fwcmd_iovar_data_set(ifp, "6g_rate", (char *)&rspec, 4);
+ break;
+ default:
+ iphy_err(drvr, "Setting bitrate unsupported on band %d\n", band);
+ ret = -EOPNOTSUPP;
+ }
+
+ if (unlikely(ret))
+ iphy_err(drvr, "set rate failed, retcode = %d\n", ret);
+
+ return ret;
+}
+
+void
+inff_he_update_wiphy_cap(struct inff_if *ifp)
+{
+ struct inff_pub *drvr = ifp->drvr;
+ struct wiphy *wiphy = drvr->wiphy;
+ struct ieee80211_supported_band *band;
+ struct ieee80211_sband_iftype_data *data;
+ struct ieee80211_sta_he_cap *he_cap;
+ struct ieee80211_he_cap_elem *he_cap_elem;
+ struct ieee80211_he_mcs_nss_supp *he_mcs;
+ u8 mac_cap_info[HE_MAC_CAP_INFO_SIZE] = { 0 };
+ u8 phy_cap_info[HE_PHY_CAP_INFO_SIZE] = { 0 };
+ u16 capa = 0;
+ u8 hemode = 0;
+ int idx = 1, i = 0, j = 0;
+
+ /* HE mode */
+ inff_he_get_enable(ifp, &hemode, sizeof(hemode));
+ if (!hemode)
+ return;
+
+ inff_dbg(INFO, "HE Enabled\n");
+
+ /* HE MAC Capabilities Information */
+ if (inff_fwcmd_xtlv_data_get(ifp, "he", INFF_HE_CMD_MACCAP, mac_cap_info,
+ HE_MAC_CAP_INFO_SIZE))
+ iphy_err(drvr, "HE MACCAP error\n");
+
+ /* HE PHY Capabilities Information */
+ if (inff_fwcmd_xtlv_data_get(ifp, "he", INFF_HE_CMD_PHYCAP, phy_cap_info,
+ HE_PHY_CAP_INFO_SIZE))
+ iphy_err(drvr, "HE PHYCAP error\n");
+
+ /* Update HE Capab for each Band */
+ for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
+ band = wiphy->bands[i];
+ if (!band)
+ continue;
+
+ data = &sdata[band->band];
+ he_cap = &data->he_cap;
+ he_cap_elem = &he_cap->he_cap_elem;
+ he_mcs = &he_cap->he_mcs_nss_supp;
+
+ switch (band->band) {
+ case NL80211_BAND_6GHZ:
+ /* HE 6 GHz band capabilities */
+ capa = (FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MIN_MPDU_START,
+ IEEE80211_HT_MPDU_DENSITY_8) |
+ FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_AMPDU_LEN_EXP,
+ IEEE80211_VHT_MAX_AMPDU_1024K) |
+ FIELD_PREP(IEEE80211_HE_6GHZ_CAP_MAX_MPDU_LEN,
+ IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454));
+ data->he_6ghz_capa.capa = cpu_to_le16(capa);
+
+ /* Band 6GHz supports HE, so */
+ fallthrough;
+
+ case NL80211_BAND_5GHZ:
+ /* Band 5GHz supports HE, so */
+ fallthrough;
+
+ case NL80211_BAND_2GHZ:
+ /* Band 2GHz supports HE */
+ data->types_mask = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_AP);
+ data->he_cap.has_he = true;
+
+ for (j = 0; j < HE_MAC_CAP_INFO_SIZE; j++)
+ he_cap_elem->mac_cap_info[j] = mac_cap_info[j];
+
+ for (j = 0; j < HE_PHY_CAP_INFO_SIZE; j++)
+ he_cap_elem->phy_cap_info[j] = phy_cap_info[j];
+
+ /* HE Supported MCS and NSS Set */
+ he_mcs->rx_mcs_80 = cpu_to_le16(0xfffa);
+ he_mcs->tx_mcs_80 = cpu_to_le16(0xfffa);
+
+ _ieee80211_set_sband_iftype_data(band, data, idx);
+
+ break;
+
+ default:
+ break;
+ }
+ }
+}
diff --git a/drivers/net/wireless/infineon/inffmac/he.h b/drivers/net/wireless/infineon/inffmac/he.h
new file mode 100644
index 000000000000..fd9c506c45a4
--- /dev/null
+++ b/drivers/net/wireless/infineon/inffmac/he.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: ISC */
+/*
+ * Copyright (c) 2025-2026, Infineon Technologies AG, or an affiliate of Infineon Technologies AG.
+ * All rights reserved.
+ */
+
+#ifndef INFF_HE_H
+#define INFF_HE_H
+
+#include "main.h"
+
+#define HE_MAC_CAP_INFO_SIZE 6
+#define HE_PHY_CAP_INFO_SIZE 11
+
+#define HE_GI_TO_RSPEC(gi) \
+ (((gi) << WL_RSPEC_HE_GI_SHIFT) & WL_RSPEC_HE_GI_MASK)
+
+#define WL_RSPEC_ENCODE_HE 0x03000000 /* HE MCS and Nss is stored in RSPEC_RATE_MASK */
+#define WL_RSPEC_HE_NSS_UNSPECIFIED 0xF
+#define WL_RSPEC_HE_NSS_SHIFT 4 /* HE Nss value shift */
+#define WL_RSPEC_HE_GI_MASK 0x00000C00 /* HE GI indices */
+#define WL_RSPEC_HE_GI_SHIFT 10
+
+/**
+ * enum inff_he_cmd - HE iovar subcmds handled by firmware HE module
+ */
+enum inff_he_cmd {
+ INFF_HE_CMD_ENAB = 0,
+ INFF_HE_CMD_FEATURES = 1,
+ INFF_HE_CMD_TWT_SETUP = 2,
+ INFF_HE_CMD_TWT_TEARDOWN = 3,
+ INFF_HE_CMD_TWT_INFO = 4,
+ INFF_HE_CMD_BSSCOLOR = 5,
+ INFF_HE_CMD_PARTIAL_BSSCOLOR = 6,
+ INFF_HE_CMD_CAP = 7,
+ INFF_HE_CMD_STAID = 8,
+ INFF_HE_CMD_RTSDURTHRESH = 10,
+ INFF_HE_CMD_PEDURATION = 11,
+ INFF_HE_CMD_TESTBED_MODE = 12,
+ INFF_HE_CMD_OMI = 13,
+ INFF_HE_CMD_MAC_PAD_DUR = 14,
+ INFF_HE_CMD_MUEDCA = 15,
+ INFF_HE_CMD_MACCAP = 16,
+ INFF_HE_CMD_PHYCAP = 17,
+ INFF_HE_CMD_DISPLAY = 18,
+ INFF_HE_CMD_ACTION = 19,
+ INFF_HE_CMD_OFDMATX = 20,
+ INFF_HE_CMD_20IN80_MODE = 21,
+ INFF_HE_CMD_SMPS = 22,
+ INFF_HE_CMD_PPETHRESH = 23,
+ INFF_HE_CMD_HTC_OMI_EN = 24,
+ INFF_HE_CMD_ERSU_EN = 25,
+ INFF_HE_CMD_PREPUNCRX_EN = 26,
+ INFF_HE_CMD_MIMOCAP_EN = 27,
+ INFF_HE_CMD_MUEDCA_OPT = 28,
+ INFF_HE_CMD_LAST
+};
+
+int inff_he_get_enable(struct inff_if *ifp, u8 *param, int param_len);
+int inff_he_get_bss_color(struct inff_if *ifp, u8 *param, int param_len);
+int inff_he_set_bss_color(struct inff_if *ifp, u8 color);
+int inff_he_get_muedca_opt(struct inff_if *ifp, u8 *param, int param_len);
+int inff_he_set_muedca_opt(struct inff_if *ifp, u8 val);
+int inff_he_set_bitrate(struct inff_if *ifp, const struct cfg80211_bitrate_mask *mask, u8 band);
+void inff_he_update_wiphy_cap(struct inff_if *ifp);
+
+#endif /* INFF_HE_H */
--
2.25.1
next prev parent reply other threads:[~2026-01-13 20:35 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-13 20:33 [PATCH wireless-next v2 00/34] wifi: inffmac: introducing a driver for Infineon's new generation chipsets Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 01/34] wifi: inffmac: add a new driver directory for infineon WLAN vendor Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 02/34] wifi: inffmac: add pmsr.c/h Gokul Sivakumar
2026-01-13 20:33 ` Gokul Sivakumar [this message]
2026-01-13 20:33 ` [PATCH wireless-next v2 04/34] wifi: inffmac: add twt.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 05/34] wifi: inffmac: add trxhdr.h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 06/34] wifi: inffmac: add chip.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 07/34] wifi: inffmac: add chip_{5591x/5551x/5557x/43022}.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 08/34] wifi: inffmac: add icdc.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 09/34] wifi: inffmac: add dfu.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 10/34] wifi: inffmac: add firmware.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 11/34] wifi: inffmac: add vendor.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 12/34] wifi: inffmac: add main.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 13/34] wifi: inffmac: add dev_evt.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 14/34] wifi: inffmac: add dev_cmd.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 15/34] wifi: inffmac: add net.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 16/34] wifi: inffmac: add cfg80211.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 17/34] wifi: inffmac: add msgbuf.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 18/34] wifi: inffmac: add pcie.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 19/34] wifi: inffmac: add p2p.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 20/34] wifi: inffmac: add interface.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 21/34] wifi: inffmac: add feature.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 22/34] wifi: inffmac: add bus_proto.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 23/34] wifi: inffmac: add commonring.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 24/34] wifi: inffmac: add flowring.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 25/34] wifi: inffmac: add sdio.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 26/34] wifi: inffmac: add ie.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 27/34] wifi: inffmac: add scan.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 28/34] wifi: inffmac: add fwsignal.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 29/34] wifi: inffmac: add security.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 30/34] wifi: inffmac: add bcdc.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 31/34] wifi: inffmac: add chan.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 32/34] wifi: inffmac: add debug.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 33/34] wifi: inffmac: add utils.c/h Gokul Sivakumar
2026-01-13 20:33 ` [PATCH wireless-next v2 34/34] wifi: inffmac: add Kconfig, Makefile Gokul Sivakumar
2026-01-14 3:22 ` [PATCH wireless-next v2 00/34] wifi: inffmac: introducing a driver for Infineon's new generation chipsets Marek Vasut
2026-01-14 8:12 ` Gokul Sivakumar
2026-01-15 17:27 ` Marek Vasut
2026-01-16 16:33 ` Gokul Sivakumar
2026-02-27 10:28 ` Marek Vasut
2026-02-27 14:34 ` Gokul Sivakumar
2026-03-21 16:24 ` Marek Vasut
2026-03-23 13:24 ` Gokul Sivakumar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260113203350.16734-4-gokulkumar.sivakumar@infineon.com \
--to=gokulkumar.sivakumar@infineon.com \
--cc=arend.vanspriel@broadcom.com \
--cc=johannes@sipsolutions.net \
--cc=linux-wireless@vger.kernel.org \
--cc=marex@nabladev.com \
--cc=wlan-kernel-dev-list@infineon.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox