diff mbox series

[19/38] ra6w: add params.c

Message ID 20250417135236.52410-20-oleksandr.savchenko.dn@bp.renesas.com
State New
Headers show
Series wireless: ra6w driver for Renesas IEEE 802.11ax devices | expand

Commit Message

Alexander Savchenko April 17, 2025, 1:52 p.m. UTC
Part of the split. Please, take a look at the cover letter for more details

Reviewed-by: Viktor Barna <viktor.barna.rj@bp.renesas.com>
Reviewed-by: Gal Gur <gal.gur.jx@renesas.com>
Signed-off-by: Alexander Savchenko <oleksandr.savchenko.dn@bp.renesas.com>
---
 drivers/net/wireless/renesas/ra6w/params.c | 387 +++++++++++++++++++++
 1 file changed, 387 insertions(+)
 create mode 100644 drivers/net/wireless/renesas/ra6w/params.c
diff mbox series

Patch

diff --git a/drivers/net/wireless/renesas/ra6w/params.c b/drivers/net/wireless/renesas/ra6w/params.c
new file mode 100644
index 000000000000..c428fe7b648b
--- /dev/null
+++ b/drivers/net/wireless/renesas/ra6w/params.c
@@ -0,0 +1,387 @@ 
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This file contains driver parameters operations.
+ *
+ * Copyright (C) [2022-2025] Renesas Electronics Corporation and/or its affiliates.
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/rtnetlink.h>
+#include <net/cfg80211.h>
+
+#include "dbg.h"
+#include "core.h"
+#include "cfg80211.h"
+#include "params.h"
+
+#define RA6W_PHY_FEAT_CHBW_MASK	0x03000000
+#define RA6W_PHY_FEAT_CHBW_LSB	24
+#define RA6W_PHY_FEAT_NSS_MASK	0x00000F00
+#define RA6W_PHY_FEAT_NSS_LSB	8
+
+struct ra6w_params ra6w_params_list = {
+	.module_params = {
+		.stbc_enabled = true,
+		.ldpc_enabled = true,
+		.dpsm_enabled = true,
+		.ht_supported = true,
+		.rx_amsdu_size = 2,
+		.mcs_map_range = IEEE80211_VHT_MCS_SUPPORT_0_8,
+		.use_sgi = true,
+		.bfmer_enabled = true,
+		.he_mcs_map_range = IEEE80211_HE_MCS_SUPPORT_0_9,
+		.ap_uapsd_enabled = true,
+		.regdom_mode = "auto",
+		.log_level = RA6W_DEFAULT_LOG_LVL,
+	},
+	.features = {
+		.uapsd_threshold = RA6W_CFG80211_UAPSD_TIMEOUT,
+	}
+};
+
+static struct ieee80211_regdomain ra6w_regdom = {
+	.n_reg_rules = 2,
+	.alpha2 = "99",
+	.reg_rules = {
+		REG_RULE(2390 - 10, 2510 + 10, 20, 0, 20, 0),
+		REG_RULE(5150 - 10, 5970 + 10, 20, 0, 20, 0),
+	}
+};
+
+module_param_named(stbc_enabled, ra6w_params_list.module_params.stbc_enabled, bool, 0444);
+MODULE_PARM_DESC(stbc_enabled, "Enable STBC (Default: 1)");
+
+module_param_named(ldpc_enabled, ra6w_params_list.module_params.ldpc_enabled, bool, 0444);
+MODULE_PARM_DESC(ldpc_enabled, "Enable LDPC (Default: 1)");
+
+module_param_named(ant_div, ra6w_params_list.module_params.ant_div, bool, 0444);
+MODULE_PARM_DESC(ant_div, "Enable Antenna Diversity (Default: 0)");
+
+module_param_named(ht_supported, ra6w_params_list.module_params.ht_supported, bool, 0444);
+MODULE_PARM_DESC(ht_supported, "HT Enabled (Default: 1)");
+
+module_param_named(amsdu_require_spp,
+		   ra6w_params_list.module_params.amsdu_require_spp, bool, 0444);
+MODULE_PARM_DESC(amsdu_require_spp, "Require usage of SPP A-MSDU (Default: 0)");
+
+module_param_named(bfmer_enabled, ra6w_params_list.module_params.bfmer_enabled, bool, 0444);
+MODULE_PARM_DESC(bfmer_enabled, "Beem Former Enabled. (Default: 1)");
+
+module_param_named(dpsm_enabled, ra6w_params_list.module_params.dpsm_enabled, bool, 0444);
+MODULE_PARM_DESC(dpsm_enabled, "Dynamic Power Save Mode Enabled (Default: 1)");
+
+module_param_named(ap_uapsd_enabled, ra6w_params_list.module_params.ap_uapsd_enabled, bool, 0444);
+MODULE_PARM_DESC(ap_uapsd_enabled, "AP UAPSD Enabled. (Default: 1)");
+
+module_param_named(use_sgi, ra6w_params_list.module_params.use_sgi, bool, 0444);
+MODULE_PARM_DESC(use_sgi, "SGI. (Default: 1: on)");
+
+module_param_named(ccmp256_supported,
+		   ra6w_params_list.module_params.ccmp256_supported, bool, 0444);
+MODULE_PARM_DESC(ccmp256_supported, "CCMP256 Supported. (Default: 0)");
+
+module_param_named(regdom_mode, ra6w_params_list.module_params.regdom_mode, charp, 0444);
+MODULE_PARM_DESC(regdom_mode, "Regulatory mode (auto/self). default: auto");
+
+module_param_named(rx_amsdu_size, ra6w_params_list.module_params.rx_amsdu_size, byte, 0444);
+MODULE_PARM_DESC(rx_amsdu_size, "RX AMSDU SIZE. (Default: 2)");
+
+module_param_named(mcs_map_range, ra6w_params_list.module_params.mcs_map_range, byte, 0444);
+MODULE_PARM_DESC(mcs_map_range, "MCS MAP. (Default: 1");
+
+module_param_named(he_mcs_map_range, ra6w_params_list.module_params.he_mcs_map_range, byte, 0444);
+MODULE_PARM_DESC(he_mcs_map_range, "HE MCS MAP. (Default: 1)");
+
+module_param_named(log_level, ra6w_params_list.module_params.log_level, int, 0644);
+MODULE_PARM_DESC(log_level, "log_level (Default: 3: info)");
+
+static u8 ra6w_params_phy_bw_get(const struct ra6w_sys_info *sinfo)
+{
+	u32 phy_feat = le32_to_cpu(sinfo->fw_ver.phy_feature);
+
+	return (phy_feat & RA6W_PHY_FEAT_CHBW_MASK) >> RA6W_PHY_FEAT_CHBW_LSB;
+}
+
+static u8 ra6w_params_phy_nss_get(const struct ra6w_sys_info *sinfo)
+{
+	u32 phy_feat = le32_to_cpu(sinfo->fw_ver.phy_feature);
+
+	return (phy_feat & RA6W_PHY_FEAT_NSS_MASK) >> RA6W_PHY_FEAT_NSS_LSB;
+}
+
+static bool ra6w_params_mac_gcmp_get(const struct ra6w_sys_info *sinfo)
+{
+	u32 mac_feat = le32_to_cpu(sinfo->fw_ver.machw_features);
+
+	return mac_feat & BIT(RA6W_MAC_FEAT_GCMP_BIT);
+}
+
+static u8 ra6w_params_rx_amsdu_size_get(const struct ra6w_sys_info *sinfo)
+{
+	u32 feat = le32_to_cpu(sinfo->fw_ver.features);
+
+	return (feat >> RA6W_DEV_FEAT_AMSDU_MAX_SIZE_0_BIT) & 0x03;
+}
+
+static bool ra6w_params_feat(u32 dev_feat, enum ra6w_params_dev_feat id)
+{
+	return dev_feat & BIT(id);
+}
+
+static int ra6w_params_features_set(struct ra6w_core *core)
+{
+	int ret = 0;
+	u32 feat;
+	u32 phy_vers;
+	u16 max_sta_nb;
+	u8 max_vif_nb;
+	u8 amsdu_rx = 0;
+	struct ra6w_sys_info *sinfo = &core->sinfo;
+	struct ra6w_params_module_params *module_params = &ra6w_params_list.module_params;
+	struct ra6w_params_dev_features *features = &ra6w_params_list.features;
+
+	feat = le32_to_cpu(sinfo->fw_ver.features);
+	if (!ra6w_params_feat(feat, RA6W_DEV_FEAT_UMAC_BIT)) {
+		ra6w_err("UMAC is not supported\n");
+		return -ENOENT;
+	}
+
+	features->vht_supported = ra6w_params_feat(feat, RA6W_DEV_FEAT_VHT_BIT);
+	features->he_supported = ra6w_params_feat(feat, RA6W_DEV_FEAT_HE_BIT);
+	features->he_ul_on = ra6w_params_feat(feat, RA6W_DEV_FEAT_HE_BIT);
+	features->ps_supported = ra6w_params_feat(feat, RA6W_DEV_FEAT_PS_BIT);
+	features->amsdu_supported = ra6w_params_feat(feat, RA6W_DEV_FEAT_AMSDU_BIT);
+	features->bfmee_enabled = ra6w_params_feat(feat, RA6W_DEV_FEAT_BFMEE_BIT);
+	features->tdls_supported = ra6w_params_feat(feat, RA6W_DEV_FEAT_TDLS_BIT);
+	features->wapi_supported = ra6w_params_feat(feat, RA6W_DEV_FEAT_WAPI_BIT);
+	features->mfp_supported = ra6w_params_feat(feat, RA6W_DEV_FEAT_MFP_BIT);
+	features->radar_supported = ra6w_params_feat(feat, RA6W_DEV_FEAT_RADAR_BIT);
+	features->mu_mimo_rx_enabled = ra6w_params_feat(feat, RA6W_DEV_FEAT_MU_MIMO_RX_BIT);
+	features->mu_mimo_tx_enabled = ra6w_params_feat(feat, RA6W_DEV_FEAT_MU_MIMO_TX_BIT);
+	features->twt_enabled = ra6w_params_feat(feat, RA6W_DEV_FEAT_TWT_BIT);
+
+	amsdu_rx = ra6w_params_rx_amsdu_size_get(sinfo);
+	module_params->rx_amsdu_size = min(amsdu_rx, module_params->rx_amsdu_size);
+
+	if (!ra6w_params_feat(feat, RA6W_DEV_FEAT_UAPSD_BIT))
+		features->uapsd_threshold = 0;
+
+	features->bw_max = ra6w_params_phy_bw_get(sinfo);
+
+	if (!module_params->ht_supported) {
+		features->vht_supported = false;
+		features->he_supported = false;
+	}
+
+	if (features->he_supported && !module_params->ldpc_enabled)
+		module_params->he_mcs_map_range = min_t(u8, module_params->he_mcs_map_range,
+							IEEE80211_HE_MCS_SUPPORT_0_9);
+
+	phy_vers = le32_to_cpu(sinfo->fw_ver.phy_version);
+
+	if (!features->mu_mimo_rx_enabled || !features->bfmee_enabled)
+		features->mu_mimo_rx_enabled = false;
+
+	features->gcmp_supported = ra6w_params_mac_gcmp_get(sinfo);
+
+	if (core->sinfo.machw_support_type >= RA6W_MACHW_SUPPORT_HE)
+		module_params->ccmp256_supported = true;
+
+	features->nss = ra6w_params_phy_nss_get(sinfo);
+
+	max_sta_nb = le16_to_cpu(sinfo->fw_ver.max_sta_nb);
+	if (max_sta_nb != RA6W_CFG80211_STA_MAX) {
+		ra6w_err("Number of supported stations by driver not fit to FW (%d != %d)\n",
+			 RA6W_CFG80211_STA_MAX, max_sta_nb);
+		ret = -ENOENT;
+	}
+
+	max_vif_nb = sinfo->fw_ver.max_vif_nb;
+	if (max_vif_nb != RA6W_CFG80211_VIF_MAX) {
+		ra6w_err("Number of virtual interfaces in driver not fit to FW (%d != %d)\n",
+			 RA6W_CFG80211_VIF_MAX, max_vif_nb);
+		ret = -ENOENT;
+	}
+
+	return ret;
+}
+
+int ra6w_params_init(struct ra6w_core *core)
+{
+	return ra6w_params_features_set(core);
+}
+
+bool ra6w_params_regd_mode_is_auto(void)
+{
+	return !strcmp(ra6w_params_list.module_params.regdom_mode, "auto");
+}
+
+int ra6w_params_regd_set_self(struct wiphy *wiphy)
+{
+	struct ra6w_cfg80211_priv *priv = wiphy_priv(wiphy);
+	int ret;
+
+	if (!(wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED))
+		return 0;
+
+	ret = regulatory_set_wiphy_regd(wiphy, &ra6w_regdom);
+	if (ret)
+		return ret;
+
+	ra6w_info("regdom mode: self\n");
+
+	memcpy(priv->phy_config.country_code, ra6w_regdom.alpha2, sizeof(ra6w_regdom.alpha2));
+
+	return ra6w_ctrl_chan_config(&priv->core->ctrl, wiphy);
+}
+
+bool ra6w_params_ps_supported(void)
+{
+	return ra6w_params_list.features.ps_supported;
+}
+
+bool ra6w_params_dpsm_enabled(void)
+{
+	return ra6w_params_list.module_params.dpsm_enabled;
+}
+
+bool ra6w_params_amsdu_require_spp(void)
+{
+	return ra6w_params_list.module_params.amsdu_require_spp;
+}
+
+bool ra6w_params_ht_supported(void)
+{
+	return ra6w_params_list.module_params.ht_supported;
+}
+
+bool ra6w_params_vht_supported(void)
+{
+	return ra6w_params_list.features.vht_supported;
+}
+
+bool ra6w_params_he_supported(void)
+{
+	return ra6w_params_list.features.he_supported;
+}
+
+bool ra6w_params_he_ul_on(void)
+{
+	return ra6w_params_list.features.he_ul_on;
+}
+
+bool ra6w_params_wapi_supported(void)
+{
+	return ra6w_params_list.features.wapi_supported;
+}
+
+bool ra6w_params_mfp_supported(void)
+{
+	return ra6w_params_list.features.mfp_supported;
+}
+
+bool ra6w_params_ap_uapsd_enabled(void)
+{
+	return ra6w_params_list.module_params.ap_uapsd_enabled;
+}
+
+bool ra6w_params_tdls_supported(void)
+{
+	return ra6w_params_list.features.tdls_supported;
+}
+
+bool ra6w_params_gcmp_supported(void)
+{
+	return ra6w_params_list.features.gcmp_supported;
+}
+
+bool ra6w_params_ccmp256_supported(void)
+{
+	return ra6w_params_list.module_params.ccmp256_supported;
+}
+
+bool ra6w_params_bfmee_enabled(void)
+{
+	return ra6w_params_list.features.bfmee_enabled;
+}
+
+bool ra6w_params_bfmer_enabled(void)
+{
+	return ra6w_params_list.module_params.bfmer_enabled;
+}
+
+bool ra6w_params_ldpc_enabled(void)
+{
+	return ra6w_params_list.module_params.ldpc_enabled;
+}
+
+bool ra6w_params_stbc_enabled(void)
+{
+	return ra6w_params_list.module_params.stbc_enabled;
+}
+
+u8 ra6w_params_bw_max_get(void)
+{
+	return ra6w_params_list.features.bw_max;
+}
+
+bool ra6w_params_use_sgi(void)
+{
+	return ra6w_params_list.module_params.use_sgi;
+}
+
+bool ra6w_params_mu_mimo_rx_enabled(void)
+{
+	return ra6w_params_list.features.mu_mimo_rx_enabled;
+}
+
+bool ra6w_params_mu_mimo_tx_enabled(void)
+{
+	return ra6w_params_list.features.mu_mimo_tx_enabled;
+}
+
+bool ra6w_params_twt_enabled(void)
+{
+	return ra6w_params_list.features.twt_enabled;
+}
+
+u32 ra6w_params_uapsd_threshold(void)
+{
+	return ra6w_params_list.features.uapsd_threshold;
+}
+
+bool ra6w_params_ant_div(void)
+{
+	return ra6w_params_list.module_params.ant_div;
+}
+
+u32 ra6w_params_log_level(void)
+{
+	return ra6w_params_list.module_params.log_level;
+}
+
+void ra6w_params_log_level_set(u32 log_level)
+{
+	ra6w_params_list.module_params.log_level = log_level;
+}
+
+u8 ra6w_params_nss(void)
+{
+	return ra6w_params_list.features.nss;
+}
+
+u8 ra6w_params_rx_amsdu_size(void)
+{
+	return ra6w_params_list.module_params.rx_amsdu_size;
+}
+
+u8 ra6w_params_mcs_map_range(void)
+{
+	return ra6w_params_list.module_params.mcs_map_range;
+}
+
+u8 ra6w_params_he_mcs_map_range(void)
+{
+	return ra6w_params_list.module_params.he_mcs_map_range;
+}