diff options
| author | Sean Wang <sean.wang@mediatek.com> | 2026-06-24 19:18:34 -0500 |
|---|---|---|
| committer | Felix Fietkau <nbd@nbd.name> | 2026-07-31 12:25:37 +0000 |
| commit | 420e0bbd52ab6fa05ebfdb4dbe5442d47e4bfdf9 (patch) | |
| tree | ef05f3a8bd0e5d56435ad93644968d09a04ffa30 | |
| parent | 9bb39d09ab0f0f0e2f341d727e65fa1712c3bffa (diff) | |
wifi: mt76: mt792x: advertise NAN data support
Advertise NAN and NAN data support when firmware exposes NAN
capability.
Add NAN interface combinations on top of the dynamic combination
framework, advertise 2.4 GHz and 5 GHz NAN bands, and enable secure
NAN.
Keep the base interface combinations unchanged when NAN is unavailable
so existing STA/AP/P2P modes keep the same limits.
Co-developed-by: Stella Liu <yu-ching.liu@mediatek.com>
Signed-off-by: Stella Liu <yu-ching.liu@mediatek.com>
Co-developed-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Jeremy Yu <chengwei.yu@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Link: https://patch.msgid.link/20260625001834.475094-10-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
| -rw-r--r-- | drivers/net/wireless/mediatek/mt76/mt792x_core.c | 96 |
1 files changed, 92 insertions, 4 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt792x_core.c b/drivers/net/wireless/mediatek/mt76/mt792x_core.c index 0c74fedf07e3..2a8384a44d9f 100644 --- a/drivers/net/wireless/mediatek/mt76/mt792x_core.c +++ b/drivers/net/wireless/mediatek/mt76/mt792x_core.c @@ -3,6 +3,7 @@ #include <linux/module.h> #include <linux/firmware.h> +#include <linux/slab.h> #include "mt792x.h" #include "dma.h" @@ -60,6 +61,40 @@ static const struct ieee80211_iface_limit if_limits_chanctx_scc[] = { } }; +static const struct ieee80211_iface_limit if_limits_nan_mcc[] = { + { + .max = 2, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_NAN), + }, + { + .max = 2, + .types = BIT(NL80211_IFTYPE_NAN_DATA), + }, +}; + +static const struct ieee80211_iface_limit if_limits_nan_scc[] = { + { + .max = 2, + .types = BIT(NL80211_IFTYPE_STATION), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_NAN), + }, + { + .max = 2, + .types = BIT(NL80211_IFTYPE_NAN_DATA), + }, + { + .max = 1, + .types = BIT(NL80211_IFTYPE_AP), + }, +}; + static const struct ieee80211_iface_combination if_comb_chanctx_base[] = { { .limits = if_limits_chanctx_mcc, @@ -77,9 +112,31 @@ static const struct ieee80211_iface_combination if_comb_chanctx_base[] = { } }; -static int mt792x_setup_iface_combinations(struct mt792x_dev *dev) +static const struct ieee80211_iface_combination if_comb_chanctx_nan[] = { + { + .limits = if_limits_nan_mcc, + .n_limits = ARRAY_SIZE(if_limits_nan_mcc), + .max_interfaces = MT792x_MAX_INTERFACES, + .num_different_channels = 2, + .beacon_int_infra_match = false, + }, + { + .limits = if_limits_nan_scc, + .n_limits = ARRAY_SIZE(if_limits_nan_scc), + .max_interfaces = MT792x_MAX_INTERFACES, + .num_different_channels = 1, + .beacon_int_infra_match = false, + }, +}; + +static int mt792x_setup_iface_combinations(struct mt792x_dev *dev, + struct wiphy *wiphy) { const bool cnm = !!(dev->fw_features & MT792x_FW_CAP_CNM); + const bool nan = !!(dev->fw_features & MT792x_FW_CAP_NAN); + const int n_base = ARRAY_SIZE(if_comb_chanctx_base); + const int n_nan = ARRAY_SIZE(if_comb_chanctx_nan); + struct ieee80211_iface_combination *comb; if (!cnm) { dev->iface_combinations = if_comb; @@ -87,8 +144,24 @@ static int mt792x_setup_iface_combinations(struct mt792x_dev *dev) return 0; } - dev->iface_combinations = if_comb_chanctx_base; - dev->n_iface_combinations = ARRAY_SIZE(if_comb_chanctx_base); + /* CNM enabled, NAN optional */ + if (!nan) { + dev->iface_combinations = if_comb_chanctx_base; + dev->n_iface_combinations = ARRAY_SIZE(if_comb_chanctx_base); + return 0; + } + + /* CNM + NAN: dynamically build base + nan list */ + comb = devm_kcalloc(&wiphy->dev, n_base + n_nan, sizeof(*comb), + GFP_KERNEL); + if (!comb) + return -ENOMEM; + + memcpy(comb, if_comb_chanctx_base, sizeof(if_comb_chanctx_base)); + memcpy(comb + n_base, if_comb_chanctx_nan, sizeof(if_comb_chanctx_nan)); + + dev->iface_combinations = comb; + dev->n_iface_combinations = n_base + n_nan; return 0; } @@ -705,7 +778,7 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw) else wiphy->flags &= ~WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL; - err = mt792x_setup_iface_combinations(dev); + err = mt792x_setup_iface_combinations(dev, wiphy); if (err) return err; @@ -719,6 +792,21 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw) BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_DEVICE); + if ((dev->fw_features & MT792x_FW_CAP_CNM) && + (dev->fw_features & MT792x_FW_CAP_NAN)) { + wiphy->interface_modes |= BIT(NL80211_IFTYPE_NAN) | + BIT(NL80211_IFTYPE_NAN_DATA); + wiphy->nan_supported_bands = BIT(NL80211_BAND_2GHZ) | + BIT(NL80211_BAND_5GHZ); + wiphy->nan_capa.flags = WIPHY_NAN_FLAGS_CONFIGURABLE_SYNC | + WIPHY_NAN_FLAGS_USERSPACE_DE; + wiphy->nan_capa.op_mode = NAN_OP_MODE_PHY_MODE_MASK; + wiphy->nan_capa.n_antennas = 0x22; + wiphy->nan_capa.max_channel_switch_time = 12; + wiphy->nan_capa.dev_capabilities = NAN_DEV_CAPA_EXT_KEY_ID_SUPPORTED; + wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_SECURE_NAN); + } + wiphy->max_scan_ie_len = MT76_CONNAC_SCAN_IE_LEN; wiphy->max_scan_ssids = 4; wiphy->max_sched_scan_plan_interval = |
