wifi: mt76: add mt7925 NAN support
Subsystems (2)
v2 cover wifi: mt76: add mt7925 NAN support
Add NAN support for mt7925. The series first advertises userspace management-frame registration and hardens BSS capability lookups used by partially configured BSS state.
The rest of the series adds the connac NAN connection type, mt7925 NAN MCU helpers and event handling, a generic init_wiphy callback, mac80211 NAN operations, firmware-gated interface combinations and NAN data advertisement.
Changes since v1
- Rebased and reworked the 7-patch v1 series into 9 focused patches.
- v1 patch 2 and 3 are folded into one BSS capability guard patch.
- v1 patch 7 is split into a framework-only interface combination patch and a final NAN/NAN_DATA advertisement patch.
- v1 patch 5 is split into NAN MCU helpers and mt7925 MCU response, event and NAN-specific BSS/STA TLV handling.
- v1 patch 6 is split so NAN PHY capability setup uses a generic init_wiphy callback before mac80211 NAN ops are wired.
- Order init_wiphy before the mt7925 NAN ops patch so each patch builds independently.
- Define MT792x_FW_CAP_NAN in the patch that first uses it.
- Move common NAN MCU command/event IDs to the connac patch and handle NAN_DATA as a NAN connection type.
- Add NAN_DATA interface support, 2.4/5 GHz NAN bands and secure NAN advertisement.
- Add NMI address programming, DW notifications, local availability updates, peer schedule updates and NDI STA mapping.
- Add cleanup and rollback for NAN peer indexes, NDP contexts and MCU failures.
- Drop temporary NAN channel debug logging and fix checkpatch issues.
Sean Wang (9):
wifi: mt76: mt792x: advertise mgmt frame registration
wifi: mt76: mt7925: guard BSS capability lookups
wifi: mt76: connac: add NAN connection type
wifi: mt76: mt7925: add NAN MCU helpers
wifi: mt76: mt7925: add NAN MCU handling
wifi: mt76: add init_wiphy callback
wifi: mt76: mt7925: wire up NAN operations
wifi: mt76: mt792x: build iface combinations dynamically
wifi: mt76: mt792x: advertise NAN data support
drivers/net/wireless/mediatek/mt76/mac80211.c | 7 + drivers/net/wireless/mediatek/mt76/mt76.h | 3 + .../wireless/mediatek/mt76/mt76_connac_mcu.c | 14 + .../wireless/mediatek/mt76/mt76_connac_mcu.h | 4 + .../wireless/mediatek/mt76/mt7925/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt7925/init.c | 29 + .../net/wireless/mediatek/mt76/mt7925/main.c | 201 ++- .../net/wireless/mediatek/mt76/mt7925/mcu.c | 125 +- .../net/wireless/mediatek/mt76/mt7925/nan.c | 1091 +++++++++++++++++ .../net/wireless/mediatek/mt76/mt7925/nan.h | 440 +++++++ .../net/wireless/mediatek/mt76/mt7925/regd.c | 30 + .../net/wireless/mediatek/mt76/mt7925/regd.h | 3 + drivers/net/wireless/mediatek/mt76/mt792x.h | 43 + .../net/wireless/mediatek/mt76/mt792x_core.c | 125 +- 14 files changed, 2077 insertions(+), 40 deletions(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt7925/nan.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt7925/nan.h
Signature · 1 line
2.43.0
PATCH v2 1/9 wifi: mt76: mt792x: advertise mgmt frame registration
From: Sean Wang <[email protected]>
Advertise multicast management frame registration support so userspace can subscribe to multicast management and action frames.
This capability is required for NAN discovery and related operations.
--- drivers/net/wireless/mediatek/mt76/mt792x_core.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/mediatek/mt76/mt792x_core.c +1 -0
@@ -719,6 +719,7 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw)wiphy_ext_feature_set (wiphy,NL80211_EXT_FEATURE_BEACON_RATE_HE );wiphy_ext_feature_set (wiphy,NL80211_EXT_FEATURE_ACK_SIGNAL_SUPPORT );wiphy_ext_feature_set (wiphy,NL80211_EXT_FEATURE_CAN_REPLACE_PTK0 ); +wiphy_ext_feature_set (wiphy,NL80211_EXT_FEATURE_MULTICAST_REGISTRATIONS );ieee80211_hw_set (hw,SINGLE_SCAN_ON_ALL_BANDS );ieee80211_hw_set (hw,HAS_RATE_CONTROL );
Signature · 1 line
2.43.0
PATCH v2 2/9 wifi: mt76: mt7925: guard BSS capability lookups
In reply to Sean WangFrom: Sean Wang <[email protected]>
mt7925 BSS setup may dereference missing channel data or query HE 6 GHz capabilities for an iftype without HE support.
Guard both lookups before adding NAN paths that can use partially configured BSS state.
--- .../net/wireless/mediatek/mt76/mt7925/mcu.c | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +20 -6
@@ -2364,11 +2364,18 @@ void mt7925_mcu_bss_rlm_tlv(struct sk_buff *skb, struct mt76_phy *phy, {struct cfg80211_chan_def *chandef = ctx ? &ctx->def : &link_conf->chanreq.oper; -int freq1 = chandef->center_freq1, freq2 = chandef->center_freq2; -enum nl80211_band band = chandef->chan->band;struct bss_rlm_tlv *req; +enum nl80211_band band; +int freq1, freq2;struct tlv *tlv; +if (WARN_ON_ONCE (!chandef || !chandef->chan)) +return ; + + freq1 = chandef->center_freq1; + freq2 = chandef->center_freq2; + band = chandef->chan->band; + tlv =mt76_connac_mcu_add_tlv (skb,UNI_BSS_INFO_RLM ,sizeof (*req)); req = (struct bss_rlm_tlv *)tlv; req->control_channel = chandef->chan->hw_value;
@@ -2506,8 +2513,8 @@ mt7925_get_phy_mode_ext(struct mt76_phy *phy, struct ieee80211_vif *vif,enum nl80211_band band, struct ieee80211_link_sta *link_sta) { - struct ieee80211_he_6ghz_capa *he_6ghz_capa; -const struct ieee80211_sta_eht_cap *eht_cap; + struct ieee80211_he_6ghz_capa *he_6ghz_capa = NULL; +const struct ieee80211_sta_eht_cap *eht_cap =NULL ;__le16 capa =0 ;u8 mode =0 ;
@@ -2515,11 +2522,18 @@ mt7925_get_phy_mode_ext(struct mt76_phy *phy, struct ieee80211_vif *vif, he_6ghz_capa = &link_sta->he_6ghz_capa; eht_cap = &link_sta->eht_cap; }else { +const struct ieee80211_sta_he_cap *he_cap;struct ieee80211_supported_band *sband; sband = phy->hw->wiphy->bands[band]; - capa =ieee80211_get_he_6ghz_capa (sband, vif->type); - he_6ghz_capa = (struct ieee80211_he_6ghz_capa *)&capa; + + he_cap = (band ==NL80211_BAND_6GHZ ) ? +ieee80211_get_he_iftype_cap (sband, vif->type) :NULL ; + +if (he_cap) { + capa =ieee80211_get_he_6ghz_capa (sband, vif->type); + he_6ghz_capa = (struct ieee80211_he_6ghz_capa *)&capa; + } eht_cap =ieee80211_get_eht_iftype_cap (sband, vif->type); }
Signature · 1 line
2.43.0
PATCH v2 3/9 wifi: mt76: connac: add NAN connection type
In reply to Sean WangFrom: Sean Wang <[email protected]>
Introduce a dedicated NAN connection type for connac firmware and use it for NAN interface device, BSS and station records.
Add the common NAN MCU command and event IDs used by mt7925.
--- .../net/wireless/mediatek/mt76/mt76_connac_mcu.c | 14 ++++++++++++++ .../net/wireless/mediatek/mt76/mt76_connac_mcu.h | 4 ++++ 2 files changed, 18 insertions(+)
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +14 -0
@@ -422,6 +422,10 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb, basic->conn_type =cpu_to_le32 (CONNECTION_IBSS_ADHOC ); basic->aid =cpu_to_le16 (link_sta->sta->aid);break ; +case NL80211_IFTYPE_NAN : +case NL80211_IFTYPE_NAN_DATA : + basic->conn_type =cpu_to_le32 (CONNECTION_NAN ); +break ;default :WARN_ON (1 );break ;
@@ -1217,6 +1221,11 @@ int mt76_connac_mcu_uni_add_dev(struct mt76_phy *phy,case NL80211_IFTYPE_ADHOC : basic_req.basic.conn_type =cpu_to_le32 (CONNECTION_IBSS_ADHOC );break ; +case NL80211_IFTYPE_NAN : +case NL80211_IFTYPE_NAN_DATA : + basic_req.basic.conn_type =cpu_to_le32 (CONNECTION_NAN ); + basic_req.basic.conn_state = !enable; +break ;default :WARN_ON (1 );break ;
@@ -1625,6 +1634,11 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,case NL80211_IFTYPE_ADHOC : basic_req.basic.conn_type =cpu_to_le32 (CONNECTION_IBSS_ADHOC );break ; +case NL80211_IFTYPE_NAN : +case NL80211_IFTYPE_NAN_DATA : + basic_req.basic.conn_type =cpu_to_le32 (CONNECTION_NAN ); + basic_req.basic.active = enable; +break ;default :WARN_ON (1 );break ;
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h +4 -0
@@ -876,6 +876,7 @@ enum {#define NETWORK_P2P BIT(17)#define NETWORK_IBSS BIT(18)#define NETWORK_WDS BIT(21) +#define NETWORK_NAN BIT(22)#define SCAN_FUNC_RANDOM_MAC BIT(0)#define SCAN_FUNC_RNR_SCAN BIT(3)
@@ -888,6 +889,7 @@ enum {#define CONNECTION_IBSS_ADHOC (STA_TYPE_ADHOC | NETWORK_IBSS)#define CONNECTION_WDS (STA_TYPE_WDS | NETWORK_WDS)#define CONNECTION_INFRA_BC (STA_TYPE_BC | NETWORK_INFRA) +#define CONNECTION_NAN (NETWORK_NAN)#define CONN_STATE_DISCONNECT 0#define CONN_STATE_CONNECT 1
@@ -1074,6 +1076,7 @@ enum {MCU_UNI_EVENT_THERMAL =0x35 ,MCU_UNI_EVENT_RSSI_MONITOR =0x41 ,MCU_UNI_EVENT_NIC_CAPAB =0x43 , +MCU_UNI_EVENT_NAN =0x56 ,MCU_UNI_EVENT_WED_RRO =0x57 ,MCU_UNI_EVENT_PER_STA_INFO =0x6d , MCU_UNI_EVENT_ALL_STA_INFO = 0x6e,
@@ -1313,6 +1316,7 @@ enum {MCU_UNI_CMD_FIXED_RATE_TABLE =0x40 ,MCU_UNI_CMD_RSSI_MONITOR =0x41 ,MCU_UNI_CMD_TESTMODE_CTRL =0x46 , +MCU_UNI_CMD_NAN =0x56 ,MCU_UNI_CMD_RRO =0x57 ,MCU_UNI_CMD_OFFCH_SCAN_CTRL =0x58 , MCU_UNI_CMD_PER_STA_INFO = 0x6d,
Signature · 1 line
2.43.0
PATCH v2 4/9 wifi: mt76: mt7925: add NAN MCU helpers
In reply to Sean WangFrom: Sean Wang <[email protected]>
Add the mt7925 NAN MCU ABI and helpers for enable, disable, configuration updates, availability updates and peer schedule commands.
Upper-layer integration is added by later patches.
--- .../wireless/mediatek/mt76/mt7925/Makefile | 2 +- .../net/wireless/mediatek/mt76/mt7925/nan.c | 920 ++++++++++++++++++ .../net/wireless/mediatek/mt76/mt7925/nan.h | 438 +++++++++ .../net/wireless/mediatek/mt76/mt7925/regd.c | 30 + .../net/wireless/mediatek/mt76/mt7925/regd.h | 3 + drivers/net/wireless/mediatek/mt76/mt792x.h | 38 + 6 files changed, 1430 insertions(+), 1 deletion(-) create mode 100644 drivers/net/wireless/mediatek/mt76/mt7925/nan.c create mode 100644 drivers/net/wireless/mediatek/mt76/mt7925/nan.h
drivers/net/wireless/mediatek/mt76/mt7925/Makefile +1 -1
@@ -4,7 +4,7 @@ obj-$(CONFIG_MT7925_COMMON) += mt7925-common.o obj-$(CONFIG_MT7925E) += mt7925e.o obj-$(CONFIG_MT7925U) += mt7925u.o -mt7925-common-y := mac.o mcu.o regd.o main.o init.o debugfs.o +mt7925-common-y := mac.o mcu.o regd.o main.o init.o debugfs.o nan.o mt7925-common-$(CONFIG_NL80211_TESTMODE) += testmode.o mt7925e-y := pci.o pci_mac.o pci_mcu.o mt7925u-y := usb.o
drivers/net/wireless/mediatek/mt76/mt7925/nan.c new file +920 -0
920 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7925/nan.h new file +438 -0
438 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7925/regd.c +30 -0
@@ -217,6 +217,36 @@ mt7925_regd_is_valid_alpha2(const char *alpha2)return false; } +bool +mt7925_regd_is_valid_channel (struct mt792x_dev *dev, +enum nl80211_band band, +struct ieee80211_channel *chan) +{ +struct ieee80211_hw *hw =mt76_hw (dev); +struct wiphy *wiphy = hw->wiphy; +struct ieee80211_supported_band *sband; +struct ieee80211_channel *ch; +int i; + +if (!chan) +return false; + + sband = wiphy->bands[band]; +if (!sband) +return false; + +for (i =0 ; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + +if (ch->hw_value == chan->hw_value && + ((ch->flags &IEEE80211_CHAN_DISABLED ) ==0 )) +return true; + } + +return false; +} +EXPORT_SYMBOL_GPL (mt7925_regd_is_valid_channel); +int mt7925_regd_change (struct mt792x_phy *phy,char *alpha2) {struct wiphy *wiphy = phy->mt76->hw->wiphy;
drivers/net/wireless/mediatek/mt76/mt7925/regd.h +3 -0
@@ -13,6 +13,9 @@ void mt7925_regd_be_ctrl(struct mt792x_dev *dev, u8 *alpha2);void mt7925_regd_notifier (struct wiphy *wiphy,struct regulatory_request *req);bool mt7925_regd_clc_supported (struct mt792x_dev *dev);int mt7925_regd_change (struct mt792x_phy *phy,char *alpha2); +bool mt7925_regd_is_valid_channel (struct mt792x_dev *dev, +enum nl80211_band band, +struct ieee80211_channel *chan);int mt7925_regd_init (struct mt792x_phy *phy);#endif
drivers/net/wireless/mediatek/mt76/mt792x.h +38 -0
@@ -115,6 +115,18 @@ struct mt792x_link_sta {struct ieee80211_link_sta *pri_link; }; +struct mt792x_sta_nan_sched { +u16 committed_dw; +u32 sch_idx; +bool idx_assigned; +unsigned long ndp_ctx_bitmap; +u8 ndp_ctx_id;/* assigned NDP context ID (for NDI sta) */ +struct { +u8 map_id; +struct cfg80211_chan_def chans[CFG80211_NAN_SCHED_NUM_TIME_SLOTS ]; + } maps[CFG80211_NAN_MAX_PEER_MAPS ]; +}; +struct mt792x_sta {struct mt792x_link_sta deflink;/* must be first */ struct mt792x_link_sta __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS ];
@@ -123,6 +135,9 @@ struct mt792x_sta {u16 valid_links;u8 deflink_id; + +/* NAN peer schedule */ +struct mt792x_sta_nan_sched nan_sched; };DECLARE_EWMA (rssi,10 ,8 );
@@ -139,6 +154,25 @@ struct mt792x_bss_conf {unsigned int link_id; }; +struct mt792x_nan_conf { +u8 master_pref; +u8 bands; +u8 cluster_id[ETH_ALEN ]; +u32 discovery_beacon_interval; +bool enable_dw_notification; +}; + +struct mt792x_nan { +struct mt792x_nan_conf conf; + +/* Scheduler */ +struct cfg80211_chan_def local_sched[CFG80211_NAN_SCHED_NUM_TIME_SLOTS ]; +u32 seq_id; + +/* Connection index bitmap, up to NAN_MAX_CONN_CFG peers */ +unsigned long conn_bitmap; +}; +struct mt792x_vif {struct mt792x_bss_conf bss_conf;/* must be first */ struct mt792x_bss_conf __rcu *link_conf[IEEE80211_MLD_MAX_NUM_LINKS ];
@@ -153,6 +187,8 @@ struct mt792x_vif {struct work_struct csa_work;struct timer_list csa_timer; + +struct mt792x_nan nan; };struct mt792x_phy {
@@ -283,6 +319,8 @@ struct mt792x_dev {u32 backup_l2;struct ieee80211_chanctx_conf *new_ctx; + +struct ieee80211_vif *nan_vif; }; static inline struct mt792x_bss_conf *
Signature · 1 line
2.43.0
PATCH v2 5/9 wifi: mt76: mt7925: add NAN MCU handling
In reply to Sean WangFrom: Sean Wang <[email protected]>
Route NAN MCU responses and unsolicited events through the mt7925 MCU path, and handle NAN-specific BSS and station TLVs.
--- .../net/wireless/mediatek/mt76/mt7925/mcu.c | 99 ++++++++++++++++--- 1 file changed, 84 insertions(+), 15 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c +84 -15
@@ -7,10 +7,17 @@#include "regd.h" #include "mcu.h" #include "mac.h" +#include "nan.h" #define MT_STA_BFER BIT(0)#define MT_STA_BFEE BIT(1) +static bool mt7925_vif_is_nan (struct ieee80211_vif *vif) +{ +return vif->type ==NL80211_IFTYPE_NAN || + vif->type ==NL80211_IFTYPE_NAN_DATA ; +} +int mt7925_mcu_parse_response (struct mt76_dev *mdev,int cmd,struct sk_buff *skb,int seq) {
@@ -37,7 +44,8 @@ int mt7925_mcu_parse_response(struct mt76_dev *mdev, int cmd, cmd == MCU_UNI_CMD(BSS_INFO_UPDATE) || cmd == MCU_UNI_CMD(STA_REC_UPDATE) || cmd == MCU_UNI_CMD(OFFLOAD) || - cmd == MCU_UNI_CMD(SUSPEND)) { + cmd == MCU_UNI_CMD(SUSPEND) || + cmd == MCU_UNI_CMD(NAN)) {struct mt7925_mcu_uni_event *event;skb_pull (skb,sizeof (*rxd));
@@ -631,6 +639,9 @@ mt7925_mcu_uni_rx_unsolicited_event(struct mt792x_dev *dev, dev->fw_assert = true;mt76_connac_mcu_coredump_event (&dev->mt76, skb, &dev->coredump);return ; +case MCU_UNI_EVENT_NAN : +mt7925_nan_mcu_event (dev, skb); +break ;default :break ; }
@@ -1835,9 +1846,20 @@ mt7925_mcu_sta_phy_tlv(struct sk_buff *skb, tlv =mt76_connac_mcu_add_tlv (skb,STA_REC_PHY ,sizeof (*phy)); phy = (struct sta_rec_phy *)tlv; - phy->phy_type =mt76_connac_get_phy_mode_v2 (mvif->phy->mt76, vif, - chandef->chan->band, - link_sta); + +if (mt7925_vif_is_nan (vif)) { +enum nl80211_band band = chandef->chan ? chandef->chan->band + :NL80211_BAND_2GHZ ; + phy->phy_type =PHY_TYPE_BIT_OFDM |PHY_TYPE_BIT_ERP ; + phy->phy_type |=mt76_connac_get_phy_mode_v2 (mvif->phy->mt76, vif, + band, + link_sta); + }else { + phy->phy_type =mt76_connac_get_phy_mode_v2 (mvif->phy->mt76, vif, + chandef->chan->band, + link_sta); + } + phy->basic_rate =cpu_to_le16 ((u16 )link_conf->basic_rates);if (link_sta->ht_cap.ht_supported) { af = link_sta->ht_cap.ampdu_factor;
@@ -1910,11 +1932,15 @@ mt7925_mcu_sta_rate_ctrl_tlv(struct sk_buff *skb, mconf =mt792x_vif_to_link (mvif, link_sta->link_id); chandef = mconf->mt76.ctx ? &mconf->mt76.ctx->def : &link_conf->chanreq.oper; - band = chandef->chan->band; tlv =mt76_connac_mcu_add_tlv (skb,STA_REC_RA ,sizeof (*ra_info)); ra_info = (struct sta_rec_ra_info *)tlv; +if (mt7925_vif_is_nan (vif)) + band = chandef->chan ? chandef->chan->band :NL80211_BAND_2GHZ ; +else + band = chandef->chan->band; + supp_rates = link_sta->supp_rates[band];if (band ==NL80211_BAND_2GHZ ) supp_rates = FIELD_PREP(RA_LEGACY_OFDM, supp_rates >> 4) |
@@ -2561,6 +2587,29 @@ mt7925_get_phy_mode_ext(struct mt76_phy *phy, struct ieee80211_vif *vif,return mode; } +static void +mt7925_mcu_bss_basic_tlv_nan (struct mt76_phy *phy, +struct ieee80211_vif *vif, +struct ieee80211_link_sta *link_sta, +struct mt76_connac_bss_basic_tlv *basic_req) +{ +u8 mode_2g, mode_5g; + + mode_2g =mt7925_get_phy_mode_ext (phy, vif,NL80211_BAND_2GHZ , + link_sta); + mode_5g =mt7925_get_phy_mode_ext (phy, vif,NL80211_BAND_5GHZ , + link_sta); + basic_req->phymode_ext = mode_2g | mode_5g; + + basic_req->nonht_basic_phy =cpu_to_le16 (PHY_TYPE_ERP_INDEX ); + + mode_2g =mt76_connac_get_phy_mode (phy, vif,NL80211_BAND_2GHZ , + link_sta); + mode_5g =mt76_connac_get_phy_mode (phy, vif,NL80211_BAND_5GHZ , + link_sta); + basic_req->phymode = (mode_2g | mode_5g) & ~PHY_MODE_B ; +} + static void mt7925_mcu_bss_basic_tlv(struct sk_buff *skb, struct ieee80211_bss_conf *link_conf,
@@ -2575,7 +2624,7 @@ mt7925_mcu_bss_basic_tlv(struct sk_buff *skb,struct mt792x_bss_conf *mconf =mt792x_link_conf_to_mconf (link_conf);struct cfg80211_chan_def *chandef = ctx ? &ctx->def : &link_conf->chanreq.oper; -enum nl80211_band band = chandef->chan->band; +enum nl80211_band band =NL80211_BAND_2GHZ ;struct mt76_connac_bss_basic_tlv *basic_req;struct tlv *tlv;int conn_type;
@@ -2588,16 +2637,25 @@ mt7925_mcu_bss_basic_tlv(struct sk_buff *skb, mconf->mt76.omac_idx; basic_req->hw_bss_idx = idx; - basic_req->phymode_ext =mt7925_get_phy_mode_ext (phy, vif, band, - link_sta); +if (mt7925_vif_is_nan (vif)) { +mt7925_mcu_bss_basic_tlv_nan (phy, vif, link_sta, basic_req); + }else { + band = chandef->chan->band; + basic_req->phymode_ext =mt7925_get_phy_mode_ext (phy, vif, band, + link_sta); -if (band ==NL80211_BAND_2GHZ ) - basic_req->nonht_basic_phy =cpu_to_le16 (PHY_TYPE_ERP_INDEX ); -else - basic_req->nonht_basic_phy =cpu_to_le16 (PHY_TYPE_OFDM_INDEX ); +if (band ==NL80211_BAND_2GHZ ) + basic_req->nonht_basic_phy = +cpu_to_le16 (PHY_TYPE_ERP_INDEX ); +else + basic_req->nonht_basic_phy = +cpu_to_le16 (PHY_TYPE_OFDM_INDEX ); + +memcpy (basic_req->bssid, link_conf->bssid,ETH_ALEN ); + basic_req->phymode =mt76_connac_get_phy_mode (phy, vif, band, + link_sta); + } -memcpy (basic_req->bssid, link_conf->bssid,ETH_ALEN ); - basic_req->phymode =mt76_connac_get_phy_mode (phy, vif, band, link_sta); basic_req->bcn_interval =cpu_to_le16 (link_conf->beacon_int); basic_req->dtim_period = link_conf->dtim_period; basic_req->bmc_tx_wlan_idx =cpu_to_le16 (bmc_tx_wlan_idx);
@@ -2630,6 +2688,11 @@ mt7925_mcu_bss_basic_tlv(struct sk_buff *skb, basic_req->conn_type =cpu_to_le32 (CONNECTION_IBSS_ADHOC ); basic_req->active = true;break ; +case NL80211_IFTYPE_NAN : +case NL80211_IFTYPE_NAN_DATA : + basic_req->conn_type =cpu_to_le32 (CONNECTION_NAN ); + basic_req->active = enable; +break ;default :WARN_ON (1 );break ;
@@ -2688,10 +2751,11 @@ mt7925_mcu_bss_bmc_tlv(struct sk_buff *skb, struct mt792x_phy *phy,struct ieee80211_chanctx_conf *ctx, struct ieee80211_bss_conf *link_conf) { + struct ieee80211_vif *vif = link_conf->vif;struct cfg80211_chan_def *chandef = ctx ? &ctx->def : &link_conf->chanreq.oper;struct mt792x_bss_conf *mconf =mt792x_link_conf_to_mconf (link_conf); -enum nl80211_band band = chandef->chan->band; +enum nl80211_band band =NL80211_BAND_2GHZ ;struct mt76_vif_link *mvif = &mconf->mt76;struct bss_rate_tlv *bmc;struct tlv *tlv;
@@ -2702,6 +2766,11 @@ mt7925_mcu_bss_bmc_tlv(struct sk_buff *skb, struct mt792x_phy *phy, bmc = (struct bss_rate_tlv *)tlv; +if (mt7925_vif_is_nan (vif)) + band = chandef->chan ? chandef->chan->band :NL80211_BAND_2GHZ ; +else + band = chandef->chan->band; +if (band ==NL80211_BAND_2GHZ ) bmc->basic_rate =cpu_to_le16 (HR_DSSS_ERP_BASIC_RATE );else
Signature · 1 line
2.43.0
PATCH v2 6/9 wifi: mt76: add init_wiphy callback
In reply to Sean WangFrom: Sean Wang <[email protected]>
Add an optional callback for drivers to finalize wiphy state after mt76 has initialized the supported bands and before registration.
--- drivers/net/wireless/mediatek/mt76/mac80211.c | 7 +++++++ drivers/net/wireless/mediatek/mt76/mt76.h | 3 +++ 2 files changed, 10 insertions(+)
drivers/net/wireless/mediatek/mt76/mac80211.c +7 -0
@@ -681,6 +681,7 @@ mt76_alloc_device(struct device *pdev, unsigned int size, dev = hw->priv; dev->hw = hw; dev->dev = pdev; + dev->init_wiphy =NULL ; dev->drv = drv_ops; dev->dma_dev = pdev;
@@ -779,6 +780,12 @@ int mt76_register_device(struct mt76_dev *dev, bool vht,mt76_check_sband (&dev->phy, &phy->sband_5g,NL80211_BAND_5GHZ );mt76_check_sband (&dev->phy, &phy->sband_6g,NL80211_BAND_6GHZ ); +if (dev->init_wiphy) { + ret = dev->init_wiphy (dev); +if (ret) +return ret; + } +if (IS_ENABLED (CONFIG_MT76_LEDS )) { ret =mt76_led_init (phy);if (ret)
drivers/net/wireless/mediatek/mt76/mt76.h +3 -0
@@ -940,6 +940,9 @@ struct mt76_dev {const struct mt76_bus_ops *bus;const struct mt76_driver_ops *drv;const struct mt76_mcu_ops *mcu_ops; + +/* Optional callback to finalize wiphy state before registration. */ +int (*init_wiphy)(struct mt76_dev *dev);struct device *dev;struct device *dma_dev;
Signature · 1 line
2.43.0
PATCH v2 7/9 wifi: mt76: mt7925: wire up NAN operations
In reply to Sean WangFrom: Sean Wang <[email protected]>
Wire mac80211 NAN start, stop and change_conf callbacks to the mt7925 NAN MCU helpers. Track the active NAN vif and notify mac80211 on cluster join events.
Initialize NAN PHY capabilities after the supported bands are ready.
--- .../net/wireless/mediatek/mt76/mt7925/init.c | 29 +++ .../net/wireless/mediatek/mt76/mt7925/main.c | 201 ++++++++++++++- .../net/wireless/mediatek/mt76/mt7925/nan.c | 239 +++++++++++++++--- .../net/wireless/mediatek/mt76/mt7925/nan.h | 2 + drivers/net/wireless/mediatek/mt76/mt792x.h | 3 + 5 files changed, 430 insertions(+), 44 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7925/init.c +29 -0
@@ -152,6 +152,33 @@ static int mt7925_init_hardware(struct mt792x_dev *dev)return 0 ; } +static int mt7925_init_nan_cap (struct mt76_dev *mdev) +{ + struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76); +const struct ieee80211_sta_he_cap *he_cap; +struct ieee80211_supported_band *sband; +struct wiphy *wiphy = mdev->hw->wiphy; + +if (!(dev->fw_features & MT792x_FW_CAP_NAN)) +return 0 ; + + sband = wiphy->bands[NL80211_BAND_2GHZ ]; +if (sband) + wiphy->nan_capa.phy.ht = sband->ht_cap; + + sband = wiphy->bands[NL80211_BAND_5GHZ ]; +if (sband) + wiphy->nan_capa.phy.vht = sband->vht_cap; + + sband = wiphy->bands[NL80211_BAND_2GHZ ]; + he_cap = sband ?ieee80211_get_he_iftype_cap (sband,NL80211_IFTYPE_NAN ) + :NULL ; +if (he_cap) + wiphy->nan_capa.phy.he = *he_cap; + +return 0 ; +} +static void mt7925_init_work (struct work_struct *work) { struct mt792x_dev *dev = container_of(work, struct mt792x_dev,
@@ -172,6 +199,8 @@ static void mt7925_init_work(struct work_struct *work)return ; } + dev->mt76.init_wiphy = mt7925_init_nan_cap; + ret =mt76_register_device (&dev->mt76, true, mt76_rates,ARRAY_SIZE (mt76_rates));if (ret) {
drivers/net/wireless/mediatek/mt76/mt7925/main.c +191 -10
265 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7925/nan.c +205 -34
435 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7925/nan.h +2 -0
@@ -422,6 +422,8 @@ int mt7925_nan_change_configure(struct ieee80211_vif *vif,void mt7925_nan_mcu_event (struct mt792x_dev *dev,struct sk_buff *skb); +int mt7925_nan_set_nmi_addr (struct mt792x_dev *dev,const u8 *addr); +void mt7925_nan_local_sched_changed (struct mt792x_dev *dev,struct ieee80211_vif *vif);
drivers/net/wireless/mediatek/mt76/mt792x.h +3 -0
@@ -23,6 +23,7 @@#define MT792x_CFEND_RATE_11B 0x03/* 11B LP, 11M */ #define MT792x_FW_TAG_FEATURE 4 +#define MT792x_FW_CAP_NAN BIT(5)#define MT792x_FW_CAP_CNM BIT(7)#define MT792x_CHIP_CAP_CLC_EVT_EN BIT(0)
@@ -116,10 +117,12 @@ struct mt792x_link_sta { };struct mt792x_sta_nan_sched { +/* protects NAN peer schedule state */ u16 committed_dw;u32 sch_idx;bool idx_assigned;unsigned long ndp_ctx_bitmap; +bool ndp_ctx_assigned;u8 ndp_ctx_id;/* assigned NDP context ID (for NDI sta) */ struct {u8 map_id;
Signature · 1 line
2.43.0
PATCH v2 8/9 wifi: mt76: mt792x: build iface combinations dynamically
In reply to Sean WangFrom: Sean Wang <[email protected]>
Move mt792x interface combination selection into a helper and store the selected table in mt792x device state.
This keeps the existing non-CNM and CNM combinations unchanged while making later firmware-gated extensions add combinations without touching the common wiphy setup path.
--- drivers/net/wireless/mediatek/mt76/mt792x.h | 2 ++ .../net/wireless/mediatek/mt76/mt792x_core.c | 36 ++++++++++++++----- 2 files changed, 30 insertions(+), 8 deletions(-)
drivers/net/wireless/mediatek/mt76/mt792x.h +2 -0
@@ -324,6 +324,8 @@ struct mt792x_dev {struct ieee80211_chanctx_conf *new_ctx;struct ieee80211_vif *nan_vif; +const struct ieee80211_iface_combination *iface_combinations; +int n_iface_combinations; }; static inline struct mt792x_bss_conf *
drivers/net/wireless/mediatek/mt76/mt792x_core.c +28 -8
@@ -60,7 +60,7 @@ static const struct ieee80211_iface_limit if_limits_chanctx_scc[] = { } }; -static const struct ieee80211_iface_combination if_comb_chanctx[] = { +static const struct ieee80211_iface_combination if_comb_chanctx_base[] = { { .limits = if_limits_chanctx_mcc, .n_limits =ARRAY_SIZE (if_limits_chanctx_mcc),
@@ -77,6 +77,22 @@ static const struct ieee80211_iface_combination if_comb_chanctx[] = { } }; +static int mt792x_setup_iface_combinations (struct mt792x_dev *dev) +{ +const bool cnm = !!(dev->fw_features & MT792x_FW_CAP_CNM); + +if (!cnm) { + dev->iface_combinations = if_comb; + dev->n_iface_combinations =ARRAY_SIZE (if_comb); +return 0 ; + } + + dev->iface_combinations = if_comb_chanctx_base; + dev->n_iface_combinations =ARRAY_SIZE (if_comb_chanctx_base); + +return 0 ; +} +void mt792x_tx (struct ieee80211_hw *hw,struct ieee80211_tx_control *control,struct sk_buff *skb) {
@@ -663,6 +679,7 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw)struct mt792x_phy *phy =mt792x_hw_phy (hw);struct mt792x_dev *dev = phy->dev;struct wiphy *wiphy = hw->wiphy; +int err; hw->queues =4 ;if (dev->has_eht) {
@@ -683,15 +700,17 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw) hw->vif_data_size =sizeof (struct mt792x_vif ); hw->chanctx_data_size =sizeof (struct mt792x_chanctx ); -if (dev->fw_features & MT792x_FW_CAP_CNM) { +if (dev->fw_features & MT792x_FW_CAP_CNM) wiphy->flags |=WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL ; - wiphy->iface_combinations = if_comb_chanctx; - wiphy->n_iface_combinations =ARRAY_SIZE (if_comb_chanctx); - }else { +else wiphy->flags &= ~WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL ; - wiphy->iface_combinations = if_comb; - wiphy->n_iface_combinations =ARRAY_SIZE (if_comb); - } + + err =mt792x_setup_iface_combinations (dev); +if (err) +return err; + + wiphy->iface_combinations = dev->iface_combinations; + wiphy->n_iface_combinations = dev->n_iface_combinations; wiphy->flags &= ~(WIPHY_FLAG_IBSS_RSN |WIPHY_FLAG_4ADDR_AP |WIPHY_FLAG_4ADDR_STATION ); wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
@@ -699,6 +718,7 @@ int mt792x_init_wiphy(struct ieee80211_hw *hw)BIT (NL80211_IFTYPE_P2P_CLIENT ) |BIT (NL80211_IFTYPE_P2P_GO ) |BIT (NL80211_IFTYPE_P2P_DEVICE ); + wiphy->max_scan_ie_len =MT76_CONNAC_SCAN_IE_LEN ; wiphy->max_scan_ssids =4 ; wiphy->max_sched_scan_plan_interval =
Signature · 1 line
2.43.0
PATCH v2 9/9 wifi: mt76: mt792x: advertise NAN data support
In reply to Sean WangFrom: Sean Wang <[email protected]>
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.
--- .../net/wireless/mediatek/mt76/mt792x_core.c | 96 ++++++++++++++++++- 1 file changed, 92 insertions(+), 4 deletions(-)
drivers/net/wireless/mediatek/mt76/mt792x_core.c +92 -4
@@ -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 =
Signature · 1 line
2.43.0