public inbox for linux-wireless@vger.kernel.org
 help / color / mirror / Atom feed
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


  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